@@ -339,7 +339,7 @@ Examples:
339
339
340
340
@evaluated
341
341
def length_or_none(s: str | None = None):
342
- if is_of_type(s, str):
342
+ if is_of_type(s, str, exclude_any=False ):
343
343
return int
344
344
else:
345
345
return None
@@ -353,9 +353,9 @@ Examples:
353
353
354
354
@evaluated
355
355
def length_or_none2(s: str | None):
356
- if is_of_type(s, str, exclude_any=True ):
356
+ if is_of_type(s, str):
357
357
return int
358
- elif is_of_type(s, None, exclude_any=True ):
358
+ elif is_of_type(s, None):
359
359
return None
360
360
else:
361
361
return Any
@@ -367,9 +367,9 @@ Examples:
367
367
368
368
@evaluated
369
369
def nested_any(s: Sequence[Any]):
370
- if is_of_type(s, str, exclude_any=True ):
370
+ if is_of_type(s, str):
371
371
show_error("error")
372
- elif is_of_type(s, Sequence[str], exclude_any=True ):
372
+ elif is_of_type(s, Sequence[str]):
373
373
return str
374
374
else:
375
375
return int
@@ -453,6 +453,31 @@ Examples:
453
453
_: Callable[[str], Path | None] = maybe_path # ok
454
454
_: Callable[[Literal["x"]], Path] = maybe_path # ok
455
455
456
+ ### Runtime behavior
457
+
458
+ At runtime, the ` @evaluated ` decorator returns a dummy function
459
+ that throws an error when called, similar to ` @overload ` . In
460
+ order to support dynamic type checkers, it also stores the
461
+ original function, keyed by its fully qualified name.
462
+
463
+ A helper function is provided to retrieve all registered
464
+ evaluation functions for a given fully qualified name:
465
+
466
+ def get_type_evaluations(
467
+ fully_qualified_name: str
468
+ ) -> Sequence[Callable[..., Any]]: ...
469
+
470
+ For example, if method ` B.c ` in module ` a ` has an evaluation function,
471
+ ` get_type_evaluations("a.B.c") ` will retrieve it.
472
+
473
+ Dummy implementations are provided for the various helper
474
+ functions (` is_provided() ` , ` is_positional() ` , ` is_keyword() ` ,
475
+ ` is_of_type() ` , and ` show_error() ` ). These throw an error
476
+ if called at runtime.
477
+
478
+ The ` reveal_type() ` function has a runtime implementation
479
+ that simply returns its argument.
480
+
456
481
## Discussion
457
482
458
483
### Interaction with Any
@@ -635,6 +660,17 @@ Thus, type evaluation provides a way to implement checks similar to mypy's
635
660
[ strict equality] ( https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-strict-equality )
636
661
flag directly in stubs.
637
662
663
+ ## Compatibility
664
+
665
+ The proposal is fully backward compatible.
666
+
667
+ Type evaluation functions are going to be most frequently useful
668
+ in library stubs, where it is often important that multiple type
669
+ checkers can parse the stub. In order to unblock usage of the new
670
+ feature in stubs, type checker authors could simply ignore the
671
+ body of evaluation functions and rely on the signature. This would
672
+ still allow other type checkers to fully use the evaluation function.
673
+
638
674
## Possible extensions
639
675
640
676
The following features may be useful, but are deferred
0 commit comments