[Python-3000-checkins] r55905 - in python/branches/p3yk: Doc/lib/libfuncs.tex Doc/ref/ref3.tex Include/abstract.h Include/longobject.h Lib/test/output/test_class Lib/test/test_class.py Lib/test/test_format.py Misc/NEWS Objects/abstract.c Objects/intobject.c Objects/longobject.c Objects/stringobject.c Objects/typeobject.c Python/bltinmodule.c

georg.brandl python-3000-checkins at python.org
Mon Jun 11 19:02:46 CEST 2007


Author: georg.brandl
Date: Mon Jun 11 19:02:26 2007
New Revision: 55905

Modified:
   python/branches/p3yk/Doc/lib/libfuncs.tex
   python/branches/p3yk/Doc/ref/ref3.tex
   python/branches/p3yk/Include/abstract.h
   python/branches/p3yk/Include/longobject.h
   python/branches/p3yk/Lib/test/output/test_class
   python/branches/p3yk/Lib/test/test_class.py
   python/branches/p3yk/Lib/test/test_format.py
   python/branches/p3yk/Misc/NEWS
   python/branches/p3yk/Objects/abstract.c
   python/branches/p3yk/Objects/intobject.c
   python/branches/p3yk/Objects/longobject.c
   python/branches/p3yk/Objects/stringobject.c
   python/branches/p3yk/Objects/typeobject.c
   python/branches/p3yk/Python/bltinmodule.c
Log:
Remove __oct__ and __hex__ and use __index__ for converting
non-ints before formatting in a base.

Add a bin() builtin.


Modified: python/branches/p3yk/Doc/lib/libfuncs.tex
==============================================================================
--- python/branches/p3yk/Doc/lib/libfuncs.tex	(original)
+++ python/branches/p3yk/Doc/lib/libfuncs.tex	Mon Jun 11 19:02:26 2007
@@ -104,6 +104,14 @@
   \versionadded{2.3}
 \end{funcdesc}
 
+\begin{funcdesc}{bin}{x}
+  Convert an integer number to a binary string.
+  The result is a valid Python expression.  If \var{x} is not a Python
+  \class{int} object, it has to define an \method{__index__} method
+  that returns an integer.
+  \versionadded{3.0}
+\end{funcdesc}
+
 \begin{funcdesc}{bool}{\optional{x}}
   Convert a value to a Boolean, using the standard truth testing
   procedure.  If \var{x} is false or omitted, this returns
@@ -540,8 +548,10 @@
 \end{funcdesc}
 
 \begin{funcdesc}{hex}{x}
-  Convert an integer number (of any size) to a hexadecimal string.
-  The result is a valid Python expression.
+  Convert an integer number to a hexadecimal string.
+  The result is a valid Python expression.  If \var{x} is not a Python
+  \class{int} object, it has to define an \method{__index__} method
+  that returns an integer.
   \versionchanged[Formerly only returned an unsigned literal]{2.4}
 \end{funcdesc}
 
@@ -707,8 +717,10 @@
 \end{funcdesc}
 
 \begin{funcdesc}{oct}{x}
-  Convert an integer number (of any size) to an octal string.  The
-  result is a valid Python expression.
+  Convert an integer number to an octal string.  The
+  result is a valid Python expression.  If \var{x} is not a Python
+  \class{int} object, it has to define an \method{__index__} method
+  that returns an integer.
   \versionchanged[Formerly only returned an unsigned literal]{2.4}
 \end{funcdesc}
 

Modified: python/branches/p3yk/Doc/ref/ref3.tex
==============================================================================
--- python/branches/p3yk/Doc/ref/ref3.tex	(original)
+++ python/branches/p3yk/Doc/ref/ref3.tex	Mon Jun 11 19:02:26 2007
@@ -2033,17 +2033,11 @@
 the appropriate type.
 \end{methoddesc}
 
-\begin{methoddesc}[numeric object]{__oct__}{self}
-\methodline[numeric object]{__hex__}{self}
-Called to implement the built-in functions
-\function{oct()}\bifuncindex{oct} and
-\function{hex()}\bifuncindex{hex}.  Should return a string value.
-\end{methoddesc}
-
 \begin{methoddesc}[numeric object]{__index__}{self}
 Called to implement \function{operator.index()}.  Also called whenever
-Python needs an integer object (such as in slicing).  Must return an
-integer (int or long).
+Python needs an integer object (such as in slicing, or in the built-in
+\function{bin()}, \function{hex()} and \function{oct()} functions).
+Must return an integer (int or long).
 \versionadded{2.5}
 \end{methoddesc}
 

Modified: python/branches/p3yk/Include/abstract.h
==============================================================================
--- python/branches/p3yk/Include/abstract.h	(original)
+++ python/branches/p3yk/Include/abstract.h	Mon Jun 11 19:02:26 2007
@@ -851,6 +851,14 @@
 	 expression: o1 |= o2.
        */
 
+     PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base);
+
+       /*
+	 Returns the integer n converted to a string with a base, with a base
+	 marker of 0b, 0o or 0x prefixed if applicable.
+	 If n is not an int object, it is converted with PyNumber_Index first.
+       */
+
 
 /*  Sequence protocol:*/
 

Modified: python/branches/p3yk/Include/longobject.h
==============================================================================
--- python/branches/p3yk/Include/longobject.h	(original)
+++ python/branches/p3yk/Include/longobject.h	Mon Jun 11 19:02:26 2007
@@ -111,6 +111,11 @@
 	unsigned char* bytes, size_t n,
 	int little_endian, int is_signed);
 
+
+/* _PyLong_Format: Convert the long to a string object with given base,
+   appending a base prefix of 0[box] if base is 2, 8 or 16. */
+PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *aa, int base);
+
 #ifdef __cplusplus
 }
 #endif

Modified: python/branches/p3yk/Lib/test/output/test_class
==============================================================================
--- python/branches/p3yk/Lib/test/output/test_class	(original)
+++ python/branches/p3yk/Lib/test/output/test_class	Mon Jun 11 19:02:26 2007
@@ -46,8 +46,7 @@
 __int__: ()
 __int__: ()
 __float__: ()
-__oct__: ()
-__hex__: ()
+__index__: ()
 __hash__: ()
 __repr__: ()
 __str__: ()

Modified: python/branches/p3yk/Lib/test/test_class.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_class.py	(original)
+++ python/branches/p3yk/Lib/test/test_class.py	Mon Jun 11 19:02:26 2007
@@ -80,18 +80,14 @@
         print("__int__:", args)
         return 1
 
+    def __index__(self, *args):
+        print("__index__:", args)
+        return 1
+
     def __float__(self, *args):
         print("__float__:", args)
         return 1.0
 
-    def __oct__(self, *args):
-        print("__oct__:", args)
-        return '01'
-
-    def __hex__(self, *args):
-        print("__hex__:", args)
-        return '0x1'
-
     def __cmp__(self, *args):
         print("__cmp__:", args)
         return 0
@@ -237,7 +233,6 @@
 int(testme)
 float(testme)
 oct(testme)
-hex(testme)
 
 # And the rest...
 
@@ -287,8 +282,6 @@
     __float__ = __int__
     __str__ = __int__
     __repr__ = __int__
-    __oct__ = __int__
-    __hex__ = __int__
 
 def check_exc(stmt, exception):
     """Raise TestFailed if executing 'stmt' does not raise 'exception'

Modified: python/branches/p3yk/Lib/test/test_format.py
==============================================================================
--- python/branches/p3yk/Lib/test/test_format.py	(original)
+++ python/branches/p3yk/Lib/test/test_format.py	Mon Jun 11 19:02:26 2007
@@ -233,14 +233,6 @@
 test_exc(u'no format', u'1', TypeError,
          "not all arguments converted during string formatting")
 
-class Foobar(int):
-    def __oct__(self):
-        # Returning a non-string should not blow up.
-        return self + 1
-
-test_exc('%o', Foobar(), TypeError,
-         "expected string or Unicode object, int found")
-
 if maxsize == 2**31-1:
     # crashes 2.2.1 and earlier:
     try:

Modified: python/branches/p3yk/Misc/NEWS
==============================================================================
--- python/branches/p3yk/Misc/NEWS	(original)
+++ python/branches/p3yk/Misc/NEWS	Mon Jun 11 19:02:26 2007
@@ -26,6 +26,9 @@
 Core and Builtins
 -----------------
 
+- Removed the __oct__ and __hex__ special methods and added a bin()
+  builtin function.
+
 - PEP 3127: octal literals now start with "0o". Old-style octal literals
   are invalid. There are binary literals with a prefix of "0b".
   This also affects int(x, 0).

Modified: python/branches/p3yk/Objects/abstract.c
==============================================================================
--- python/branches/p3yk/Objects/abstract.c	(original)
+++ python/branches/p3yk/Objects/abstract.c	Mon Jun 11 19:02:26 2007
@@ -971,6 +971,22 @@
 	return PyFloat_FromString(o);
 }
 
+
+PyObject *
+PyNumber_ToBase(PyObject *n, int base)
+{
+	PyObject *res;
+	PyObject *index = PyNumber_Index(n);
+
+	if (!index)
+		return NULL;
+	assert(PyLong_Check(index));
+	res = _PyLong_Format(index, base);
+	Py_DECREF(index);
+	return res;
+}
+
+
 /* Operations on sequences */
 
 int

Modified: python/branches/p3yk/Objects/intobject.c
==============================================================================
--- python/branches/p3yk/Objects/intobject.c	(original)
+++ python/branches/p3yk/Objects/intobject.c	Mon Jun 11 19:02:26 2007
@@ -922,30 +922,6 @@
 }
 
 static PyObject *
-int_oct(PyIntObject *v)
-{
-	char buf[100];
-	long x = v -> ob_ival;
-	if (x < 0)
-		PyOS_snprintf(buf, sizeof(buf), "-0o%lo", -x);
-	else
-		PyOS_snprintf(buf, sizeof(buf), "0o%lo", x);
-	return PyString_FromString(buf);
-}
-
-static PyObject *
-int_hex(PyIntObject *v)
-{
-	char buf[100];
-	long x = v -> ob_ival;
-	if (x < 0)
-		PyOS_snprintf(buf, sizeof(buf), "-0x%lx", -x);
-	else
-		PyOS_snprintf(buf, sizeof(buf), "0x%lx", x);
-	return PyString_FromString(buf);
-}
-
-static PyObject *
 int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 
 static PyObject *
@@ -1072,8 +1048,8 @@
 	(unaryfunc)int_int,	/*nb_int*/
 	(unaryfunc)int_long,	/*nb_long*/
 	(unaryfunc)int_float,	/*nb_float*/
-	(unaryfunc)int_oct,	/*nb_oct*/
-	(unaryfunc)int_hex, 	/*nb_hex*/
+	0,			/*nb_oct*/ /* not in use */
+	0, 			/*nb_hex*/ /* not in use */
 	0,			/*nb_inplace_add*/
 	0,			/*nb_inplace_subtract*/
 	0,			/*nb_inplace_multiply*/

Modified: python/branches/p3yk/Objects/longobject.c
==============================================================================
--- python/branches/p3yk/Objects/longobject.c	(original)
+++ python/branches/p3yk/Objects/longobject.c	Mon Jun 11 19:02:26 2007
@@ -80,7 +80,6 @@
 static PyLongObject *mul1(PyLongObject *, wdigit);
 static PyLongObject *muladd1(PyLongObject *, wdigit, wdigit);
 static PyLongObject *divrem1(PyLongObject *, digit, digit *);
-static PyObject *long_format(PyObject *aa, int base);
 
 #define SIGCHECK(PyTryBlock) \
 	if (--_Py_Ticker < 0) { \
@@ -1384,7 +1383,7 @@
 /* Divide long pin, w/ size digits, by non-zero digit n, storing quotient
    in pout, and returning the remainder.  pin and pout point at the LSD.
    It's OK for pin == pout on entry, which saves oodles of mallocs/frees in
-   long_format, but that should be done with great care since longs are
+   _PyLong_Format, but that should be done with great care since longs are
    immutable. */
 
 static digit
@@ -1426,8 +1425,8 @@
    Return a string object.
    If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. */
 
-static PyObject *
-long_format(PyObject *aa, int base)
+PyObject *
+_PyLong_Format(PyObject *aa, int base)
 {
 	register PyLongObject *a = (PyLongObject *)aa;
 	PyStringObject *str;
@@ -2154,7 +2153,7 @@
 static PyObject *
 long_repr(PyObject *v)
 {
-	return long_format(v, 10);
+	return _PyLong_Format(v, 10);
 }
 
 static int
@@ -3513,18 +3512,6 @@
 }
 
 static PyObject *
-long_oct(PyObject *v)
-{
-	return long_format(v, 8);
-}
-
-static PyObject *
-long_hex(PyObject *v)
-{
-	return long_format(v, 16);
-}
-
-static PyObject *
 long_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
 
 static PyObject *
@@ -3648,8 +3635,8 @@
 			long_int,	/*nb_int*/
 			long_long,	/*nb_long*/
 			long_float,	/*nb_float*/
-			long_oct,	/*nb_oct*/
-			long_hex,	/*nb_hex*/
+			0,		/*nb_oct*/ /* not used */
+			0,		/*nb_hex*/ /* not used */
 	0,				/* nb_inplace_add */
 	0,				/* nb_inplace_subtract */
 	0,				/* nb_inplace_multiply */

Modified: python/branches/p3yk/Objects/stringobject.c
==============================================================================
--- python/branches/p3yk/Objects/stringobject.c	(original)
+++ python/branches/p3yk/Objects/stringobject.c	Mon Jun 11 19:02:26 2007
@@ -4255,12 +4255,12 @@
 		break;
 	case 'o':
 		numnondigits = 2;
-		result = val->ob_type->tp_as_number->nb_oct(val);
+		result = PyNumber_ToBase(val, 8);
 		break;
 	case 'x':
 	case 'X':
 		numnondigits = 2;
-		result = val->ob_type->tp_as_number->nb_hex(val);
+		result = PyNumber_ToBase(val, 16);
 		break;
 	default:
 		assert(!"'type' not in [duoxX]");

Modified: python/branches/p3yk/Objects/typeobject.c
==============================================================================
--- python/branches/p3yk/Objects/typeobject.c	(original)
+++ python/branches/p3yk/Objects/typeobject.c	Mon Jun 11 19:02:26 2007
@@ -3236,8 +3236,6 @@
 		COPYNUM(nb_int);
 		COPYNUM(nb_long);
 		COPYNUM(nb_float);
-		COPYNUM(nb_oct);
-		COPYNUM(nb_hex);
 		COPYNUM(nb_inplace_add);
 		COPYNUM(nb_inplace_subtract);
 		COPYNUM(nb_inplace_multiply);
@@ -4556,8 +4554,6 @@
 SLOT0(slot_nb_int, "__int__")
 SLOT0(slot_nb_long, "__long__")
 SLOT0(slot_nb_float, "__float__")
-SLOT0(slot_nb_oct, "__oct__")
-SLOT0(slot_nb_hex, "__hex__")
 SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O")
 SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O")
 SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O")
@@ -5208,10 +5204,6 @@
 	       "long(x)"),
 	UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc,
 	       "float(x)"),
-	UNSLOT("__oct__", nb_oct, slot_nb_oct, wrap_unaryfunc,
-	       "oct(x)"),
-	UNSLOT("__hex__", nb_hex, slot_nb_hex, wrap_unaryfunc,
-	       "hex(x)"),
 	NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, 
 	       "x[y:z] <==> x[y.__index__():z.__index__()]"),
 	IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add,

Modified: python/branches/p3yk/Python/bltinmodule.c
==============================================================================
--- python/branches/p3yk/Python/bltinmodule.c	(original)
+++ python/branches/p3yk/Python/bltinmodule.c	Mon Jun 11 19:02:26 2007
@@ -247,6 +247,18 @@
 
 
 static PyObject *
+builtin_bin(PyObject *self, PyObject *v)
+{
+	return PyNumber_ToBase(v, 2);
+}
+
+PyDoc_STRVAR(bin_doc,
+"bin(number) -> string\n\
+\n\
+Return the binary representation of an integer or long integer.");
+
+
+static PyObject *
 builtin_filter(PyObject *self, PyObject *args)
 {
 	PyObject *func, *seq, *result, *it, *arg;
@@ -1230,24 +1242,7 @@
 static PyObject *
 builtin_hex(PyObject *self, PyObject *v)
 {
-	PyNumberMethods *nb;
-	PyObject *res;
-
-	if ((nb = v->ob_type->tp_as_number) == NULL ||
-	    nb->nb_hex == NULL) {
-		PyErr_SetString(PyExc_TypeError,
-			   "hex() argument can't be converted to hex");
-		return NULL;
-	}
-	res = (*nb->nb_hex)(v);
-	if (res && !PyString_Check(res)) {
-		PyErr_Format(PyExc_TypeError,
-			     "__hex__ returned non-string (type %.200s)",
-			     res->ob_type->tp_name);
-		Py_DECREF(res);
-		return NULL;
-	}
-	return res;
+	return PyNumber_ToBase(v, 16);
 }
 
 PyDoc_STRVAR(hex_doc,
@@ -1430,24 +1425,7 @@
 static PyObject *
 builtin_oct(PyObject *self, PyObject *v)
 {
-	PyNumberMethods *nb;
-	PyObject *res;
-
-	if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
-	    nb->nb_oct == NULL) {
-		PyErr_SetString(PyExc_TypeError,
-			   "oct() argument can't be converted to oct");
-		return NULL;
-	}
-	res = (*nb->nb_oct)(v);
-	if (res && !PyString_Check(res)) {
-		PyErr_Format(PyExc_TypeError,
-			     "__oct__ returned non-string (type %.200s)",
-			     res->ob_type->tp_name);
-		Py_DECREF(res);
-		return NULL;
-	}
-	return res;
+	return PyNumber_ToBase(v, 8);
 }
 
 PyDoc_STRVAR(oct_doc,
@@ -1949,6 +1927,7 @@
  	{"abs",		builtin_abs,        METH_O, abs_doc},
  	{"all",		builtin_all,        METH_O, all_doc},
  	{"any",		builtin_any,        METH_O, any_doc},
+	{"bin",		builtin_bin,	    METH_O, bin_doc},
  	{"chr",		builtin_chr,        METH_VARARGS, chr_doc},
  	{"cmp",		builtin_cmp,        METH_VARARGS, cmp_doc},
  	{"compile",	(PyCFunction)builtin_compile,    METH_VARARGS | METH_KEYWORDS, compile_doc},


More information about the Python-3000-checkins mailing list