summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-12-20 14:36:34 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-12-20 14:36:34 (GMT)
commit5aac3ed79999f6948d11f979ab3e42b9b60e9083 (patch)
treeb338eac95f23fe5bdebacc996986d43204621ac7
parent5185597a69f1df8c68ba8d42fe39991124863488 (diff)
downloadcpython-5aac3ed79999f6948d11f979ab3e42b9b60e9083.zip
cpython-5aac3ed79999f6948d11f979ab3e42b9b60e9083.tar.gz
cpython-5aac3ed79999f6948d11f979ab3e42b9b60e9083.tar.bz2
Issue #25766: Special method __bytes__() now works in str subclasses.
-rw-r--r--Lib/test/test_bytes.py6
-rw-r--r--Misc/NEWS2
-rw-r--r--Objects/bytesobject.c18
3 files changed, 20 insertions, 6 deletions
diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py
index 8158f78..caf28fd 100644
--- a/Lib/test/test_bytes.py
+++ b/Lib/test/test_bytes.py
@@ -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):
diff --git a/Misc/NEWS b/Misc/NEWS
index 299ed3c..6a496b8 100644
--- 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.
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 8e09849..d8fb96b 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -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()) {