Tornado update
This commit is contained in:
+78
-29
@@ -1,7 +1,9 @@
|
||||
"""Miscellaneous utility functions."""
|
||||
|
||||
from __future__ import absolute_import, division, with_statement
|
||||
from __future__ import absolute_import, division, print_function, with_statement
|
||||
|
||||
import inspect
|
||||
import sys
|
||||
import zlib
|
||||
|
||||
|
||||
@@ -62,38 +64,47 @@ def import_object(name):
|
||||
obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)
|
||||
return getattr(obj, parts[-1])
|
||||
|
||||
# Fake byte literal support: In python 2.6+, you can say b"foo" to get
|
||||
# a byte literal (str in 2.x, bytes in 3.x). There's no way to do this
|
||||
# in a way that supports 2.5, though, so we need a function wrapper
|
||||
# to convert our string literals. b() should only be applied to literal
|
||||
# latin1 strings. Once we drop support for 2.5, we can remove this function
|
||||
# and just use byte literals.
|
||||
if str is unicode:
|
||||
def b(s):
|
||||
return s.encode('latin1')
|
||||
bytes_type = bytes
|
||||
else:
|
||||
def b(s):
|
||||
# Fake unicode literal support: Python 3.2 doesn't have the u'' marker for
|
||||
# literal strings, and alternative solutions like "from __future__ import
|
||||
# unicode_literals" have other problems (see PEP 414). u() can be applied
|
||||
# to ascii strings that include \u escapes (but they must not contain
|
||||
# literal non-ascii characters).
|
||||
if type('') is not type(b''):
|
||||
def u(s):
|
||||
return s
|
||||
bytes_type = bytes
|
||||
unicode_type = str
|
||||
basestring_type = str
|
||||
else:
|
||||
def u(s):
|
||||
return s.decode('unicode_escape')
|
||||
bytes_type = str
|
||||
unicode_type = unicode
|
||||
basestring_type = basestring
|
||||
|
||||
|
||||
if sys.version_info > (3,):
|
||||
exec("""
|
||||
def raise_exc_info(exc_info):
|
||||
"""Re-raise an exception (with original traceback) from an exc_info tuple.
|
||||
raise exc_info[1].with_traceback(exc_info[2])
|
||||
|
||||
The argument is a ``(type, value, traceback)`` tuple as returned by
|
||||
`sys.exc_info`.
|
||||
"""
|
||||
# 2to3 isn't smart enough to convert three-argument raise
|
||||
# statements correctly in some cases.
|
||||
if isinstance(exc_info[1], exc_info[0]):
|
||||
raise exc_info[1], None, exc_info[2]
|
||||
# After 2to3: raise exc_info[1].with_traceback(exc_info[2])
|
||||
else:
|
||||
# I think this branch is only taken for string exceptions,
|
||||
# which were removed in Python 2.6.
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
# After 2to3: raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
|
||||
def exec_in(code, glob, loc=None):
|
||||
if isinstance(code, str):
|
||||
code = compile(code, '<string>', 'exec', dont_inherit=True)
|
||||
exec(code, glob, loc)
|
||||
""")
|
||||
else:
|
||||
exec("""
|
||||
def raise_exc_info(exc_info):
|
||||
raise exc_info[0], exc_info[1], exc_info[2]
|
||||
|
||||
def exec_in(code, glob, loc=None):
|
||||
if isinstance(code, basestring):
|
||||
# exec(string) inherits the caller's future imports; compile
|
||||
# the string first to prevent that.
|
||||
code = compile(code, '<string>', 'exec', dont_inherit=True)
|
||||
exec code in glob, loc
|
||||
""")
|
||||
|
||||
|
||||
class Configurable(object):
|
||||
@@ -164,7 +175,7 @@ class Configurable(object):
|
||||
some parameters.
|
||||
"""
|
||||
base = cls.configurable_base()
|
||||
if isinstance(impl, (unicode, bytes_type)):
|
||||
if isinstance(impl, (unicode_type, bytes_type)):
|
||||
impl = import_object(impl)
|
||||
if impl is not None and not issubclass(impl, cls):
|
||||
raise ValueError("Invalid subclass of %s" % cls)
|
||||
@@ -179,7 +190,6 @@ class Configurable(object):
|
||||
base.__impl_class = cls.configurable_default()
|
||||
return base.__impl_class
|
||||
|
||||
|
||||
@classmethod
|
||||
def _save_configuration(cls):
|
||||
base = cls.configurable_base()
|
||||
@@ -192,6 +202,45 @@ class Configurable(object):
|
||||
base.__impl_kwargs = saved[1]
|
||||
|
||||
|
||||
class ArgReplacer(object):
|
||||
"""Replaces one value in an ``args, kwargs`` pair.
|
||||
|
||||
Inspects the function signature to find an argument by name
|
||||
whether it is passed by position or keyword. For use in decorators
|
||||
and similar wrappers.
|
||||
"""
|
||||
def __init__(self, func, name):
|
||||
"""Create an ArgReplacer for the named argument to the given function.
|
||||
"""
|
||||
self.name = name
|
||||
try:
|
||||
self.arg_pos = inspect.getargspec(func).args.index(self.name)
|
||||
except ValueError:
|
||||
# Not a positional parameter
|
||||
self.arg_pos = None
|
||||
|
||||
def replace(self, new_value, args, kwargs):
|
||||
"""Replace the named argument in ``args, kwargs`` with ``new_value``.
|
||||
|
||||
Returns ``(old_value, args, kwargs)``. The returned ``args`` and
|
||||
``kwargs`` objects may not be the same as the input objects, or
|
||||
the input objects may be mutated.
|
||||
|
||||
If the named argument was not found, ``new_value`` will be added
|
||||
to ``kwargs`` and None will be returned as ``old_value``.
|
||||
"""
|
||||
if self.arg_pos is not None and len(args) > self.arg_pos:
|
||||
# The arg to replace is passed positionally
|
||||
old_value = args[self.arg_pos]
|
||||
args = list(args) # *args is normally a tuple
|
||||
args[self.arg_pos] = new_value
|
||||
else:
|
||||
# The arg to replace is either omitted or passed by keyword.
|
||||
old_value = kwargs.get(self.name)
|
||||
kwargs[self.name] = new_value
|
||||
return old_value, args, kwargs
|
||||
|
||||
|
||||
def doctests():
|
||||
import doctest
|
||||
return doctest.DocTestSuite()
|
||||
|
||||
Reference in New Issue
Block a user