Author: christian.heimes
Date: Sun Nov  4 13:32:02 2007
New Revision: 58839

Modified:
   python/branches/py3k-pep3137/   (props changed)
   python/branches/py3k-pep3137/Doc/reference/datamodel.rst
   python/branches/py3k-pep3137/Include/unicodeobject.h
   python/branches/py3k-pep3137/Lib/test/test_bytes.py
   python/branches/py3k-pep3137/Lib/test/test_import.py
   python/branches/py3k-pep3137/Objects/bytesobject.c
   python/branches/py3k-pep3137/Objects/unicodeobject.c
   python/branches/py3k-pep3137/Python/import.c
   python/branches/py3k-pep3137/Python/sysmodule.c
Log:
Merged revisions 58818-58838 via svnmerge from 
svn+ssh://[EMAIL PROTECTED]/python/branches/py3k

........
  r58819 | guido.van.rossum | 2007-11-03 01:24:24 +0100 (Sat, 03 Nov 2007) | 4 
lines
  
  Patch 1171 by mfenniak -- allow subclassing of bytes.
  I suspect this has some problems when the subclass is evil,
  but that's for later.
........
  r58824 | georg.brandl | 2007-11-03 09:44:43 +0100 (Sat, 03 Nov 2007) | 2 lines
  
  Re-add two paragraphs that seem to have been lost during the merge from trunk.
........
  r58836 | christian.heimes | 2007-11-04 12:37:22 +0100 (Sun, 04 Nov 2007) | 2 
lines
  
  Disabled test_sys_path_with_unicode for now
  Fixed encoding of author name in tarfile.py.
........
  r58837 | christian.heimes | 2007-11-04 12:43:14 +0100 (Sun, 04 Nov 2007) | 3 
lines
  
  Fixed a bug in PyUnicode_DecodeFSDefault. strcmp() returns 0 on success.
  Added PyUnicode_DecodeFSDefaultAndSize
  Fixed a problem with the sys.path code that caused a segfault on Windows when 
the path contains non ASCII chars. The code for sys.executable, exec_prefix and 
prefix should be fixed, too.
........
  r58838 | christian.heimes | 2007-11-04 13:10:01 +0100 (Sun, 04 Nov 2007) | 2 
lines
  
  Applied patch #1379 with a minor tweak.
  PyModule_GetName() returns a char* from PyUnicode_AsString but the code in 
import.c was using PyString_FromString on it.
........


Modified: python/branches/py3k-pep3137/Doc/reference/datamodel.rst
==============================================================================
--- python/branches/py3k-pep3137/Doc/reference/datamodel.rst    (original)
+++ python/branches/py3k-pep3137/Doc/reference/datamodel.rst    Sun Nov  4 
13:32:02 2007
@@ -1289,8 +1289,7 @@
    instances are compared by object identity ("address").  See also the
    description of :meth:`__hash__` for some important notes on creating
    :term:`hashable` objects which support custom comparison operations and are
-   usable as dictionary keys. (Note: the restriction that exceptions are not
-   propagated by :meth:`__cmp__` has been removed since Python 1.5.)
+   usable as dictionary keys.
 
 
 .. method:: object.__hash__(self)
@@ -1307,8 +1306,18 @@
    (e.g., using exclusive or) the hash values for the components of the object 
that
    also play a part in comparison of objects.
 
-   :meth:`__hash__` may also return a long integer object; the 32-bit integer 
is
-   then derived from the hash of that object.
+   If a class does not define a :meth:`__cmp__` or :meth:`__eq__` method it
+   should not define a :meth:`__hash__` operation either; if it defines
+   :meth:`__cmp__` or :meth:`__eq__` but not :meth:`__hash__`, its instances
+   will not be usable as dictionary keys.  If a class defines mutable objects
+   and implements a :meth:`__cmp__` or :meth:`__eq__` method, it should not
+   implement :meth:`__hash__`, since the dictionary implementation requires 
that
+   a key's hash value is immutable (if the object's hash value changes, it will
+   be in the wrong hash bucket).
+
+   User-defined classes have :meth:`__cmp__` and :meth:`__hash__` methods
+   by default; with them, all objects compare unequal and ``x.__hash__()``
+   returns ``id(x)``.
 
 
 .. method:: object.__bool__(self)

Modified: python/branches/py3k-pep3137/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k-pep3137/Include/unicodeobject.h        (original)
+++ python/branches/py3k-pep3137/Include/unicodeobject.h        Sun Nov  4 
13:32:02 2007
@@ -155,6 +155,7 @@
 # define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap
 # define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1
 # define PyUnicode_DecodeFSDefault PyUnicodeUCS2_DecodeFSDefault
+# define PyUnicode_DecodeFSDefaultAndSize PyUnicodeUCS2_DecodeFSDefaultAndSize
 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape
 # define PyUnicode_DecodeUTF32 PyUnicodeUCS2_DecodeUTF32
 # define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS2_DecodeUTF32Stateful
@@ -247,6 +248,7 @@
 # define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap
 # define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1
 # define PyUnicode_DecodeFSDefault PyUnicodeUCS4_DecodeFSDefault
+# define PyUnicode_DecodeFSDefaultAndSize PyUnicodeUCS4_DecodeFSDefaultAndSize
 # define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape
 # define PyUnicode_DecodeUTF32 PyUnicodeUCS4_DecodeUTF32
 # define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS4_DecodeUTF32Stateful
@@ -657,6 +659,12 @@
     const char *s               /* encoded string */
     );
 
+PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize(
+    const char *s,               /* encoded string */
+    Py_ssize_t size              /* size */
+    );
+
+
 /* Return a char* holding the UTF-8 encoded value of the
    Unicode object.
 

Modified: python/branches/py3k-pep3137/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k-pep3137/Lib/test/test_bytes.py (original)
+++ python/branches/py3k-pep3137/Lib/test/test_bytes.py Sun Nov  4 13:32:02 2007
@@ -8,6 +8,7 @@
 import os
 import re
 import sys
+import copy
 import pickle
 import tempfile
 import unittest
@@ -804,11 +805,89 @@
         pass
 
 
+class BytesSubclass(bytes):
+    pass
+
+class BytesSubclassTest(unittest.TestCase):
+
+    def test_basic(self):
+        self.assert_(issubclass(BytesSubclass, bytes))
+        self.assert_(isinstance(BytesSubclass(), bytes))
+
+        a, b = b"abcd", b"efgh"
+        _a, _b = BytesSubclass(a), BytesSubclass(b)
+
+        # test comparison operators with subclass instances
+        self.assert_(_a == _a)
+        self.assert_(_a != _b)
+        self.assert_(_a < _b)
+        self.assert_(_a <= _b)
+        self.assert_(_b >= _a)
+        self.assert_(_b > _a)
+        self.assert_(_a is not a)
+
+        # test concat of subclass instances
+        self.assertEqual(a + b, _a + _b)
+        self.assertEqual(a + b, a + _b)
+        self.assertEqual(a + b, _a + b)
+
+        # test repeat
+        self.assert_(a*5 == _a*5)
+
+    def test_join(self):
+        # Make sure join returns a NEW object for single item sequences
+        # involving a subclass.
+        # Make sure that it is of the appropriate type.
+        s1 = BytesSubclass(b"abcd")
+        s2 = b"".join([s1])
+        self.assert_(s1 is not s2)
+        self.assert_(type(s2) is bytes)
+
+        # Test reverse, calling join on subclass
+        s3 = s1.join([b"abcd"])
+        self.assert_(type(s3) is bytes)
+
+    def test_pickle(self):
+        a = BytesSubclass(b"abcd")
+        a.x = 10
+        a.y = BytesSubclass(b"efgh")
+        for proto in range(pickle.HIGHEST_PROTOCOL):
+            b = pickle.loads(pickle.dumps(a, proto))
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+            self.assertEqual(a.x, b.x)
+            self.assertEqual(a.y, b.y)
+            self.assertEqual(type(a), type(b))
+            self.assertEqual(type(a.y), type(b.y))
+
+    def test_copy(self):
+        a = BytesSubclass(b"abcd")
+        a.x = 10
+        a.y = BytesSubclass(b"efgh")
+        for copy_method in (copy.copy, copy.deepcopy):
+            b = copy_method(a)
+            self.assertNotEqual(id(a), id(b))
+            self.assertEqual(a, b)
+            self.assertEqual(a.x, b.x)
+            self.assertEqual(a.y, b.y)
+            self.assertEqual(type(a), type(b))
+            self.assertEqual(type(a.y), type(b.y))
+
+    def test_init_override(self):
+        class subclass(bytes):
+            def __init__(self, newarg=1, *args, **kwargs):
+                bytes.__init__(self, *args, **kwargs)
+        x = subclass(4, source=b"abcd")
+        self.assertEqual(x, b"abcd")
+        x = subclass(newarg=4, source=b"abcd")
+        self.assertEqual(x, b"abcd")
+
+
 def test_main():
     test.test_support.run_unittest(BytesTest)
     test.test_support.run_unittest(BytesAsStringTest)
+    test.test_support.run_unittest(BytesSubclassTest)
     test.test_support.run_unittest(BufferPEP3137Test)
 
 if __name__ == "__main__":
-    ##test_main()
-    unittest.main()
+    test_main()

Modified: python/branches/py3k-pep3137/Lib/test/test_import.py
==============================================================================
--- python/branches/py3k-pep3137/Lib/test/test_import.py        (original)
+++ python/branches/py3k-pep3137/Lib/test/test_import.py        Sun Nov  4 
13:32:02 2007
@@ -171,7 +171,7 @@
         shutil.rmtree(self.path)
         sys.path = self.syspath
 
-    def test_sys_path_with_unicode(self):
+    def XXX_test_sys_path_with_unicode(self):
         for i, subpath in enumerate(self.SAMPLES):
             path = os.path.join(self.path, subpath)
             os.mkdir(path)

Modified: python/branches/py3k-pep3137/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k-pep3137/Objects/bytesobject.c  (original)
+++ python/branches/py3k-pep3137/Objects/bytesobject.c  Sun Nov  4 13:32:02 2007
@@ -2923,13 +2923,21 @@
 static PyObject *
 bytes_reduce(PyBytesObject *self)
 {
-    PyObject *latin1;
+    PyObject *latin1, *dict;
     if (self->ob_bytes)
         latin1 = PyUnicode_DecodeLatin1(self->ob_bytes,
                                         Py_Size(self), NULL);
     else
         latin1 = PyUnicode_FromString("");
-    return Py_BuildValue("(O(Ns))", Py_Type(self), latin1, "latin-1");
+
+    dict = PyObject_GetAttrString((PyObject *)self, "__dict__");
+    if (dict == NULL) {
+        PyErr_Clear();
+        dict = Py_None;
+        Py_INCREF(dict);
+    }
+
+    return Py_BuildValue("(O(Ns)N)", Py_Type(self), latin1, "latin-1", dict);
 }
 
 static PySequenceMethods bytes_as_sequence = {
@@ -3059,8 +3067,7 @@
     PyObject_GenericGetAttr,            /* tp_getattro */
     0,                                  /* tp_setattro */
     &bytes_as_buffer,                   /* tp_as_buffer */
-    /* bytes is 'final' or 'sealed' */
-    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
     bytes_doc,                          /* tp_doc */
     0,                                  /* tp_traverse */
     0,                                  /* tp_clear */

Modified: python/branches/py3k-pep3137/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k-pep3137/Objects/unicodeobject.c        (original)
+++ python/branches/py3k-pep3137/Objects/unicodeobject.c        Sun Nov  4 
13:32:02 2007
@@ -1256,10 +1256,14 @@
 }
 
 PyObject*
-PyUnicode_DecodeFSDefault(const char *s)
-{
+PyUnicode_DecodeFSDefault(const char *s) {
     Py_ssize_t size = (Py_ssize_t)strlen(s);
+    return PyUnicode_DecodeFSDefaultAndSize(s, size);
+}
 
+PyObject*
+PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
+{
     /* During the early bootstrapping process, Py_FileSystemDefaultEncoding
        can be undefined. If it is case, decode using UTF-8. The following 
assumes
        that Py_FileSystemDefaultEncoding is set to a built-in encoding during 
the
@@ -1267,11 +1271,11 @@
     */
     if (Py_FileSystemDefaultEncoding) {
 #if defined(MS_WINDOWS) && defined(HAVE_USABLE_WCHAR_T)
-        if (strcmp(Py_FileSystemDefaultEncoding, "mbcs")) {
+        if (strcmp(Py_FileSystemDefaultEncoding, "mbcs") == 0) {
             return PyUnicode_DecodeMBCS(s, size, "replace");
         }
 #elif defined(__APPLE__)
-        if (strcmp(Py_FileSystemDefaultEncoding, "utf-8")) {
+        if (strcmp(Py_FileSystemDefaultEncoding, "utf-8") == 0) {
             return PyUnicode_DecodeUTF8(s, size, "replace");
         }
 #endif

Modified: python/branches/py3k-pep3137/Python/import.c
==============================================================================
--- python/branches/py3k-pep3137/Python/import.c        (original)
+++ python/branches/py3k-pep3137/Python/import.c        Sun Nov  4 13:32:02 2007
@@ -2385,7 +2385,7 @@
                subname = name;
        else {
                PyObject *parentname, *parent;
-               parentname = PyString_FromStringAndSize(name, (subname-name));
+               parentname = PyUnicode_FromStringAndSize(name, (subname-name));
                if (parentname == NULL) {
                        imp_modules_reloading_clear();
                        return NULL;
@@ -2394,7 +2394,7 @@
                if (parent == NULL) {
                        PyErr_Format(PyExc_ImportError,
                            "reload(): parent %.200s not in sys.modules",
-                           PyString_AS_STRING(parentname));
+                            PyUnicode_AsString(parentname));
                        Py_DECREF(parentname);
                        imp_modules_reloading_clear();
                        return NULL;

Modified: python/branches/py3k-pep3137/Python/sysmodule.c
==============================================================================
--- python/branches/py3k-pep3137/Python/sysmodule.c     (original)
+++ python/branches/py3k-pep3137/Python/sysmodule.c     Sun Nov  4 13:32:02 2007
@@ -1145,7 +1145,7 @@
                p = strchr(path, delim);
                if (p == NULL)
                        p = strchr(path, '\0'); /* End of string */
-               w = PyUnicode_FromStringAndSize(path, (Py_ssize_t) (p - path));
+               w = PyUnicode_DecodeFSDefaultAndSize(path, (Py_ssize_t) (p - 
path));
                if (w == NULL) {
                        Py_DECREF(v);
                        return NULL;
_______________________________________________
Python-3000-checkins mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000-checkins

Reply via email to