Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2007165
[WIP] Include param_spec in callable types and support reveal_Type
JukkaL Nov 18, 2021
da6d041
[WIP] Simple type inference involving ParamSpec
JukkaL Nov 18, 2021
2506647
[WIP] Work towards using ParamSpec in classes
JukkaL Nov 18, 2021
56971f0
[WIP] Support defining decorators
JukkaL Nov 18, 2021
774a558
Various fixes
JukkaL Nov 19, 2021
cc8fc46
Fixes to mypy daemon (not tested yet)
JukkaL Nov 19, 2021
5b8a1c6
Various updates/fixes to ParamSpecType
JukkaL Nov 19, 2021
bb928ce
Fix to type semantic analysis
JukkaL Nov 19, 2021
f3a2596
Add missing get_proper_type call
JukkaL Nov 19, 2021
ef52db7
Fixes to self check
JukkaL Nov 19, 2021
c76ce08
Fix type check of mypy.constraints
JukkaL Nov 19, 2021
8a69923
Add missing get_proper_type() calls
JukkaL Nov 19, 2021
76ffb14
Move some param spec logic to CallableType
JukkaL Nov 19, 2021
be6f8e8
Fix applying types with ParamSpec
JukkaL Nov 19, 2021
c1686b0
Switch to simpler ParamSpec implementation + cleanup
JukkaL Nov 19, 2021
a3cb0ad
Fix inference against Any
JukkaL Nov 19, 2021
fd124c5
Update test cases
JukkaL Nov 19, 2021
22afc1d
Don't wrap ParamSpec *args and **kwargs types in tuple[...] or dict[...]
JukkaL Nov 19, 2021
044ddfd
Implement basic type checking for ParamSpec types
JukkaL Nov 19, 2021
6d25da4
Use Callable[P, T] in error messages
JukkaL Nov 22, 2021
1047f85
Support subtype checks
JukkaL Nov 22, 2021
a9b410e
Implement ParamSpec join
JukkaL Nov 22, 2021
f621fb7
Fix type erasure
JukkaL Nov 22, 2021
080049e
Add test case
JukkaL Nov 22, 2021
504267c
Disallow ParamSpec type in bad location
JukkaL Nov 22, 2021
2d02b62
Fix type check and lint
JukkaL Nov 22, 2021
dd28b93
Minor tweaks
JukkaL Nov 22, 2021
01ae7d5
Fix TODO in string conversion
JukkaL Nov 22, 2021
b6b09f1
Update docstrings
JukkaL Nov 22, 2021
1af097f
Respond to feedback
JukkaL Nov 23, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix inference against Any
  • Loading branch information
JukkaL committed Nov 22, 2021
commit a3cb0ad3b1f19bc026db6625ecf98bc1d46db18c
17 changes: 12 additions & 5 deletions mypy/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
CallableType, Type, TypeVisitor, UnboundType, AnyType, NoneType, TypeVarType, Instance,
TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType,
UninhabitedType, TypeType, TypeVarId, TypeQuery, is_named_instance, TypeOfAny, LiteralType,
ProperType, ParamSpecType, get_proper_type, TypeAliasType, is_union_with_any
ProperType, ParamSpecType, get_proper_type, TypeAliasType, is_union_with_any,
callable_with_ellipsis
)
from mypy.maptype import map_instance_to_supertype
import mypy.subtypes
Expand Down Expand Up @@ -575,11 +576,17 @@ def visit_callable_type(self, template: CallableType) -> List[Constraint]:
self.direction))
return res
elif isinstance(self.actual, AnyType):
# FIX what if generic
res = self.infer_against_any(template.arg_types, self.actual)
param_spec = template.param_spec()
any_type = AnyType(TypeOfAny.from_another_any, source_any=self.actual)
res.extend(infer_constraints(template.ret_type, any_type, self.direction))
return res
if param_spec is None:
# FIX what if generic
res = self.infer_against_any(template.arg_types, self.actual)
res.extend(infer_constraints(template.ret_type, any_type, self.direction))
return res
else:
return [Constraint(param_spec.id,
SUBTYPE_OF,
callable_with_ellipsis(any_type, any_type, template.fallback))]
elif isinstance(self.actual, Overloaded):
return self.infer_against_overloaded(self.actual, template)
elif isinstance(self.actual, TypeType):
Expand Down
19 changes: 5 additions & 14 deletions mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
StarType, PartialType, EllipsisType, UninhabitedType, TypeType, CallableArgument,
TypeQuery, union_items, TypeOfAny, LiteralType, RawExpressionType,
PlaceholderType, Overloaded, get_proper_type, TypeAliasType,
TypeVarLikeType, ParamSpecType, ParamSpecFlavor
TypeVarLikeType, ParamSpecType, ParamSpecFlavor, callable_with_ellipsis
)

from mypy.nodes import (
Expand Down Expand Up @@ -747,12 +747,7 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
if len(t.args) == 0:
# Callable (bare). Treat as Callable[..., Any].
any_type = self.get_omitted_any(t)
ret = CallableType([any_type, any_type],
[nodes.ARG_STAR, nodes.ARG_STAR2],
[None, None],
ret_type=any_type,
fallback=fallback,
is_ellipsis_args=True)
ret = callable_with_ellipsis(any_type, any_type,fallback)
elif len(t.args) == 2:
callable_args = t.args[0]
ret_type = t.args[1]
Expand All @@ -769,13 +764,9 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
fallback=fallback)
elif isinstance(callable_args, EllipsisType):
# Callable[..., RET] (with literal ellipsis; accept arbitrary arguments)
ret = CallableType([AnyType(TypeOfAny.explicit),
AnyType(TypeOfAny.explicit)],
[nodes.ARG_STAR, nodes.ARG_STAR2],
[None, None],
ret_type=ret_type,
fallback=fallback,
is_ellipsis_args=True)
ret = callable_with_ellipsis(AnyType(TypeOfAny.explicit),
ret_type=ret_type,
fallback=fallback)
else:
# Callable[P, RET] (where P is ParamSpec)
maybe_ret = self.analyze_callable_args_for_paramspec(
Expand Down
12 changes: 12 additions & 0 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2489,3 +2489,15 @@ def is_literal_type(typ: ProperType, fallback_fullname: str, value: LiteralValue
for key, obj in names.items()
if isinstance(obj, type) and issubclass(obj, Type) and obj is not Type
}


def callable_with_ellipsis(any_type: AnyType,
ret_type: Type,
fallback: Instance) -> CallableType:
"""Construct type Callable[..., ret_type]."""
return CallableType([any_type, any_type],
[ARG_STAR, ARG_STAR2],
[None, None],
ret_type=ret_type,
fallback=fallback,
is_ellipsis_args=True)
14 changes: 14 additions & 0 deletions test-data/unit/check-parameter-specification.test
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,17 @@ def f(x: int, y: str, z: int, a: str) -> None: ...

x = register(f, 1, '', 1, '')
[builtins fixtures/dict.pyi]

[case testParamSpecInferredFromAny]
from typing import Callable, Any
from typing_extensions import ParamSpec

P = ParamSpec('P')

def f(x: Callable[P, int]) -> Callable[P, str]: ...

g: Any
reveal_type(f(g)) # N: Revealed type is "def (*Any, **Any) -> builtins.str"

f(g)(1, 3, x=1, y=2)
[builtins fixtures/tuple.pyi]