]> granicus.if.org Git - python/commitdiff
Issue #25766: Special method __bytes__() now works in str subclasses.
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 20 Dec 2015 14:36:34 +0000 (16:36 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 20 Dec 2015 14:36:34 +0000 (16:36 +0200)
Lib/test/test_bytes.py
Misc/NEWS
Objects/bytesobject.c

index 8158f783cc50e65cb93024a4c8401d6d3268eac1..caf28fd346e9b8cfaf5eb0c85f83e4618a2f457b 100644 (file)
@@ -779,6 +779,12 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
             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):
index 299ed3c9fcc2b54b6878c35d19d8b5a2aa9abe51..6a496b8c6df8bcaa8047e84f1bf7bbc3da79bb60 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ Release date: tba
 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.
index 8e098494de6d71cf8bf18fb8bb780597685e075b..d8fb96b458611a66a5d65179dd6e08f3cf6809fa 100644 (file)
@@ -3175,11 +3175,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         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);
@@ -3189,10 +3189,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
         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;
     }
 
@@ -3217,6 +3218,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     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()) {