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},
_______________________________________________
Python-3000-checkins mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-3000-checkins

Reply via email to