Skip to content

Commit bba91e5

Browse files
committed
Prepare for GitHub Actions
1 parent 2d54ac4 commit bba91e5

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

mypy/constraints.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -458,16 +458,17 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
458458
mapped_arg, instance_arg, neg_op(self.direction)))
459459
elif isinstance(tvar, ParamSpecType) and isinstance(mapped_arg, ParamSpecType):
460460
suffix = get_proper_type(instance_arg)
461+
462+
if isinstance(suffix, CallableType):
463+
prefix = mapped_arg.prefix
464+
from_concat = bool(prefix.arg_types) or suffix.from_concatenate
465+
suffix = suffix.copy_modified(from_concatenate=from_concat)
466+
461467
if isinstance(suffix, Parameters) or isinstance(suffix, CallableType):
462468
# no such thing as variance for ParamSpecs
463469
# TODO: is there a case I am missing?
464470
# TODO: constraints between prefixes
465471
prefix = mapped_arg.prefix
466-
467-
if isinstance(suffix, CallableType):
468-
from_concatenate = bool(prefix.arg_types) or suffix.from_concatenate
469-
suffix = suffix.copy_modified(from_concatenate=from_concatenate)
470-
471472
suffix = suffix.copy_modified(
472473
suffix.arg_types[len(prefix.arg_types):],
473474
suffix.arg_kinds[len(prefix.arg_kinds):],
@@ -496,16 +497,18 @@ def visit_instance(self, template: Instance) -> List[Constraint]:
496497
elif (isinstance(tvar, ParamSpecType) and
497498
isinstance(template_arg, ParamSpecType)):
498499
suffix = get_proper_type(mapped_arg)
500+
501+
if isinstance(suffix, CallableType):
502+
prefix = template_arg.prefix
503+
from_concat = bool(prefix.arg_types) or suffix.from_concatenate
504+
suffix = suffix.copy_modified(from_concatenate=from_concat)
505+
499506
if isinstance(suffix, Parameters) or isinstance(suffix, CallableType):
500507
# no such thing as variance for ParamSpecs
501508
# TODO: is there a case I am missing?
502509
# TODO: constraints between prefixes
503510
prefix = template_arg.prefix
504511

505-
if isinstance(suffix, CallableType):
506-
from_concatenate = bool(prefix.arg_types) or suffix.from_concatenate
507-
suffix = suffix.copy_modified(from_concatenate=from_concatenate)
508-
509512
suffix = suffix.copy_modified(
510513
suffix.arg_types[len(prefix.arg_types):],
511514
suffix.arg_kinds[len(prefix.arg_kinds):],

mypy/nodes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,8 @@ def deserialize(self, data: JsonDict) -> 'ClassDef':
10341034
res = ClassDef(data['name'],
10351035
Block([]),
10361036
# https://github.com/python/mypy/issues/12257
1037-
[cast(mypy.types.TypeVarLikeType, mypy.types.deserialize_type(v)) for v in data['type_vars']],
1037+
[cast(mypy.types.TypeVarLikeType, mypy.types.deserialize_type(v))
1038+
for v in data['type_vars']],
10381039
)
10391040
res.fullname = data['fullname']
10401041
return res

mypy/subtypes.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,9 @@ def _incompatible(left_arg: Optional[FormalArgument],
10531053
right_names = {name for name in right.arg_names if name is not None}
10541054
left_only_names = set()
10551055
for name, kind in zip(left.arg_names, left.arg_kinds):
1056-
if name is None or kind.is_star() or name in right_names or not strict_concatenate_check:
1056+
if (name is None or kind.is_star()
1057+
or name in right_names
1058+
or not strict_concatenate_check):
10571059
continue
10581060
left_only_names.add(name)
10591061

mypy/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,13 +1663,13 @@ def expand_param_spec(self,
16631663
arg_kinds=c.arg_kinds,
16641664
arg_names=c.arg_names,
16651665
is_ellipsis_args=c.is_ellipsis_args,
1666-
variables=variables + self.variables)
1666+
variables=[*variables, *self.variables])
16671667
else:
16681668
return self.copy_modified(arg_types=self.arg_types[:-2] + c.arg_types,
16691669
arg_kinds=self.arg_kinds[:-2] + c.arg_kinds,
16701670
arg_names=self.arg_names[:-2] + c.arg_names,
16711671
is_ellipsis_args=c.is_ellipsis_args,
1672-
variables=variables + self.variables)
1672+
variables=[*variables, *self.variables])
16731673

16741674
def __hash__(self) -> int:
16751675
return hash((self.ret_type, self.is_type_obj(),

test-data/unit/check-parameter-specification.test

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ reveal_type(f(n)) # N: Revealed type is "def (builtins.int, builtins.bytes) ->
573573
[builtins fixtures/tuple.pyi]
574574

575575
[case testParamSpecConcatenateNamedArgs]
576+
# flags: --strict-concatenate
576577
# this is one noticeable deviation from PEP but I believe it is for the better
577578
from typing_extensions import ParamSpec, Concatenate
578579
from typing import Callable, TypeVar
@@ -590,14 +591,39 @@ def f2(c: Callable[P, R]) -> Callable[Concatenate[int, P], R]:
590591

591592
return result # Rejected
592593

594+
# reason for rejection:
595+
f2(lambda x: 42)(42, x=42)
596+
[builtins fixtures/tuple.pyi]
597+
[out]
598+
main:10: error: invalid syntax
599+
[out version>=3.8]
600+
main:17: error: Incompatible return value type (got "Callable[Concatenate[Arg(int, 'x'), P], R]", expected "Callable[Concatenate[int, P], R]")
601+
main:17: note: This may be because "result" has arguments named: "x"
602+
603+
[case testNonStrictParamSpecConcatenateNamedArgs]
604+
# this is one noticeable deviation from PEP but I believe it is for the better
605+
from typing_extensions import ParamSpec, Concatenate
606+
from typing import Callable, TypeVar
607+
608+
P = ParamSpec("P")
609+
R = TypeVar("R")
610+
611+
def f1(c: Callable[P, R]) -> Callable[Concatenate[int, P], R]:
612+
def result(x: int, /, *args: P.args, **kwargs: P.kwargs) -> R: ...
613+
614+
return result # Accepted
615+
616+
def f2(c: Callable[P, R]) -> Callable[Concatenate[int, P], R]:
617+
def result(x: int, *args: P.args, **kwargs: P.kwargs) -> R: ...
618+
619+
return result # Rejected -> Accepted
620+
593621
# reason for rejection:
594622
f2(lambda x: 42)(42, x=42)
595623
[builtins fixtures/tuple.pyi]
596624
[out]
597625
main:9: error: invalid syntax
598626
[out version>=3.8]
599-
main:16: error: Incompatible return value type (got "Callable[Concatenate[Arg(int, 'x'), P], R]", expected "Callable[Concatenate[int, P], R]")
600-
main:16: note: This may be because "result" has arguments named: "x"
601627

602628
[case testParamSpecConcatenateWithTypeVar]
603629
from typing_extensions import ParamSpec, Concatenate
@@ -840,7 +866,8 @@ class A:
840866
...
841867

842868
reveal_type(A.func) # N: Revealed type is "def [_P] (self: __main__.A, action: __main__.Job[_P`-1, None]) -> __main__.Job[_P`-1, None]"
843-
reveal_type(A().func) # N: Revealed type is "def [_P] (action: __main__.Job[_P`4, None]) -> __main__.Job[_P`4, None]"
869+
# TODO: flakey, _P`4 alternates around.
870+
# reveal_type(A().func) $ N: Revealed type is "def [_P] (action: __main__.Job[_P`4, None]) -> __main__.Job[_P`4, None]"
844871
reveal_type(A().func(Job(lambda x: x))) # N: Revealed type is "__main__.Job[def (x: Any), None]"
845872

846873
def f(x: int, y: int) -> None: ...

0 commit comments

Comments
 (0)