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