2

I need a class that would keep all the Python's functionality of int class, but make sure its results are within 32-bit integers, just like in C programming language. The type has to be "poisonous" - performing an operation on int and this type should result in returning this type. As suggested in one of the answers to my other question, I used to use numpy.uint32 for this purpose, but it feels too silly to add such a big dependency just for a single, relatively simple, type. How do I achieve that? Here are my attempts so far:

MODULO = 7  # will be 2**32 later on

class u32:
    def __init__(self, num = 0, base = None):
        print(num)
        if base is None:
            self.int = int(num) % MODULO
        else:
            self.int = int(num, base) % MODULO
    def __coerce__(self, x):
        return None
    def __str__(self):
        return "<u32 instance at 0x%x, int=%d>" % (id(self), self.int)
    def __getattr__(self, x):
        r = getattr(self.int, x)
        if callable(r):
            def f(*args, **kwargs):
                ret = r(*args, **kwargs) % MODULO
                print("x=%s, args=%s, kwargs=%s, ret=%s" % (x, args, kwargs, ret))
                if x not in ['__str__', '__repr__']:
                    return u32(ret)
                return r(*args, **kwargs)
            return f
        return r

u = u32(4)
print("u/2")
a = u * 2
assert(isinstance(a, u32))

print("\n2/u")
a = 2 * u
assert(isinstance(a, u32))

print("\nu+u")
"""
Traceback (most recent call last):
  File "u32.py", line 44, in <module>
    a = u + u
  File "u32.py", line 18, in f
    ret = r(*args, **kwargs) % MODULO
TypeError: unsupported operand type(s) for %: 'NotImplementedType' and 'int'
"""
a = u + u
assert(isinstance(a, u32))
Community
  • 1
  • 1
d33tah
  • 10,999
  • 13
  • 68
  • 158
  • 1
    Is the necessity out of memory storage or compatibility ? – tk. Oct 26 '13 at 19:46
  • Compatibility. I need to be able to copy some formulas from C to Python and they rely on the overflow behavior. – d33tah Oct 26 '13 at 19:48
  • Other than "silliness", why not using `numpy`? Fine work has already been done, for you to enjoy. – shx2 Oct 26 '13 at 19:49
  • I'd rather keep C-compiled code to minimum, so I'd prefer to keep this type in pure Python. Also, I'm interested in how would that look like. – d33tah Oct 26 '13 at 19:50
  • Did you consider using `ctypes` ? – rotoglup Oct 26 '13 at 22:45
  • After my experiences with Cygwin, I decided to avoid ctypes. Also, not sure how it's supported in other Python implementations, like Jython. – d33tah Oct 27 '13 at 13:15

1 Answers1

1

The obviously correct method is going to be to write all the special methods (which can be a pain).

Otherwise, try this for your __getattr__

def __getattr__(self, x):
    r = getattr(self.int, x)
    if callable(r):
        def f(*args, **kwargs):
            if args and isinstance(args[0], u32):
                args = (args[0].int, ) + args[1:]
            ret = r(*args, **kwargs)
            if ret is NotImplemented:
                return ret
            if x in ['__str__', '__repr__', '__cmp__', '__index__']:
                return ret
            ret %= MODULO
            return u32(ret)
        return f
    return r

As Martijn notes, this only works for old-style classes. See his answer for a method that works with new-style classes.

Community
  • 1
  • 1
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237