diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index c57c5f9a18d9..acbb0460ae07 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -2,10 +2,9 @@ from typing import Callable, Optional, List from mypy import message_registry -from mypy.nodes import Expression, StrExpr, IntExpr, DictExpr, UnaryExpr +from mypy.nodes import StrExpr, IntExpr, DictExpr, UnaryExpr from mypy.plugin import ( - Plugin, FunctionContext, MethodContext, MethodSigContext, AttributeContext, ClassDefContext, - CheckerPluginInterface, + Plugin, FunctionContext, MethodContext, MethodSigContext, AttributeContext, ClassDefContext ) from mypy.plugins.common import try_getting_str_literals from mypy.types import ( @@ -26,8 +25,6 @@ def get_function_hook(self, fullname: str if fullname in ('contextlib.contextmanager', 'contextlib.asynccontextmanager'): return contextmanager_callback - elif fullname == 'builtins.open' and self.python_version[0] == 3: - return open_callback elif fullname == 'ctypes.Array': return ctypes.array_constructor_callback elif fullname == 'functools.singledispatch': @@ -74,8 +71,6 @@ def get_method_hook(self, fullname: str return ctypes.array_getitem_callback elif fullname == 'ctypes.Array.__iter__': return ctypes.array_iter_callback - elif fullname == 'pathlib.Path.open': - return path_open_callback elif fullname == singledispatch.SINGLEDISPATCH_REGISTER_METHOD: return singledispatch.singledispatch_register_callback elif fullname == singledispatch.REGISTER_CALLABLE_CALL_METHOD: @@ -129,58 +124,6 @@ def get_class_decorator_hook(self, fullname: str return None -def open_callback(ctx: FunctionContext) -> Type: - """Infer a better return type for 'open'.""" - return _analyze_open_signature( - arg_types=ctx.arg_types, - args=ctx.args, - mode_arg_index=1, - default_return_type=ctx.default_return_type, - api=ctx.api, - ) - - -def path_open_callback(ctx: MethodContext) -> Type: - """Infer a better return type for 'pathlib.Path.open'.""" - return _analyze_open_signature( - arg_types=ctx.arg_types, - args=ctx.args, - mode_arg_index=0, - default_return_type=ctx.default_return_type, - api=ctx.api, - ) - - -def _analyze_open_signature(arg_types: List[List[Type]], - args: List[List[Expression]], - mode_arg_index: int, - default_return_type: Type, - api: CheckerPluginInterface, - ) -> Type: - """A helper for analyzing any function that has approximately - the same signature as the builtin 'open(...)' function. - - Currently, the only thing the caller can customize is the index - of the 'mode' argument. If the mode argument is omitted or is a - string literal, we refine the return type to either 'TextIO' or - 'BinaryIO' as appropriate. - """ - mode = None - if not arg_types or len(arg_types[mode_arg_index]) != 1: - mode = 'r' - else: - mode_expr = args[mode_arg_index][0] - if isinstance(mode_expr, StrExpr): - mode = mode_expr.value - if mode is not None: - assert isinstance(default_return_type, Instance) # type: ignore - if 'b' in mode: - return api.named_generic_type('typing.BinaryIO', []) - else: - return api.named_generic_type('typing.TextIO', []) - return default_return_type - - def contextmanager_callback(ctx: FunctionContext) -> Type: """Infer a better return type for 'contextlib.contextmanager'.""" # Be defensive, just in case. diff --git a/mypy/report.py b/mypy/report.py index 380a8c6b6441..23b5c78ef929 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -245,10 +245,10 @@ def _write_out_report(self, f.write(separator + '\n') for row_values in rows: r = ("{:>{}}" * len(widths)).format(*itertools.chain(*zip(row_values, widths))) - f.writelines(r + '\n') + f.write(r + '\n') f.write(separator + '\n') footer_str = ("{:>{}}" * len(widths)).format(*itertools.chain(*zip(footer, widths))) - f.writelines(footer_str + '\n') + f.write(footer_str + '\n') def _report_any_exprs(self) -> None: total_any = sum(num_any for num_any, _ in self.counts.values()) diff --git a/mypyc/build.py b/mypyc/build.py index 571fb0dd2f5a..8528aa088ac0 100644 --- a/mypyc/build.py +++ b/mypyc/build.py @@ -308,8 +308,8 @@ def write_file(path: str, contents: str) -> None: old_contents = None if old_contents != encoded_contents: os.makedirs(os.path.dirname(path), exist_ok=True) - with open(path, 'wb') as f: - f.write(encoded_contents) + with open(path, 'wb') as g: + g.write(encoded_contents) # Fudge the mtime forward because otherwise when two builds happen close # together (like in a test) setuptools might not realize the source is newer diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 993af4ced61e..de15055927ae 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -271,8 +271,8 @@ f.write('x') f.write(b'x') f.foobar() [out] -_program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" -_program.py:4: error: "TextIO" has no attribute "foobar" +_program.py:3: error: Argument 1 to "write" of "TextIOBase" has incompatible type "bytes"; expected "str" +_program.py:4: error: "TextIOWrapper" has no attribute "foobar" [case testOpenReturnTypeInference] reveal_type(open('x')) @@ -281,9 +281,9 @@ reveal_type(open('x', 'rb')) mode = 'rb' reveal_type(open('x', mode)) [out] -_program.py:1: note: Revealed type is "typing.TextIO" -_program.py:2: note: Revealed type is "typing.TextIO" -_program.py:3: note: Revealed type is "typing.BinaryIO" +_program.py:1: note: Revealed type is "io.TextIOWrapper" +_program.py:2: note: Revealed type is "io.TextIOWrapper" +_program.py:3: note: Revealed type is "io.BufferedReader" _program.py:5: note: Revealed type is "typing.IO[Any]" [case testOpenReturnTypeInferenceSpecialCases] @@ -292,8 +292,8 @@ reveal_type(open(file='x', mode='rb')) mode = 'rb' reveal_type(open(mode=mode, file='r')) [out] -_testOpenReturnTypeInferenceSpecialCases.py:1: note: Revealed type is "typing.BinaryIO" -_testOpenReturnTypeInferenceSpecialCases.py:2: note: Revealed type is "typing.BinaryIO" +_testOpenReturnTypeInferenceSpecialCases.py:1: note: Revealed type is "io.BufferedReader" +_testOpenReturnTypeInferenceSpecialCases.py:2: note: Revealed type is "io.BufferedReader" _testOpenReturnTypeInferenceSpecialCases.py:4: note: Revealed type is "typing.IO[Any]" [case testPathOpenReturnTypeInference] @@ -305,21 +305,21 @@ reveal_type(p.open('rb')) mode = 'rb' reveal_type(p.open(mode)) [out] -_program.py:3: note: Revealed type is "typing.TextIO" -_program.py:4: note: Revealed type is "typing.TextIO" -_program.py:5: note: Revealed type is "typing.BinaryIO" +_program.py:3: note: Revealed type is "io.TextIOWrapper" +_program.py:4: note: Revealed type is "io.TextIOWrapper" +_program.py:5: note: Revealed type is "io.BufferedReader" _program.py:7: note: Revealed type is "typing.IO[Any]" [case testPathOpenReturnTypeInferenceSpecialCases] from pathlib import Path p = Path("x") -reveal_type(p.open(mode='rb', errors='replace')) -reveal_type(p.open(errors='replace', mode='rb')) -mode = 'rb' +reveal_type(p.open(mode='r', errors='replace')) +reveal_type(p.open(errors='replace', mode='r')) +mode = 'r' reveal_type(p.open(mode=mode, errors='replace')) [out] -_program.py:3: note: Revealed type is "typing.BinaryIO" -_program.py:4: note: Revealed type is "typing.BinaryIO" +_program.py:3: note: Revealed type is "io.TextIOWrapper" +_program.py:4: note: Revealed type is "io.TextIOWrapper" _program.py:6: note: Revealed type is "typing.IO[Any]" [case testGenericPatterns]