From e3ae655edfea3dd8ed32fcca63cb3eae861a58b7 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Jun 2008 04:18:15 +0000 Subject: [PATCH] Make bin() implementation parallel oct() and hex() so that int/long subclasses can override or so that other classes can support. --- Include/object.h | 3 +++ Lib/test/test_sys.py | 2 +- Misc/NEWS | 9 +++++++++ Objects/intobject.c | 7 +++++++ Objects/longobject.c | 7 +++++++ Objects/typeobject.c | 4 ++++ Python/bltinmodule.c | 19 ++++++++++++++++++- 7 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Include/object.h b/Include/object.h index 59f3b9e1b10..709174fdf5b 100644 --- a/Include/object.h +++ b/Include/object.h @@ -267,6 +267,9 @@ typedef struct { /* Added in release 2.5 */ unaryfunc nb_index; + + /* Added in release 2.6 */ + unaryfunc nb_bin; } PyNumberMethods; typedef struct { diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index f1fb61549e2..c98117ac5b6 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -523,7 +523,7 @@ class SizeofTest(unittest.TestCase): len_typeobject = p + 2*l + 15*p + l + 4*p + l + 9*p +\ l + 11*p + self.align(4) self.check_sizeof(class_newstyle, - h + len_typeobject + 41*p + 10*p + 3*p + 6*p) + h + len_typeobject + 42*p + 10*p + 3*p + 6*p) def test_specialtypes(self): i = self.i diff --git a/Misc/NEWS b/Misc/NEWS index 9bd4f3cb88e..9e02d763b86 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -4,6 +4,15 @@ Python News (editors: check NEWS.help for information about editing NEWS using ReST.) +What's New in Python 2.6 beta 2? +================================ + +Core and Builtins +----------------- + +- Make bin() implementation parallel oct() and hex(). + + What's New in Python 2.6 beta 1? ================================ diff --git a/Objects/intobject.c b/Objects/intobject.c index f98aee0e2e1..5210ee8db7c 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -933,6 +933,12 @@ int_float(PyIntObject *v) return PyFloat_FromDouble((double)(v -> ob_ival)); } +static PyObject * +int_bin(PyObject *v) +{ + return PyNumber_ToBase(v, 2); +} + static PyObject * int_oct(PyIntObject *v) { @@ -1231,6 +1237,7 @@ static PyNumberMethods int_as_number = { 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ (unaryfunc)int_int, /* nb_index */ + (unaryfunc)int_bin, /* nb_bin */ }; PyTypeObject PyInt_Type = { diff --git a/Objects/longobject.c b/Objects/longobject.c index c65d0c00abe..b603dda269f 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3300,6 +3300,12 @@ long_float(PyObject *v) return PyFloat_FromDouble(result); } +static PyObject * +long_bin(PyObject *v) +{ + return PyNumber_ToBase(v, 2); +} + static PyObject * long_oct(PyObject *v) { @@ -3540,6 +3546,7 @@ static PyNumberMethods long_as_number = { 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ long_long, /* nb_index */ + long_bin, /* nb_bin */ }; PyTypeObject PyLong_Type = { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e0ae55b057c..093fd20a828 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3743,6 +3743,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) if (base->tp_flags & Py_TPFLAGS_HAVE_INDEX) { COPYNUM(nb_index); } + COPYNUM(nb_hex); } if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) { @@ -5135,6 +5136,7 @@ slot_nb_coerce(PyObject **a, PyObject **b) SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") SLOT0(slot_nb_float, "__float__") +SLOT0(slot_nb_bin, "__bin__") SLOT0(slot_nb_oct, "__oct__") SLOT0(slot_nb_hex, "__hex__") SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O") @@ -5802,6 +5804,8 @@ static slotdef slotdefs[] = { "long(x)"), UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, "float(x)"), + UNSLOT("__bin__", nb_bin, slot_nb_bin, wrap_unaryfunc, + "bin(x)"), UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc, "oct(x)"), UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc, diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index e18eb2a95a9..7647523b580 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -211,7 +211,24 @@ Deprecated since release 2.3. Instead, use the extended call syntax:\n\ static PyObject * builtin_bin(PyObject *self, PyObject *v) { - return PyNumber_ToBase(v, 2); + PyNumberMethods *nb; + PyObject *res; + + if ((nb = v->ob_type->tp_as_number) == NULL || + nb->nb_hex == NULL) { + PyErr_SetString(PyExc_TypeError, + "bin() argument can't be converted to hex"); + return NULL; + } + res = (*nb->nb_bin)(v); + if (res && !PyString_Check(res)) { + PyErr_Format(PyExc_TypeError, + "__bin__ returned non-string (type %.200s)", + res->ob_type->tp_name); + Py_DECREF(res); + return NULL; + } + return res; } PyDoc_STRVAR(bin_doc,