]> granicus.if.org Git - python/commitdiff
Issue #27007: The fromhex() class methods of bytes and bytearray subclasses
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 1 Jul 2016 14:22:31 +0000 (17:22 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Fri, 1 Jul 2016 14:22:31 +0000 (17:22 +0300)
now return an instance of corresponding subclass.

Lib/test/test_bytes.py
Misc/NEWS
Objects/bytearrayobject.c
Objects/bytesobject.c
Objects/clinic/bytearrayobject.c.h

index 1cedd3a855351ee8e7e4a0ee0cea7a6a77a61a66..9d878caa4471a2ea04023c403979994e7a9f2f8c 100644 (file)
@@ -1589,7 +1589,32 @@ class SubclassTest:
             self.assertEqual(type(a), type(b))
             self.assertEqual(type(a.y), type(b.y))
 
-    test_fromhex = BaseBytesTest.test_fromhex
+    def test_fromhex(self):
+        b = self.type2test.fromhex('1a2B30')
+        self.assertEqual(b, b'\x1a\x2b\x30')
+        self.assertIs(type(b), self.type2test)
+
+        class B1(self.basetype):
+            def __new__(cls, value):
+                me = self.basetype.__new__(cls, value)
+                me.foo = 'bar'
+                return me
+
+        b = B1.fromhex('1a2B30')
+        self.assertEqual(b, b'\x1a\x2b\x30')
+        self.assertIs(type(b), B1)
+        self.assertEqual(b.foo, 'bar')
+
+        class B2(self.basetype):
+            def __init__(me, *args, **kwargs):
+                if self.basetype is not bytes:
+                    self.basetype.__init__(me, *args, **kwargs)
+                me.foo = 'bar'
+
+        b = B2.fromhex('1a2B30')
+        self.assertEqual(b, b'\x1a\x2b\x30')
+        self.assertIs(type(b), B2)
+        self.assertEqual(b.foo, 'bar')
 
 
 class ByteArraySubclass(bytearray):
index d5081f193a06d0d09e08755998d01d2e9627499c..7dc5887dde99f800b4619d08769d89f82247cf24 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -7,6 +7,12 @@ What's New in Python 3.6.0 alpha 3
 
 *Release date: XXXX-XX-XX*
 
+Core and Builtins
+-----------------
+
+- Issue #27007: The fromhex() class methods of bytes and bytearray subclasses
+  now return an instance of corresponding subclass.
+
 Library
 -------
 
index b7dfd6f20f3e9a920c3c9538e68263fc83f0773d..85990e0be44b7b5c27cc231a529230151f43d026 100644 (file)
@@ -1968,7 +1968,6 @@ bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
 @classmethod
 bytearray.fromhex
 
-    cls: self(type="PyObject*")
     string: unicode
     /
 
@@ -1979,10 +1978,15 @@ Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
 [clinic start generated code]*/
 
 static PyObject *
-bytearray_fromhex_impl(PyObject*cls, PyObject *string)
-/*[clinic end generated code: output=df3da60129b3700c input=907bbd2d34d9367a]*/
+bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
+/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
 {
-    return _PyBytes_FromHex(string, 1);
+    PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
+    if (type != &PyByteArray_Type && result != NULL) {
+        Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type,
+                                                       result, NULL));
+    }
+    return result;
 }
 
 PyDoc_STRVAR(hex__doc__,
index 83776aa1135e68bc744059b11fee0d719c48f6e6..8ad27829347e003b703bf45cccd128aed3aae5df 100644 (file)
@@ -2303,7 +2303,12 @@ static PyObject *
 bytes_fromhex_impl(PyTypeObject *type, PyObject *string)
 /*[clinic end generated code: output=0973acc63661bb2e input=bf4d1c361670acd3]*/
 {
-    return _PyBytes_FromHex(string, 0);
+    PyObject *result = _PyBytes_FromHex(string, 0);
+    if (type != &PyBytes_Type && result != NULL) {
+        Py_SETREF(result, PyObject_CallFunctionObjArgs((PyObject *)type,
+                                                       result, NULL));
+    }
+    return result;
 }
 
 PyObject*
index f1ccaf159b66b650f1c855e47d3838af7396e012..e1cf03bbc28318fc6cd88e6b9a984d9d9bb9c4a3 100644 (file)
@@ -636,10 +636,10 @@ PyDoc_STRVAR(bytearray_fromhex__doc__,
     {"fromhex", (PyCFunction)bytearray_fromhex, METH_O|METH_CLASS, bytearray_fromhex__doc__},
 
 static PyObject *
-bytearray_fromhex_impl(PyObject*cls, PyObject *string);
+bytearray_fromhex_impl(PyTypeObject *type, PyObject *string);
 
 static PyObject *
-bytearray_fromhex(PyTypeObject *cls, PyObject *arg)
+bytearray_fromhex(PyTypeObject *type, PyObject *arg)
 {
     PyObject *return_value = NULL;
     PyObject *string;
@@ -647,7 +647,7 @@ bytearray_fromhex(PyTypeObject *cls, PyObject *arg)
     if (!PyArg_Parse(arg, "U:fromhex", &string)) {
         goto exit;
     }
-    return_value = bytearray_fromhex_impl((PyObject*)cls, string);
+    return_value = bytearray_fromhex_impl(type, string);
 
 exit:
     return return_value;
@@ -716,4 +716,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
 {
     return bytearray_sizeof_impl(self);
 }
-/*[clinic end generated code: output=044a6c26a836bcfe input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a32f183ebef159cc input=a9049054013a1b77]*/