22import weakref
33from collections import OrderedDict
44
5+ from six .moves import _thread
6+
57
68class _TzSingleton (type ):
79 def __init__ (cls , * args , ** kwargs ):
@@ -26,6 +28,8 @@ def __init__(cls, *args, **kwargs):
2628 cls .__strong_cache = OrderedDict ()
2729 cls .__strong_cache_size = 8
2830
31+ cls ._cache_lock = _thread .allocate_lock ()
32+
2933 def __call__ (cls , name , offset ):
3034 if isinstance (offset , timedelta ):
3135 key = (name , offset .total_seconds ())
@@ -37,12 +41,13 @@ def __call__(cls, name, offset):
3741 instance = cls .__instances .setdefault (key ,
3842 cls .instance (name , offset ))
3943
40- cls .__strong_cache [key ] = cls .__strong_cache .pop (key , instance )
44+ # This lock may not be necessary in Python 3. See GH issue #901
45+ with cls ._cache_lock :
46+ cls .__strong_cache [key ] = cls .__strong_cache .pop (key , instance )
4147
42- # Remove an item if the strong cache is overpopulated
43- # TODO: Maybe this should be under a lock?
44- if len (cls .__strong_cache ) > cls .__strong_cache_size :
45- cls .__strong_cache .popitem (last = False )
48+ # Remove an item if the strong cache is overpopulated
49+ if len (cls .__strong_cache ) > cls .__strong_cache_size :
50+ cls .__strong_cache .popitem (last = False )
4651
4752 return instance
4853
@@ -53,6 +58,8 @@ def __init__(cls, *args, **kwargs):
5358 cls .__strong_cache = OrderedDict ()
5459 cls .__strong_cache_size = 8
5560
61+ cls .__cache_lock = _thread .allocate_lock ()
62+
5663 def __call__ (cls , s , posix_offset = False ):
5764 key = (s , posix_offset )
5865 instance = cls .__instances .get (key , None )
@@ -61,13 +68,13 @@ def __call__(cls, s, posix_offset=False):
6168 instance = cls .__instances .setdefault (key ,
6269 cls .instance (s , posix_offset ))
6370
64- cls .__strong_cache [key ] = cls .__strong_cache .pop (key , instance )
65-
71+ # This lock may not be necessary in Python 3. See GH issue #901
72+ with cls .__cache_lock :
73+ cls .__strong_cache [key ] = cls .__strong_cache .pop (key , instance )
6674
67- # Remove an item if the strong cache is overpopulated
68- # TODO: Maybe this should be under a lock?
69- if len (cls .__strong_cache ) > cls .__strong_cache_size :
70- cls .__strong_cache .popitem (last = False )
75+ # Remove an item if the strong cache is overpopulated
76+ if len (cls .__strong_cache ) > cls .__strong_cache_size :
77+ cls .__strong_cache .popitem (last = False )
7178
7279 return instance
7380
0 commit comments