[pypy-commit] pypy py3k: refactor hex() and oct().

antocuni noreply at buildbot.pypy.org
Wed Feb 29 12:10:55 CET 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: py3k
Changeset: r53017:4d73687506dd
Date: 2012-02-29 12:10 +0100
http://bitbucket.org/pypy/pypy/changeset/4d73687506dd/

Log:	refactor hex() and oct().

	In py2 they support the special methods __hex__ and __oct__, and
	thus are rendered as regular objspace methods (space.oct and
	space.hex).

	In py3k, __hex__ and __oct__ are gone, so they are just normal
	builtins, which are implemented on top of __format__ for consistency
	with bin() (the alternative would be to implement them on top of the
	rpython hex() and oct()).

	Killing support for hex and oct from the objspace is not trivial,
	e.g. we need to keep them in the method table because the flow
	objspace expects them. I hope not to have broken anything. Any
	review is appreciated :-)

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1528,8 +1528,10 @@
     ('neg',             'neg',       1, ['__neg__']),
     ('nonzero',         'truth',     1, ['__bool__']),
     ('abs' ,            'abs',       1, ['__abs__']),
-    ('hex',             'hex',       1, ['__hex__']),
-    ('oct',             'oct',       1, ['__oct__']),
+    # hex and oct no longer calls special methods in py3k, but we need to keep
+    # them in this table for the flow object space
+    ('hex',             'hex',       1, []),
+    ('oct',             'oct',       1, []),
     ('ord',             'ord',       1, []),
     ('invert',          '~',         1, ['__invert__']),
     ('add',             '+',         2, ['__add__', '__radd__']),
diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -28,7 +28,8 @@
         'dir'           : 'app_inspect.dir',
 
         'bin'           : 'app_operation.bin',
-
+        'oct'           : 'app_operation.oct',
+        'hex'           : 'app_operation.hex',
     }
 
     interpleveldefs = {
@@ -53,8 +54,6 @@
         'pow'           : 'operation.pow',
         'repr'          : 'operation.repr',
         'hash'          : 'operation.hash',
-        'oct'           : 'operation.oct',
-        'hex'           : 'operation.hex',
         'round'         : 'operation.round',
         'cmp'           : 'operation.cmp',
         'divmod'        : 'operation.divmod',
diff --git a/pypy/module/__builtin__/app_operation.py b/pypy/module/__builtin__/app_operation.py
--- a/pypy/module/__builtin__/app_operation.py
+++ b/pypy/module/__builtin__/app_operation.py
@@ -1,5 +1,16 @@
 import operator
 
 def bin(x):
+    """Return the binary representation of an integer."""
     x = operator.index(x)
     return x.__format__("#b")
+
+def oct(x):
+    """Return the octal representation of an integer."""
+    x = operator.index(x)
+    return x.__format__("#o")
+
+def hex(x):
+    """Return the hexadecimal representation of an integer."""
+    x = operator.index(x)
+    return x.__format__("#x")
diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py
--- a/pypy/module/__builtin__/operation.py
+++ b/pypy/module/__builtin__/operation.py
@@ -94,15 +94,6 @@
 two un-equal objects to have the same hash value."""
     return space.hash(w_object)
 
-def oct(space, w_val):
-    """Return the octal representation of an integer."""
-    # XXX does this need to be a space operation?
-    return space.oct(w_val)
-
-def hex(space, w_val):
-    """Return the hexadecimal representation of an integer."""
-    return space.hex(w_val)
-
 def id(space, w_object):
     "Return the identity of an object: id(x) == id(y) if and only if x is y."
     return space.id(w_object)
diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -87,6 +87,28 @@
         assert bin(Foo()) == "0b100"
         raises(TypeError, bin, 0.)
 
+    def test_oct(self):
+        class Foo:
+            def __index__(self):
+                return 4
+        assert oct(0) == "0o0"
+        assert oct(-1) == "-0o1"
+        assert oct(8) == "0o10"
+        assert oct(-8) == "-0o10"
+        assert oct(Foo()) == "0o4"
+        raises(TypeError, oct, 0.)
+
+    def test_hex(self):
+        class Foo:
+            def __index__(self):
+                return 4
+        assert hex(0) == "0x0"
+        assert hex(-1) == "-0x1"
+        assert hex(16) == "0x10"
+        assert hex(-16) == "-0x10"
+        assert hex(Foo()) == "0x4"
+        raises(TypeError, hex, 0.)
+
     def test_chr(self):
         import sys
         assert chr(65) == 'A'
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -718,9 +718,7 @@
 
 for targetname, specialname in [
     ('str', '__str__'),
-    ('repr', '__repr__'),
-    ('oct', '__oct__'),
-    ('hex', '__hex__')]:
+    ('repr', '__repr__')]:
 
     source = """if 1:
         def %(targetname)s(space, w_obj):
diff --git a/pypy/objspace/std/builtinshortcut.py b/pypy/objspace/std/builtinshortcut.py
--- a/pypy/objspace/std/builtinshortcut.py
+++ b/pypy/objspace/std/builtinshortcut.py
@@ -35,7 +35,7 @@
                  'setattr', 'delattr', 'userdel',  # mostly for non-builtins
                  'get', 'set', 'delete',   # uncommon (except on functions)
                  'delitem', 'trunc',              # rare stuff?
-                 'abs', 'hex', 'oct',             # rare stuff?
+                 'abs',                           # rare stuff?
                  'pos', 'divmod', 'cmp',          # rare stuff?
                  'float', 'long',                 # rare stuff?
                  'isinstance', 'issubtype',
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -330,12 +330,6 @@
     x = float(a)
     return space.newfloat(x)
 
-def oct__Int(space, w_int1):
-    return space.wrap(oct(w_int1.intval))
-
-def hex__Int(space, w_int1):
-    return space.wrap(hex(w_int1.intval))
-
 def getnewargs__Int(space, w_int1):
     return space.newtuple([wrapint(space, w_int1.intval)])
 
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -287,12 +287,6 @@
 def or__Long_Long(space, w_long1, w_long2):
     return W_LongObject(w_long1.num.or_(w_long2.num))
 
-def oct__Long(space, w_long1):
-    return space.wrap(w_long1.num.oct())
-
-def hex__Long(space, w_long1):
-    return space.wrap(w_long1.num.hex())
-
 def getnewargs__Long(space, w_long1):
     return space.newtuple([W_LongObject(w_long1.num)])
 
diff --git a/pypy/objspace/std/test/test_intobject.py b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -271,18 +271,6 @@
         result = iobj.int__Int(self.space, f1)
         assert result == f1
 
-    def test_oct(self):
-        x = 012345
-        f1 = iobj.W_IntObject(x)
-        result = iobj.oct__Int(self.space, f1)
-        assert self.space.unwrap(result) == oct(x)
-
-    def test_hex(self):
-        x = 0x12345
-        f1 = iobj.W_IntObject(x)
-        result = iobj.hex__Int(self.space, f1)
-        assert self.space.unwrap(result) == hex(x)
-
 class AppTestInt:
 
     def test_conjugate(self):
diff --git a/pypy/objspace/std/test/test_smallintobject.py b/pypy/objspace/std/test/test_smallintobject.py
--- a/pypy/objspace/std/test/test_smallintobject.py
+++ b/pypy/objspace/std/test/test_smallintobject.py
@@ -213,18 +213,6 @@
         result = self.space.int(f1)
         assert result == f1
 
-    def test_oct(self):
-        x = 012345
-        f1 = wrapint(self.space, x)
-        result = self.space.oct(f1)
-        assert self.space.unwrap(result) == oct(x)
-
-    def test_hex(self):
-        x = 0x12345
-        f1 = wrapint(self.space, x)
-        result = self.space.hex(f1)
-        assert self.space.unwrap(result) == hex(x)
-
 
 class AppTestSmallInt(AppTestInt):
 
diff --git a/pypy/objspace/test/test_descriptor.py b/pypy/objspace/test/test_descriptor.py
--- a/pypy/objspace/test/test_descriptor.py
+++ b/pypy/objspace/test/test_descriptor.py
@@ -97,7 +97,7 @@
         raises(TypeError, repr, inst) 
         raises(TypeError, oct, inst) 
         raises(TypeError, hex, inst) 
-        assert A.seen == [1,2,3,4]
+        assert A.seen == [1,2] # __oct__ and __hex__ are no longer called
 
     def test_hash(self): 
         class A(object):


More information about the pypy-commit mailing list