@@ -85,39 +85,32 @@ class BaseFileLock(ABC, contextlib.ContextDecorator):
8585 def __new__ ( # noqa: PLR0913
8686 cls ,
8787 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
9191 * ,
92- blocking : bool = True ,
92+ blocking : bool = True , # noqa: ARG003
9393 is_singleton : bool = False ,
9494 ** kwargs : Any , # capture remaining kwargs for subclasses # noqa: ARG003, ANN401
9595 ) -> Self :
9696 """Create a new lock object or if specified return the singleton instance for the lock file."""
9797 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 )
10199
102100 instance = cls ._instances .get (str (lock_file ))
103101 if not instance :
104102 self = super ().__new__ (cls )
105- self ._initialize (lock_file , timeout , mode , thread_local , blocking = blocking , is_singleton = is_singleton )
106103 cls ._instances [str (lock_file )] = self
107104 return self
108105
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-
113106 return instance # type: ignore[return-value] # https://github.com/python/mypy/issues/15322
114107
115108 def __init_subclass__ (cls , ** kwargs : dict [str , Any ]) -> None :
116109 """Setup unique state for lock subclasses."""
117110 super ().__init_subclass__ (** kwargs )
118111 cls ._instances = WeakValueDictionary ()
119112
120- def _initialize ( # noqa: PLR0913
113+ def __init__ ( # noqa: PLR0913
121114 self ,
122115 lock_file : str | os .PathLike [str ],
123116 timeout : float = - 1 ,
@@ -143,6 +136,34 @@ def _initialize( # noqa: PLR0913
143136 to pass the same object around.
144137
145138 """
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+
146167 self ._is_thread_local = thread_local
147168 self ._is_singleton = is_singleton
148169
0 commit comments