Skip to content

Commit 77dd1cd

Browse files
author
hauntsaninja
committed
typeanal: error for unbound ParamSpec
1 parent 21a15ae commit 77dd1cd

File tree

2 files changed

+7
-2
lines changed

2 files changed

+7
-2
lines changed

mypy/typeanal.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
CallableType, NoneType, ErasedType, DeletedType, TypeList, TypeVarDef, SyntheticTypeVisitor,
1717
StarType, PartialType, EllipsisType, UninhabitedType, TypeType,
1818
CallableArgument, TypeQuery, union_items, TypeOfAny, LiteralType, RawExpressionType,
19-
PlaceholderType, Overloaded, get_proper_type, TypeAliasType, TypeVarLikeDef
19+
PlaceholderType, Overloaded, get_proper_type, TypeAliasType, TypeVarLikeDef, ParamSpecDef
2020
)
2121

2222
from mypy.nodes import (
2323
TypeInfo, Context, SymbolTableNode, Var, Expression,
2424
nongen_builtins, check_arg_names, check_arg_kinds, ARG_POS, ARG_NAMED,
25-
ARG_OPT, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, TypeVarExpr, TypeVarLikeExpr,
25+
ARG_OPT, ARG_NAMED_OPT, ARG_STAR, ARG_STAR2, TypeVarExpr, TypeVarLikeExpr, ParamSpecExpr,
2626
TypeAlias, PlaceholderNode, SYMBOL_FUNCBASE_TYPES, Decorator, MypyFile
2727
)
2828
from mypy.typetraverser import TypeTraverserVisitor
@@ -200,6 +200,10 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool)
200200
self.fail(no_subscript_builtin_alias(fullname,
201201
propose_alt=not self.defining_alias), t)
202202
tvar_def = self.tvar_scope.get_binding(sym)
203+
if isinstance(sym.node, ParamSpecExpr):
204+
if tvar_def is None:
205+
self.fail('ParamSpec "{}" is unbound'.format(t.name), t)
206+
return AnyType(TypeOfAny.from_error)
203207
if isinstance(sym.node, TypeVarExpr) and tvar_def is not None and self.defining_alias:
204208
self.fail('Can\'t use bound type variable "{}"'
205209
' to define generic alias'.format(t.name), t)

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

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ from typing import Callable, List
88
from typing_extensions import ParamSpec, Concatenate
99
P = ParamSpec('P')
1010

11+
x: P # E: ParamSpec "P" is unbound
1112
def foo1(x: Callable[P, int]) -> Callable[P, str]: ...
1213
def foo2(x: P) -> P: ... # E: Invalid location for ParamSpec "P"
1314
# TODO(shantanu): uncomment once we have support for Concatenate

0 commit comments

Comments
 (0)