@@ -215,17 +215,21 @@ def __new__(
215215 mcs , name : str , bases : Tuple [Type ["StoreMeta" ], ...],
216216 attrs : Dict [str , Any ],
217217 ) -> "StoreMeta" :
218+ # Create the class first to ensure annotations are available
219+ # Python 3.14+ (PEP 649) defers annotation evaluation
220+ cls = super ().__new__ (mcs , name , bases , attrs )
221+
218222 annotations = merge_annotations (
219- attrs . get ( "__annotations__" , {}), * bases ,
223+ getattr ( cls , "__annotations__" , {}), * bases ,
220224 )
221- attrs [ " __annotations__" ] = annotations
222- attrs [ " _fields" ] = tuple (
225+ cls . __annotations__ = annotations
226+ cls . _fields = tuple (
223227 filter (
224228 lambda x : not x .startswith ("_" ),
225229 annotations .keys (),
226230 ),
227231 )
228- return super (). __new__ ( mcs , name , bases , attrs )
232+ return cls
229233
230234
231235class Store (metaclass = StoreMeta ):
@@ -236,10 +240,12 @@ def __new__(cls, **kwargs: Any) -> "Store":
236240 obj = super ().__new__ (cls )
237241
238242 type_map : Dict [str , Tuple [Type , Any ]] = {}
239- for key , value in obj .__annotations__ .items ():
243+ # Use cls.__annotations__ instead of obj.__annotations__ to avoid
244+ # triggering __getattr__ before _values is initialized (Python 3.14+)
245+ for key , value in cls .__annotations__ .items ():
240246 if key .startswith ("_" ):
241247 continue
242- type_map [key ] = (value , getattr (obj , key , cls ._default_value ))
248+ type_map [key ] = (value , getattr (cls , key , cls ._default_value ))
243249
244250 for key , (value_type , default ) in type_map .items ():
245251 if default is cls ._default_value and key not in kwargs :
@@ -420,8 +426,14 @@ def __new__(
420426 mcs , name : str , bases : Tuple [Type ["Meta" ], ...],
421427 attrs : Dict [str , Any ],
422428 ) -> "Meta" :
429+ # Create the class first to ensure annotations are available
430+ # Python 3.14+ (PEP 649) defers annotation evaluation, so
431+ # __annotations__ may not be in attrs during class creation
432+ cls = super ().__new__ (mcs , name , bases , attrs )
433+
434+ # Now get annotations from the created class
423435 annotations = merge_annotations (
424- attrs . get ( "__annotations__" , {}), * bases ,
436+ getattr ( cls , "__annotations__" , {}), * bases ,
425437 )
426438
427439 arguments = {}
@@ -441,7 +453,7 @@ def __new__(
441453 if not isinstance (
442454 argument , (TypedArgument , AbstractGroup , AbstractParser ),
443455 ):
444- attrs [ key ] = ...
456+ setattr ( cls , key , ...)
445457
446458 is_required = argument is None or argument is Ellipsis
447459
@@ -481,10 +493,9 @@ def __new__(
481493 elif isinstance (value , AbstractParser ):
482494 subparsers [key ] = value
483495
484- attrs ["__arguments__" ] = MappingProxyType (arguments )
485- attrs ["__argument_groups__" ] = MappingProxyType (argument_groups )
486- attrs ["__subparsers__" ] = MappingProxyType (subparsers )
487- cls = super ().__new__ (mcs , name , bases , attrs )
496+ cls .__arguments__ = MappingProxyType (arguments )
497+ cls .__argument_groups__ = MappingProxyType (argument_groups )
498+ cls .__subparsers__ = MappingProxyType (subparsers )
488499 return cls
489500
490501
0 commit comments