[Python-checkins] cpython (merge 3.5 -> default): Issue #25766: Special method __bytes__() now works in str subclasses.

serhiy.storchaka python-checkins at python.org
Sun Dec 20 11:04:20 EST 2015


https://hg.python.org/cpython/rev/af0b95fb1c19
changeset:   99644:af0b95fb1c19
parent:      99641:72016e8df85a
parent:      99643:1e54adef4064
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Sun Dec 20 16:37:21 2015 +0200
summary:
  Issue #25766: Special method __bytes__() now works in str subclasses.

files:
  Lib/test/test_bytes.py |   6 ++++++
  Misc/NEWS              |   2 ++
  Objects/bytesobject.c  |  18 ++++++++++++------
  3 files changed, 20 insertions(+), 6 deletions(-)


diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -793,6 +793,12 @@
             def __index__(self):
                 return 42
         self.assertEqual(bytes(A()), b'a')
+        # Issue #25766
+        class A(str):
+            def __bytes__(self):
+                return b'abc'
+        self.assertEqual(bytes(A('\u20ac')), b'abc')
+        self.assertEqual(bytes(A('\u20ac'), 'iso8859-15'), b'\xa4')
         # Issue #24731
         class A:
             def __bytes__(self):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #25766: Special method __bytes__() now works in str subclasses.
+
 - Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size.
   This allows sys.getsize() to work correctly with their subclasses with
   __slots__ defined.
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -3320,11 +3320,11 @@
         return PyBytes_FromStringAndSize(NULL, 0);
     }
 
-    if (PyUnicode_Check(x)) {
+    if (encoding != NULL) {
         /* Encode via the codec registry */
-        if (encoding == NULL) {
+        if (!PyUnicode_Check(x)) {
             PyErr_SetString(PyExc_TypeError,
-                            "string argument without an encoding");
+                            "encoding without a string argument");
             return NULL;
         }
         new = PyUnicode_AsEncodedString(x, encoding, errors);
@@ -3334,10 +3334,11 @@
         return new;
     }
 
-    /* If it's not unicode, there can't be encoding or errors */
-    if (encoding != NULL || errors != NULL) {
+    if (errors != NULL) {
         PyErr_SetString(PyExc_TypeError,
-            "encoding or errors without a string argument");
+                        PyUnicode_Check(x) ?
+                        "string argument without an encoding" :
+                        "errors without a string argument");
         return NULL;
     }
 
@@ -3362,6 +3363,11 @@
     else if (PyErr_Occurred())
         return NULL;
 
+    if (PyUnicode_Check(x)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "string argument without an encoding");
+        return NULL;
+    }
     /* Is it an integer? */
     size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
     if (size == -1 && PyErr_Occurred()) {

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list