Skip to content

Commit

Permalink
Fix last bits
Browse files Browse the repository at this point in the history
  • Loading branch information
ilevkivskyi committed Nov 1, 2016
1 parent c106204 commit feb9413
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 17 deletions.
6 changes: 3 additions & 3 deletions docs/source/kinds_of_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -485,9 +485,9 @@ Following previous examples:

A type alias does not create a new type. It's just a shorthand notation for
another type -- it's equivalent to the target type. For generic type aliases
this means that variance or constraints of type variables used for alias
definition don't apply to aliases. Parameterized generic alias is treated
simply as an original type with corresponding type variables substituted.
this means that variance of type variables used for alias definition does not
apply to aliases. Parameterized generic alias is treated simply as an original
type with corresponding type variables substituted.

.. _newtypes:

Expand Down
16 changes: 9 additions & 7 deletions mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,15 @@ def visit_unbound_type(self, t: UnboundType) -> Type:
act_len = len(an_args)
if exp_len > 0 and act_len == 0:
# Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...]
return self.replace_alias_tvars(override, all_vars, [AnyType()] * exp_len)
return self.replace_alias_tvars(override, all_vars, [AnyType()] * exp_len,
t.line, t.column)
if exp_len == 0 and act_len == 0:
return override
if act_len != exp_len:
self.fail('Bad number of arguments for type alias, expected: %s, given: %s'
% (exp_len, act_len), t)
return t
return self.replace_alias_tvars(override, all_vars, an_args)
return self.replace_alias_tvars(override, all_vars, an_args, t.line, t.column)
elif not isinstance(sym.node, TypeInfo):
name = sym.fullname
if name is None:
Expand Down Expand Up @@ -233,9 +234,10 @@ def get_tvar_name(self, t: Type) -> Optional[str]:
return t.name
return None

def replace_alias_tvars(self, tp: Type, vars: List[str], subs: List[Type]) -> Type:
"""Replace type variables in a generic type alias tp with substitutions subs.
Length of subs should be already checked.
def replace_alias_tvars(self, tp: Type, vars: List[str], subs: List[Type],
newline: int, newcolumn: int) -> Type:
"""Replace type variables in a generic type alias tp with substitutions subs
resetting context. Length of subs should be already checked.
"""
typ_args = get_typ_args(tp)
new_args = typ_args[:]
Expand All @@ -246,8 +248,8 @@ def replace_alias_tvars(self, tp: Type, vars: List[str], subs: List[Type]) -> Ty
new_args[i] = subs[vars.index(tvar)]
else:
# ...recursively, if needed.
new_args[i] = self.replace_alias_tvars(arg, vars, subs)
return set_typ_args(tp, new_args)
new_args[i] = self.replace_alias_tvars(arg, vars, subs, newline, newcolumn)
return set_typ_args(tp, new_args, newline, newcolumn)

def visit_any(self, t: AnyType) -> Type:
return t
Expand Down
11 changes: 7 additions & 4 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1536,14 +1536,17 @@ def get_typ_args(tp: Type) -> List[Type]:
return typ_args


def set_typ_args(tp: Type, new_args: List[Type]) -> Type:
def set_typ_args(tp: Type, new_args: List[Type], line: int = -1, column: int = -1) -> Type:
"""Return a copy of a parameterizable Type with arguments set to new_args."""
line = line if line > 0 else tp.line
column = column if column > 0 else tp.column
if isinstance(tp, Instance):
return Instance(tp.type, new_args, tp.line, tp.column)
return Instance(tp.type, new_args, line, column)
if isinstance(tp, TupleType):
return tp.copy_modified(items=new_args)
if isinstance(tp, UnionType):
return UnionType.make_simplified_union(new_args, tp.line, tp.column)
return UnionType.make_simplified_union(new_args, line, column)
if isinstance(tp, CallableType):
return tp.copy_modified(arg_types=new_args[:-1], ret_type=new_args[-1])
return tp.copy_modified(arg_types=new_args[:-1], ret_type=new_args[-1],
line=line, column=column)
return tp
10 changes: 7 additions & 3 deletions test-data/unit/check-generics.test
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ E = Node[Node[T, T], List[T]]
F = Node[List[T, T], S] # E: "list" expects 1 type argument, but 2 given
G = Callable[..., List[T, T]] # E: "list" expects 1 type argument, but 2 given
H = Union[int, Tuple[T, Node[T]]] # E: "Node" expects 2 type arguments, but 1 given
h = None # type: H
h = None # type: H # E: "Node" expects 2 type arguments, but 1 given
h1 = None # type: H[int, str] # E: Bad number of arguments for type alias, expected: 1, given: 2

x = None # type: D[int, str]
Expand Down Expand Up @@ -945,13 +945,17 @@ S = TypeVar('S', int, list)
class A(Generic[T, S]):
def __init__(self, x: T, y: S) -> None: ...

BadA = A[str, T] # E: Bad ...
BadA = A[str, T] # This error is reported twice (but it actually looks useful)
SameA = A[T, T]

x = None # type: SameA[int]
y = None # type: SameA[str] # E: Bad ...
y = None # type: SameA[str] # E: Invalid type argument value for "A"

[builtins fixtures/list.pyi]
[out]
main:8: error: Invalid type argument value for "A"
main:8: error: Type argument 1 of "A" has incompatible value "str"


-- Multiple assignment with lists
-- ------------------------------
Expand Down

0 comments on commit feb9413

Please sign in to comment.