summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSviatoslav Sydorenko <wk@sydorenko.org.ua>2016-09-16 21:33:48 +0300
committerSviatoslav Sydorenko <wk@sydorenko.org.ua>2016-09-16 21:33:48 +0300
commit18ca113767fdf483ff0e820ac558e3b03334e22e (patch)
tree36b1b2bf0c4dcc41c3cf5477e8f25348f40d1422
parentba195929880397baa09f1dfba8b112deb64e2b92 (diff)
downloadcherrypy-git-18ca113767fdf483ff0e820ac558e3b03334e22e.tar.gz
Drop cherrypy._cpthreadinglocal
It's in stdlib since Python 2.4
-rw-r--r--cherrypy/__init__.py2
-rw-r--r--cherrypy/_cpcompat.py5
-rw-r--r--cherrypy/_cpthreadinglocal.py241
-rw-r--r--docs/pkg/cherrypy.rst8
4 files changed, 1 insertions, 255 deletions
diff --git a/cherrypy/__init__.py b/cherrypy/__init__.py
index 8c3f0dac..ccf6100a 100644
--- a/cherrypy/__init__.py
+++ b/cherrypy/__init__.py
@@ -61,7 +61,7 @@ try:
except ImportError:
pass
-from cherrypy._cpcompat import threadlocal as _local
+from threading import local as _local
from cherrypy._cperror import HTTPError, HTTPRedirect, InternalRedirect # noqa
from cherrypy._cperror import NotFound, CherryPyException, TimeoutError # noqa
diff --git a/cherrypy/_cpcompat.py b/cherrypy/_cpcompat.py
index 9430dbbf..6c158cb9 100644
--- a/cherrypy/_cpcompat.py
+++ b/cherrypy/_cpcompat.py
@@ -145,11 +145,6 @@ except ImportError:
from urllib2 import parse_http_list, parse_keqv_list # noqa
try:
- from threading import local as threadlocal
-except ImportError:
- from cherrypy._cpthreadinglocal import local as threadlocal # noqa
-
-try:
dict.iteritems
# Python 2
iteritems = lambda d: d.iteritems()
diff --git a/cherrypy/_cpthreadinglocal.py b/cherrypy/_cpthreadinglocal.py
deleted file mode 100644
index 04679018..00000000
--- a/cherrypy/_cpthreadinglocal.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# This is a backport of Python-2.4's threading.local() implementation
-
-"""Thread-local objects
-
-(Note that this module provides a Python version of thread
- threading.local class. Depending on the version of Python you're
- using, there may be a faster one available. You should always import
- the local class from threading.)
-
-Thread-local objects support the management of thread-local data.
-If you have data that you want to be local to a thread, simply create
-a thread-local object and use its attributes:
-
- >>> mydata = local()
- >>> mydata.number = 42
- >>> mydata.number
- 42
-
-You can also access the local-object's dictionary:
-
- >>> mydata.__dict__
- {'number': 42}
- >>> mydata.__dict__.setdefault('widgets', [])
- []
- >>> mydata.widgets
- []
-
-What's important about thread-local objects is that their data are
-local to a thread. If we access the data in a different thread:
-
- >>> log = []
- >>> def f():
- ... items = mydata.__dict__.items()
- ... items.sort()
- ... log.append(items)
- ... mydata.number = 11
- ... log.append(mydata.number)
-
- >>> import threading
- >>> thread = threading.Thread(target=f)
- >>> thread.start()
- >>> thread.join()
- >>> log
- [[], 11]
-
-we get different data. Furthermore, changes made in the other thread
-don't affect data seen in this thread:
-
- >>> mydata.number
- 42
-
-Of course, values you get from a local object, including a __dict__
-attribute, are for whatever thread was current at the time the
-attribute was read. For that reason, you generally don't want to save
-these values across threads, as they apply only to the thread they
-came from.
-
-You can create custom local objects by subclassing the local class:
-
- >>> class MyLocal(local):
- ... number = 2
- ... initialized = False
- ... def __init__(self, **kw):
- ... if self.initialized:
- ... raise SystemError('__init__ called too many times')
- ... self.initialized = True
- ... self.__dict__.update(kw)
- ... def squared(self):
- ... return self.number ** 2
-
-This can be useful to support default values, methods and
-initialization. Note that if you define an __init__ method, it will be
-called each time the local object is used in a separate thread. This
-is necessary to initialize each thread's dictionary.
-
-Now if we create a local object:
-
- >>> mydata = MyLocal(color='red')
-
-Now we have a default number:
-
- >>> mydata.number
- 2
-
-an initial color:
-
- >>> mydata.color
- 'red'
- >>> del mydata.color
-
-And a method that operates on the data:
-
- >>> mydata.squared()
- 4
-
-As before, we can access the data in a separate thread:
-
- >>> log = []
- >>> thread = threading.Thread(target=f)
- >>> thread.start()
- >>> thread.join()
- >>> log
- [[('color', 'red'), ('initialized', True)], 11]
-
-without affecting this thread's data:
-
- >>> mydata.number
- 2
- >>> mydata.color
- Traceback (most recent call last):
- ...
- AttributeError: 'MyLocal' object has no attribute 'color'
-
-Note that subclasses can define slots, but they are not thread
-local. They are shared across threads:
-
- >>> class MyLocal(local):
- ... __slots__ = 'number'
-
- >>> mydata = MyLocal()
- >>> mydata.number = 42
- >>> mydata.color = 'red'
-
-So, the separate thread:
-
- >>> thread = threading.Thread(target=f)
- >>> thread.start()
- >>> thread.join()
-
-affects what we see:
-
- >>> mydata.number
- 11
-
->>> del mydata
-"""
-
-# Threading import is at end
-
-
-class _localbase(object):
- __slots__ = '_local__key', '_local__args', '_local__lock'
-
- def __new__(cls, *args, **kw):
- self = object.__new__(cls)
- key = 'thread.local.' + str(id(self))
- object.__setattr__(self, '_local__key', key)
- object.__setattr__(self, '_local__args', (args, kw))
- object.__setattr__(self, '_local__lock', RLock())
-
- if args or kw and (cls.__init__ is object.__init__):
- raise TypeError('Initialization arguments are not supported')
-
- # We need to create the thread dict in anticipation of
- # __init__ being called, to make sure we don't call it
- # again ourselves.
- dict = object.__getattribute__(self, '__dict__')
- currentThread().__dict__[key] = dict
-
- return self
-
-
-def _patch(self):
- key = object.__getattribute__(self, '_local__key')
- d = currentThread().__dict__.get(key)
- if d is None:
- d = {}
- currentThread().__dict__[key] = d
- object.__setattr__(self, '__dict__', d)
-
- # we have a new instance dict, so call out __init__ if we have
- # one
- cls = type(self)
- if cls.__init__ is not object.__init__:
- args, kw = object.__getattribute__(self, '_local__args')
- cls.__init__(self, *args, **kw)
- else:
- object.__setattr__(self, '__dict__', d)
-
-
-class local(_localbase):
-
- def __getattribute__(self, name):
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
- return object.__getattribute__(self, name)
- finally:
- lock.release()
-
- def __setattr__(self, name, value):
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
- return object.__setattr__(self, name, value)
- finally:
- lock.release()
-
- def __delattr__(self, name):
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
- return object.__delattr__(self, name)
- finally:
- lock.release()
-
- def __del__():
- threading_enumerate = enumerate
- __getattribute__ = object.__getattribute__
-
- def __del__(self):
- key = __getattribute__(self, '_local__key')
-
- try:
- threads = list(threading_enumerate())
- except:
- # if enumerate fails, as it seems to do during
- # shutdown, we'll skip cleanup under the assumption
- # that there is nothing to clean up
- return
-
- for thread in threads:
- try:
- __dict__ = thread.__dict__
- except AttributeError:
- # Thread is dying, rest in peace
- continue
-
- if key in __dict__:
- try:
- del __dict__[key]
- except KeyError:
- pass # didn't have anything in this thread
-
- return __del__
- __del__ = __del__()
-
-from threading import currentThread, enumerate, RLock # noqa
diff --git a/docs/pkg/cherrypy.rst b/docs/pkg/cherrypy.rst
index e9287331..c03b7971 100644
--- a/docs/pkg/cherrypy.rst
+++ b/docs/pkg/cherrypy.rst
@@ -112,14 +112,6 @@ cherrypy._cpserver module
:undoc-members:
:show-inheritance:
-cherrypy._cpthreadinglocal module
----------------------------------
-
-.. automodule:: cherrypy._cpthreadinglocal
- :members:
- :undoc-members:
- :show-inheritance:
-
cherrypy._cptools module
------------------------