1""" 2Comaptibility layer to support both Python 2 and Python 3 runtimes. 3""" 4from __future__ import absolute_import 5 6from future.builtins import int 7from future.utils import with_metaclass, PY3 8 9if PY3: 10 # Python 3 does not have long. Map it to int. 11 long = int 12 13 14class BaseValueInt(type): 15 """ Metaclass for valueint. 16 17 Allows to use valueint in places where long/int is expected. 18 """ 19 20 def __instancecheck__(cls, instance): 21 if cls == valueint: 22 # Special case for Py2 short or long int 23 return isinstance(instance, (int, long)) 24 25 return issubclass(instance.__class__, cls) 26 27 28# The class below inherits form int on Python 3 (see the long = int above). 29# In Python 2 mode it becames children of future's newint. 30class valueint(with_metaclass(BaseValueInt, long)): 31 """ Python 2/3 compatible integer that works with value class. 32 33 The newint from future mostly works but does not implement all 34 operators correctly so it breaks support for value class in Python 2. 35 """ 36 37 def __floordiv__(self, other): 38 """ Fix up // operator. 39 40 newint class tries to construct newint even though the __floordiv__ 41 has returned NotImplemented. It is required to catch the exception 42 and retry with __rfloordiv__. 43 """ 44 try: 45 result = super(valueint, self).__floordiv__(other) 46 except TypeError: 47 return other.__rfloordiv__(self) 48 return result 49 50 # The __rfloordiv__ operator has similar problem as __floordiv__ because it 51 # does not forward to reverse operator. However it is not causing any extra 52 # problems because expressions in form of valueint // value are always 53 # handled by value class which converts second argument to int. 54