1
1
import inspect
2
- import sys
3
2
import types
4
3
from typing import (
5
4
Annotated ,
14
13
)
15
14
from typing_extensions import TypeAlias
16
15
17
- import typeguard
18
-
19
16
20
17
# We don't actually care what people have subscripted with.
21
18
# In practice this should be thought of as TypeLike = Union[type, types.UnionType]. Plus
22
19
# maybe type(Literal) and so on?
23
20
TypeLike : TypeAlias = Any
24
21
25
22
26
- def better_isinstance (x , annotation ) -> bool :
27
- """As `isinstance`, but supports general type hints."""
23
+ _T = TypeVar ("_T" )
28
24
29
- @typeguard .typechecked
30
- def f (y : annotation ):
31
- pass
32
25
33
- try :
34
- f (x )
35
- except TypeError :
36
- return False
37
- else :
38
- return True
26
+ class _Foo (Generic [_T ]):
27
+ pass
28
+
39
29
30
+ _generic_alias_types = (types .GenericAlias , type (_Foo [int ]))
31
+ _union_origins = (Union , types .UnionType )
32
+ del _Foo , _T
40
33
41
- _union_types : list = [Union ]
42
- if sys .version_info >= (3 , 10 ):
43
- _union_types .append (types .UnionType )
34
+
35
+ def better_isinstance (x , annotation ) -> bool :
36
+ """As `isinstance`, but supports a few other types that are useful to us."""
37
+ origin = get_origin (annotation )
38
+ if origin in _union_origins :
39
+ return any (better_isinstance (x , arg ) for arg in get_args (annotation ))
40
+ elif isinstance (annotation , _generic_alias_types ):
41
+ assert origin is not None
42
+ return better_isinstance (x , origin )
43
+ elif annotation is Any :
44
+ return True
45
+ elif isinstance (annotation , type ):
46
+ return isinstance (x , annotation )
47
+ else :
48
+ raise NotImplementedError (
49
+ f"Do not know how to check whether `{ x } ` is an instance of `{ annotation } `."
50
+ )
44
51
45
52
46
53
def get_origin_no_specials (x , error_msg : str ) -> Optional [type ]:
@@ -59,7 +66,7 @@ def get_origin_no_specials(x, error_msg: str) -> Optional[type]:
59
66
As `get_origin`, specifically either `None` or a class.
60
67
"""
61
68
origin = get_origin (x )
62
- if origin in _union_types :
69
+ if origin in _union_origins :
63
70
raise NotImplementedError (f"Cannot use unions in `{ error_msg } `." )
64
71
elif origin is Annotated :
65
72
# We do allow Annotated, just because it's easy to handle.
0 commit comments