@@ -343,8 +343,7 @@ def resolve_upload_handler_param(handler: "EventHandler") -> tuple[str, Any]:
343343 )
344344 raise UploadTypeError (msg )
345345
346- func = handler .fn .func if isinstance (handler .fn , partial ) else handler .fn
347- for name , annotation in get_type_hints (func ).items ():
346+ for name , annotation in handler ._get_type_hints ().items ():
348347 if name == "return" or get_origin (annotation ) is not list :
349348 continue
350349 args = get_args (annotation )
@@ -380,8 +379,7 @@ def resolve_upload_chunk_handler_param(handler: "EventHandler") -> tuple[str, ty
380379 msg = f"@rx.event(background=True) is required for upload_files_chunk handler `{ handler_name } `."
381380 raise UploadTypeError (msg )
382381
383- func = handler .fn .func if isinstance (handler .fn , partial ) else handler .fn
384- for name , annotation in get_type_hints (func ).items ():
382+ for name , annotation in handler ._get_type_hints ().items ():
385383 if name == "return" :
386384 continue
387385 if annotation is UploadChunkIterator :
@@ -490,6 +488,39 @@ class EventHandler(EventActionsMixin):
490488
491489 state : "type[BaseState] | None" = dataclasses .field (default = None , repr = False )
492490
491+ _type_hints : dict [str , Any ] | None = dataclasses .field (
492+ default = None , repr = False , compare = False
493+ )
494+
495+ def __post_init__ (self ) -> None :
496+ """Resolve handler annotations while the state class is stable."""
497+ if self .state is not None :
498+ self ._get_type_hints ()
499+
500+ def _get_type_hints (self ) -> dict [str , Any ]:
501+ """Get and cache the type hints for the handler function.
502+
503+ Caching successful resolution at handler creation avoids deferred
504+ annotation evaluation observing attributes assigned to the owning
505+ state class after the handler was registered.
506+
507+ Returns:
508+ The resolved type hints, or an empty mapping when forward references
509+ cannot be resolved yet.
510+ """
511+ if self ._type_hints is not None :
512+ return self ._type_hints
513+ if self .fn is None :
514+ object .__setattr__ (self , "_type_hints" , {})
515+ return {}
516+ func = self .fn .func if isinstance (self .fn , partial ) else self .fn
517+ try :
518+ type_hints = get_type_hints (func )
519+ except NameError :
520+ return {}
521+ object .__setattr__ (self , "_type_hints" , type_hints )
522+ return type_hints
523+
493524 @property
494525 def state_full_name (self ) -> str :
495526 """Get the full name of the state class this event handler is attached to.
@@ -2035,10 +2066,7 @@ def call_event_handler(
20352066
20362067 event_callback_spec_args = list (parameters )
20372068
2038- try :
2039- type_hints_of_provided_callback = get_type_hints (event_callback .handler .fn )
2040- except NameError :
2041- type_hints_of_provided_callback = {}
2069+ type_hints_of_provided_callback = event_callback .handler ._get_type_hints ()
20422070
20432071 argument_names = [str (arg ) for arg , value in event_callback .args ]
20442072
@@ -2073,10 +2101,7 @@ def call_event_handler(
20732101 if event_spec_return_types :
20742102 event_callback_spec_args = list (parameters )
20752103
2076- try :
2077- type_hints_of_provided_callback = get_type_hints (event_callback .fn )
2078- except NameError :
2079- type_hints_of_provided_callback = {}
2104+ type_hints_of_provided_callback = event_callback ._get_type_hints ()
20802105
20812106 _check_event_args_subclass_of_callback (
20822107 event_callback_spec_args [n_self_args :],
0 commit comments