summaryrefslogtreecommitdiff
path: root/passlib/utils/compat/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/utils/compat/__init__.py')
-rw-r--r--passlib/utils/compat/__init__.py284
1 files changed, 12 insertions, 272 deletions
diff --git a/passlib/utils/compat/__init__.py b/passlib/utils/compat/__init__.py
index f6ead24..06bd266 100644
--- a/passlib/utils/compat/__init__.py
+++ b/passlib/utils/compat/__init__.py
@@ -7,14 +7,10 @@
# python version
#------------------------------------------------------------------------
import sys
-PY2 = sys.version_info < (3,0)
-PY3 = sys.version_info >= (3,0)
# make sure it's not an unsupported version, even if we somehow got this far
-if sys.version_info < (2,6) or (3,0) <= sys.version_info < (3,2):
- raise RuntimeError("Passlib requires Python 2.6, 2.7, or >= 3.2 (as of passlib 1.7)")
-
-PY26 = sys.version_info < (2,7)
+if sys.version_info < (3, 5):
+ raise RuntimeError("Passlib requires Python >= 3.5 (as of passlib 1.8)")
#------------------------------------------------------------------------
# python implementation
@@ -26,18 +22,10 @@ PYPY = hasattr(sys, "pypy_version_info")
if PYPY and sys.pypy_version_info < (2,0):
raise RuntimeError("passlib requires pypy >= 2.0 (as of passlib 1.7)")
-# e.g. '2.7.7\n[Pyston 0.5.1]'
-# NOTE: deprecated support 2019-11
-PYSTON = "Pyston" in sys.version
-
#=============================================================================
# common imports
#=============================================================================
import logging; log = logging.getLogger(__name__)
-if PY3:
- import builtins
-else:
- import __builtin__ as builtins
def add_doc(obj, doc):
"""add docstring to an object"""
@@ -47,38 +35,15 @@ def add_doc(obj, doc):
# the default exported vars
#=============================================================================
__all__ = [
- # python versions
- 'PY2', 'PY3', 'PY26',
-
- # io
- 'BytesIO', 'StringIO', 'NativeStringIO', 'SafeConfigParser',
- 'print_',
-
# type detection
## 'is_mapping',
- 'int_types',
'num_types',
- 'unicode_or_bytes_types',
- 'native_string_types',
+ 'unicode_or_bytes',
# unicode/bytes types & helpers
- 'u',
- 'unicode',
- 'uascii_to_str', 'bascii_to_str',
- 'str_to_uascii', 'str_to_bascii',
+ 'bascii_to_str',
+ 'str_to_bascii',
'join_unicode', 'join_bytes',
- 'join_byte_values', 'join_byte_elems',
- 'byte_elem_value',
- 'iter_byte_values',
-
- # iteration helpers
- 'irange', #'lrange',
- 'imap', 'lmap',
- 'iteritems', 'itervalues',
- 'next',
-
- # collections
- 'OrderedDict',
# context helpers
'nullcontext',
@@ -94,179 +59,47 @@ _lazy_attrs = dict()
#=============================================================================
# unicode & bytes types
#=============================================================================
-if PY3:
- unicode = str
-
- # TODO: once we drop python 3.2 support, can use u'' again!
- def u(s):
- assert isinstance(s, str)
- return s
-
- unicode_or_bytes_types = (str, bytes)
- native_string_types = (unicode,)
-else:
- unicode = builtins.unicode
-
- def u(s):
- assert isinstance(s, str)
- return s.decode("unicode_escape")
-
- unicode_or_bytes_types = (basestring,)
- native_string_types = (basestring,)
-
-# shorter preferred aliases
-unicode_or_bytes = unicode_or_bytes_types
-unicode_or_str = native_string_types
-
-# unicode -- unicode type, regardless of python version
-# bytes -- bytes type, regardless of python version
-# unicode_or_bytes_types -- types that text can occur in, whether encoded or not
-# native_string_types -- types that native python strings (dict keys etc) can occur in.
+#: alias for isinstance() tests to detect any string type
+unicode_or_bytes = (str, bytes)
#=============================================================================
# unicode & bytes helpers
#=============================================================================
# function to join list of unicode strings
-join_unicode = u('').join
+join_unicode = u''.join
# function to join list of byte strings
join_bytes = b''.join
-if PY3:
- def uascii_to_str(s):
- assert isinstance(s, unicode)
- return s
+if True: # legacy PY3 indent
def bascii_to_str(s):
assert isinstance(s, bytes)
return s.decode("ascii")
- def str_to_uascii(s):
- assert isinstance(s, str)
- return s
-
def str_to_bascii(s):
assert isinstance(s, str)
return s.encode("ascii")
- join_byte_values = join_byte_elems = bytes
-
- def byte_elem_value(elem):
- assert isinstance(elem, int)
- return elem
-
- def iter_byte_values(s):
- assert isinstance(s, bytes)
- return s
-
def iter_byte_chars(s):
assert isinstance(s, bytes)
# FIXME: there has to be a better way to do this
return (bytes([c]) for c in s)
-else:
- def uascii_to_str(s):
- assert isinstance(s, unicode)
- return s.encode("ascii")
-
- def bascii_to_str(s):
- assert isinstance(s, bytes)
- return s
-
- def str_to_uascii(s):
- assert isinstance(s, str)
- return s.decode("ascii")
-
- def str_to_bascii(s):
- assert isinstance(s, str)
- return s
-
- def join_byte_values(values):
- return join_bytes(chr(v) for v in values)
-
- join_byte_elems = join_bytes
-
- byte_elem_value = ord
-
- def iter_byte_values(s):
- assert isinstance(s, bytes)
- return (ord(c) for c in s)
-
- def iter_byte_chars(s):
- assert isinstance(s, bytes)
- return s
-
-add_doc(uascii_to_str, "helper to convert ascii unicode -> native str")
+# TODO: move docstrings to funcs...
add_doc(bascii_to_str, "helper to convert ascii bytes -> native str")
-add_doc(str_to_uascii, "helper to convert ascii native str -> unicode")
add_doc(str_to_bascii, "helper to convert ascii native str -> bytes")
-# join_byte_values -- function to convert list of ordinal integers to byte string.
-
-# join_byte_elems -- function to convert list of byte elements to byte string;
-# i.e. what's returned by ``b('a')[0]``...
-# this is b('a') under PY2, but 97 under PY3.
-
# byte_elem_value -- function to convert byte element to integer -- a noop under PY3
-add_doc(iter_byte_values, "iterate over byte string as sequence of ints 0-255")
add_doc(iter_byte_chars, "iterate over byte string as sequence of 1-byte strings")
#=============================================================================
# numeric
#=============================================================================
-if PY3:
- int_types = (int,)
- num_types = (int, float)
-else:
- int_types = (int, long)
- num_types = (int, long, float)
-
-#=============================================================================
-# iteration helpers
-#
-# irange - range iterable / view (xrange under py2, range under py3)
-# lrange - range list (range under py2, list(range()) under py3)
-#
-# imap - map to iterator
-# lmap - map to list
-#=============================================================================
-if PY3:
- irange = range
- ##def lrange(*a,**k):
- ## return list(range(*a,**k))
-
- def lmap(*a, **k):
- return list(map(*a,**k))
- imap = map
-
- def iteritems(d):
- return d.items()
- def itervalues(d):
- return d.values()
-
- def nextgetter(obj):
- return obj.__next__
-
- izip = zip
-
-else:
- irange = xrange
- ##lrange = range
- lmap = map
- from itertools import imap, izip
-
- def iteritems(d):
- return d.iteritems()
- def itervalues(d):
- return d.itervalues()
-
- def nextgetter(obj):
- return obj.next
-
-add_doc(nextgetter, "return function that yields successive values from iterable")
+num_types = (int, float)
#=============================================================================
# typing
@@ -278,103 +111,10 @@ add_doc(nextgetter, "return function that yields successive values from iterable
#=============================================================================
# introspection
#=============================================================================
-if PY3:
- method_function_attr = "__func__"
-else:
- method_function_attr = "im_func"
def get_method_function(func):
"""given (potential) method, return underlying function"""
- return getattr(func, method_function_attr, func)
-
-def get_unbound_method_function(func):
- """given unbound method, return underlying function"""
- return func if PY3 else func.__func__
-
-def error_from(exc, # *,
- cause=None):
- """
- backward compat hack to suppress exception cause in python3.3+
-
- one python < 3.3 support is dropped, can replace all uses with "raise exc from None"
- """
- exc.__cause__ = cause
- exc.__suppress_context__ = True
- return exc
-
-# legacy alias
-suppress_cause = error_from
-
-#=============================================================================
-# input/output
-#=============================================================================
-if PY3:
- _lazy_attrs = dict(
- BytesIO="io.BytesIO",
- UnicodeIO="io.StringIO",
- NativeStringIO="io.StringIO",
- SafeConfigParser="configparser.ConfigParser",
- )
-
- print_ = getattr(builtins, "print")
-
-else:
- _lazy_attrs = dict(
- BytesIO="cStringIO.StringIO",
- UnicodeIO="StringIO.StringIO",
- NativeStringIO="cStringIO.StringIO",
- SafeConfigParser="ConfigParser.SafeConfigParser",
- )
-
- def print_(*args, **kwds):
- """The new-style print function."""
- # extract kwd args
- fp = kwds.pop("file", sys.stdout)
- sep = kwds.pop("sep", None)
- end = kwds.pop("end", None)
- if kwds:
- raise TypeError("invalid keyword arguments")
-
- # short-circuit if no target
- if fp is None:
- return
-
- # use unicode or bytes ?
- want_unicode = isinstance(sep, unicode) or isinstance(end, unicode) or \
- any(isinstance(arg, unicode) for arg in args)
-
- # pick default end sequence
- if end is None:
- end = u("\n") if want_unicode else "\n"
- elif not isinstance(end, unicode_or_bytes_types):
- raise TypeError("end must be None or a string")
-
- # pick default separator
- if sep is None:
- sep = u(" ") if want_unicode else " "
- elif not isinstance(sep, unicode_or_bytes_types):
- raise TypeError("sep must be None or a string")
-
- # write to buffer
- first = True
- write = fp.write
- for arg in args:
- if first:
- first = False
- else:
- write(sep)
- if not isinstance(arg, basestring):
- arg = str(arg)
- write(arg)
- write(end)
-
-#=============================================================================
-# collections
-#=============================================================================
-if PY26:
- _lazy_attrs['OrderedDict'] = 'passlib.utils.compat._ordered_dict.OrderedDict'
-else:
- _lazy_attrs['OrderedDict'] = 'collections.OrderedDict'
+ return getattr(func, "__func__", func)
#=============================================================================
# context managers