import inspect
|
import platform
|
import sys
|
import types
|
|
WIN = platform.system() == 'Windows'
|
|
try: # pragma: no cover
|
import __pypy__
|
|
PYPY = True
|
except BaseException: # pragma: no cover
|
__pypy__ = None
|
PYPY = False
|
|
try:
|
import cPickle as pickle
|
except ImportError: # pragma: no cover
|
import pickle
|
|
try:
|
from functools import lru_cache
|
except ImportError:
|
from repoze.lru import lru_cache
|
|
# PY3 is left as bw-compat but PY2 should be used for most checks.
|
PY2 = sys.version_info[0] == 2
|
PY3 = sys.version_info[0] == 3
|
|
if PY2:
|
string_types = (basestring,)
|
integer_types = (int, long)
|
class_types = (type, types.ClassType)
|
text_type = unicode
|
binary_type = str
|
long = long
|
else:
|
string_types = (str,)
|
integer_types = (int,)
|
class_types = (type,)
|
text_type = str
|
binary_type = bytes
|
long = int
|
|
|
def text_(s, encoding='latin-1', errors='strict'):
|
""" If ``s`` is an instance of ``binary_type``, return
|
``s.decode(encoding, errors)``, otherwise return ``s``"""
|
if isinstance(s, binary_type):
|
return s.decode(encoding, errors)
|
return s
|
|
|
def bytes_(s, encoding='latin-1', errors='strict'):
|
""" If ``s`` is an instance of ``text_type``, return
|
``s.encode(encoding, errors)``, otherwise return ``s``"""
|
if isinstance(s, text_type):
|
return s.encode(encoding, errors)
|
return s
|
|
|
if PY2:
|
|
def ascii_native_(s):
|
if isinstance(s, text_type):
|
s = s.encode('ascii')
|
return str(s)
|
|
|
else:
|
|
def ascii_native_(s):
|
if isinstance(s, text_type):
|
s = s.encode('ascii')
|
return str(s, 'ascii', 'strict')
|
|
|
ascii_native_.__doc__ = """
|
Python 3: If ``s`` is an instance of ``text_type``, return
|
``s.encode('ascii')``, otherwise return ``str(s, 'ascii', 'strict')``
|
|
Python 2: If ``s`` is an instance of ``text_type``, return
|
``s.encode('ascii')``, otherwise return ``str(s)``
|
"""
|
|
|
if PY2:
|
|
def native_(s, encoding='latin-1', errors='strict'):
|
""" If ``s`` is an instance of ``text_type``, return
|
``s.encode(encoding, errors)``, otherwise return ``str(s)``"""
|
if isinstance(s, text_type):
|
return s.encode(encoding, errors)
|
return str(s)
|
|
|
else:
|
|
def native_(s, encoding='latin-1', errors='strict'):
|
""" If ``s`` is an instance of ``text_type``, return
|
``s``, otherwise return ``str(s, encoding, errors)``"""
|
if isinstance(s, text_type):
|
return s
|
return str(s, encoding, errors)
|
|
|
native_.__doc__ = """
|
Python 3: If ``s`` is an instance of ``text_type``, return ``s``, otherwise
|
return ``str(s, encoding, errors)``
|
|
Python 2: If ``s`` is an instance of ``text_type``, return
|
``s.encode(encoding, errors)``, otherwise return ``str(s)``
|
"""
|
|
if PY2:
|
import urlparse
|
from urllib import quote as url_quote
|
from urllib import quote_plus as url_quote_plus
|
from urllib import unquote as url_unquote
|
from urllib import urlencode as url_encode
|
from urllib2 import urlopen as url_open
|
|
def url_unquote_text(
|
v, encoding='utf-8', errors='replace'
|
): # pragma: no cover
|
v = url_unquote(v)
|
return v.decode(encoding, errors)
|
|
def url_unquote_native(
|
v, encoding='utf-8', errors='replace'
|
): # pragma: no cover
|
return native_(url_unquote_text(v, encoding, errors))
|
|
|
else:
|
from urllib import parse
|
|
urlparse = parse
|
from urllib.parse import quote as url_quote
|
from urllib.parse import quote_plus as url_quote_plus
|
from urllib.parse import unquote as url_unquote
|
from urllib.parse import urlencode as url_encode
|
from urllib.request import urlopen as url_open
|
|
url_unquote_text = url_unquote
|
url_unquote_native = url_unquote
|
|
|
if PY2: # pragma: no cover
|
|
def exec_(code, globs=None, locs=None):
|
"""Execute code in a namespace."""
|
if globs is None:
|
frame = sys._getframe(1)
|
globs = frame.f_globals
|
if locs is None:
|
locs = frame.f_locals
|
del frame
|
elif locs is None:
|
locs = globs
|
exec("""exec code in globs, locs""")
|
|
exec_(
|
"""def reraise(tp, value, tb=None):
|
raise tp, value, tb
|
"""
|
)
|
|
else: # pragma: no cover
|
import builtins
|
|
exec_ = getattr(builtins, "exec")
|
|
def reraise(tp, value, tb=None):
|
if value is None:
|
value = tp
|
if value.__traceback__ is not tb:
|
raise value.with_traceback(tb)
|
raise value
|
|
del builtins
|
|
|
if PY2: # pragma: no cover
|
|
def iteritems_(d):
|
return d.iteritems()
|
|
def itervalues_(d):
|
return d.itervalues()
|
|
def iterkeys_(d):
|
return d.iterkeys()
|
|
|
else: # pragma: no cover
|
|
def iteritems_(d):
|
return d.items()
|
|
def itervalues_(d):
|
return d.values()
|
|
def iterkeys_(d):
|
return d.keys()
|
|
|
if PY2:
|
map_ = map
|
else:
|
|
def map_(*arg):
|
return list(map(*arg))
|
|
|
if PY2:
|
|
def is_nonstr_iter(v):
|
return hasattr(v, '__iter__')
|
|
|
else:
|
|
def is_nonstr_iter(v):
|
if isinstance(v, str):
|
return False
|
return hasattr(v, '__iter__')
|
|
|
if PY2:
|
im_func = 'im_func'
|
im_self = 'im_self'
|
else:
|
im_func = '__func__'
|
im_self = '__self__'
|
|
try:
|
import configparser
|
except ImportError:
|
import ConfigParser as configparser
|
|
try:
|
from http.cookies import SimpleCookie
|
except ImportError:
|
from Cookie import SimpleCookie
|
|
if PY2:
|
from cgi import escape
|
else:
|
from html import escape
|
|
if PY2:
|
input_ = raw_input
|
else:
|
input_ = input
|
|
if PY2:
|
from io import BytesIO as NativeIO
|
else:
|
from io import StringIO as NativeIO
|
|
# "json" is not an API; it's here to support older pyramid_debugtoolbar
|
# versions which attempt to import it
|
import json
|
|
if PY2:
|
|
def decode_path_info(path):
|
return path.decode('utf-8')
|
|
|
else:
|
# see PEP 3333 for why we encode WSGI PATH_INFO to latin-1 before
|
# decoding it to utf-8
|
def decode_path_info(path):
|
return path.encode('latin-1').decode('utf-8')
|
|
|
if PY2:
|
from urlparse import unquote as unquote_to_bytes
|
|
def unquote_bytes_to_wsgi(bytestring):
|
return unquote_to_bytes(bytestring)
|
|
|
else:
|
# see PEP 3333 for why we decode the path to latin-1
|
from urllib.parse import unquote_to_bytes
|
|
def unquote_bytes_to_wsgi(bytestring):
|
return unquote_to_bytes(bytestring).decode('latin-1')
|
|
|
def is_bound_method(ob):
|
return inspect.ismethod(ob) and getattr(ob, im_self, None) is not None
|
|
|
# support annotations and keyword-only arguments in PY3
|
if PY2:
|
from inspect import getargspec
|
else:
|
from inspect import getfullargspec as getargspec
|
|
if PY2:
|
from itertools import izip_longest as zip_longest
|
else:
|
from itertools import zip_longest
|
|
|
def is_unbound_method(fn):
|
"""
|
This consistently verifies that the callable is bound to a
|
class.
|
"""
|
is_bound = is_bound_method(fn)
|
|
if not is_bound and inspect.isroutine(fn):
|
spec = getargspec(fn)
|
has_self = len(spec.args) > 0 and spec.args[0] == 'self'
|
|
if PY2 and inspect.ismethod(fn):
|
return True
|
elif inspect.isfunction(fn) and has_self:
|
return True
|
|
return False
|