00001 """Miscellaneous utility functions and classes.
00002
00003 This module is used internally by Tornado. It is not necessarily expected
00004 that the functions and classes defined here will be useful to other
00005 applications, but they are documented here in case they are.
00006
00007 The one public-facing part of this module is the `Configurable` class
00008 and its `~Configurable.configure` method, which becomes a part of the
00009 interface of its subclasses, including `.AsyncHTTPClient`, `.IOLoop`,
00010 and `.Resolver`.
00011 """
00012
00013 from __future__ import absolute_import, division, print_function, with_statement
00014
00015 import array
00016 import inspect
00017 import os
00018 import sys
00019 import zlib
00020
00021
00022 try:
00023 xrange
00024 except NameError:
00025 xrange = range
00026
00027
00028 class ObjectDict(dict):
00029 """Makes a dictionary behave like an object, with attribute-style access.
00030 """
00031 def __getattr__(self, name):
00032 try:
00033 return self[name]
00034 except KeyError:
00035 raise AttributeError(name)
00036
00037 def __setattr__(self, name, value):
00038 self[name] = value
00039
00040
00041 class GzipDecompressor(object):
00042 """Streaming gzip decompressor.
00043
00044 The interface is like that of `zlib.decompressobj` (without some of the
00045 optional arguments, but it understands gzip headers and checksums.
00046 """
00047 def __init__(self):
00048
00049
00050
00051 self.decompressobj = zlib.decompressobj(16 + zlib.MAX_WBITS)
00052
00053 def decompress(self, value, max_length=None):
00054 """Decompress a chunk, returning newly-available data.
00055
00056 Some data may be buffered for later processing; `flush` must
00057 be called when there is no more input data to ensure that
00058 all data was processed.
00059
00060 If ``max_length`` is given, some input data may be left over
00061 in ``unconsumed_tail``; you must retrieve this value and pass
00062 it back to a future call to `decompress` if it is not empty.
00063 """
00064 return self.decompressobj.decompress(value, max_length)
00065
00066 @property
00067 def unconsumed_tail(self):
00068 """Returns the unconsumed portion left over
00069 """
00070 return self.decompressobj.unconsumed_tail
00071
00072 def flush(self):
00073 """Return any remaining buffered data not yet returned by decompress.
00074
00075 Also checks for errors such as truncated input.
00076 No other methods may be called on this object after `flush`.
00077 """
00078 return self.decompressobj.flush()
00079
00080
00081 def import_object(name):
00082 """Imports an object by name.
00083
00084 import_object('x') is equivalent to 'import x'.
00085 import_object('x.y.z') is equivalent to 'from x.y import z'.
00086
00087 >>> import tornado.escape
00088 >>> import_object('tornado.escape') is tornado.escape
00089 True
00090 >>> import_object('tornado.escape.utf8') is tornado.escape.utf8
00091 True
00092 >>> import_object('tornado') is tornado
00093 True
00094 >>> import_object('tornado.missing_module')
00095 Traceback (most recent call last):
00096 ...
00097 ImportError: No module named missing_module
00098 """
00099 if name.count('.') == 0:
00100 return __import__(name, None, None)
00101
00102 parts = name.split('.')
00103 obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)
00104 try:
00105 return getattr(obj, parts[-1])
00106 except AttributeError:
00107 raise ImportError("No module named %s" % parts[-1])
00108
00109
00110
00111
00112
00113
00114
00115 if type('') is not type(b''):
00116 def u(s):
00117 return s
00118 bytes_type = bytes
00119 unicode_type = str
00120 basestring_type = str
00121 else:
00122 def u(s):
00123 return s.decode('unicode_escape')
00124 bytes_type = str
00125 unicode_type = unicode
00126 basestring_type = basestring
00127
00128
00129 if sys.version_info > (3,):
00130 exec("""
00131 def raise_exc_info(exc_info):
00132 raise exc_info[1].with_traceback(exc_info[2])
00133
00134 def exec_in(code, glob, loc=None):
00135 if isinstance(code, str):
00136 code = compile(code, '<string>', 'exec', dont_inherit=True)
00137 exec(code, glob, loc)
00138 """)
00139 else:
00140 exec("""
00141 def raise_exc_info(exc_info):
00142 raise exc_info[0], exc_info[1], exc_info[2]
00143
00144 def exec_in(code, glob, loc=None):
00145 if isinstance(code, basestring):
00146 # exec(string) inherits the caller's future imports; compile
00147 # the string first to prevent that.
00148 code = compile(code, '<string>', 'exec', dont_inherit=True)
00149 exec code in glob, loc
00150 """)
00151
00152
00153 def errno_from_exception(e):
00154 """Provides the errno from an Exception object.
00155
00156 There are cases that the errno attribute was not set so we pull
00157 the errno out of the args but if someone instatiates an Exception
00158 without any args you will get a tuple error. So this function
00159 abstracts all that behavior to give you a safe way to get the
00160 errno.
00161 """
00162
00163 if hasattr(e, 'errno'):
00164 return e.errno
00165 elif e.args:
00166 return e.args[0]
00167 else:
00168 return None
00169
00170
00171 class Configurable(object):
00172 """Base class for configurable interfaces.
00173
00174 A configurable interface is an (abstract) class whose constructor
00175 acts as a factory function for one of its implementation subclasses.
00176 The implementation subclass as well as optional keyword arguments to
00177 its initializer can be set globally at runtime with `configure`.
00178
00179 By using the constructor as the factory method, the interface
00180 looks like a normal class, `isinstance` works as usual, etc. This
00181 pattern is most useful when the choice of implementation is likely
00182 to be a global decision (e.g. when `~select.epoll` is available,
00183 always use it instead of `~select.select`), or when a
00184 previously-monolithic class has been split into specialized
00185 subclasses.
00186
00187 Configurable subclasses must define the class methods
00188 `configurable_base` and `configurable_default`, and use the instance
00189 method `initialize` instead of ``__init__``.
00190 """
00191 __impl_class = None
00192 __impl_kwargs = None
00193
00194 def __new__(cls, **kwargs):
00195 base = cls.configurable_base()
00196 args = {}
00197 if cls is base:
00198 impl = cls.configured_class()
00199 if base.__impl_kwargs:
00200 args.update(base.__impl_kwargs)
00201 else:
00202 impl = cls
00203 args.update(kwargs)
00204 instance = super(Configurable, cls).__new__(impl)
00205
00206
00207
00208 instance.initialize(**args)
00209 return instance
00210
00211 @classmethod
00212 def configurable_base(cls):
00213 """Returns the base class of a configurable hierarchy.
00214
00215 This will normally return the class in which it is defined.
00216 (which is *not* necessarily the same as the cls classmethod parameter).
00217 """
00218 raise NotImplementedError()
00219
00220 @classmethod
00221 def configurable_default(cls):
00222 """Returns the implementation class to be used if none is configured."""
00223 raise NotImplementedError()
00224
00225 def initialize(self):
00226 """Initialize a `Configurable` subclass instance.
00227
00228 Configurable classes should use `initialize` instead of ``__init__``.
00229 """
00230
00231 @classmethod
00232 def configure(cls, impl, **kwargs):
00233 """Sets the class to use when the base class is instantiated.
00234
00235 Keyword arguments will be saved and added to the arguments passed
00236 to the constructor. This can be used to set global defaults for
00237 some parameters.
00238 """
00239 base = cls.configurable_base()
00240 if isinstance(impl, (unicode_type, bytes_type)):
00241 impl = import_object(impl)
00242 if impl is not None and not issubclass(impl, cls):
00243 raise ValueError("Invalid subclass of %s" % cls)
00244 base.__impl_class = impl
00245 base.__impl_kwargs = kwargs
00246
00247 @classmethod
00248 def configured_class(cls):
00249 """Returns the currently configured class."""
00250 base = cls.configurable_base()
00251 if cls.__impl_class is None:
00252 base.__impl_class = cls.configurable_default()
00253 return base.__impl_class
00254
00255 @classmethod
00256 def _save_configuration(cls):
00257 base = cls.configurable_base()
00258 return (base.__impl_class, base.__impl_kwargs)
00259
00260 @classmethod
00261 def _restore_configuration(cls, saved):
00262 base = cls.configurable_base()
00263 base.__impl_class = saved[0]
00264 base.__impl_kwargs = saved[1]
00265
00266
00267 class ArgReplacer(object):
00268 """Replaces one value in an ``args, kwargs`` pair.
00269
00270 Inspects the function signature to find an argument by name
00271 whether it is passed by position or keyword. For use in decorators
00272 and similar wrappers.
00273 """
00274 def __init__(self, func, name):
00275 self.name = name
00276 try:
00277 self.arg_pos = inspect.getargspec(func).args.index(self.name)
00278 except ValueError:
00279
00280 self.arg_pos = None
00281
00282 def get_old_value(self, args, kwargs, default=None):
00283 """Returns the old value of the named argument without replacing it.
00284
00285 Returns ``default`` if the argument is not present.
00286 """
00287 if self.arg_pos is not None and len(args) > self.arg_pos:
00288 return args[self.arg_pos]
00289 else:
00290 return kwargs.get(self.name, default)
00291
00292 def replace(self, new_value, args, kwargs):
00293 """Replace the named argument in ``args, kwargs`` with ``new_value``.
00294
00295 Returns ``(old_value, args, kwargs)``. The returned ``args`` and
00296 ``kwargs`` objects may not be the same as the input objects, or
00297 the input objects may be mutated.
00298
00299 If the named argument was not found, ``new_value`` will be added
00300 to ``kwargs`` and None will be returned as ``old_value``.
00301 """
00302 if self.arg_pos is not None and len(args) > self.arg_pos:
00303
00304 old_value = args[self.arg_pos]
00305 args = list(args)
00306 args[self.arg_pos] = new_value
00307 else:
00308
00309 old_value = kwargs.get(self.name)
00310 kwargs[self.name] = new_value
00311 return old_value, args, kwargs
00312
00313
00314 def timedelta_to_seconds(td):
00315 """Equivalent to td.total_seconds() (introduced in python 2.7)."""
00316 return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / float(10 ** 6)
00317
00318
00319 def _websocket_mask_python(mask, data):
00320 """Websocket masking function.
00321
00322 `mask` is a `bytes` object of length 4; `data` is a `bytes` object of any length.
00323 Returns a `bytes` object of the same length as `data` with the mask applied
00324 as specified in section 5.3 of RFC 6455.
00325
00326 This pure-python implementation may be replaced by an optimized version when available.
00327 """
00328 mask = array.array("B", mask)
00329 unmasked = array.array("B", data)
00330 for i in xrange(len(data)):
00331 unmasked[i] = unmasked[i] ^ mask[i % 4]
00332 if hasattr(unmasked, 'tobytes'):
00333
00334
00335
00336 return unmasked.tobytes()
00337 else:
00338 return unmasked.tostring()
00339
00340 if (os.environ.get('TORNADO_NO_EXTENSION') or
00341 os.environ.get('TORNADO_EXTENSION') == '0'):
00342
00343
00344 _websocket_mask = _websocket_mask_python
00345 else:
00346 try:
00347 from tornado.speedups import websocket_mask as _websocket_mask
00348 except ImportError:
00349 if os.environ.get('TORNADO_EXTENSION') == '1':
00350 raise
00351 _websocket_mask = _websocket_mask_python
00352
00353
00354 def doctests():
00355 import doctest
00356 return doctest.DocTestSuite()