Skip to content

Commit

Permalink
Now print >> is properly checked (#11576)
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn authored Nov 18, 2021
1 parent cc6c8a9 commit e2178b8
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 2 deletions.
17 changes: 15 additions & 2 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3938,8 +3938,21 @@ def visit_print_stmt(self, s: PrintStmt) -> None:
if s.target:
target_type = get_proper_type(self.expr_checker.accept(s.target))
if not isinstance(target_type, NoneType):
# TODO: Also verify the type of 'write'.
self.expr_checker.analyze_external_member_access('write', target_type, s.target)
write_type = self.expr_checker.analyze_external_member_access(
'write', target_type, s.target)
required_type = CallableType(
arg_types=[self.named_type('builtins.str')],
arg_kinds=[ARG_POS],
arg_names=[None],
ret_type=AnyType(TypeOfAny.implementation_artifact),
fallback=self.named_type('builtins.function'),
)
# This has to be hard-coded, since it is a syntax pattern, not a function call.
if not is_subtype(write_type, required_type):
self.fail(message_registry.PYTHON2_PRINT_FILE_TYPE.format(
write_type,
required_type,
), s.target)

def visit_break_stmt(self, s: BreakStmt) -> None:
self.binder.handle_break()
Expand Down
3 changes: 3 additions & 0 deletions mypy/message_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage":
code=codes.TRUTHY_BOOL,
)
NOT_CALLABLE: Final = '{} not callable'
PYTHON2_PRINT_FILE_TYPE: Final = (
'Argument "file" to "print" has incompatible type "{}"; expected "{}"'
)

# Generic
GENERIC_INSTANCE_VAR_CLASS_ACCESS: Final = (
Expand Down
6 changes: 6 additions & 0 deletions test-data/unit/check-python2.test
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,16 @@ class A:
# type: (str) -> None
pass

class B:
def write(self):
# type: () -> int
pass

print >>A(), ''
print >>None, ''
print >>1, '' # E: "int" has no attribute "write"
print >>(None + ''), None # E: Unsupported left operand type for + ("None")
print >> B(), '' # E: Argument "file" to "print" has incompatible type "def () -> builtins.int"; expected "def (builtins.str) -> Any"

[case testDivision]
class A:
Expand Down

0 comments on commit e2178b8

Please sign in to comment.