Skip to content

Commit 6ea2a4a

Browse files
committed
Special-case strings for forward refs similarly to typing
1 parent d3d6e64 commit 6ea2a4a

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

Lib/functools.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,9 @@ def _find_impl(cls, registry):
890890

891891

892892
def _get_dispatch_param_name(func, *, skip_first=False):
893+
if not hasattr(func, '__code__'):
894+
skip_first = not isinstance(func, staticmethod)
895+
func = func.__func__
893896
func_code = func.__code__
894897
pos_param_count = func_code.co_argcount
895898
params = func_code.co_varnames
@@ -900,12 +903,20 @@ def _get_dispatch_annotation(func, param):
900903
import annotationlib
901904
annotations = annotationlib.get_annotations(func, format=annotationlib.Format.FORWARDREF)
902905
try:
903-
return annotations[param]
906+
ref_or_type = annotations[param]
904907
except KeyError:
905908
raise TypeError(
906909
f"Invalid first argument to `register()`: {param!r}. "
907910
f"Add missing annotation to parameter {param!r} of {func.__qualname__!r} or use `@register(some_class)`."
908911
) from None
912+
if isinstance(ref_or_type, str):
913+
ref_or_type = annotationlib.ForwardRef(ref_or_type, owner=func)
914+
if isinstance(ref_or_type, annotationlib.ForwardRef):
915+
try:
916+
return ref_or_type.evaluate(owner=func)
917+
except Exception:
918+
pass
919+
return ref_or_type
909920

910921

911922
def _get_dispatch_param_and_annotation(func, *, skip_first=False):

0 commit comments

Comments
 (0)