Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aa0d186

Browse files
authored
Add UnpackType type and basic semanal (#12367)
Adds very basic support for Unpack expressions (where Unpack is either from typing or typing_extensions). Many of the visitors implementations are not implemented yet. The only supported feature we have so far is validating that the argument to UnpackType actually makes sense. Currently we don't support unions, though. Since TypeVarTuple isn't yet implemented, we don't support that from UnpackType either. We don't want anyone to start using variadic generics at all until we have real support for it. We also don't want to implement it in one huge PR. So mypy is learning a new flag called --enable-incomplete-features which we can enable by default in any testsuite that needs to use incomplete features, as well as pass on the command line for debugging, but it is undocumented and suppressed from the help output so nobody should find it.
1 parent e639cfd commit aa0d186

23 files changed

Lines changed: 142 additions & 17 deletions

mypy/constraints.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType,
99
UninhabitedType, TypeType, TypeVarId, TypeQuery, is_named_instance, TypeOfAny, LiteralType,
1010
ProperType, ParamSpecType, get_proper_type, TypeAliasType, is_union_with_any,
11-
callable_with_ellipsis,
12-
TUPLE_LIKE_INSTANCE_NAMES,
11+
UnpackType, callable_with_ellipsis, TUPLE_LIKE_INSTANCE_NAMES,
1312
)
1413
from mypy.maptype import map_instance_to_supertype
1514
import mypy.subtypes
@@ -404,6 +403,9 @@ def visit_param_spec(self, template: ParamSpecType) -> List[Constraint]:
404403
# Can't infer ParamSpecs from component values (only via Callable[P, T]).
405404
return []
406405

406+
def visit_unpack_type(self, template: UnpackType) -> List[Constraint]:
407+
raise NotImplementedError
408+
407409
# Non-leaf types
408410

409411
def visit_instance(self, template: Instance) -> List[Constraint]:

mypy/erasetype.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Type, TypeVisitor, UnboundType, AnyType, NoneType, TypeVarId, Instance, TypeVarType,
55
CallableType, TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType,
66
DeletedType, TypeTranslator, UninhabitedType, TypeType, TypeOfAny, LiteralType, ProperType,
7-
get_proper_type, get_proper_types, TypeAliasType, ParamSpecType
7+
get_proper_type, get_proper_types, TypeAliasType, ParamSpecType, UnpackType
88
)
99
from mypy.nodes import ARG_STAR, ARG_STAR2
1010

@@ -59,6 +59,9 @@ def visit_type_var(self, t: TypeVarType) -> ProperType:
5959
def visit_param_spec(self, t: ParamSpecType) -> ProperType:
6060
return AnyType(TypeOfAny.special_form)
6161

62+
def visit_unpack_type(self, t: UnpackType) -> ProperType:
63+
raise NotImplementedError
64+
6265
def visit_callable_type(self, t: CallableType) -> ProperType:
6366
# We must preserve the fallback type for overload resolution to work.
6467
any_type = AnyType(TypeOfAny.special_form)

mypy/expandtype.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
NoneType, Overloaded, TupleType, TypedDictType, UnionType,
66
ErasedType, PartialType, DeletedType, UninhabitedType, TypeType, TypeVarId,
77
FunctionLike, TypeVarType, LiteralType, get_proper_type, ProperType,
8-
TypeAliasType, ParamSpecType, TypeVarLikeType
8+
TypeAliasType, ParamSpecType, TypeVarLikeType, UnpackType
99
)
1010

1111

@@ -111,6 +111,9 @@ def visit_param_spec(self, t: ParamSpecType) -> Type:
111111
else:
112112
return repl
113113

114+
def visit_unpack_type(self, t: UnpackType) -> Type:
115+
raise NotImplementedError
116+
114117
def visit_callable_type(self, t: CallableType) -> Type:
115118
param_spec = t.param_spec()
116119
if param_spec is not None:

mypy/fixup.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from mypy.types import (
1111
CallableType, Instance, Overloaded, TupleType, TypedDictType,
1212
TypeVarType, UnboundType, UnionType, TypeVisitor, LiteralType,
13-
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny, ParamSpecType
13+
TypeType, NOT_READY, TypeAliasType, AnyType, TypeOfAny, ParamSpecType,
14+
UnpackType,
1415
)
1516
from mypy.visitor import NodeVisitor
1617
from mypy.lookup import lookup_fully_qualified
@@ -251,6 +252,9 @@ def visit_type_var(self, tvt: TypeVarType) -> None:
251252
def visit_param_spec(self, p: ParamSpecType) -> None:
252253
p.upper_bound.accept(self)
253254

255+
def visit_unpack_type(self, u: UnpackType) -> None:
256+
u.type.accept(self)
257+
254258
def visit_unbound_type(self, o: UnboundType) -> None:
255259
for a in o.args:
256260
a.accept(self)

mypy/indirection.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ def visit_type_var(self, t: types.TypeVarType) -> Set[str]:
6767
def visit_param_spec(self, t: types.ParamSpecType) -> Set[str]:
6868
return set()
6969

70+
def visit_unpack_type(self, t: types.UnpackType) -> Set[str]:
71+
return t.type.accept(self)
72+
7073
def visit_instance(self, t: types.Instance) -> Set[str]:
7174
out = self._visit(t.args)
7275
if t.type:

mypy/join.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
Type, AnyType, NoneType, TypeVisitor, Instance, UnboundType, TypeVarType, CallableType,
88
TupleType, TypedDictType, ErasedType, UnionType, FunctionLike, Overloaded, LiteralType,
99
PartialType, DeletedType, UninhabitedType, TypeType, TypeOfAny, get_proper_type,
10-
ProperType, get_proper_types, TypeAliasType, PlaceholderType, ParamSpecType
10+
ProperType, get_proper_types, TypeAliasType, PlaceholderType, ParamSpecType,
11+
UnpackType
1112
)
1213
from mypy.maptype import map_instance_to_supertype
1314
from mypy.subtypes import (
@@ -256,6 +257,9 @@ def visit_param_spec(self, t: ParamSpecType) -> ProperType:
256257
return t
257258
return self.default(self.s)
258259

260+
def visit_unpack_type(self, t: UnpackType) -> UnpackType:
261+
raise NotImplementedError
262+
259263
def visit_instance(self, t: Instance) -> ProperType:
260264
if isinstance(self.s, Instance):
261265
if self.instance_joiner is None:

mypy/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,8 @@ def add_invertible_flag(flag: str,
862862
# Must be followed by another flag or by '--' (and then only file args may follow).
863863
parser.add_argument('--cache-map', nargs='+', dest='special-opts:cache_map',
864864
help=argparse.SUPPRESS)
865+
parser.add_argument('--enable-incomplete-features', default=False,
866+
help=argparse.SUPPRESS)
865867

866868
# options specifying code to check
867869
code_group = parser.add_argument_group(

mypy/meet.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
TupleType, TypedDictType, ErasedType, UnionType, PartialType, DeletedType,
77
UninhabitedType, TypeType, TypeOfAny, Overloaded, FunctionLike, LiteralType,
88
ProperType, get_proper_type, get_proper_types, TypeAliasType, TypeGuardedType,
9-
ParamSpecType
9+
ParamSpecType, UnpackType,
1010
)
1111
from mypy.subtypes import is_equivalent, is_subtype, is_callable_compatible, is_proper_subtype
1212
from mypy.erasetype import erase_type
@@ -506,6 +506,9 @@ def visit_param_spec(self, t: ParamSpecType) -> ProperType:
506506
else:
507507
return self.default(self.s)
508508

509+
def visit_unpack_type(self, t: UnpackType) -> ProperType:
510+
raise NotImplementedError
511+
509512
def visit_instance(self, t: Instance) -> ProperType:
510513
if isinstance(self.s, Instance):
511514
if t.type == self.s.type:

mypy/message_registry.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage":
152152
IMPLICIT_GENERIC_ANY_BUILTIN: Final = (
153153
'Implicit generic "Any". Use "{}" and specify generic parameters'
154154
)
155+
INVALID_UNPACK = "{} cannot be unpacked (must be tuple or TypeVarTuple)"
155156

156157
# TypeVar
157158
INCOMPATIBLE_TYPEVAR_VALUE: Final = 'Value of type variable "{}" of {} cannot be {}'

mypy/options.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ def __init__(self) -> None:
258258
self.dump_type_stats = False
259259
self.dump_inference_stats = False
260260
self.dump_build_stats = False
261+
self.enable_incomplete_features = False
261262

262263
# -- test options --
263264
# Stop after the semantic analysis phase

0 commit comments

Comments
 (0)