@@ -9,33 +9,37 @@ class _CVar:
9
9
"""Storage utility for Local."""
10
10
11
11
def __init__ (self ) -> None :
12
+ self ._thread_lock = threading .RLock ()
12
13
self ._data : dict [str , contextvars .ContextVar [Any ]] = {}
13
14
14
15
def __getattr__ (self , key : str ) -> Any :
15
- try :
16
- var = self ._data [key ]
17
- except KeyError :
18
- raise AttributeError (f"{ self !r} object has no attribute { key !r} " )
16
+ with self ._thread_lock :
17
+ try :
18
+ var = self ._data [key ]
19
+ except KeyError :
20
+ raise AttributeError (f"{ self !r} object has no attribute { key !r} " )
19
21
20
22
try :
21
23
return var .get ()
22
24
except LookupError :
23
25
raise AttributeError (f"{ self !r} object has no attribute { key !r} " )
24
26
25
27
def __setattr__ (self , key : str , value : Any ) -> None :
26
- if key == "_data" :
28
+ if key in ( "_data" , "_thread_lock" ) :
27
29
return super ().__setattr__ (key , value )
28
30
29
- var = self ._data .get (key )
30
- if var is None :
31
- self ._data [key ] = var = contextvars .ContextVar (key )
31
+ with self ._thread_lock :
32
+ var = self ._data .get (key )
33
+ if var is None :
34
+ self ._data [key ] = var = contextvars .ContextVar (key )
32
35
var .set (value )
33
36
34
37
def __delattr__ (self , key : str ) -> None :
35
- if key in self ._data :
36
- del self ._data [key ]
37
- else :
38
- raise AttributeError (f"{ self !r} object has no attribute { key !r} " )
38
+ with self ._thread_lock :
39
+ if key in self ._data :
40
+ del self ._data [key ]
41
+ else :
42
+ raise AttributeError (f"{ self !r} object has no attribute { key !r} " )
39
43
40
44
41
45
def Local (thread_critical : bool = False ) -> threading .local | _CVar :
0 commit comments