Issue #25766: Special method __bytes__() now works in str subclasses.

This commit is contained in:
Serhiy Storchaka 2015-12-20 16:36:34 +02:00
parent 5185597a69
commit 5aac3ed799
3 changed files with 20 additions and 6 deletions

View File

@ -779,6 +779,12 @@ class BytesTest(BaseBytesTest, unittest.TestCase):
def __index__(self): def __index__(self):
return 42 return 42
self.assertEqual(bytes(A()), b'a') 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 # Issue #24731
class A: class A:
def __bytes__(self): def __bytes__(self):

View File

@ -10,6 +10,8 @@ Release date: tba
Core and Builtins 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. - Issue #25421: __sizeof__ methods of builtin types now use dynamic basic size.
This allows sys.getsize() to work correctly with their subclasses with This allows sys.getsize() to work correctly with their subclasses with
__slots__ defined. __slots__ defined.

View File

@ -3175,11 +3175,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return PyBytes_FromStringAndSize(NULL, 0); return PyBytes_FromStringAndSize(NULL, 0);
} }
if (PyUnicode_Check(x)) { if (encoding != NULL) {
/* Encode via the codec registry */ /* Encode via the codec registry */
if (encoding == NULL) { if (!PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"string argument without an encoding"); "encoding without a string argument");
return NULL; return NULL;
} }
new = PyUnicode_AsEncodedString(x, encoding, errors); new = PyUnicode_AsEncodedString(x, encoding, errors);
@ -3189,10 +3189,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return new; return new;
} }
/* If it's not unicode, there can't be encoding or errors */ if (errors != NULL) {
if (encoding != NULL || errors != NULL) {
PyErr_SetString(PyExc_TypeError, 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; return NULL;
} }
@ -3217,6 +3218,11 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
else if (PyErr_Occurred()) else if (PyErr_Occurred())
return NULL; return NULL;
if (PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError,
"string argument without an encoding");
return NULL;
}
/* Is it an integer? */ /* Is it an integer? */
size = PyNumber_AsSsize_t(x, PyExc_OverflowError); size = PyNumber_AsSsize_t(x, PyExc_OverflowError);
if (size == -1 && PyErr_Occurred()) { if (size == -1 && PyErr_Occurred()) {