Skip to content

Commit

Permalink
Fixed check for type comments
Browse files Browse the repository at this point in the history
  • Loading branch information
cdce8p committed Nov 1, 2020
1 parent 21e7919 commit ae5771e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
14 changes: 9 additions & 5 deletions mypy/fastparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from mypy.types import (
Type, CallableType, AnyType, UnboundType, TupleType, TypeList, EllipsisType, CallableArgument,
TypeOfAny, Instance, RawExpressionType, ProperType,
UnionType)
UnionType, Pep604Syntax)
from mypy import defaults
from mypy import message_registry, errorcodes as codes
from mypy.errors import Errors
Expand Down Expand Up @@ -241,7 +241,8 @@ def parse_type_comment(type_comment: str,
converted = TypeConverter(errors,
line=line,
override_column=column,
assume_str_is_unicode=assume_str_is_unicode).visit(typ.body)
assume_str_is_unicode=assume_str_is_unicode
).visit(typ.body, is_type_comment=True)
return ignored, converted


Expand Down Expand Up @@ -1318,7 +1319,8 @@ def visit(self, node: ast3.expr) -> ProperType: ...
@overload
def visit(self, node: Optional[AST]) -> Optional[ProperType]: ...

def visit(self, node: Optional[AST]) -> Optional[ProperType]:
def visit(self, node: Optional[AST],
is_type_comment: Optional[bool] = False) -> Optional[ProperType]:
"""Modified visit -- keep track of the stack of nodes"""
if node is None:
return None
Expand All @@ -1327,6 +1329,8 @@ def visit(self, node: Optional[AST]) -> Optional[ProperType]:
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, None)
if visitor is not None:
if visitor == self.visit_BinOp:
return visitor(node, is_type_comment)
return visitor(node)
else:
return self.invalid_type(node)
Expand Down Expand Up @@ -1422,7 +1426,7 @@ def _extract_argument_name(self, n: ast3.expr) -> Optional[str]:
def visit_Name(self, n: Name) -> Type:
return UnboundType(n.id, line=self.line, column=self.convert_column(n.col_offset))

def visit_BinOp(self, n: ast3.BinOp) -> Type:
def visit_BinOp(self, n: ast3.BinOp, is_type_comment: Optional[bool] = False) -> Type:
if not isinstance(n.op, ast3.BitOr):
return self.invalid_type(n)

Expand All @@ -1431,7 +1435,7 @@ def visit_BinOp(self, n: ast3.BinOp) -> Type:
return UnionType([left, right],
line=self.line,
column=self.convert_column(n.col_offset),
uses_pep604_syntax=True)
pep604_syntax=Pep604Syntax(True, is_type_comment))

def visit_NameConstant(self, n: NameConstant) -> Type:
if isinstance(n.value, bool):
Expand Down
4 changes: 3 additions & 1 deletion mypy/typeanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,9 @@ def visit_star_type(self, t: StarType) -> Type:
return StarType(self.anal_type(t.type), t.line)

def visit_union_type(self, t: UnionType) -> Type:
if (t.uses_pep604_syntax is True
if (t.pep604_syntax
and t.pep604_syntax.uses_pep_604_syntax is True
and t.pep604_syntax.is_type_comment is False
and self.api.is_stub_file is False
and self.options.python_version < (3, 10)
and self.api.is_future_flag_set('annotations') is False):
Expand Down
11 changes: 8 additions & 3 deletions mypy/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -1719,18 +1719,23 @@ def serialize(self) -> JsonDict:
assert False, "Synthetic types don't serialize"


class Pep604Syntax(NamedTuple):
uses_pep_604_syntax: bool
is_type_comment: bool


class UnionType(ProperType):
"""The union type Union[T1, ..., Tn] (at least one type argument)."""

__slots__ = ('items',)
__slots__ = ('items', 'pep604_syntax')

def __init__(self, items: Sequence[Type], line: int = -1, column: int = -1,
uses_pep604_syntax: bool = False) -> None:
pep604_syntax: Optional[Pep604Syntax] = None) -> None:
super().__init__(line, column)
self.items = flatten_nested_unions(items)
self.can_be_true = any(item.can_be_true for item in items)
self.can_be_false = any(item.can_be_false for item in items)
self.uses_pep604_syntax = uses_pep604_syntax
self.pep604_syntax = pep604_syntax

def __hash__(self) -> int:
return hash(frozenset(self.items))
Expand Down
2 changes: 1 addition & 1 deletion test-data/unit/check-union-or-syntax.test
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ y: 42 | int # E: Invalid type: try using Literal[42] instead?
z: str | 42 | int # E: Invalid type: try using Literal[42] instead?

[case testUnionOrSyntaxInComment]
# flags: --python-version 3.10
# flags: --python-version 3.6
x = 1 # type: int | str

[case testUnionOrSyntaxFutureImport]
Expand Down

0 comments on commit ae5771e

Please sign in to comment.