Search code examples
pythonpython-3.xhexmagic-methods

Overriding __hex__ in python 3?


I have the following class:

from __future__ import print_function

class Proxy(object):
    __slots__ = ['_value']

    def __init__(self, obj):
        self._value = obj

    def __hex__(self):
        return hex(self._value)

print(hex(42))
print(hex(Proxy(42)))

in Python 2.7 this prints

(py2.7) c:\hextest> python hextest.py
0x2a
0x2a

but in Py3.8 this raises an exception:

(py3.8) c:\hextest> python hextest.py
0x2a
Traceback (most recent call last):
  File "hextest.py", line 14, in <module>
    print(hex(Proxy(42)))
TypeError: 'Proxy' object cannot be interpreted as an integer

what do I need to implement to make Proxy be interpreted as an integer?


Solution

  • One of the goals of PEP3100 (Miscellaneous Python 3.0 Plans) was to:

    [remove] __oct__, __hex__: use __index__ in oct() and hex() instead.

    To make this work, you need to implement __index__, likely as:

    def __index__(self):
        # or self._value if you know _value is an integer already
        return operator.index(self._value)
    

    You can see the commit that changed this behavior here:

    r55905 | georg.brandl | 2007-06-11 10:02:26 -0700 (Mon, 11 Jun 2007) | 5 lines
    
    Remove __oct__ and __hex__ and use __index__ for converting
    non-ints before formatting in a base.
    
    Add a bin() builtin.