Michael Merickel
2018-10-18 e4c0570d5c67ddf0ad9502169b59475ba0784d82
commit | author | age
a1a9fb 1 import threading
17b8bc 2
b60bdb 3 from pyramid.registry import global_registry
a1a9fb 4
0c29cf 5
a1a9fb 6 class ThreadLocalManager(threading.local):
67ed63 7     def __init__(self, default=None):
CM 8         # http://code.google.com/p/google-app-engine-django/issues/detail?id=119
815471 9         # we *must* use a keyword argument for ``default`` here instead
67ed63 10         # of a positional argument to work around a bug in the
CM 11         # implementation of _threading_local.local in Python, which is
12         # used by GAE instead of _thread.local
a1a9fb 13         self.stack = []
CM 14         self.default = default
815471 15
a1a9fb 16     def push(self, info):
CM 17         self.stack.append(info)
18
0c29cf 19     set = push  # b/c
a1a9fb 20
CM 21     def pop(self):
22         if self.stack:
23             return self.stack.pop()
24
25     def get(self):
26         try:
27             return self.stack[-1]
28         except IndexError:
29             return self.default()
30
31     def clear(self):
32         self.stack[:] = []
33
0c29cf 34
a1a9fb 35 def defaults():
dda9fa 36     return {'request': None, 'registry': global_registry}
a1a9fb 37
0c29cf 38
67ed63 39 manager = ThreadLocalManager(default=defaults)
0c29cf 40
947b8b 41
CM 42 def get_current_request():
822653 43     """
MM 44     Return the currently active request or ``None`` if no request
925580 45     is currently active.
CM 46
47     This function should be used *extremely sparingly*, usually only
67bfa0 48     in unit testing code.  It's almost always usually a mistake to use
925580 49     ``get_current_request`` outside a testing context because its
CM 50     usage makes it possible to write code that can be neither easily
51     tested nor scripted.
822653 52
947b8b 53     """
CM 54     return manager.get()['request']
55
0c29cf 56
MM 57 def get_current_registry(
58     context=None
59 ):  # context required by getSiteManager API
822653 60     """
MM 61     Return the currently active :term:`application registry` or the
2cfb02 62     global application registry if no request is currently active.
925580 63
CM 64     This function should be used *extremely sparingly*, usually only
859ff0 65     in unit testing code.  It's almost always usually a mistake to use
925580 66     ``get_current_registry`` outside a testing context because its
CM 67     usage makes it possible to write code that can be neither easily
68     tested nor scripted.
822653 69
947b8b 70     """
CM 71     return manager.get()['registry']
822653 72
0c29cf 73
822653 74 class RequestContext(object):
MM 75     def __init__(self, request):
76         self.request = request
77
78     def begin(self):
79         request = self.request
80         registry = request.registry
81         manager.push({'registry': registry, 'request': request})
82         return request
83
84     def end(self):
85         manager.pop()
86
87     def __enter__(self):
88         return self.begin()
89
90     def __exit__(self, *args):
91         self.end()