File tree Expand file tree Collapse file tree 2 files changed +31
-0
lines changed Expand file tree Collapse file tree 2 files changed +31
-0
lines changed Original file line number Diff line number Diff line change 55from __future__ import annotations
66
77import sys
8+ from types import FunctionType
89from typing import ( # type: ignore[attr-defined]
910 TYPE_CHECKING ,
1011 Any ,
5354 "Untyped" ,
5455 "Intersection" ,
5556 "TypeForm" ,
57+ "as_functiontype" ,
5658)
5759
5860if TYPE_CHECKING :
@@ -574,3 +576,21 @@ def f[T](t: TypeForm[T]) -> T: ...
574576 reveal_type(f(int | str)) # int | str
575577 """
576578)
579+
580+
581+ # TODO: conditionally declare FunctionType with a BASEDMYPY so that this doesn't break everyone else
582+ # https://github.com/KotlinIsland/basedmypy/issues/524
583+ def as_functiontype (fn : Callable [P , T ]) -> FunctionType [P , T ]: # type: ignore[type-arg]
584+ """Asserts that a ``Callable`` is a ``FunctionType`` and returns it
585+
586+ best used as a decorator to fix other incorrectly typed decorators:
587+
588+ def deco(fn: Callable[[], None]) -> Callable[[], None]: ...
589+
590+ @as_functiontype
591+ @deco
592+ def foo(): ...
593+ """
594+ if not isinstance (fn , FunctionType ): # type: ignore[redundant-expr]
595+ raise TypeError (f"{ fn } is not a FunctionType" )
596+ return fn # type: ignore[unreachable]
Original file line number Diff line number Diff line change 1+ from __future__ import annotations
2+
3+ import pytest
4+
5+ from basedtyping import as_functiontype
6+
7+
8+ def test_as_functiontype ():
9+ with pytest .raises (TypeError ):
10+ as_functiontype (all )
11+ assert as_functiontype (test_as_functiontype ) is test_as_functiontype # type: ignore[comparison-overlap]
You can’t perform that action at this time.
0 commit comments