1""" 
    2A selection of cross-compatible functions for Python 2 and 3. 
    3 
    4This module exports useful functions for 2/3 compatible code: 
    5 
    6    * bind_method: binds functions to classes 
    7    * ``native_str_to_bytes`` and ``bytes_to_native_str`` 
    8    * ``native_str``: always equal to the native platform string object (because 
    9      this may be shadowed by imports from future.builtins) 
    10    * lists: lrange(), lmap(), lzip(), lfilter() 
    11    * iterable method compatibility: 
    12        - iteritems, iterkeys, itervalues 
    13        - viewitems, viewkeys, viewvalues 
    14 
    15        These use the original method if available, otherwise they use items, 
    16        keys, values. 
    17 
    18    * types: 
    19 
    20        * text_type: unicode in Python 2, str in Python 3 
    21        * string_types: basestring in Python 2, str in Python 3 
    22        * binary_type: str in Python 2, bytes in Python 3 
    23        * integer_types: (int, long) in Python 2, int in Python 3 
    24        * class_types: (type, types.ClassType) in Python 2, type in Python 3 
    25 
    26    * bchr(c): 
    27        Take an integer and make a 1-character byte string 
    28    * bord(c) 
    29        Take the result of indexing on a byte string and make an integer 
    30    * tobytes(s) 
    31        Take a text string, a byte string, or a sequence of characters taken 
    32        from a byte string, and make a byte string. 
    33 
    34    * raise_from() 
    35    * raise_with_traceback() 
    36 
    37This module also defines these decorators: 
    38 
    39    * ``python_2_unicode_compatible`` 
    40    * ``with_metaclass`` 
    41    * ``implements_iterator`` 
    42 
    43Some of the functions in this module come from the following sources: 
    44 
    45    * Jinja2 (BSD licensed: see 
    46      https://github.com/mitsuhiko/jinja2/blob/master/LICENSE) 
    47    * Pandas compatibility module pandas.compat 
    48    * six.py by Benjamin Peterson 
    49    * Django 
    50""" 
    51 
    52import types 
    53import sys 
    54import numbers 
    55import functools 
    56import copy 
    57import inspect 
    58 
    59 
    60PY3 = sys.version_info[0] >= 3 
    61PY34_PLUS = sys.version_info[0:2] >= (3, 4) 
    62PY35_PLUS = sys.version_info[0:2] >= (3, 5) 
    63PY36_PLUS = sys.version_info[0:2] >= (3, 6) 
    64PY37_PLUS = sys.version_info[0:2] >= (3, 7) 
    65PY38_PLUS = sys.version_info[0:2] >= (3, 8) 
    66PY39_PLUS = sys.version_info[0:2] >= (3, 9) 
    67PY2 = sys.version_info[0] == 2 
    68PY26 = sys.version_info[0:2] == (2, 6) 
    69PY27 = sys.version_info[0:2] == (2, 7) 
    70PYPY = hasattr(sys, 'pypy_translation_info') 
    71 
    72 
    73def python_2_unicode_compatible(cls): 
    74    """ 
    75    A decorator that defines __unicode__ and __str__ methods under Python 
    76    2. Under Python 3, this decorator is a no-op. 
    77 
    78    To support Python 2 and 3 with a single code base, define a __str__ 
    79    method returning unicode text and apply this decorator to the class, like 
    80    this:: 
    81 
    82    >>> from future.utils import python_2_unicode_compatible 
    83 
    84    >>> @python_2_unicode_compatible 
    85    ... class MyClass(object): 
    86    ...     def __str__(self): 
    87    ...         return u'Unicode string: \u5b54\u5b50' 
    88 
    89    >>> a = MyClass() 
    90 
    91    Then, after this import: 
    92 
    93    >>> from future.builtins import str 
    94 
    95    the following is ``True`` on both Python 3 and 2:: 
    96 
    97    >>> str(a) == a.encode('utf-8').decode('utf-8') 
    98    True 
    99 
    100    and, on a Unicode-enabled terminal with the right fonts, these both print the 
    101    Chinese characters for Confucius:: 
    102 
    103    >>> print(a) 
    104    >>> print(str(a)) 
    105 
    106    The implementation comes from django.utils.encoding. 
    107    """ 
    108    if not PY3: 
    109        cls.__unicode__ = cls.__str__ 
    110        cls.__str__ = lambda self: self.__unicode__().encode('utf-8') 
    111    return cls 
    112 
    113 
    114def with_metaclass(meta, *bases): 
    115    """ 
    116    Function from jinja2/_compat.py. License: BSD. 
    117 
    118    Use it like this:: 
    119 
    120        class BaseForm(object): 
    121            pass 
    122 
    123        class FormType(type): 
    124            pass 
    125 
    126        class Form(with_metaclass(FormType, BaseForm)): 
    127            pass 
    128 
    129    This requires a bit of explanation: the basic idea is to make a 
    130    dummy metaclass for one level of class instantiation that replaces 
    131    itself with the actual metaclass.  Because of internal type checks 
    132    we also need to make sure that we downgrade the custom metaclass 
    133    for one level to something closer to type (that's why __call__ and 
    134    __init__ comes back from type etc.). 
    135 
    136    This has the advantage over six.with_metaclass of not introducing 
    137    dummy classes into the final MRO. 
    138    """ 
    139    class metaclass(meta): 
    140        __call__ = type.__call__ 
    141        __init__ = type.__init__ 
    142        def __new__(cls, name, this_bases, d): 
    143            if this_bases is None: 
    144                return type.__new__(cls, name, (), d) 
    145            return meta(name, bases, d) 
    146    return metaclass('temporary_class', None, {}) 
    147 
    148 
    149# Definitions from pandas.compat and six.py follow: 
    150if PY3: 
    151    def bchr(s): 
    152        return bytes([s]) 
    153    def bstr(s): 
    154        if isinstance(s, str): 
    155            return bytes(s, 'latin-1') 
    156        else: 
    157            return bytes(s) 
    158    def bord(s): 
    159        return s 
    160 
    161    string_types = str, 
    162    integer_types = int, 
    163    class_types = type, 
    164    text_type = str 
    165    binary_type = bytes 
    166 
    167else: 
    168    # Python 2 
    169    def bchr(s): 
    170        return chr(s) 
    171    def bstr(s): 
    172        return str(s) 
    173    def bord(s): 
    174        return ord(s) 
    175 
    176    string_types = basestring, 
    177    integer_types = (int, long) 
    178    class_types = (type, types.ClassType) 
    179    text_type = unicode 
    180    binary_type = str 
    181 
    182### 
    183 
    184if PY3: 
    185    def tobytes(s): 
    186        if isinstance(s, bytes): 
    187            return s 
    188        else: 
    189            if isinstance(s, str): 
    190                return s.encode('latin-1') 
    191            else: 
    192                return bytes(s) 
    193else: 
    194    # Python 2 
    195    def tobytes(s): 
    196        if isinstance(s, unicode): 
    197            return s.encode('latin-1') 
    198        else: 
    199            return ''.join(s) 
    200 
    201tobytes.__doc__ = """ 
    202    Encodes to latin-1 (where the first 256 chars are the same as 
    203    ASCII.) 
    204    """ 
    205 
    206if PY3: 
    207    def native_str_to_bytes(s, encoding='utf-8'): 
    208        return s.encode(encoding) 
    209 
    210    def bytes_to_native_str(b, encoding='utf-8'): 
    211        return b.decode(encoding) 
    212 
    213    def text_to_native_str(t, encoding=None): 
    214        return t 
    215else: 
    216    # Python 2 
    217    def native_str_to_bytes(s, encoding=None): 
    218        from future.types import newbytes    # to avoid a circular import 
    219        return newbytes(s) 
    220 
    221    def bytes_to_native_str(b, encoding=None): 
    222        return native(b) 
    223 
    224    def text_to_native_str(t, encoding='ascii'): 
    225        """ 
    226        Use this to create a Py2 native string when "from __future__ import 
    227        unicode_literals" is in effect. 
    228        """ 
    229        return unicode(t).encode(encoding) 
    230 
    231native_str_to_bytes.__doc__ = """ 
    232    On Py3, returns an encoded string. 
    233    On Py2, returns a newbytes type, ignoring the ``encoding`` argument. 
    234    """ 
    235 
    236if PY3: 
    237    # list-producing versions of the major Python iterating functions 
    238    def lrange(*args, **kwargs): 
    239        return list(range(*args, **kwargs)) 
    240 
    241    def lzip(*args, **kwargs): 
    242        return list(zip(*args, **kwargs)) 
    243 
    244    def lmap(*args, **kwargs): 
    245        return list(map(*args, **kwargs)) 
    246 
    247    def lfilter(*args, **kwargs): 
    248        return list(filter(*args, **kwargs)) 
    249else: 
    250    import __builtin__ 
    251    # Python 2-builtin ranges produce lists 
    252    lrange = __builtin__.range 
    253    lzip = __builtin__.zip 
    254    lmap = __builtin__.map 
    255    lfilter = __builtin__.filter 
    256 
    257 
    258def isidentifier(s, dotted=False): 
    259    ''' 
    260    A function equivalent to the str.isidentifier method on Py3 
    261    ''' 
    262    if dotted: 
    263        return all(isidentifier(a) for a in s.split('.')) 
    264    if PY3: 
    265        return s.isidentifier() 
    266    else: 
    267        import re 
    268        _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$") 
    269        return bool(_name_re.match(s)) 
    270 
    271 
    272def viewitems(obj, **kwargs): 
    273    """ 
    274    Function for iterating over dictionary items with the same set-like 
    275    behaviour on Py2.7 as on Py3. 
    276 
    277    Passes kwargs to method.""" 
    278    func = getattr(obj, "viewitems", None) 
    279    if not func: 
    280        func = obj.items 
    281    return func(**kwargs) 
    282 
    283 
    284def viewkeys(obj, **kwargs): 
    285    """ 
    286    Function for iterating over dictionary keys with the same set-like 
    287    behaviour on Py2.7 as on Py3. 
    288 
    289    Passes kwargs to method.""" 
    290    func = getattr(obj, "viewkeys", None) 
    291    if not func: 
    292        func = obj.keys 
    293    return func(**kwargs) 
    294 
    295 
    296def viewvalues(obj, **kwargs): 
    297    """ 
    298    Function for iterating over dictionary values with the same set-like 
    299    behaviour on Py2.7 as on Py3. 
    300 
    301    Passes kwargs to method.""" 
    302    func = getattr(obj, "viewvalues", None) 
    303    if not func: 
    304        func = obj.values 
    305    return func(**kwargs) 
    306 
    307 
    308def iteritems(obj, **kwargs): 
    309    """Use this only if compatibility with Python versions before 2.7 is 
    310    required. Otherwise, prefer viewitems(). 
    311    """ 
    312    func = getattr(obj, "iteritems", None) 
    313    if not func: 
    314        func = obj.items 
    315    return func(**kwargs) 
    316 
    317 
    318def iterkeys(obj, **kwargs): 
    319    """Use this only if compatibility with Python versions before 2.7 is 
    320    required. Otherwise, prefer viewkeys(). 
    321    """ 
    322    func = getattr(obj, "iterkeys", None) 
    323    if not func: 
    324        func = obj.keys 
    325    return func(**kwargs) 
    326 
    327 
    328def itervalues(obj, **kwargs): 
    329    """Use this only if compatibility with Python versions before 2.7 is 
    330    required. Otherwise, prefer viewvalues(). 
    331    """ 
    332    func = getattr(obj, "itervalues", None) 
    333    if not func: 
    334        func = obj.values 
    335    return func(**kwargs) 
    336 
    337 
    338def bind_method(cls, name, func): 
    339    """Bind a method to class, python 2 and python 3 compatible. 
    340 
    341    Parameters 
    342    ---------- 
    343 
    344    cls : type 
    345        class to receive bound method 
    346    name : basestring 
    347        name of method on class instance 
    348    func : function 
    349        function to be bound as method 
    350 
    351    Returns 
    352    ------- 
    353    None 
    354    """ 
    355    # only python 2 has an issue with bound/unbound methods 
    356    if not PY3: 
    357        setattr(cls, name, types.MethodType(func, None, cls)) 
    358    else: 
    359        setattr(cls, name, func) 
    360 
    361 
    362def getexception(): 
    363    return sys.exc_info()[1] 
    364 
    365 
    366def _get_caller_globals_and_locals(): 
    367    """ 
    368    Returns the globals and locals of the calling frame. 
    369 
    370    Is there an alternative to frame hacking here? 
    371    """ 
    372    caller_frame = inspect.stack()[2] 
    373    myglobals = caller_frame[0].f_globals 
    374    mylocals = caller_frame[0].f_locals 
    375    return myglobals, mylocals 
    376 
    377 
    378def _repr_strip(mystring): 
    379    """ 
    380    Returns the string without any initial or final quotes. 
    381    """ 
    382    r = repr(mystring) 
    383    if r.startswith("'") and r.endswith("'"): 
    384        return r[1:-1] 
    385    else: 
    386        return r 
    387 
    388 
    389if PY3: 
    390    def raise_from(exc, cause): 
    391        """ 
    392        Equivalent to: 
    393 
    394            raise EXCEPTION from CAUSE 
    395 
    396        on Python 3. (See PEP 3134). 
    397        """ 
    398        myglobals, mylocals = _get_caller_globals_and_locals() 
    399 
    400        # We pass the exception and cause along with other globals 
    401        # when we exec(): 
    402        myglobals = myglobals.copy() 
    403        myglobals['__python_future_raise_from_exc'] = exc 
    404        myglobals['__python_future_raise_from_cause'] = cause 
    405        execstr = "raise __python_future_raise_from_exc from __python_future_raise_from_cause" 
    406        exec(execstr, myglobals, mylocals) 
    407 
    408    def raise_(tp, value=None, tb=None): 
    409        """ 
    410        A function that matches the Python 2.x ``raise`` statement. This 
    411        allows re-raising exceptions with the cls value and traceback on 
    412        Python 2 and 3. 
    413        """ 
    414        if isinstance(tp, BaseException): 
    415            # If the first object is an instance, the type of the exception 
    416            # is the class of the instance, the instance itself is the value, 
    417            # and the second object must be None. 
    418            if value is not None: 
    419                raise TypeError("instance exception may not have a separate value") 
    420            exc = tp 
    421        elif isinstance(tp, type) and not issubclass(tp, BaseException): 
    422            # If the first object is a class, it becomes the type of the 
    423            # exception. 
    424            raise TypeError("class must derive from BaseException, not %s" % tp.__name__) 
    425        else: 
    426            # The second object is used to determine the exception value: If it 
    427            # is an instance of the class, the instance becomes the exception 
    428            # value. If the second object is a tuple, it is used as the argument 
    429            # list for the class constructor; if it is None, an empty argument 
    430            # list is used, and any other object is treated as a single argument 
    431            # to the constructor. The instance so created by calling the 
    432            # constructor is used as the exception value. 
    433            if isinstance(value, tp): 
    434                exc = value 
    435            elif isinstance(value, tuple): 
    436                exc = tp(*value) 
    437            elif value is None: 
    438                exc = tp() 
    439            else: 
    440                exc = tp(value) 
    441 
    442        if exc.__traceback__ is not tb: 
    443            raise exc.with_traceback(tb) 
    444        raise exc 
    445 
    446    def raise_with_traceback(exc, traceback=Ellipsis): 
    447        if traceback == Ellipsis: 
    448            _, _, traceback = sys.exc_info() 
    449        raise exc.with_traceback(traceback) 
    450 
    451else: 
    452    def raise_from(exc, cause): 
    453        """ 
    454        Equivalent to: 
    455 
    456            raise EXCEPTION from CAUSE 
    457 
    458        on Python 3. (See PEP 3134). 
    459        """ 
    460        # Is either arg an exception class (e.g. IndexError) rather than 
    461        # instance (e.g. IndexError('my message here')? If so, pass the 
    462        # name of the class undisturbed through to "raise ... from ...". 
    463        if isinstance(exc, type) and issubclass(exc, Exception): 
    464            e = exc() 
    465            # exc = exc.__name__ 
    466            # execstr = "e = " + _repr_strip(exc) + "()" 
    467            # myglobals, mylocals = _get_caller_globals_and_locals() 
    468            # exec(execstr, myglobals, mylocals) 
    469        else: 
    470            e = exc 
    471        e.__suppress_context__ = False 
    472        if isinstance(cause, type) and issubclass(cause, Exception): 
    473            e.__cause__ = cause() 
    474            e.__cause__.__traceback__ = sys.exc_info()[2] 
    475            e.__suppress_context__ = True 
    476        elif cause is None: 
    477            e.__cause__ = None 
    478            e.__suppress_context__ = True 
    479        elif isinstance(cause, BaseException): 
    480            e.__cause__ = cause 
    481            object.__setattr__(e.__cause__,  '__traceback__', sys.exc_info()[2]) 
    482            e.__suppress_context__ = True 
    483        else: 
    484            raise TypeError("exception causes must derive from BaseException") 
    485        e.__context__ = sys.exc_info()[1] 
    486        raise e 
    487 
    488    exec(''' 
    489def raise_(tp, value=None, tb=None): 
    490    raise tp, value, tb 
    491 
    492def raise_with_traceback(exc, traceback=Ellipsis): 
    493    if traceback == Ellipsis: 
    494        _, _, traceback = sys.exc_info() 
    495    raise exc, None, traceback 
    496'''.strip()) 
    497 
    498 
    499raise_with_traceback.__doc__ = ( 
    500"""Raise exception with existing traceback. 
    501If traceback is not passed, uses sys.exc_info() to get traceback.""" 
    502) 
    503 
    504 
    505# Deprecated alias for backward compatibility with ``future`` versions < 0.11: 
    506reraise = raise_ 
    507 
    508 
    509def implements_iterator(cls): 
    510    ''' 
    511    From jinja2/_compat.py. License: BSD. 
    512 
    513    Use as a decorator like this:: 
    514 
    515        @implements_iterator 
    516        class UppercasingIterator(object): 
    517            def __init__(self, iterable): 
    518                self._iter = iter(iterable) 
    519            def __iter__(self): 
    520                return self 
    521            def __next__(self): 
    522                return next(self._iter).upper() 
    523 
    524    ''' 
    525    if PY3: 
    526        return cls 
    527    else: 
    528        cls.next = cls.__next__ 
    529        del cls.__next__ 
    530        return cls 
    531 
    532if PY3: 
    533    get_next = lambda x: x.__next__ 
    534else: 
    535    get_next = lambda x: x.next 
    536 
    537 
    538def encode_filename(filename): 
    539    if PY3: 
    540        return filename 
    541    else: 
    542        if isinstance(filename, unicode): 
    543            return filename.encode('utf-8') 
    544        return filename 
    545 
    546 
    547def is_new_style(cls): 
    548    """ 
    549    Python 2.7 has both new-style and old-style classes. Old-style classes can 
    550    be pesky in some circumstances, such as when using inheritance.  Use this 
    551    function to test for whether a class is new-style. (Python 3 only has 
    552    new-style classes.) 
    553    """ 
    554    return hasattr(cls, '__class__') and ('__dict__' in dir(cls) 
    555                                          or hasattr(cls, '__slots__')) 
    556 
    557# The native platform string and bytes types. Useful because ``str`` and 
    558# ``bytes`` are redefined on Py2 by ``from future.builtins import *``. 
    559native_str = str 
    560native_bytes = bytes 
    561 
    562 
    563def istext(obj): 
    564    """ 
    565    Deprecated. Use:: 
    566        >>> isinstance(obj, str) 
    567    after this import: 
    568        >>> from future.builtins import str 
    569    """ 
    570    return isinstance(obj, type(u'')) 
    571 
    572 
    573def isbytes(obj): 
    574    """ 
    575    Deprecated. Use:: 
    576        >>> isinstance(obj, bytes) 
    577    after this import: 
    578        >>> from future.builtins import bytes 
    579    """ 
    580    return isinstance(obj, type(b'')) 
    581 
    582 
    583def isnewbytes(obj): 
    584    """ 
    585    Equivalent to the result of ``type(obj)  == type(newbytes)`` 
    586    in other words, it is REALLY a newbytes instance, not a Py2 native str 
    587    object? 
    588 
    589    Note that this does not cover subclasses of newbytes, and it is not 
    590    equivalent to ininstance(obj, newbytes) 
    591    """ 
    592    return type(obj).__name__ == 'newbytes' 
    593 
    594 
    595def isint(obj): 
    596    """ 
    597    Deprecated. Tests whether an object is a Py3 ``int`` or either a Py2 ``int`` or 
    598    ``long``. 
    599 
    600    Instead of using this function, you can use: 
    601 
    602        >>> from future.builtins import int 
    603        >>> isinstance(obj, int) 
    604 
    605    The following idiom is equivalent: 
    606 
    607        >>> from numbers import Integral 
    608        >>> isinstance(obj, Integral) 
    609    """ 
    610 
    611    return isinstance(obj, numbers.Integral) 
    612 
    613 
    614def native(obj): 
    615    """ 
    616    On Py3, this is a no-op: native(obj) -> obj 
    617 
    618    On Py2, returns the corresponding native Py2 types that are 
    619    superclasses for backported objects from Py3: 
    620 
    621    >>> from builtins import str, bytes, int 
    622 
    623    >>> native(str(u'ABC')) 
    624    u'ABC' 
    625    >>> type(native(str(u'ABC'))) 
    626    unicode 
    627 
    628    >>> native(bytes(b'ABC')) 
    629    b'ABC' 
    630    >>> type(native(bytes(b'ABC'))) 
    631    bytes 
    632 
    633    >>> native(int(10**20)) 
    634    100000000000000000000L 
    635    >>> type(native(int(10**20))) 
    636    long 
    637 
    638    Existing native types on Py2 will be returned unchanged: 
    639 
    640    >>> type(native(u'ABC')) 
    641    unicode 
    642    """ 
    643    if hasattr(obj, '__native__'): 
    644        return obj.__native__() 
    645    else: 
    646        return obj 
    647 
    648 
    649# Implementation of exec_ is from ``six``: 
    650if PY3: 
    651    import builtins 
    652    exec_ = getattr(builtins, "exec") 
    653else: 
    654    def exec_(code, globs=None, locs=None): 
    655        """Execute code in a namespace.""" 
    656        if globs is None: 
    657            frame = sys._getframe(1) 
    658            globs = frame.f_globals 
    659            if locs is None: 
    660                locs = frame.f_locals 
    661            del frame 
    662        elif locs is None: 
    663            locs = globs 
    664        exec("""exec code in globs, locs""") 
    665 
    666 
    667# Defined here for backward compatibility: 
    668def old_div(a, b): 
    669    """ 
    670    DEPRECATED: import ``old_div`` from ``past.utils`` instead. 
    671 
    672    Equivalent to ``a / b`` on Python 2 without ``from __future__ import 
    673    division``. 
    674 
    675    TODO: generalize this to other objects (like arrays etc.) 
    676    """ 
    677    if isinstance(a, numbers.Integral) and isinstance(b, numbers.Integral): 
    678        return a // b 
    679    else: 
    680        return a / b 
    681 
    682 
    683def as_native_str(encoding='utf-8'): 
    684    ''' 
    685    A decorator to turn a function or method call that returns text, i.e. 
    686    unicode, into one that returns a native platform str. 
    687 
    688    Use it as a decorator like this:: 
    689 
    690        from __future__ import unicode_literals 
    691 
    692        class MyClass(object): 
    693            @as_native_str(encoding='ascii') 
    694            def __repr__(self): 
    695                return next(self._iter).upper() 
    696    ''' 
    697    if PY3: 
    698        return lambda f: f 
    699    else: 
    700        def encoder(f): 
    701            @functools.wraps(f) 
    702            def wrapper(*args, **kwargs): 
    703                return f(*args, **kwargs).encode(encoding=encoding) 
    704            return wrapper 
    705        return encoder 
    706 
    707# listvalues and listitems definitions from Nick Coghlan's (withdrawn) 
    708# PEP 496: 
    709try: 
    710    dict.iteritems 
    711except AttributeError: 
    712    # Python 3 
    713    def listvalues(d): 
    714        return list(d.values()) 
    715    def listitems(d): 
    716        return list(d.items()) 
    717else: 
    718    # Python 2 
    719    def listvalues(d): 
    720        return d.values() 
    721    def listitems(d): 
    722        return d.items() 
    723 
    724if PY3: 
    725    def ensure_new_type(obj): 
    726        return obj 
    727else: 
    728    def ensure_new_type(obj): 
    729        from future.types.newbytes import newbytes 
    730        from future.types.newstr import newstr 
    731        from future.types.newint import newint 
    732        from future.types.newdict import newdict 
    733 
    734        native_type = type(native(obj)) 
    735 
    736        # Upcast only if the type is already a native (non-future) type 
    737        if issubclass(native_type, type(obj)): 
    738            # Upcast 
    739            if native_type == str:  # i.e. Py2 8-bit str 
    740                return newbytes(obj) 
    741            elif native_type == unicode: 
    742                return newstr(obj) 
    743            elif native_type == int: 
    744                return newint(obj) 
    745            elif native_type == long: 
    746                return newint(obj) 
    747            elif native_type == dict: 
    748                return newdict(obj) 
    749            else: 
    750                return obj 
    751        else: 
    752            # Already a new type 
    753            assert type(obj) in [newbytes, newstr] 
    754            return obj 
    755 
    756 
    757__all__ = ['PY2', 'PY26', 'PY3', 'PYPY', 
    758           'as_native_str', 'binary_type', 'bind_method', 'bord', 'bstr', 
    759           'bytes_to_native_str', 'class_types', 'encode_filename', 
    760           'ensure_new_type', 'exec_', 'get_next', 'getexception', 
    761           'implements_iterator', 'integer_types', 'is_new_style', 'isbytes', 
    762           'isidentifier', 'isint', 'isnewbytes', 'istext', 'iteritems', 
    763           'iterkeys', 'itervalues', 'lfilter', 'listitems', 'listvalues', 
    764           'lmap', 'lrange', 'lzip', 'native', 'native_bytes', 'native_str', 
    765           'native_str_to_bytes', 'old_div', 
    766           'python_2_unicode_compatible', 'raise_', 
    767           'raise_with_traceback', 'reraise', 'string_types', 
    768           'text_to_native_str', 'text_type', 'tobytes', 'viewitems', 
    769           'viewkeys', 'viewvalues', 'with_metaclass' 
    770           ]