diff options
author | florent <florent.pigout@gmail.com> | 2011-07-09 00:33:26 (GMT) |
---|---|---|
committer | florent <florent.pigout@gmail.com> | 2011-07-09 00:33:26 (GMT) |
commit | 0767eedcd06485f30ee6b00df348b22847c7c7ad (patch) | |
tree | de339586453b0b638889ec607f4ded7de2edc05a /werkzeug/local.py | |
parent | 89198c864831bea0a17f136b897aebc59f606166 (diff) |
make the flask based tools more clean for a nicer use -> move requirement to lib dir + limit import code to the minimumHEADmaster
Diffstat (limited to 'werkzeug/local.py')
-rw-r--r-- | werkzeug/local.py | 405 |
1 files changed, 0 insertions, 405 deletions
diff --git a/werkzeug/local.py b/werkzeug/local.py deleted file mode 100644 index 595c87d..0000000 --- a/werkzeug/local.py +++ /dev/null @@ -1,405 +0,0 @@ -# -*- coding: utf-8 -*- -""" - werkzeug.local - ~~~~~~~~~~~~~~ - - This module implements context-local objects. - - :copyright: (c) 2010 by the Werkzeug Team, see AUTHORS for more details. - :license: BSD, see LICENSE for more details. -""" -try: - from greenlet import getcurrent as get_current_greenlet -except ImportError: # pragma: no cover - try: - from py.magic import greenlet - get_current_greenlet = greenlet.getcurrent - del greenlet - except: - # catch all, py.* fails with so many different errors. - get_current_greenlet = int -try: - from thread import get_ident as get_current_thread, allocate_lock -except ImportError: # pragma: no cover - from dummy_thread import get_ident as get_current_thread, allocate_lock - -from werkzeug.wsgi import ClosingIterator -from werkzeug._internal import _patch_wrapper - - -# get the best ident function. if greenlets are not installed we can -# safely just use the builtin thread function and save a python methodcall -# and the cost of calculating a hash. -if get_current_greenlet is int: # pragma: no cover - get_ident = get_current_thread -else: - get_ident = lambda: (get_current_thread(), get_current_greenlet()) - - -def release_local(local): - """Releases the contents of the local for the current context. - This makes it possible to use locals without a manager. - - Example:: - - >>> loc = Local() - >>> loc.foo = 42 - >>> release_local(loc) - >>> hasattr(loc, 'foo') - False - - With this function one can release :class:`Local` objects as well - as :class:`StackLocal` objects. However it is not possible to - release data held by proxies that way, one always has to retain - a reference to the underlying local object in order to be able - to release it. - - .. versionadded:: 0.6.1 - """ - local.__release_local__() - - -class Local(object): - __slots__ = ('__storage__', '__lock__') - - def __init__(self): - object.__setattr__(self, '__storage__', {}) - object.__setattr__(self, '__lock__', allocate_lock()) - - def __iter__(self): - return self.__storage__.iteritems() - - def __call__(self, proxy): - """Create a proxy for a name.""" - return LocalProxy(self, proxy) - - def __release_local__(self): - self.__storage__.pop(get_ident(), None) - - def __getattr__(self, name): - self.__lock__.acquire() - try: - try: - return self.__storage__[get_ident()][name] - except KeyError: - raise AttributeError(name) - finally: - self.__lock__.release() - - def __setattr__(self, name, value): - self.__lock__.acquire() - try: - ident = get_ident() - storage = self.__storage__ - if ident in storage: - storage[ident][name] = value - else: - storage[ident] = {name: value} - finally: - self.__lock__.release() - - def __delattr__(self, name): - self.__lock__.acquire() - try: - try: - del self.__storage__[get_ident()][name] - except KeyError: - raise AttributeError(name) - finally: - self.__lock__.release() - - -class LocalStack(object): - """This class works similar to a :class:`Local` but keeps a stack - of objects instead. This is best explained with an example:: - - >>> ls = LocalStack() - >>> ls.push(42) - >>> ls.top - 42 - >>> ls.push(23) - >>> ls.top - 23 - >>> ls.pop() - 23 - >>> ls.top - 42 - - They can be force released by using a :class:`LocalManager` or with - the :func:`release_local` function but the correct way is to pop the - item from the stack after using. When the stack is empty it will - no longer be bound to the current context (and as such released). - - By calling the stack without arguments it returns a proxy that resolves to - the topmost item on the stack. - - .. versionadded:: 0.6.1 - """ - - def __init__(self): - self._local = Local() - self._lock = allocate_lock() - - def __release_local__(self): - self._local.__release_local__() - - def __call__(self): - def _lookup(): - rv = self.top - if rv is None: - raise RuntimeError('object unbound') - return rv - return LocalProxy(_lookup) - - def push(self, obj): - """Pushes a new item to the stack""" - self._lock.acquire() - try: - rv = getattr(self._local, 'stack', None) - if rv is None: - self._local.stack = rv = [] - rv.append(obj) - return rv - finally: - self._lock.release() - - def pop(self): - """Removes the topmost item from the stack, will return the - old value or `None` if the stack was already empty. - """ - self._lock.acquire() - try: - stack = getattr(self._local, 'stack', None) - if stack is None: - return None - elif len(stack) == 1: - release_local(self._local) - return stack[-1] - else: - return stack.pop() - finally: - self._lock.release() - - @property - def top(self): - """The topmost item on the stack. If the stack is empty, - `None` is returned. - """ - try: - return self._local.stack[-1] - except (AttributeError, IndexError): - return None - - -class LocalManager(object): - """Local objects cannot manage themselves. For that you need a local - manager. You can pass a local manager multiple locals or add them later - by appending them to `manager.locals`. Everytime the manager cleans up - it, will clean up all the data left in the locals for this context. - - .. versionchanged:: 0.6.1 - Instead of a manager the :func:`release_local` function can be used - as well. - """ - - def __init__(self, locals=None): - if locals is None: - self.locals = [] - elif isinstance(locals, Local): - self.locals = [locals] - else: - self.locals = list(locals) - - def get_ident(self): - """Return the context identifier the local objects use internally for - this context. You cannot override this method to change the behavior - but use it to link other context local objects (such as SQLAlchemy's - scoped sessions) to the Werkzeug locals. - """ - return get_ident() - - def cleanup(self): - """Manually clean up the data in the locals for this context. Call - this at the end of the request or use `make_middleware()`. - """ - ident = self.get_ident() - for local in self.locals: - release_local(local) - - def make_middleware(self, app): - """Wrap a WSGI application so that cleaning up happens after - request end. - """ - def application(environ, start_response): - return ClosingIterator(app(environ, start_response), self.cleanup) - return application - - def middleware(self, func): - """Like `make_middleware` but for decorating functions. - - Example usage:: - - @manager.middleware - def application(environ, start_response): - ... - - The difference to `make_middleware` is that the function passed - will have all the arguments copied from the inner application - (name, docstring, module). - """ - return _patch_wrapper(func, self.make_middleware(func)) - - def __repr__(self): - return '<%s storages: %d>' % ( - self.__class__.__name__, - len(self.locals) - ) - - -class LocalProxy(object): - """Acts as a proxy for a werkzeug local. Forwards all operations to - a proxied object. The only operations not supported for forwarding - are right handed operands and any kind of assignment. - - Example usage:: - - from werkzeug import Local - l = Local() - - # these are proxies - request = l('request') - user = l('user') - - - from werkzeug import LocalStack - _response_local = LocalStack() - - # this is a proxy - response = _response_local() - - Whenever something is bound to l.user / l.request the proxy objects - will forward all operations. If no object is bound a :exc:`RuntimeError` - will be raised. - - To create proxies to :class:`Local` or :class:`LocalStack` objects, - call the object as shown above. If you want to have a proxy to an - object looked up by a function, you can (as of Werkzeug 0.6.1) pass - a function to the :class:`LocalProxy` constructor:: - - session = LocalProxy(lambda: get_current_request().session) - - .. versionchanged:: 0.6.1 - The class can be instanciated with a callable as well now. - """ - __slots__ = ('__local', '__dict__', '__name__') - - def __init__(self, local, name=None): - object.__setattr__(self, '_LocalProxy__local', local) - object.__setattr__(self, '__name__', name) - - def _get_current_object(self): - """Return the current object. This is useful if you want the real - object behind the proxy at a time for performance reasons or because - you want to pass the object into a different context. - """ - if not hasattr(self.__local, '__release_local__'): - return self.__local() - try: - return getattr(self.__local, self.__name__) - except AttributeError: - raise RuntimeError('no object bound to %s' % self.__name__) - - @property - def __dict__(self): - try: - return self._get_current_object().__dict__ - except RuntimeError: - return AttributeError('__dict__') - - def __repr__(self): - try: - obj = self._get_current_object() - except RuntimeError: - return '<%s unbound>' % self.__class__.__name__ - return repr(obj) - - def __nonzero__(self): - try: - return bool(self._get_current_object()) - except RuntimeError: - return False - - def __unicode__(self): - try: - return unicode(self._get_current_object()) - except RuntimeError: - return repr(self) - - def __dir__(self): - try: - return dir(self._get_current_object()) - except RuntimeError: - return [] - - def __getattr__(self, name): - if name == '__members__': - return dir(self._get_current_object()) - return getattr(self._get_current_object(), name) - - def __setitem__(self, key, value): - self._get_current_object()[key] = value - - def __delitem__(self, key): - del self._get_current_object()[key] - - def __setslice__(self, i, j, seq): - self._get_current_object()[i:j] = seq - - def __delslice__(self, i, j): - del self._get_current_object()[i:j] - - __setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v) - __delattr__ = lambda x, n: delattr(x._get_current_object(), n) - __str__ = lambda x: str(x._get_current_object()) - __lt__ = lambda x, o: x._get_current_object() < o - __le__ = lambda x, o: x._get_current_object() <= o - __eq__ = lambda x, o: x._get_current_object() == o - __ne__ = lambda x, o: x._get_current_object() != o - __gt__ = lambda x, o: x._get_current_object() > o - __ge__ = lambda x, o: x._get_current_object() >= o - __cmp__ = lambda x, o: cmp(x._get_current_object(), o) - __hash__ = lambda x: hash(x._get_current_object()) - __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw) - __len__ = lambda x: len(x._get_current_object()) - __getitem__ = lambda x, i: x._get_current_object()[i] - __iter__ = lambda x: iter(x._get_current_object()) - __contains__ = lambda x, i: i in x._get_current_object() - __getslice__ = lambda x, i, j: x._get_current_object()[i:j] - __add__ = lambda x, o: x._get_current_object() + o - __sub__ = lambda x, o: x._get_current_object() - o - __mul__ = lambda x, o: x._get_current_object() * o - __floordiv__ = lambda x, o: x._get_current_object() // o - __mod__ = lambda x, o: x._get_current_object() % o - __divmod__ = lambda x, o: x._get_current_object().__divmod__(o) - __pow__ = lambda x, o: x._get_current_object() ** o - __lshift__ = lambda x, o: x._get_current_object() << o - __rshift__ = lambda x, o: x._get_current_object() >> o - __and__ = lambda x, o: x._get_current_object() & o - __xor__ = lambda x, o: x._get_current_object() ^ o - __or__ = lambda x, o: x._get_current_object() | o - __div__ = lambda x, o: x._get_current_object().__div__(o) - __truediv__ = lambda x, o: x._get_current_object().__truediv__(o) - __neg__ = lambda x: -(x._get_current_object()) - __pos__ = lambda x: +(x._get_current_object()) - __abs__ = lambda x: abs(x._get_current_object()) - __invert__ = lambda x: ~(x._get_current_object()) - __complex__ = lambda x: complex(x._get_current_object()) - __int__ = lambda x: int(x._get_current_object()) - __long__ = lambda x: long(x._get_current_object()) - __float__ = lambda x: float(x._get_current_object()) - __oct__ = lambda x: oct(x._get_current_object()) - __hex__ = lambda x: hex(x._get_current_object()) - __index__ = lambda x: x._get_current_object().__index__() - __coerce__ = lambda x, o: x.__coerce__(x, o) - __enter__ = lambda x: x.__enter__() - __exit__ = lambda x, *a, **kw: x.__exit__(*a, **kw) |