mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
Все подряд
This commit is contained in:
474
.venv2/Lib/site-packages/passlib/utils/compat/__init__.py
Normal file
474
.venv2/Lib/site-packages/passlib/utils/compat/__init__.py
Normal file
@@ -0,0 +1,474 @@
|
||||
"""passlib.utils.compat - python 2/3 compatibility helpers"""
|
||||
#=============================================================================
|
||||
# figure out what we're running
|
||||
#=============================================================================
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# 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)
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
# python implementation
|
||||
#------------------------------------------------------------------------
|
||||
JYTHON = sys.platform.startswith('java')
|
||||
|
||||
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"""
|
||||
obj.__doc__ = 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/bytes types & helpers
|
||||
'u',
|
||||
'unicode',
|
||||
'uascii_to_str', 'bascii_to_str',
|
||||
'str_to_uascii', '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',
|
||||
|
||||
# introspection
|
||||
'get_method_function', 'add_doc',
|
||||
]
|
||||
|
||||
# begin accumulating mapping of lazy-loaded attrs,
|
||||
# 'merged' into module at bottom
|
||||
_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.
|
||||
|
||||
#=============================================================================
|
||||
# unicode & bytes helpers
|
||||
#=============================================================================
|
||||
# function to join list of unicode strings
|
||||
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
|
||||
|
||||
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")
|
||||
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")
|
||||
|
||||
#=============================================================================
|
||||
# typing
|
||||
#=============================================================================
|
||||
##def is_mapping(obj):
|
||||
## # non-exhaustive check, enough to distinguish from lists, etc
|
||||
## return hasattr(obj, "items")
|
||||
|
||||
#=============================================================================
|
||||
# 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'
|
||||
|
||||
#=============================================================================
|
||||
# context managers
|
||||
#=============================================================================
|
||||
|
||||
try:
|
||||
# new in py37
|
||||
from contextlib import nullcontext
|
||||
except ImportError:
|
||||
|
||||
class nullcontext(object):
|
||||
"""
|
||||
Context manager that does no additional processing.
|
||||
"""
|
||||
def __init__(self, enter_result=None):
|
||||
self.enter_result = enter_result
|
||||
|
||||
def __enter__(self):
|
||||
return self.enter_result
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
pass
|
||||
|
||||
#=============================================================================
|
||||
# lazy overlay module
|
||||
#=============================================================================
|
||||
from types import ModuleType
|
||||
|
||||
def _import_object(source):
|
||||
"""helper to import object from module; accept format `path.to.object`"""
|
||||
modname, modattr = source.rsplit(".",1)
|
||||
mod = __import__(modname, fromlist=[modattr], level=0)
|
||||
return getattr(mod, modattr)
|
||||
|
||||
class _LazyOverlayModule(ModuleType):
|
||||
"""proxy module which overlays original module,
|
||||
and lazily imports specified attributes.
|
||||
|
||||
this is mainly used to prevent importing of resources
|
||||
that are only needed by certain password hashes,
|
||||
yet allow them to be imported from a single location.
|
||||
|
||||
used by :mod:`passlib.utils`, :mod:`passlib.crypto`,
|
||||
and :mod:`passlib.utils.compat`.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def replace_module(cls, name, attrmap):
|
||||
orig = sys.modules[name]
|
||||
self = cls(name, attrmap, orig)
|
||||
sys.modules[name] = self
|
||||
return self
|
||||
|
||||
def __init__(self, name, attrmap, proxy=None):
|
||||
ModuleType.__init__(self, name)
|
||||
self.__attrmap = attrmap
|
||||
self.__proxy = proxy
|
||||
self.__log = logging.getLogger(name)
|
||||
|
||||
def __getattr__(self, attr):
|
||||
proxy = self.__proxy
|
||||
if proxy and hasattr(proxy, attr):
|
||||
return getattr(proxy, attr)
|
||||
attrmap = self.__attrmap
|
||||
if attr in attrmap:
|
||||
source = attrmap[attr]
|
||||
if callable(source):
|
||||
value = source()
|
||||
else:
|
||||
value = _import_object(source)
|
||||
setattr(self, attr, value)
|
||||
self.__log.debug("loaded lazy attr %r: %r", attr, value)
|
||||
return value
|
||||
raise AttributeError("'module' object has no attribute '%s'" % (attr,))
|
||||
|
||||
def __repr__(self):
|
||||
proxy = self.__proxy
|
||||
if proxy:
|
||||
return repr(proxy)
|
||||
else:
|
||||
return ModuleType.__repr__(self)
|
||||
|
||||
def __dir__(self):
|
||||
attrs = set(dir(self.__class__))
|
||||
attrs.update(self.__dict__)
|
||||
attrs.update(self.__attrmap)
|
||||
proxy = self.__proxy
|
||||
if proxy is not None:
|
||||
attrs.update(dir(proxy))
|
||||
return list(attrs)
|
||||
|
||||
# replace this module with overlay that will lazily import attributes.
|
||||
_LazyOverlayModule.replace_module(__name__, _lazy_attrs)
|
||||
|
||||
#=============================================================================
|
||||
# eof
|
||||
#=============================================================================
|
Reference in New Issue
Block a user