comparison planemo/lib/python3.7/site-packages/future/utils/__init__.py @ 0:d30785e31577 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:18:57 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:d30785e31577
1 """
2 A selection of cross-compatible functions for Python 2 and 3.
3
4 This 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
37 This module also defines these decorators:
38
39 * ``python_2_unicode_compatible``
40 * ``with_metaclass``
41 * ``implements_iterator``
42
43 Some 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
52 import types
53 import sys
54 import numbers
55 import functools
56 import copy
57 import inspect
58
59
60 PY3 = sys.version_info[0] >= 3
61 PY34_PLUS = sys.version_info[0:2] >= (3, 4)
62 PY35_PLUS = sys.version_info[0:2] >= (3, 5)
63 PY36_PLUS = sys.version_info[0:2] >= (3, 6)
64 PY2 = sys.version_info[0] == 2
65 PY26 = sys.version_info[0:2] == (2, 6)
66 PY27 = sys.version_info[0:2] == (2, 7)
67 PYPY = hasattr(sys, 'pypy_translation_info')
68
69
70 def 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
111 def 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:
147 if 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
164 else:
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
181 if 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)
190 else:
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
198 tobytes.__doc__ = """
199 Encodes to latin-1 (where the first 256 chars are the same as
200 ASCII.)
201 """
202
203 if 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
212 else:
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
228 native_str_to_bytes.__doc__ = """
229 On Py3, returns an encoded string.
230 On Py2, returns a newbytes type, ignoring the ``encoding`` argument.
231 """
232
233 if 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))
246 else:
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
255 def 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
269 def 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
281 def 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
293 def 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
305 def 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
315 def 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
325 def 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
335 def 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
359 def getexception():
360 return sys.exc_info()[1]
361
362
363 def _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
375 def _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
386 if 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
448 else:
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('''
486 def raise_(tp, value=None, tb=None):
487 raise tp, value, tb
488
489 def raise_with_traceback(exc, traceback=Ellipsis):
490 if traceback == Ellipsis:
491 _, _, traceback = sys.exc_info()
492 raise exc, None, traceback
493 '''.strip())
494
495
496 raise_with_traceback.__doc__ = (
497 """Raise exception with existing traceback.
498 If 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:
503 reraise = raise_
504
505
506 def 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
529 if PY3:
530 get_next = lambda x: x.next
531 else:
532 get_next = lambda x: x.__next__
533
534
535 def 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
544 def 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 *``.
556 native_str = str
557 native_bytes = bytes
558
559
560 def 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
570 def 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
580 def 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
592 def 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
611 def 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``:
647 if PY3:
648 import builtins
649 exec_ = getattr(builtins, "exec")
650 else:
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:
665 def 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
680 def 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:
706 try:
707 dict.iteritems
708 except AttributeError:
709 # Python 3
710 def listvalues(d):
711 return list(d.values())
712 def listitems(d):
713 return list(d.items())
714 else:
715 # Python 2
716 def listvalues(d):
717 return d.values()
718 def listitems(d):
719 return d.items()
720
721 if PY3:
722 def ensure_new_type(obj):
723 return obj
724 else:
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 ]