Skip to content

Commit 0386528

Browse files
author
Sylvain MARIE
committed
Aligned with latest typing inspect.
1 parent 9787151 commit 0386528

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

valid8/utils/typing_inspect.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,19 @@
1515
if NEW_TYPING:
1616
import collections.abc
1717

18-
1918
if NEW_TYPING:
2019
from typing import (
2120
Generic, Callable, Union, TypeVar, ClassVar, Tuple, _GenericAlias
2221
)
22+
# from typing_extensions import Literal
2323
else:
2424
from typing import (
2525
Callable, CallableMeta, Union, TupleMeta, TypeVar, GenericMeta,
2626
)
27+
# try: # python 3.6
28+
# from typing_extensions import _Literal
29+
# except ImportError: # python 2.7
30+
# from typing import _Literal
2731

2832

2933
def _gorg(cls):
@@ -116,15 +120,19 @@ class MyClass(Tuple[str, int]):
116120

117121

118122
def is_optional_type(tp):
119-
"""Returns `True` if the type is `type(None)`, or is a direct `Union` to `type(None)`, such as `Optional[T]`.
123+
"""Test if the type is type(None), or is a direct union with it, such as Optional[T].
120124
121-
WARNING: this method might return a misleading `False` if
125+
NOTE: this method inspects nested `Union` arguments but not `TypeVar` definition
126+
bounds and constraints. So it will return `False` if
122127
- `tp` is a `TypeVar` bound, or constrained to, an optional type
123128
- `tp` is a `Union` to a `TypeVar` bound or constrained to an optional type,
124129
- `tp` refers to a *nested* `Union` containing an optional type or one of the above.
130+
131+
Users wishing to check for optionality in types relying on type variables might wish
132+
to use this method in combination with `get_constraints` and `get_bound`
125133
"""
126134

127-
if tp is type(None):
135+
if tp is type(None): # noqa
128136
return True
129137
elif is_union_type(tp):
130138
# TODO should we force evaluate to be True here or set it as a parameter?
@@ -152,6 +160,13 @@ def is_union_type(tp):
152160
return type(tp) is Union or type(tp) is type(Union) # not _Union
153161

154162

163+
# def is_literal_type(tp):
164+
# if NEW_TYPING:
165+
# return (tp is Literal or
166+
# isinstance(tp, _GenericAlias) and tp.__origin__ is Literal)
167+
# return type(tp) is _Literal
168+
169+
155170
def is_typevar(tp):
156171
"""Test if the type represents a type variable. Examples::
157172
@@ -292,12 +307,13 @@ def _eval_args(args):
292307
if not isinstance(arg, tuple):
293308
res.append(arg)
294309
elif is_callable_type(arg[0]):
310+
callable_args = _eval_args(arg[1:])
295311
if len(arg) == 2:
296-
res.append(Callable[[], arg[1]])
312+
res.append(Callable[[], callable_args[0]])
297313
elif arg[1] is Ellipsis:
298-
res.append(Callable[..., arg[2]])
314+
res.append(Callable[..., callable_args[1]])
299315
else:
300-
res.append(Callable[list(arg[1:-1]), arg[-1]])
316+
res.append(Callable[list(callable_args[:-1]), callable_args[-1]])
301317
else:
302318
res.append(type(arg[0]).__getitem__(arg[0], _eval_args(arg[1:])))
303319
return tuple(res)
@@ -333,15 +349,17 @@ def get_args(tp, evaluate=None):
333349
return res
334350
return ()
335351
if is_classvar(tp):
336-
return (tp.__type__,)
352+
return (tp.__type__,) if tp.__type__ is not None else ()
353+
# if is_literal_type(tp):
354+
# return tp.__values__ or ()
337355
if (
338356
is_generic_type(tp) or is_union_type(tp) or
339357
is_callable_type(tp) or is_tuple_type(tp)
340358
):
341359
try:
342360
tree = tp._subs_tree()
343361
except AttributeError:
344-
# even older python!
362+
# Old python typing module <= 3.5.3
345363
if is_union_type(tp):
346364
return tp.__union_params__
347365
elif is_generic_type(tp):
@@ -362,8 +380,9 @@ def get_args(tp, evaluate=None):
362380

363381

364382
def get_bound(tp):
365-
"""Returns the type bound to a `TypeVar` if any. It the type is not a `TypeVar`, a `TypeError` is raised
383+
"""Returns the type bound to a `TypeVar` if any.
366384
385+
It the type is not a `TypeVar`, a `TypeError` is raised.
367386
Examples::
368387
369388
get_bound(TypeVar('T')) == None
@@ -377,8 +396,9 @@ def get_bound(tp):
377396

378397

379398
def get_constraints(tp):
380-
"""Returns the constraints of a `TypeVar` if any. It the type is not a `TypeVar`, a `TypeError` is raised
399+
"""Returns the constraints of a `TypeVar` if any.
381400
401+
It the type is not a `TypeVar`, a `TypeError` is raised
382402
Examples::
383403
384404
get_constraints(TypeVar('T')) == ()

0 commit comments

Comments
 (0)