xref: /xnu-8796.141.3/tools/lldbmacros/core/compat.py (revision 1b191cb58250d0705d8a51287127505aa4bc0789)
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