@@ -85,39 +85,32 @@ class BaseFileLock(ABC, contextlib.ContextDecorator):
85
85
def __new__ ( # noqa: PLR0913
86
86
cls ,
87
87
lock_file : str | os .PathLike [str ],
88
- timeout : float = - 1 ,
89
- mode : int = 0o644 ,
90
- thread_local : bool = True , # noqa: FBT001, FBT002
88
+ timeout : float = - 1 , # noqa: ARG003
89
+ mode : int = 0o644 , # noqa: ARG003
90
+ thread_local : bool = True , # noqa: FBT001, FBT002, ARG003
91
91
* ,
92
- blocking : bool = True ,
92
+ blocking : bool = True , # noqa: ARG003
93
93
is_singleton : bool = False ,
94
94
** kwargs : Any , # capture remaining kwargs for subclasses # noqa: ARG003, ANN401
95
95
) -> Self :
96
96
"""Create a new lock object or if specified return the singleton instance for the lock file."""
97
97
if not is_singleton :
98
- self = super ().__new__ (cls )
99
- self ._initialize (lock_file , timeout , mode , thread_local , blocking = blocking , is_singleton = is_singleton )
100
- return self
98
+ return super ().__new__ (cls )
101
99
102
100
instance = cls ._instances .get (str (lock_file ))
103
101
if not instance :
104
102
self = super ().__new__ (cls )
105
- self ._initialize (lock_file , timeout , mode , thread_local , blocking = blocking , is_singleton = is_singleton )
106
103
cls ._instances [str (lock_file )] = self
107
104
return self
108
105
109
- if timeout != instance .timeout or mode != instance .mode :
110
- msg = "Singleton lock instances cannot be initialized with differing arguments"
111
- raise ValueError (msg )
112
-
113
106
return instance # type: ignore[return-value] # https://github.com/python/mypy/issues/15322
114
107
115
108
def __init_subclass__ (cls , ** kwargs : dict [str , Any ]) -> None :
116
109
"""Setup unique state for lock subclasses."""
117
110
super ().__init_subclass__ (** kwargs )
118
111
cls ._instances = WeakValueDictionary ()
119
112
120
- def _initialize ( # noqa: PLR0913
113
+ def __init__ ( # noqa: PLR0913
121
114
self ,
122
115
lock_file : str | os .PathLike [str ],
123
116
timeout : float = - 1 ,
@@ -143,6 +136,34 @@ def _initialize( # noqa: PLR0913
143
136
to pass the same object around.
144
137
145
138
"""
139
+ if is_singleton and hasattr (self , "_context" ):
140
+ # test whether other parameters match existing instance.
141
+ if not self .is_singleton :
142
+ msg = "__init__ should only be called on initialized object if it is a singleton"
143
+ raise RuntimeError (msg )
144
+
145
+ params_to_check = {
146
+ "thread_local" : (thread_local , self .is_thread_local ()),
147
+ "timeout" : (timeout , self .timeout ),
148
+ "mode" : (mode , self .mode ),
149
+ "blocking" : (blocking , self .blocking ),
150
+ }
151
+
152
+ non_matching_params = {
153
+ name : (passed_param , set_param )
154
+ for name , (passed_param , set_param ) in params_to_check .items ()
155
+ if passed_param != set_param
156
+ }
157
+ if not non_matching_params :
158
+ return # bypass initialization because object is already initialized
159
+
160
+ # parameters do not match; raise error
161
+ msg = "Singleton lock instances cannot be initialized with differing arguments"
162
+ msg += "\n Non-matching arguments: "
163
+ for param_name , (passed_param , set_param ) in non_matching_params .items ():
164
+ msg += f"\n \t { param_name } (existing lock has { set_param } but { passed_param } was passed)"
165
+ raise ValueError (msg )
166
+
146
167
self ._is_thread_local = thread_local
147
168
self ._is_singleton = is_singleton
148
169
0 commit comments