From 1cdeecdcc11115a3d15610801fdf91b0ed6bbe0a Mon Sep 17 00:00:00 2001 From: Wesley Collin Wright Date: Mon, 4 Dec 2023 12:56:59 -0600 Subject: [PATCH 01/69] bump version to 1.9.0+dev (#16615) Preparation step for the 1.8.0 release. --- mypy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/version.py b/mypy/version.py index 2c2c2b052da2..74e80839308c 100644 --- a/mypy/version.py +++ b/mypy/version.py @@ -8,7 +8,7 @@ # - Release versions have the form "1.2.3". # - Dev versions have the form "1.2.3+dev" (PLUS sign to conform to PEP 440). # - Before 1.0 we had the form "0.NNN". -__version__ = "1.8.0+dev" +__version__ = "1.9.0+dev" base_version = __version__ mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) From 88bf6f20754c1713e3eaeee8cc882a7ba6c9483d Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Thu, 7 Dec 2023 16:37:31 +0300 Subject: [PATCH 02/69] Add `alias` support to `field()` in `attrs` plugin (#16610) Closes https://github.com/python/mypy/issues/16586 CC @ikonst --- mypy/plugins/attrs.py | 23 +++++++++++++++++--- test-data/unit/check-plugin-attrs.test | 25 ++++++++++++++++++++++ test-data/unit/lib-stub/attrs/__init__.pyi | 4 ++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index 3ddc234a7e4a..81f96c088ecd 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -105,6 +105,7 @@ class Attribute: def __init__( self, name: str, + alias: str | None, info: TypeInfo, has_default: bool, init: bool, @@ -114,6 +115,7 @@ def __init__( init_type: Type | None, ) -> None: self.name = name + self.alias = alias self.info = info self.has_default = has_default self.init = init @@ -171,12 +173,14 @@ def argument(self, ctx: mypy.plugin.ClassDefContext) -> Argument: arg_kind = ARG_OPT if self.has_default else ARG_POS # Attrs removes leading underscores when creating the __init__ arguments. - return Argument(Var(self.name.lstrip("_"), init_type), init_type, None, arg_kind) + name = self.alias or self.name.lstrip("_") + return Argument(Var(name, init_type), init_type, None, arg_kind) def serialize(self) -> JsonDict: """Serialize this object so it can be saved and restored.""" return { "name": self.name, + "alias": self.alias, "has_default": self.has_default, "init": self.init, "kw_only": self.kw_only, @@ -205,6 +209,7 @@ def deserialize( return Attribute( data["name"], + data["alias"], info, data["has_default"], data["init"], @@ -498,6 +503,7 @@ def _attributes_from_assignment( or if auto_attribs is enabled also like this: x: type x: type = default_value + x: type = attr.ib(...) """ for lvalue in stmt.lvalues: lvalues, rvalues = _parse_assignments(lvalue, stmt) @@ -564,7 +570,7 @@ def _attribute_from_auto_attrib( has_rhs = not isinstance(rvalue, TempNode) sym = ctx.cls.info.names.get(name) init_type = sym.type if sym else None - return Attribute(name, ctx.cls.info, has_rhs, True, kw_only, None, stmt, init_type) + return Attribute(name, None, ctx.cls.info, has_rhs, True, kw_only, None, stmt, init_type) def _attribute_from_attrib_maker( @@ -628,9 +634,20 @@ def _attribute_from_attrib_maker( converter = convert converter_info = _parse_converter(ctx, converter) + # Custom alias might be defined: + alias = None + alias_expr = _get_argument(rvalue, "alias") + if alias_expr: + alias = ctx.api.parse_str_literal(alias_expr) + if alias is None: + ctx.api.fail( + '"alias" argument to attrs field must be a string literal', + rvalue, + code=LITERAL_REQ, + ) name = unmangle(lhs.name) return Attribute( - name, ctx.cls.info, attr_has_default, init, kw_only, converter_info, stmt, init_type + name, alias, ctx.cls.info, attr_has_default, init, kw_only, converter_info, stmt, init_type ) diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index fb5f1f9472c2..b2161b91e225 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -1055,6 +1055,31 @@ C() C(_x=42) # E: Unexpected keyword argument "_x" for "C" [builtins fixtures/list.pyi] +[case testAttrsAliasForInit] +from attrs import define, field + +@define +class C1: + _x: int = field(alias="x1") + +c1 = C1(x1=42) +reveal_type(c1._x) # N: Revealed type is "builtins.int" +c1.x1 # E: "C1" has no attribute "x1" +C1(_x=42) # E: Unexpected keyword argument "_x" for "C1" + +alias = "x2" +@define +class C2: + _x: int = field(alias=alias) # E: "alias" argument to attrs field must be a string literal + +@define +class C3: + _x: int = field(alias="_x") + +c3 = C3(_x=1) +reveal_type(c3._x) # N: Revealed type is "builtins.int" +[builtins fixtures/plugin_attrs.pyi] + [case testAttrsAutoMustBeAll] import attr @attr.s(auto_attribs=True) diff --git a/test-data/unit/lib-stub/attrs/__init__.pyi b/test-data/unit/lib-stub/attrs/__init__.pyi index 7a88170d7271..f610957a48a3 100644 --- a/test-data/unit/lib-stub/attrs/__init__.pyi +++ b/test-data/unit/lib-stub/attrs/__init__.pyi @@ -79,6 +79,7 @@ def field( eq: Optional[bool] = ..., order: Optional[bool] = ..., on_setattr: Optional[_OnSetAttrArgType] = ..., + alias: Optional[str] = ..., ) -> Any: ... # This form catches an explicit None or no default and infers the type from the @@ -98,6 +99,7 @@ def field( eq: Optional[bool] = ..., order: Optional[bool] = ..., on_setattr: Optional[object] = ..., + alias: Optional[str] = ..., ) -> _T: ... # This form catches an explicit default argument. @@ -116,6 +118,7 @@ def field( eq: Optional[bool] = ..., order: Optional[bool] = ..., on_setattr: Optional[object] = ..., + alias: Optional[str] = ..., ) -> _T: ... # This form covers type=non-Type: e.g. forward references (str), Any @@ -134,6 +137,7 @@ def field( eq: Optional[bool] = ..., order: Optional[bool] = ..., on_setattr: Optional[object] = ..., + alias: Optional[str] = ..., ) -> Any: ... def evolve(inst: _T, **changes: Any) -> _T: ... From cbbcdb8a2c0fb70f3b89a518b7aa36925d9c4c37 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 7 Dec 2023 10:02:57 -0800 Subject: [PATCH 03/69] Allow type ignores of PEP 695 constructs (#16608) This is basically a pre-existing bug and affects other errors that ASTConverter might raise, like merging overloads. It could vaguely be nice to move all the set_file_ignored_lines into fastparse, instead of BuildManager.parse_file. Could also clean up the ignore_errors logic a little bit more. Fixes #16607 --- misc/dump-ast.py | 4 ++-- mypy/build.py | 4 ++-- mypy/fastparse.py | 31 ++++++++++++++-------------- mypy/parse.py | 12 +++++++++-- mypy/test/testparse.py | 16 +++++++++++--- test-data/unit/check-errorcodes.test | 6 ++++-- test-data/unit/check-python312.test | 5 +++++ 7 files changed, 52 insertions(+), 26 deletions(-) diff --git a/misc/dump-ast.py b/misc/dump-ast.py index 6f70bbc8c9ed..7fdf905bae0b 100755 --- a/misc/dump-ast.py +++ b/misc/dump-ast.py @@ -9,7 +9,7 @@ import sys from mypy import defaults -from mypy.errors import CompileError +from mypy.errors import CompileError, Errors from mypy.options import Options from mypy.parse import parse @@ -19,7 +19,7 @@ def dump(fname: str, python_version: tuple[int, int], quiet: bool = False) -> No options.python_version = python_version with open(fname, "rb") as f: s = f.read() - tree = parse(s, fname, None, errors=None, options=options) + tree = parse(s, fname, None, errors=Errors(options), options=options) if not quiet: print(tree) diff --git a/mypy/build.py b/mypy/build.py index 961198fc2fa4..b3ca8d06916d 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -2174,8 +2174,8 @@ def parse_file(self, *, temporary: bool = False) -> None: self.id, self.xpath, source, - self.ignore_all or self.options.ignore_errors, - self.options, + ignore_errors=self.ignore_all or self.options.ignore_errors, + options=self.options, ) else: diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 95d99db84a15..cba01eab2e4e 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -190,7 +190,7 @@ def parse( source: str | bytes, fnam: str, module: str | None, - errors: Errors | None = None, + errors: Errors, options: Options | None = None, ) -> MypyFile: """Parse a source file, without doing any semantic analysis. @@ -199,16 +199,13 @@ def parse( on failure. Otherwise, use the errors object to report parse errors. """ ignore_errors = (options is not None and options.ignore_errors) or ( - errors is not None and fnam in errors.ignored_files + fnam in errors.ignored_files ) # If errors are ignored, we can drop many function bodies to speed up type checking. strip_function_bodies = ignore_errors and (options is None or not options.preserve_asts) - raise_on_error = False + if options is None: options = Options() - if errors is None: - errors = Errors(options) - raise_on_error = True errors.set_file(fnam, module, options=options) is_stub_file = fnam.endswith(".pyi") if is_stub_file: @@ -228,11 +225,9 @@ def parse( options=options, is_stub=is_stub_file, errors=errors, - ignore_errors=ignore_errors, strip_function_bodies=strip_function_bodies, + path=fnam, ).visit(ast) - tree.path = fnam - tree.is_stub = is_stub_file except SyntaxError as e: # alias to please mypyc is_py38_or_earlier = sys.version_info < (3, 9) @@ -254,9 +249,6 @@ def parse( ) tree = MypyFile([], [], False, {}) - if raise_on_error and errors.is_errors(): - errors.raise_error() - assert isinstance(tree, MypyFile) return tree @@ -357,8 +349,8 @@ def __init__( is_stub: bool, errors: Errors, *, - ignore_errors: bool, strip_function_bodies: bool, + path: str, ) -> None: # 'C' for class, 'D' for function signature, 'F' for function, 'L' for lambda self.class_and_function_stack: list[Literal["C", "D", "F", "L"]] = [] @@ -367,8 +359,8 @@ def __init__( self.options = options self.is_stub = is_stub self.errors = errors - self.ignore_errors = ignore_errors self.strip_function_bodies = strip_function_bodies + self.path = path self.type_ignores: dict[int, list[str]] = {} @@ -380,6 +372,10 @@ def note(self, msg: str, line: int, column: int) -> None: def fail(self, msg: ErrorMessage, line: int, column: int, blocker: bool = True) -> None: if blocker or not self.options.ignore_errors: + # Make sure self.errors reflects any type ignores that we have parsed + self.errors.set_file_ignored_lines( + self.path, self.type_ignores, self.options.ignore_errors + ) self.errors.report(line, column, msg.value, blocker=blocker, code=msg.code) def fail_merge_overload(self, node: IfStmt) -> None: @@ -858,8 +854,13 @@ def visit_Module(self, mod: ast3.Module) -> MypyFile: self.type_ignores[ti.lineno] = parsed else: self.fail(message_registry.INVALID_TYPE_IGNORE, ti.lineno, -1, blocker=False) + body = self.fix_function_overloads(self.translate_stmt_list(mod.body, ismodule=True)) - return MypyFile(body, self.imports, False, self.type_ignores) + + ret = MypyFile(body, self.imports, False, ignored_lines=self.type_ignores) + ret.is_stub = self.is_stub + ret.path = self.path + return ret # --- stmt --- # FunctionDef(identifier name, arguments args, diff --git a/mypy/parse.py b/mypy/parse.py index 8bf9983967ba..ee61760c0ac0 100644 --- a/mypy/parse.py +++ b/mypy/parse.py @@ -6,7 +6,12 @@ def parse( - source: str | bytes, fnam: str, module: str | None, errors: Errors | None, options: Options + source: str | bytes, + fnam: str, + module: str | None, + errors: Errors, + options: Options, + raise_on_error: bool = False, ) -> MypyFile: """Parse a source file, without doing any semantic analysis. @@ -19,4 +24,7 @@ def parse( source = options.transform_source(source) import mypy.fastparse - return mypy.fastparse.parse(source, fnam=fnam, module=module, errors=errors, options=options) + tree = mypy.fastparse.parse(source, fnam=fnam, module=module, errors=errors, options=options) + if raise_on_error and errors.is_errors(): + errors.raise_error() + return tree diff --git a/mypy/test/testparse.py b/mypy/test/testparse.py index 0140eb072821..e33fa7e53ff0 100644 --- a/mypy/test/testparse.py +++ b/mypy/test/testparse.py @@ -8,7 +8,7 @@ from mypy import defaults from mypy.config_parser import parse_mypy_comments -from mypy.errors import CompileError +from mypy.errors import CompileError, Errors from mypy.options import Options from mypy.parse import parse from mypy.test.data import DataDrivenTestCase, DataSuite @@ -51,7 +51,12 @@ def test_parser(testcase: DataDrivenTestCase) -> None: try: n = parse( - bytes(source, "ascii"), fnam="main", module="__main__", errors=None, options=options + bytes(source, "ascii"), + fnam="main", + module="__main__", + errors=Errors(options), + options=options, + raise_on_error=True, ) a = n.str_with_options(options).split("\n") except CompileError as e: @@ -82,7 +87,12 @@ def test_parse_error(testcase: DataDrivenTestCase) -> None: skip() # Compile temporary file. The test file contains non-ASCII characters. parse( - bytes("\n".join(testcase.input), "utf-8"), INPUT_FILE_NAME, "__main__", None, options + bytes("\n".join(testcase.input), "utf-8"), + INPUT_FILE_NAME, + "__main__", + errors=Errors(options), + options=options, + raise_on_error=True, ) raise AssertionError("No errors reported") except CompileError as e: diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 28487a456156..1dd058730f28 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -975,11 +975,13 @@ def f(d: D, s: str) -> None: [typing fixtures/typing-typeddict.pyi] [case testRecommendErrorCode] -# type: ignore[whatever] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever"` [syntax] +# type: ignore[whatever] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever"` [syntax] \ + # N: Error code "syntax" not covered by "type: ignore" comment 1 + "asdf" [case testRecommendErrorCode2] -# type: ignore[whatever, other] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever, other"` [syntax] +# type: ignore[whatever, other] # E: type ignore with error code is not supported for modules; use `# mypy: disable-error-code="whatever, other"` [syntax] \ + # N: Error code "syntax" not covered by "type: ignore" comment 1 + "asdf" [case testShowErrorCodesInConfig] diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index cb89eb34880c..285563c19991 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -11,6 +11,11 @@ def g(x: MyList[int]) -> MyList[int]: # E: Variable "__main__.MyList" is not va # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases return reveal_type(x) # N: Revealed type is "MyList?[builtins.int]" +type MyInt2 = int # type: ignore[valid-type] + +def h(x: MyInt2) -> MyInt2: + return reveal_type(x) # N: Revealed type is "builtins.int" + [case test695Class] class MyGen[T]: # E: PEP 695 generics are not yet supported def __init__(self, x: T) -> None: # E: Name "T" is not defined From 13e7213ad958a50ab4bf28abd63fa1f324f58a69 Mon Sep 17 00:00:00 2001 From: Maarten Huijsmans Date: Fri, 8 Dec 2023 20:00:50 +0100 Subject: [PATCH 04/69] Add exist_ok=True in write_junit_xml (#16637) Fixes #16630 --- mypy/util.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mypy/util.py b/mypy/util.py index 7a13de427e8e..be8a22d08a27 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -314,10 +314,9 @@ def write_junit_xml( ) -> None: xml = _generate_junit_contents(dt, serious, messages_by_file, version, platform) - # checks for a directory structure in path and creates folders if needed + # creates folders if needed xml_dirs = os.path.dirname(os.path.abspath(path)) - if not os.path.isdir(xml_dirs): - os.makedirs(xml_dirs) + os.makedirs(xml_dirs, exist_ok=True) with open(path, "wb") as f: f.write(xml.encode("utf-8")) From 0567da99784c376e723907daf4f16df2f03368c1 Mon Sep 17 00:00:00 2001 From: Lukas Geiger Date: Sat, 9 Dec 2023 20:32:42 +0000 Subject: [PATCH 05/69] Prefer `exist_ok=True` over explicit `os.path.exists(...)` checks (#16642) This PR replaces explicit `os.path.exists(...)` checks with `os.makedirs(..., exist_ok=True)` where possible. This removes the need for an extra existence check and slightly simplifies the code. This can also prevent race conditions like #16630. --- mypy/report.py | 6 +++--- mypy/stats.py | 5 ----- mypy/stubgen.py | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/mypy/report.py b/mypy/report.py index 86fcee0521a6..764cfec7799a 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -99,7 +99,7 @@ class AbstractReporter(metaclass=ABCMeta): def __init__(self, reports: Reports, output_dir: str) -> None: self.output_dir = output_dir if output_dir != "": - stats.ensure_dir_exists(output_dir) + os.makedirs(output_dir, exist_ok=True) @abstractmethod def on_file( @@ -737,7 +737,7 @@ def on_file( if path.startswith(".."): return out_path = os.path.join(self.output_dir, "xml", path + ".xml") - stats.ensure_dir_exists(os.path.dirname(out_path)) + os.makedirs(os.path.dirname(out_path), exist_ok=True) last_xml.write(out_path, encoding="utf-8") def on_finish(self) -> None: @@ -782,7 +782,7 @@ def on_file( if path.startswith(".."): return out_path = os.path.join(self.output_dir, "html", path + ".html") - stats.ensure_dir_exists(os.path.dirname(out_path)) + os.makedirs(os.path.dirname(out_path), exist_ok=True) transformed_html = bytes(self.xslt_html(last_xml, ext=self.param_html)) with open(out_path, "wb") as out_file: out_file.write(transformed_html) diff --git a/mypy/stats.py b/mypy/stats.py index b8803e03b9d2..b167a41b0e34 100644 --- a/mypy/stats.py +++ b/mypy/stats.py @@ -477,11 +477,6 @@ def is_complex(t: Type) -> bool: return is_generic(t) or isinstance(t, (FunctionLike, TupleType, TypeVarType)) -def ensure_dir_exists(dir: str) -> None: - if not os.path.exists(dir): - os.makedirs(dir) - - def is_special_form_any(t: AnyType) -> bool: return get_original_any(t).type_of_any == TypeOfAny.special_form diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 23b5fde9dff2..7ec3d7069fb2 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -1833,8 +1833,7 @@ def parse_options(args: list[str]) -> Options: parser.error("Cannot specify both --parse-only/--no-analysis and --inspect-mode") # Create the output folder if it doesn't already exist. - if not os.path.exists(ns.output_dir): - os.makedirs(ns.output_dir) + os.makedirs(ns.output_dir, exist_ok=True) return Options( pyversion=pyversion, From 5fa95693bb3ca312224a5194dbb5149f8e7d7a55 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Tue, 12 Dec 2023 19:12:26 +0000 Subject: [PATCH 06/69] Fix crash with type alias to `Callable[[Unpack[Tuple[Any, ...]]], Any]` (#16541) Fixes #16533 --- mypy/expandtype.py | 28 ++++++++++------- test-data/unit/check-typevar-tuple.test | 42 +++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 3acec4b96d06..f6aa74add9d8 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -307,18 +307,24 @@ def interpolate_args_for_unpack(self, t: CallableType, var_arg: UnpackType) -> l suffix = self.expand_types(t.arg_types[star_index + 1 :]) var_arg_type = get_proper_type(var_arg.type) - # We have something like Unpack[Tuple[Unpack[Ts], X1, X2]] - if isinstance(var_arg_type, TupleType): - expanded_tuple = var_arg_type.accept(self) - assert isinstance(expanded_tuple, ProperType) and isinstance(expanded_tuple, TupleType) - expanded_items = expanded_tuple.items - fallback = var_arg_type.partial_fallback + if isinstance(var_arg_type, Instance): + # we have something like Unpack[Tuple[Any, ...]] + new_unpack = var_arg else: - # We have plain Unpack[Ts] - assert isinstance(var_arg_type, TypeVarTupleType) - fallback = var_arg_type.tuple_fallback - expanded_items = self.expand_unpack(var_arg) - new_unpack = UnpackType(TupleType(expanded_items, fallback)) + if isinstance(var_arg_type, TupleType): + # We have something like Unpack[Tuple[Unpack[Ts], X1, X2]] + expanded_tuple = var_arg_type.accept(self) + assert isinstance(expanded_tuple, ProperType) and isinstance( + expanded_tuple, TupleType + ) + expanded_items = expanded_tuple.items + fallback = var_arg_type.partial_fallback + else: + # We have plain Unpack[Ts] + assert isinstance(var_arg_type, TypeVarTupleType), type(var_arg_type) + fallback = var_arg_type.tuple_fallback + expanded_items = self.expand_unpack(var_arg) + new_unpack = UnpackType(TupleType(expanded_items, fallback)) return prefix + [new_unpack] + suffix def visit_callable_type(self, t: CallableType) -> CallableType: diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 487f22699724..9c8d21114d4c 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2235,3 +2235,45 @@ z: Tuple[int, Unpack[Tuple[int, ...]]] = (1,) w: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *[2, 3, 4]) t: Tuple[int, Unpack[Tuple[int, ...]]] = (1, *(2, 3, 4)) [builtins fixtures/tuple.pyi] + +[case testAliasToCallableWithUnpack] +from typing import Any, Callable, Tuple, Unpack + +_CallableValue = Callable[[Unpack[Tuple[Any, ...]]], Any] +def higher_order(f: _CallableValue) -> None: ... + +def good1(*args: int) -> None: ... +def good2(*args: str) -> int: ... + +def bad1(a: str, b: int, /) -> None: ... +def bad2(c: bytes, *args: int) -> str: ... +def bad3(*, d: str) -> int: ... +def bad4(**kwargs: None) -> None: ... + +higher_order(good1) +higher_order(good2) + +higher_order(bad1) # E: Argument 1 to "higher_order" has incompatible type "Callable[[str, int], None]"; expected "Callable[[VarArg(Any)], Any]" +higher_order(bad2) # E: Argument 1 to "higher_order" has incompatible type "Callable[[bytes, VarArg(int)], str]"; expected "Callable[[VarArg(Any)], Any]" +higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Callable[[NamedArg(str, 'd')], int]"; expected "Callable[[VarArg(Any)], Any]" +higher_order(bad4) # E: Argument 1 to "higher_order" has incompatible type "Callable[[KwArg(None)], None]"; expected "Callable[[VarArg(Any)], Any]" +[builtins fixtures/tuple.pyi] + +[case testAliasToCallableWithUnpack2] +from typing import Any, Callable, Tuple, Unpack + +_CallableValue = Callable[[int, str, Unpack[Tuple[Any, ...]], int], Any] +def higher_order(f: _CallableValue) -> None: ... + +def good(a: int, b: str, *args: Unpack[Tuple[Unpack[Tuple[Any, ...]], int]]) -> int: ... +def bad1(a: str, b: int, /) -> None: ... +def bad2(c: bytes, *args: int) -> str: ... +def bad3(*, d: str) -> int: ... +def bad4(**kwargs: None) -> None: ... + +higher_order(good) +higher_order(bad1) # E: Argument 1 to "higher_order" has incompatible type "Callable[[str, int], None]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" +higher_order(bad2) # E: Argument 1 to "higher_order" has incompatible type "Callable[[bytes, VarArg(int)], str]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" +higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Callable[[NamedArg(str, 'd')], int]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" +higher_order(bad4) # E: Argument 1 to "higher_order" has incompatible type "Callable[[KwArg(None)], None]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" +[builtins fixtures/tuple.pyi] From 91be28552e062601adc2a07075263994c102d5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tin=20Tvrtkovi=C4=87?= Date: Tue, 12 Dec 2023 21:08:14 +0100 Subject: [PATCH 07/69] Improve attrs hashability detection (#16556) Fixes #16550 Improve hashability detection for attrs classes. I added a new parameter to `add_attribute_to_class`, `overwrite_existing`, since I needed it. Frozen classes remain hashable, non-frozen default to no. This can be overriden by passing in `hash=True` or `unsafe_hash=True` (new parameter, added to stubs) to `define()`. Inheritance-wise I think we're correct, if a non-hashable class inherits from a hashable one, it's still unhashable at runtime. Accompanying tests. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- mypy/plugins/attrs.py | 15 ++++++ mypy/plugins/common.py | 3 +- test-data/unit/check-plugin-attrs.test | 59 ++++++++++++++++++++++ test-data/unit/fixtures/plugin_attrs.pyi | 1 + test-data/unit/lib-stub/attr/__init__.pyi | 2 + test-data/unit/lib-stub/attrs/__init__.pyi | 2 + 6 files changed, 81 insertions(+), 1 deletion(-) diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index 81f96c088ecd..19a402492aef 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -310,6 +310,8 @@ def attr_class_maker_callback( it will add an __init__ or all the compare methods. For frozen=True it will turn the attrs into properties. + Hashability will be set according to https://www.attrs.org/en/stable/hashing.html. + See https://www.attrs.org/en/stable/how-does-it-work.html for information on how attrs works. If this returns False, some required metadata was not ready yet and we need another @@ -321,6 +323,9 @@ def attr_class_maker_callback( frozen = _get_frozen(ctx, frozen_default) order = _determine_eq_order(ctx) slots = _get_decorator_bool_argument(ctx, "slots", slots_default) + hashable = _get_decorator_bool_argument(ctx, "hash", False) or _get_decorator_bool_argument( + ctx, "unsafe_hash", False + ) auto_attribs = _get_decorator_optional_bool_argument(ctx, "auto_attribs", auto_attribs_default) kw_only = _get_decorator_bool_argument(ctx, "kw_only", False) @@ -359,10 +364,13 @@ def attr_class_maker_callback( adder = MethodAdder(ctx) # If __init__ is not being generated, attrs still generates it as __attrs_init__ instead. _add_init(ctx, attributes, adder, "__init__" if init else ATTRS_INIT_NAME) + if order: _add_order(ctx, adder) if frozen: _make_frozen(ctx, attributes) + elif not hashable: + _remove_hashability(ctx) return True @@ -943,6 +951,13 @@ def _add_match_args(ctx: mypy.plugin.ClassDefContext, attributes: list[Attribute add_attribute_to_class(api=ctx.api, cls=ctx.cls, name="__match_args__", typ=match_args) +def _remove_hashability(ctx: mypy.plugin.ClassDefContext) -> None: + """Remove hashability from a class.""" + add_attribute_to_class( + ctx.api, ctx.cls, "__hash__", NoneType(), is_classvar=True, overwrite_existing=True + ) + + class MethodAdder: """Helper to add methods to a TypeInfo. diff --git a/mypy/plugins/common.py b/mypy/plugins/common.py index 03041bfcebcd..f0ff6f30a3b9 100644 --- a/mypy/plugins/common.py +++ b/mypy/plugins/common.py @@ -399,6 +399,7 @@ def add_attribute_to_class( override_allow_incompatible: bool = False, fullname: str | None = None, is_classvar: bool = False, + overwrite_existing: bool = False, ) -> Var: """ Adds a new attribute to a class definition. @@ -408,7 +409,7 @@ def add_attribute_to_class( # NOTE: we would like the plugin generated node to dominate, but we still # need to keep any existing definitions so they get semantically analyzed. - if name in info.names: + if name in info.names and not overwrite_existing: # Get a nice unique name instead. r_name = get_unique_redefinition_name(name, info.names) info.names[r_name] = info.names[name] diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index b2161b91e225..0f379724553a 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -2321,3 +2321,62 @@ reveal_type(b.x) # N: Revealed type is "builtins.int" reveal_type(b.y) # N: Revealed type is "builtins.int" [builtins fixtures/plugin_attrs.pyi] + +[case testDefaultHashability] +from attrs import define + +@define +class A: + a: int + +reveal_type(A.__hash__) # N: Revealed type is "None" + +[builtins fixtures/plugin_attrs.pyi] + +[case testFrozenHashability] +from attrs import frozen + +@frozen +class A: + a: int + +reveal_type(A.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testManualHashHashability] +from attrs import define + +@define(hash=True) +class A: + a: int + +reveal_type(A.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testManualUnsafeHashHashability] +from attrs import define + +@define(unsafe_hash=True) +class A: + a: int + +reveal_type(A.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testSubclassingHashability] +from attrs import define + +@define(unsafe_hash=True) +class A: + a: int + +@define +class B(A): + pass + +reveal_type(B.__hash__) # N: Revealed type is "None" + +[builtins fixtures/plugin_attrs.pyi] diff --git a/test-data/unit/fixtures/plugin_attrs.pyi b/test-data/unit/fixtures/plugin_attrs.pyi index 57e5ecd1b2bc..5b87c47b5bc8 100644 --- a/test-data/unit/fixtures/plugin_attrs.pyi +++ b/test-data/unit/fixtures/plugin_attrs.pyi @@ -5,6 +5,7 @@ class object: def __init__(self) -> None: pass def __eq__(self, o: object) -> bool: pass def __ne__(self, o: object) -> bool: pass + def __hash__(self) -> int: ... class type: pass class bytes: pass diff --git a/test-data/unit/lib-stub/attr/__init__.pyi b/test-data/unit/lib-stub/attr/__init__.pyi index 24ffc0f3f275..466c6913062d 100644 --- a/test-data/unit/lib-stub/attr/__init__.pyi +++ b/test-data/unit/lib-stub/attr/__init__.pyi @@ -131,6 +131,7 @@ def define( *, these: Optional[Mapping[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool]=None, hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., @@ -153,6 +154,7 @@ def define( *, these: Optional[Mapping[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool]=None, hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., diff --git a/test-data/unit/lib-stub/attrs/__init__.pyi b/test-data/unit/lib-stub/attrs/__init__.pyi index f610957a48a3..d0a65c84d9d8 100644 --- a/test-data/unit/lib-stub/attrs/__init__.pyi +++ b/test-data/unit/lib-stub/attrs/__init__.pyi @@ -22,6 +22,7 @@ def define( *, these: Optional[Mapping[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool]=None, hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., @@ -44,6 +45,7 @@ def define( *, these: Optional[Mapping[str, Any]] = ..., repr: bool = ..., + unsafe_hash: Optional[bool]=None, hash: Optional[bool] = ..., init: bool = ..., slots: bool = ..., From 728e03a687c065bf82256675d53309e60290e108 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:29:46 -0800 Subject: [PATCH 08/69] Fix tests broken by hatchling (#16655) --- test-data/packages/typedpkg-stubs/pyproject.toml | 2 +- test-data/packages/typedpkg/pyproject.toml | 2 +- test-data/packages/typedpkg_ns_a/pyproject.toml | 2 +- test-data/packages/typedpkg_ns_b-stubs/pyproject.toml | 2 +- test-data/packages/typedpkg_ns_b/pyproject.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test-data/packages/typedpkg-stubs/pyproject.toml b/test-data/packages/typedpkg-stubs/pyproject.toml index 125816151ef8..c984c5d91e0a 100644 --- a/test-data/packages/typedpkg-stubs/pyproject.toml +++ b/test-data/packages/typedpkg-stubs/pyproject.toml @@ -7,5 +7,5 @@ description = 'test' include = ["**/*.pyi"] [build-system] -requires = ["hatchling"] +requires = ["hatchling==1.18"] build-backend = "hatchling.build" diff --git a/test-data/packages/typedpkg/pyproject.toml b/test-data/packages/typedpkg/pyproject.toml index 5269c94320e1..6b55d4b3df60 100644 --- a/test-data/packages/typedpkg/pyproject.toml +++ b/test-data/packages/typedpkg/pyproject.toml @@ -4,5 +4,5 @@ version = '0.1' description = 'test' [build-system] -requires = ["hatchling"] +requires = ["hatchling==1.18"] build-backend = "hatchling.build" diff --git a/test-data/packages/typedpkg_ns_a/pyproject.toml b/test-data/packages/typedpkg_ns_a/pyproject.toml index cc464af75b17..f41ad16b5bc2 100644 --- a/test-data/packages/typedpkg_ns_a/pyproject.toml +++ b/test-data/packages/typedpkg_ns_a/pyproject.toml @@ -7,5 +7,5 @@ description = 'test' include = ["**/*.py", "**/*.pyi", "**/py.typed"] [build-system] -requires = ["hatchling"] +requires = ["hatchling==1.18"] build-backend = "hatchling.build" diff --git a/test-data/packages/typedpkg_ns_b-stubs/pyproject.toml b/test-data/packages/typedpkg_ns_b-stubs/pyproject.toml index d5275d1ed8b3..2c1c206c361d 100644 --- a/test-data/packages/typedpkg_ns_b-stubs/pyproject.toml +++ b/test-data/packages/typedpkg_ns_b-stubs/pyproject.toml @@ -7,5 +7,5 @@ description = 'test' include = ["**/*.pyi"] [build-system] -requires = ["hatchling"] +requires = ["hatchling==1.18"] build-backend = "hatchling.build" diff --git a/test-data/packages/typedpkg_ns_b/pyproject.toml b/test-data/packages/typedpkg_ns_b/pyproject.toml index 8567af11152e..b8ae0d59072e 100644 --- a/test-data/packages/typedpkg_ns_b/pyproject.toml +++ b/test-data/packages/typedpkg_ns_b/pyproject.toml @@ -4,5 +4,5 @@ version = '0.1' description = 'test' [build-system] -requires = ["hatchling"] +requires = ["hatchling==1.18"] build-backend = "hatchling.build" From 6acccd13dc4e5a630b8cd95061f2bc352e4dbac6 Mon Sep 17 00:00:00 2001 From: Dheeraj <44266862+dheerajreal@users.noreply.github.com> Date: Wed, 13 Dec 2023 05:00:57 +0530 Subject: [PATCH 09/69] Update `project_urls` in `setup.py` (#16622) Made the following changes to `project_urls` in `setup.py`: - removed link to "News" - added link to "Changelog" - added link to "Issues" --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e3ebe9dd62ec..140020b18bc4 100644 --- a/setup.py +++ b/setup.py @@ -234,8 +234,9 @@ def run(self): python_requires=">=3.8", include_package_data=True, project_urls={ - "News": "https://mypy-lang.org/news.html", "Documentation": "https://mypy.readthedocs.io/en/stable/index.html", "Repository": "https://github.com/python/mypy", + "Changelog": "https://github.com/python/mypy/blob/master/CHANGELOG.md", + "Issues": "https://github.com/python/mypy/issues", }, ) From 09cb2d17cd16003937835b78bde9a6dbe627204c Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 13 Dec 2023 02:35:45 +0300 Subject: [PATCH 10/69] Remove `_is_compatible_stub_package` check from `modulefinder` (#16633) Closes https://github.com/python/mypy/issues/16632 --- mypy/modulefinder.py | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/mypy/modulefinder.py b/mypy/modulefinder.py index c36a382848bf..455aa40e5975 100644 --- a/mypy/modulefinder.py +++ b/mypy/modulefinder.py @@ -13,18 +13,11 @@ import subprocess import sys from enum import Enum, unique - -from mypy.errors import CompileError - -if sys.version_info >= (3, 11): - import tomllib -else: - import tomli as tomllib - from typing import Dict, Final, List, NamedTuple, Optional, Tuple, Union from typing_extensions import TypeAlias as _TypeAlias from mypy import pyinfo +from mypy.errors import CompileError from mypy.fscache import FileSystemCache from mypy.nodes import MypyFile from mypy.options import Options @@ -426,7 +419,7 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult: for pkg_dir in self.search_paths.package_path: stub_name = components[0] + "-stubs" stub_dir = os.path.join(pkg_dir, stub_name) - if fscache.isdir(stub_dir) and self._is_compatible_stub_package(stub_dir): + if fscache.isdir(stub_dir): stub_typed_file = os.path.join(stub_dir, "py.typed") stub_components = [stub_name] + components[1:] path = os.path.join(pkg_dir, *stub_components[:-1]) @@ -562,19 +555,6 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult: else: return ModuleNotFoundReason.NOT_FOUND - def _is_compatible_stub_package(self, stub_dir: str) -> bool: - """Does a stub package support the target Python version? - - Stub packages may contain a metadata file which specifies - whether the stubs are compatible with Python 2 and 3. - """ - metadata_fnam = os.path.join(stub_dir, "METADATA.toml") - if not os.path.isfile(metadata_fnam): - return True - with open(metadata_fnam, "rb") as f: - metadata = tomllib.load(f) - return bool(metadata.get("python3", True)) - def find_modules_recursive(self, module: str) -> list[BuildSource]: module_path = self.find_module(module) if isinstance(module_path, ModuleNotFoundReason): From 5e77c3e96d3f3720d177c74acff07cc3319e8684 Mon Sep 17 00:00:00 2001 From: Froger David Date: Wed, 13 Dec 2023 22:28:12 +0100 Subject: [PATCH 11/69] Document --enable-incomplete-feature possible values in "mypy --help" (#16661) By the way, also remove `--enable-incomplete-feature=Unpack --enable-incomplete-feature=TypeVarTuple` when running the tests, as they are no more incomplete features. Fixes #14452 Co-authored-by: David Froger --- docs/source/command_line.rst | 2 +- mypy/main.py | 2 +- mypyc/test/test_run.py | 3 +-- test-data/unit/pythoneval.test | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index 09836e2ffd20..c8e0ef3df11f 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -995,7 +995,7 @@ format into the specified directory. Enabling incomplete/experimental features ***************************************** -.. option:: --enable-incomplete-feature FEATURE +.. option:: --enable-incomplete-feature {PreciseTupleTypes} Some features may require several mypy releases to implement, for example due to their complexity, potential for backwards incompatibility, or diff --git a/mypy/main.py b/mypy/main.py index 8a35c2056963..ee090a03d3cf 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -1010,7 +1010,7 @@ def add_invertible_flag( parser.add_argument( "--enable-incomplete-feature", action="append", - metavar="FEATURE", + metavar="{" + ",".join(sorted(INCOMPLETE_FEATURES)) + "}", help="Enable support of incomplete/experimental features for early preview", ) internals_group.add_argument( diff --git a/mypyc/test/test_run.py b/mypyc/test/test_run.py index f5c902bf3b3d..467ef8b87a92 100644 --- a/mypyc/test/test_run.py +++ b/mypyc/test/test_run.py @@ -15,7 +15,7 @@ from mypy import build from mypy.errors import CompileError -from mypy.options import TYPE_VAR_TUPLE, UNPACK, Options +from mypy.options import Options from mypy.test.config import test_temp_dir from mypy.test.data import DataDrivenTestCase from mypy.test.helpers import assert_module_equivalence, perform_file_operations @@ -194,7 +194,6 @@ def run_case_step(self, testcase: DataDrivenTestCase, incremental_step: int) -> options.preserve_asts = True options.allow_empty_bodies = True options.incremental = self.separate - options.enable_incomplete_feature = [TYPE_VAR_TUPLE, UNPACK] # Avoid checking modules/packages named 'unchecked', to provide a way # to test interacting with code we don't have types for. diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index c6ca71f5d56a..9f6f5d3838a4 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -2007,7 +2007,7 @@ _testInferenceOfDunderDictOnClassObjects.py:4: error: Property "__dict__" define _testInferenceOfDunderDictOnClassObjects.py:4: error: Incompatible types in assignment (expression has type "Dict[Never, Never]", variable has type "MappingProxyType[str, Any]") [case testTypeVarTuple] -# flags: --enable-incomplete-feature=TypeVarTuple --enable-incomplete-feature=Unpack --python-version=3.11 +# flags: --python-version=3.11 from typing import Any, Callable, Unpack, TypeVarTuple Ts = TypeVarTuple("Ts") @@ -2019,7 +2019,6 @@ def call(callback: Callable[[Unpack[Ts]], Any], *args: Unpack[Ts]) -> Any: ... [case testTypeVarTupleTypingExtensions] -# flags: --enable-incomplete-feature=TypeVarTuple --enable-incomplete-feature=Unpack from typing_extensions import Unpack, TypeVarTuple from typing import Any, Callable From 43ffb49102e2508b5e4767d200872060ddc9f0fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 19:32:04 -0800 Subject: [PATCH 12/69] Sync typeshed (#16665) Source commit: https://github.com/python/typeshed/commit/b6740d0bf4b4cf89befae74a0b12ebef6ce7bda6 --- mypy/typeshed/stdlib/VERSIONS | 1 + mypy/typeshed/stdlib/_ctypes.pyi | 4 +- mypy/typeshed/stdlib/_operator.pyi | 21 ++-- mypy/typeshed/stdlib/_typeshed/__init__.pyi | 9 ++ mypy/typeshed/stdlib/asyncio/base_events.pyi | 23 ++-- mypy/typeshed/stdlib/asyncio/events.pyi | 31 +++--- mypy/typeshed/stdlib/asyncio/exceptions.pyi | 7 +- mypy/typeshed/stdlib/asyncio/locks.pyi | 12 ++- mypy/typeshed/stdlib/asyncio/queues.pyi | 9 +- mypy/typeshed/stdlib/asyncio/unix_events.pyi | 25 ++--- mypy/typeshed/stdlib/builtins.pyi | 2 +- .../stdlib/concurrent/futures/_base.pyi | 6 +- mypy/typeshed/stdlib/ctypes/wintypes.pyi | 102 +++++++++--------- mypy/typeshed/stdlib/dis.pyi | 7 +- mypy/typeshed/stdlib/email/_policybase.pyi | 51 +++++++++ mypy/typeshed/stdlib/email/feedparser.pyi | 5 +- mypy/typeshed/stdlib/email/message.pyi | 57 ++++++++-- mypy/typeshed/stdlib/email/policy.pyi | 46 +------- mypy/typeshed/stdlib/importlib/_abc.pyi | 15 +++ mypy/typeshed/stdlib/importlib/abc.pyi | 36 ++++--- .../stdlib/importlib/metadata/__init__.pyi | 75 +++++++++++-- mypy/typeshed/stdlib/io.pyi | 3 + mypy/typeshed/stdlib/lzma.pyi | 4 +- mypy/typeshed/stdlib/os/__init__.pyi | 10 +- mypy/typeshed/stdlib/pstats.pyi | 5 +- mypy/typeshed/stdlib/pyclbr.pyi | 56 +++++----- mypy/typeshed/stdlib/socketserver.pyi | 4 +- mypy/typeshed/stdlib/sre_parse.pyi | 3 + mypy/typeshed/stdlib/tkinter/__init__.pyi | 13 +-- mypy/typeshed/stdlib/trace.pyi | 24 ++++- mypy/typeshed/stdlib/unittest/case.pyi | 2 + mypy/typeshed/stdlib/urllib/response.pyi | 22 +--- mypy/typeshed/stdlib/xml/sax/__init__.pyi | 28 ++--- mypy/typeshed/stdlib/xml/sax/_exceptions.pyi | 19 ++++ mypy/typeshed/stdlib/xxlimited.pyi | 6 +- 35 files changed, 464 insertions(+), 279 deletions(-) create mode 100644 mypy/typeshed/stdlib/email/_policybase.pyi create mode 100644 mypy/typeshed/stdlib/importlib/_abc.pyi create mode 100644 mypy/typeshed/stdlib/xml/sax/_exceptions.pyi diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index d24e85c8fe44..f5e30c4602b4 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -150,6 +150,7 @@ imaplib: 2.7- imghdr: 2.7- imp: 2.7-3.11 importlib: 2.7- +importlib._abc: 3.10- importlib.metadata: 3.8- importlib.metadata._meta: 3.10- importlib.readers: 3.10- diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 8a891971e9f1..0fa041844028 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -51,8 +51,8 @@ class _CDataMeta(type): # By default mypy complains about the following two methods, because strictly speaking cls # might not be a Type[_CT]. However this can never actually happen, because the only class that # uses _CDataMeta as its metaclass is _CData. So it's safe to ignore the errors here. - def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] - def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] + def __mul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] + def __rmul__(cls: type[_CT], other: int) -> type[Array[_CT]]: ... # type: ignore[misc] class _CData(metaclass=_CDataMeta): _b_base_: int diff --git a/mypy/typeshed/stdlib/_operator.pyi b/mypy/typeshed/stdlib/_operator.pyi index e7d1a98c4027..26e69f130728 100644 --- a/mypy/typeshed/stdlib/_operator.pyi +++ b/mypy/typeshed/stdlib/_operator.pyi @@ -2,14 +2,17 @@ import sys from _typeshed import SupportsGetItem from collections.abc import Callable, Container, Iterable, MutableMapping, MutableSequence, Sequence from typing import Any, AnyStr, Generic, Protocol, SupportsAbs, TypeVar, overload -from typing_extensions import ParamSpec, SupportsIndex, TypeAlias, final +from typing_extensions import ParamSpec, SupportsIndex, TypeAlias, TypeVarTuple, Unpack, final _R = TypeVar("_R") _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") _K = TypeVar("_K") _V = TypeVar("_V") _P = ParamSpec("_P") +_Ts = TypeVarTuple("_Ts") # The following protocols return "Any" instead of bool, since the comparison # operators can be overloaded to return an arbitrary object. For example, @@ -105,22 +108,10 @@ class attrgetter(Generic[_T_co]): @final class itemgetter(Generic[_T_co]): - # mypy lacks support for PEP 646 https://github.com/python/mypy/issues/12280 - # So we have to define all of these overloads to simulate unpacking the arguments @overload - def __new__(cls, item: _T_co) -> itemgetter[_T_co]: ... + def __new__(cls, __item: _T) -> itemgetter[_T]: ... @overload - def __new__(cls, item: _T_co, __item2: _T_co) -> itemgetter[tuple[_T_co, _T_co]]: ... - @overload - def __new__(cls, item: _T_co, __item2: _T_co, __item3: _T_co) -> itemgetter[tuple[_T_co, _T_co, _T_co]]: ... - @overload - def __new__( - cls, item: _T_co, __item2: _T_co, __item3: _T_co, __item4: _T_co - ) -> itemgetter[tuple[_T_co, _T_co, _T_co, _T_co]]: ... - @overload - def __new__( - cls, item: _T_co, __item2: _T_co, __item3: _T_co, __item4: _T_co, *items: _T_co - ) -> itemgetter[tuple[_T_co, ...]]: ... + def __new__(cls, __item1: _T1, __item2: _T2, *items: Unpack[_Ts]) -> itemgetter[tuple[_T1, _T2, Unpack[_Ts]]]: ... # __key: _KT_contra in SupportsGetItem seems to be causing variance issues, ie: # TypeVar "_KT_contra@SupportsGetItem" is contravariant # "tuple[int, int]" is incompatible with protocol "SupportsIndex" diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 33659cf31a12..05892c8aab11 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -320,3 +320,12 @@ class DataclassInstance(Protocol): # Anything that can be passed to the int/float constructors ConvertibleToInt: TypeAlias = str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc ConvertibleToFloat: TypeAlias = str | ReadableBuffer | SupportsFloat | SupportsIndex + +# A few classes updated from Foo(str, Enum) to Foo(StrEnum). This is a convenience so these +# can be accurate on all python versions without getting too wordy +if sys.version_info >= (3, 11): + from enum import StrEnum as StrEnum +else: + from enum import Enum + + class StrEnum(str, Enum): ... diff --git a/mypy/typeshed/stdlib/asyncio/base_events.pyi b/mypy/typeshed/stdlib/asyncio/base_events.pyi index afddcd918584..ff6c42c3645a 100644 --- a/mypy/typeshed/stdlib/asyncio/base_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_events.pyi @@ -11,7 +11,7 @@ from collections.abc import Callable, Iterable, Sequence from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket from typing import IO, Any, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing_extensions import Literal, TypeAlias, TypeVarTuple, Unpack if sys.version_info >= (3, 9): __all__ = ("BaseEventLoop", "Server") @@ -19,6 +19,7 @@ else: __all__ = ("BaseEventLoop",) _T = TypeVar("_T") +_Ts = TypeVarTuple("_Ts") _ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol) _Context: TypeAlias = dict[str, Any] _ExceptionHandler: TypeAlias = Callable[[AbstractEventLoop, _Context], object] @@ -71,12 +72,14 @@ class BaseEventLoop(AbstractEventLoop): def close(self) -> None: ... async def shutdown_asyncgens(self) -> None: ... # Methods scheduling callbacks. All these return Handles. - def call_soon(self, callback: Callable[..., object], *args: Any, context: Context | None = None) -> Handle: ... + def call_soon( + self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None + ) -> Handle: ... def call_later( - self, delay: float, callback: Callable[..., object], *args: Any, context: Context | None = None + self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None ) -> TimerHandle: ... def call_at( - self, when: float, callback: Callable[..., object], *args: Any, context: Context | None = None + self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None ) -> TimerHandle: ... def time(self) -> float: ... # Future methods @@ -92,8 +95,10 @@ class BaseEventLoop(AbstractEventLoop): def set_task_factory(self, factory: _TaskFactory | None) -> None: ... def get_task_factory(self) -> _TaskFactory | None: ... # Methods for interacting with threads - def call_soon_threadsafe(self, callback: Callable[..., object], *args: Any, context: Context | None = None) -> Handle: ... - def run_in_executor(self, executor: Any, func: Callable[..., _T], *args: Any) -> Future[_T]: ... + def call_soon_threadsafe( + self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None + ) -> Handle: ... + def run_in_executor(self, executor: Any, func: Callable[[Unpack[_Ts]], _T], *args: Unpack[_Ts]) -> Future[_T]: ... def set_default_executor(self, executor: Any) -> None: ... # Network I/O methods returning Futures. async def getaddrinfo( @@ -441,9 +446,9 @@ class BaseEventLoop(AbstractEventLoop): errors: None = None, **kwargs: Any, ) -> tuple[SubprocessTransport, _ProtocolT]: ... - def add_reader(self, fd: FileDescriptorLike, callback: Callable[..., Any], *args: Any) -> None: ... + def add_reader(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... def remove_reader(self, fd: FileDescriptorLike) -> bool: ... - def add_writer(self, fd: FileDescriptorLike, callback: Callable[..., Any], *args: Any) -> None: ... + def add_writer(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... def remove_writer(self, fd: FileDescriptorLike) -> bool: ... # The sock_* methods (and probably some others) are not actually implemented on # BaseEventLoop, only on subclasses. We list them here for now for convenience. @@ -457,7 +462,7 @@ class BaseEventLoop(AbstractEventLoop): async def sock_recvfrom_into(self, sock: socket, buf: WriteableBuffer, nbytes: int = 0) -> tuple[int, _RetAddress]: ... async def sock_sendto(self, sock: socket, data: ReadableBuffer, address: _Address) -> int: ... # Signal handling. - def add_signal_handler(self, sig: int, callback: Callable[..., Any], *args: Any) -> None: ... + def add_signal_handler(self, sig: int, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... def remove_signal_handler(self, sig: int) -> bool: ... # Error handlers. def set_exception_handler(self, handler: _ExceptionHandler | None) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 87e7edb461ac..0f51c457fc24 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -6,7 +6,7 @@ from collections.abc import Callable, Coroutine, Generator, Sequence from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket from typing import IO, Any, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias, deprecated +from typing_extensions import Literal, Self, TypeAlias, TypeVarTuple, Unpack, deprecated from . import _AwaitableLike, _CoroutineLike from .base_events import Server @@ -56,6 +56,7 @@ else: ) _T = TypeVar("_T") +_Ts = TypeVarTuple("_Ts") _ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol) _Context: TypeAlias = dict[str, Any] _ExceptionHandler: TypeAlias = Callable[[AbstractEventLoop, _Context], object] @@ -131,22 +132,24 @@ class AbstractEventLoop: # Methods scheduling callbacks. All these return Handles. if sys.version_info >= (3, 9): # "context" added in 3.9.10/3.10.2 @abstractmethod - def call_soon(self, callback: Callable[..., object], *args: Any, context: Context | None = None) -> Handle: ... + def call_soon( + self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None + ) -> Handle: ... @abstractmethod def call_later( - self, delay: float, callback: Callable[..., object], *args: Any, context: Context | None = None + self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None ) -> TimerHandle: ... @abstractmethod def call_at( - self, when: float, callback: Callable[..., object], *args: Any, context: Context | None = None + self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None ) -> TimerHandle: ... else: @abstractmethod - def call_soon(self, callback: Callable[..., object], *args: Any) -> Handle: ... + def call_soon(self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> Handle: ... @abstractmethod - def call_later(self, delay: float, callback: Callable[..., object], *args: Any) -> TimerHandle: ... + def call_later(self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> TimerHandle: ... @abstractmethod - def call_at(self, when: float, callback: Callable[..., object], *args: Any) -> TimerHandle: ... + def call_at(self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> TimerHandle: ... @abstractmethod def time(self) -> float: ... @@ -173,13 +176,15 @@ class AbstractEventLoop: # Methods for interacting with threads if sys.version_info >= (3, 9): # "context" added in 3.9.10/3.10.2 @abstractmethod - def call_soon_threadsafe(self, callback: Callable[..., object], *args: Any, context: Context | None = None) -> Handle: ... + def call_soon_threadsafe( + self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None + ) -> Handle: ... else: @abstractmethod - def call_soon_threadsafe(self, callback: Callable[..., object], *args: Any) -> Handle: ... + def call_soon_threadsafe(self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> Handle: ... @abstractmethod - def run_in_executor(self, executor: Any, func: Callable[..., _T], *args: Any) -> Future[_T]: ... + def run_in_executor(self, executor: Any, func: Callable[[Unpack[_Ts]], _T], *args: Unpack[_Ts]) -> Future[_T]: ... @abstractmethod def set_default_executor(self, executor: Any) -> None: ... # Network I/O methods returning Futures. @@ -542,11 +547,11 @@ class AbstractEventLoop: **kwargs: Any, ) -> tuple[SubprocessTransport, _ProtocolT]: ... @abstractmethod - def add_reader(self, fd: FileDescriptorLike, callback: Callable[..., Any], *args: Any) -> None: ... + def add_reader(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_reader(self, fd: FileDescriptorLike) -> bool: ... @abstractmethod - def add_writer(self, fd: FileDescriptorLike, callback: Callable[..., Any], *args: Any) -> None: ... + def add_writer(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_writer(self, fd: FileDescriptorLike) -> bool: ... # Completion based I/O methods returning Futures prior to 3.7 @@ -569,7 +574,7 @@ class AbstractEventLoop: async def sock_sendto(self, sock: socket, data: ReadableBuffer, address: _Address) -> int: ... # Signal handling. @abstractmethod - def add_signal_handler(self, sig: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_signal_handler(self, sig: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_signal_handler(self, sig: int) -> bool: ... # Error handlers. diff --git a/mypy/typeshed/stdlib/asyncio/exceptions.pyi b/mypy/typeshed/stdlib/asyncio/exceptions.pyi index 075fbb805bb9..0746394d582f 100644 --- a/mypy/typeshed/stdlib/asyncio/exceptions.pyi +++ b/mypy/typeshed/stdlib/asyncio/exceptions.pyi @@ -21,7 +21,12 @@ else: ) class CancelledError(BaseException): ... -class TimeoutError(Exception): ... + +if sys.version_info >= (3, 11): + from builtins import TimeoutError as TimeoutError +else: + class TimeoutError(Exception): ... + class InvalidStateError(Exception): ... class SendfileNotAvailableError(RuntimeError): ... diff --git a/mypy/typeshed/stdlib/asyncio/locks.pyi b/mypy/typeshed/stdlib/asyncio/locks.pyi index ab4e63ab59b1..394b82a5b3d9 100644 --- a/mypy/typeshed/stdlib/asyncio/locks.pyi +++ b/mypy/typeshed/stdlib/asyncio/locks.pyi @@ -10,8 +10,10 @@ from typing_extensions import Literal, Self from .events import AbstractEventLoop from .futures import Future -if sys.version_info >= (3, 11): +if sys.version_info >= (3, 10): from .mixins import _LoopBoundMixin +else: + _LoopBoundMixin = object if sys.version_info >= (3, 11): __all__ = ("Lock", "Event", "Condition", "Semaphore", "BoundedSemaphore", "Barrier") @@ -44,7 +46,7 @@ else: self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None ) -> None: ... -class Lock(_ContextManagerMixin): +class Lock(_ContextManagerMixin, _LoopBoundMixin): if sys.version_info >= (3, 10): def __init__(self) -> None: ... else: @@ -54,7 +56,7 @@ class Lock(_ContextManagerMixin): async def acquire(self) -> Literal[True]: ... def release(self) -> None: ... -class Event: +class Event(_LoopBoundMixin): if sys.version_info >= (3, 10): def __init__(self) -> None: ... else: @@ -65,7 +67,7 @@ class Event: def clear(self) -> None: ... async def wait(self) -> Literal[True]: ... -class Condition(_ContextManagerMixin): +class Condition(_ContextManagerMixin, _LoopBoundMixin): if sys.version_info >= (3, 10): def __init__(self, lock: Lock | None = None) -> None: ... else: @@ -79,7 +81,7 @@ class Condition(_ContextManagerMixin): def notify(self, n: int = 1) -> None: ... def notify_all(self) -> None: ... -class Semaphore(_ContextManagerMixin): +class Semaphore(_ContextManagerMixin, _LoopBoundMixin): _value: int _waiters: deque[Future[Any]] if sys.version_info >= (3, 10): diff --git a/mypy/typeshed/stdlib/asyncio/queues.pyi b/mypy/typeshed/stdlib/asyncio/queues.pyi index f56a09524e71..bb4ee71f9267 100644 --- a/mypy/typeshed/stdlib/asyncio/queues.pyi +++ b/mypy/typeshed/stdlib/asyncio/queues.pyi @@ -5,6 +5,11 @@ from typing import Any, Generic, TypeVar if sys.version_info >= (3, 9): from types import GenericAlias +if sys.version_info >= (3, 10): + from .mixins import _LoopBoundMixin +else: + _LoopBoundMixin = object + __all__ = ("Queue", "PriorityQueue", "LifoQueue", "QueueFull", "QueueEmpty") class QueueEmpty(Exception): ... @@ -12,7 +17,9 @@ class QueueFull(Exception): ... _T = TypeVar("_T") -class Queue(Generic[_T]): +# If Generic[_T] is last and _LoopBoundMixin is object, pyright is unhappy. +# We can remove the noqa pragma when dropping 3.9 support. +class Queue(Generic[_T], _LoopBoundMixin): # noqa: Y059 if sys.version_info >= (3, 10): def __init__(self, maxsize: int = 0) -> None: ... else: diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index d440206aa0b9..ee16035f86a8 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -2,12 +2,13 @@ import sys import types from abc import ABCMeta, abstractmethod from collections.abc import Callable -from typing import Any -from typing_extensions import Literal, Self, deprecated +from typing_extensions import Literal, Self, TypeVarTuple, Unpack, deprecated from .events import AbstractEventLoop, BaseDefaultEventLoopPolicy from .selector_events import BaseSelectorEventLoop +_Ts = TypeVarTuple("_Ts") + # This is also technically not available on Win, # but other parts of typeshed need this definition. # So, it is special cased. @@ -15,7 +16,7 @@ if sys.version_info >= (3, 12): @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") class AbstractChildWatcher: @abstractmethod - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_child_handler(self, pid: int) -> bool: ... @abstractmethod @@ -35,7 +36,7 @@ if sys.version_info >= (3, 12): else: class AbstractChildWatcher: @abstractmethod - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_child_handler(self, pid: int) -> bool: ... @abstractmethod @@ -91,26 +92,26 @@ if sys.platform != "win32": class SafeChildWatcher(BaseChildWatcher): def __enter__(self) -> Self: ... def __exit__(self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") class FastChildWatcher(BaseChildWatcher): def __enter__(self) -> Self: ... def __exit__(self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... else: class SafeChildWatcher(BaseChildWatcher): def __enter__(self) -> Self: ... def __exit__(self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... class FastChildWatcher(BaseChildWatcher): def __enter__(self) -> Self: ... def __exit__(self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... class _UnixSelectorEventLoop(BaseSelectorEventLoop): ... @@ -137,7 +138,7 @@ if sys.platform != "win32": def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None ) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... elif sys.version_info >= (3, 8): @@ -148,7 +149,7 @@ if sys.platform != "win32": def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None ) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... @@ -161,7 +162,7 @@ if sys.platform != "win32": self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None ) -> None: ... def __del__(self) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... @@ -174,5 +175,5 @@ if sys.platform != "win32": def is_active(self) -> bool: ... def close(self) -> None: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index e3d7ee7e5cc1..dca3c2160b5a 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -202,7 +202,7 @@ class type: def __instancecheck__(self, __instance: Any) -> bool: ... def __subclasscheck__(self, __subclass: type) -> bool: ... @classmethod - def __prepare__(metacls, __name: str, __bases: tuple[type, ...], **kwds: Any) -> Mapping[str, object]: ... + def __prepare__(metacls, __name: str, __bases: tuple[type, ...], **kwds: Any) -> MutableMapping[str, object]: ... if sys.version_info >= (3, 10): def __or__(self, __value: Any) -> types.UnionType: ... def __ror__(self, __value: Any) -> types.UnionType: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi index eb5ca4e2dd35..8a11f47e5670 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi @@ -24,7 +24,11 @@ LOGGER: Logger class Error(Exception): ... class CancelledError(Error): ... -class TimeoutError(Error): ... + +if sys.version_info >= (3, 11): + from builtins import TimeoutError as TimeoutError +else: + class TimeoutError(Error): ... if sys.version_info >= (3, 8): class InvalidStateError(Error): ... diff --git a/mypy/typeshed/stdlib/ctypes/wintypes.pyi b/mypy/typeshed/stdlib/ctypes/wintypes.pyi index 59c7ae3e599f..84c9c9157a88 100644 --- a/mypy/typeshed/stdlib/ctypes/wintypes.pyi +++ b/mypy/typeshed/stdlib/ctypes/wintypes.pyi @@ -186,55 +186,53 @@ class WIN32_FIND_DATAW(Structure): cFileName: _CField[Array[WCHAR], str, str] cAlternateFileName: _CField[Array[WCHAR], str, str] -# These pointer type definitions use _Pointer[...] instead of POINTER(...), to allow them -# to be used in type annotations. -PBOOL: TypeAlias = _Pointer[BOOL] -LPBOOL: TypeAlias = _Pointer[BOOL] -PBOOLEAN: TypeAlias = _Pointer[BOOLEAN] -PBYTE: TypeAlias = _Pointer[BYTE] -LPBYTE: TypeAlias = _Pointer[BYTE] -PCHAR: TypeAlias = _Pointer[CHAR] -LPCOLORREF: TypeAlias = _Pointer[COLORREF] -PDWORD: TypeAlias = _Pointer[DWORD] -LPDWORD: TypeAlias = _Pointer[DWORD] -PFILETIME: TypeAlias = _Pointer[FILETIME] -LPFILETIME: TypeAlias = _Pointer[FILETIME] -PFLOAT: TypeAlias = _Pointer[FLOAT] -PHANDLE: TypeAlias = _Pointer[HANDLE] -LPHANDLE: TypeAlias = _Pointer[HANDLE] -PHKEY: TypeAlias = _Pointer[HKEY] -LPHKL: TypeAlias = _Pointer[HKL] -PINT: TypeAlias = _Pointer[INT] -LPINT: TypeAlias = _Pointer[INT] -PLARGE_INTEGER: TypeAlias = _Pointer[LARGE_INTEGER] -PLCID: TypeAlias = _Pointer[LCID] -PLONG: TypeAlias = _Pointer[LONG] -LPLONG: TypeAlias = _Pointer[LONG] -PMSG: TypeAlias = _Pointer[MSG] -LPMSG: TypeAlias = _Pointer[MSG] -PPOINT: TypeAlias = _Pointer[POINT] -LPPOINT: TypeAlias = _Pointer[POINT] -PPOINTL: TypeAlias = _Pointer[POINTL] -PRECT: TypeAlias = _Pointer[RECT] -LPRECT: TypeAlias = _Pointer[RECT] -PRECTL: TypeAlias = _Pointer[RECTL] -LPRECTL: TypeAlias = _Pointer[RECTL] -LPSC_HANDLE: TypeAlias = _Pointer[SC_HANDLE] -PSHORT: TypeAlias = _Pointer[SHORT] -PSIZE: TypeAlias = _Pointer[SIZE] -LPSIZE: TypeAlias = _Pointer[SIZE] -PSIZEL: TypeAlias = _Pointer[SIZEL] -LPSIZEL: TypeAlias = _Pointer[SIZEL] -PSMALL_RECT: TypeAlias = _Pointer[SMALL_RECT] -PUINT: TypeAlias = _Pointer[UINT] -LPUINT: TypeAlias = _Pointer[UINT] -PULARGE_INTEGER: TypeAlias = _Pointer[ULARGE_INTEGER] -PULONG: TypeAlias = _Pointer[ULONG] -PUSHORT: TypeAlias = _Pointer[USHORT] -PWCHAR: TypeAlias = _Pointer[WCHAR] -PWIN32_FIND_DATAA: TypeAlias = _Pointer[WIN32_FIND_DATAA] -LPWIN32_FIND_DATAA: TypeAlias = _Pointer[WIN32_FIND_DATAA] -PWIN32_FIND_DATAW: TypeAlias = _Pointer[WIN32_FIND_DATAW] -LPWIN32_FIND_DATAW: TypeAlias = _Pointer[WIN32_FIND_DATAW] -PWORD: TypeAlias = _Pointer[WORD] -LPWORD: TypeAlias = _Pointer[WORD] +class PBOOL(_Pointer[BOOL]): ... +class LPBOOL(_Pointer[BOOL]): ... +class PBOOLEAN(_Pointer[BOOLEAN]): ... +class PBYTE(_Pointer[BYTE]): ... +class LPBYTE(_Pointer[BYTE]): ... +class PCHAR(_Pointer[CHAR]): ... +class LPCOLORREF(_Pointer[COLORREF]): ... +class PDWORD(_Pointer[DWORD]): ... +class LPDWORD(_Pointer[DWORD]): ... +class PFILETIME(_Pointer[FILETIME]): ... +class LPFILETIME(_Pointer[FILETIME]): ... +class PFLOAT(_Pointer[FLOAT]): ... +class PHANDLE(_Pointer[HANDLE]): ... +class LPHANDLE(_Pointer[HANDLE]): ... +class PHKEY(_Pointer[HKEY]): ... +class LPHKL(_Pointer[HKL]): ... +class PINT(_Pointer[INT]): ... +class LPINT(_Pointer[INT]): ... +class PLARGE_INTEGER(_Pointer[LARGE_INTEGER]): ... +class PLCID(_Pointer[LCID]): ... +class PLONG(_Pointer[LONG]): ... +class LPLONG(_Pointer[LONG]): ... +class PMSG(_Pointer[MSG]): ... +class LPMSG(_Pointer[MSG]): ... +class PPOINT(_Pointer[POINT]): ... +class LPPOINT(_Pointer[POINT]): ... +class PPOINTL(_Pointer[POINTL]): ... +class PRECT(_Pointer[RECT]): ... +class LPRECT(_Pointer[RECT]): ... +class PRECTL(_Pointer[RECTL]): ... +class LPRECTL(_Pointer[RECTL]): ... +class LPSC_HANDLE(_Pointer[SC_HANDLE]): ... +class PSHORT(_Pointer[SHORT]): ... +class PSIZE(_Pointer[SIZE]): ... +class LPSIZE(_Pointer[SIZE]): ... +class PSIZEL(_Pointer[SIZEL]): ... +class LPSIZEL(_Pointer[SIZEL]): ... +class PSMALL_RECT(_Pointer[SMALL_RECT]): ... +class PUINT(_Pointer[UINT]): ... +class LPUINT(_Pointer[UINT]): ... +class PULARGE_INTEGER(_Pointer[ULARGE_INTEGER]): ... +class PULONG(_Pointer[ULONG]): ... +class PUSHORT(_Pointer[USHORT]): ... +class PWCHAR(_Pointer[WCHAR]): ... +class PWIN32_FIND_DATAA(_Pointer[WIN32_FIND_DATAA]): ... +class LPWIN32_FIND_DATAA(_Pointer[WIN32_FIND_DATAA]): ... +class PWIN32_FIND_DATAW(_Pointer[WIN32_FIND_DATAW]): ... +class LPWIN32_FIND_DATAW(_Pointer[WIN32_FIND_DATAW]): ... +class PWORD(_Pointer[WORD]): ... +class LPWORD(_Pointer[WORD]): ... diff --git a/mypy/typeshed/stdlib/dis.pyi b/mypy/typeshed/stdlib/dis.pyi index ab101a517a6f..796d81d8bf70 100644 --- a/mypy/typeshed/stdlib/dis.pyi +++ b/mypy/typeshed/stdlib/dis.pyi @@ -48,7 +48,7 @@ if sys.version_info >= (3, 11): end_col_offset: int | None = None if sys.version_info >= (3, 11): - class Instruction(NamedTuple): + class _Instruction(NamedTuple): opname: str opcode: int arg: int | None @@ -60,7 +60,7 @@ if sys.version_info >= (3, 11): positions: Positions | None = None else: - class Instruction(NamedTuple): + class _Instruction(NamedTuple): opname: str opcode: int arg: int | None @@ -70,6 +70,9 @@ else: starts_line: int | None is_jump_target: bool +class Instruction(_Instruction): + def _disassemble(self, lineno_width: int = 3, mark_as_current: bool = False, offset_width: int = 4) -> str: ... + class Bytecode: codeobj: types.CodeType first_line: int diff --git a/mypy/typeshed/stdlib/email/_policybase.pyi b/mypy/typeshed/stdlib/email/_policybase.pyi new file mode 100644 index 000000000000..a3dd61a282ce --- /dev/null +++ b/mypy/typeshed/stdlib/email/_policybase.pyi @@ -0,0 +1,51 @@ +from abc import ABCMeta, abstractmethod +from collections.abc import Callable +from email.errors import MessageDefect +from email.header import Header +from email.message import Message +from typing import Any +from typing_extensions import Self + +class _PolicyBase: + def __add__(self, other: Any) -> Self: ... + def clone(self, **kw: Any) -> Self: ... + +class Policy(_PolicyBase, metaclass=ABCMeta): + max_line_length: int | None + linesep: str + cte_type: str + raise_on_defect: bool + mangle_from_: bool + message_factory: Callable[[Policy], Message] | None + def __init__( + self, + *, + max_line_length: int | None = 78, + linesep: str = "\n", + cte_type: str = "8bit", + raise_on_defect: bool = False, + mangle_from_: bool = False, + message_factory: Callable[[Policy], Message] | None = None, + ) -> None: ... + def handle_defect(self, obj: Message, defect: MessageDefect) -> None: ... + def register_defect(self, obj: Message, defect: MessageDefect) -> None: ... + def header_max_count(self, name: str) -> int | None: ... + @abstractmethod + def header_source_parse(self, sourcelines: list[str]) -> tuple[str, str]: ... + @abstractmethod + def header_store_parse(self, name: str, value: str) -> tuple[str, str]: ... + @abstractmethod + def header_fetch_parse(self, name: str, value: str) -> str: ... + @abstractmethod + def fold(self, name: str, value: str) -> str: ... + @abstractmethod + def fold_binary(self, name: str, value: str) -> bytes: ... + +class Compat32(Policy): + def header_source_parse(self, sourcelines: list[str]) -> tuple[str, str]: ... + def header_store_parse(self, name: str, value: str) -> tuple[str, str]: ... + def header_fetch_parse(self, name: str, value: str) -> str | Header: ... # type: ignore[override] + def fold(self, name: str, value: str) -> str: ... + def fold_binary(self, name: str, value: str) -> bytes: ... + +compat32: Compat32 diff --git a/mypy/typeshed/stdlib/email/feedparser.pyi b/mypy/typeshed/stdlib/email/feedparser.pyi index 4b7f73b9c015..22920fc99c69 100644 --- a/mypy/typeshed/stdlib/email/feedparser.pyi +++ b/mypy/typeshed/stdlib/email/feedparser.pyi @@ -15,10 +15,9 @@ class FeedParser(Generic[_MessageT]): def feed(self, data: str) -> None: ... def close(self) -> _MessageT: ... -class BytesFeedParser(Generic[_MessageT]): +class BytesFeedParser(FeedParser[_MessageT]): @overload def __init__(self: BytesFeedParser[Message], _factory: None = None, *, policy: Policy = ...) -> None: ... @overload def __init__(self, _factory: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... - def feed(self, data: bytes | bytearray) -> None: ... - def close(self) -> _MessageT: ... + def feed(self, data: bytes | bytearray) -> None: ... # type: ignore[override] diff --git a/mypy/typeshed/stdlib/email/message.pyi b/mypy/typeshed/stdlib/email/message.pyi index 18852f4d3bb2..71c8da3a6a5a 100644 --- a/mypy/typeshed/stdlib/email/message.pyi +++ b/mypy/typeshed/stdlib/email/message.pyi @@ -3,17 +3,27 @@ from email import _ParamsType, _ParamType from email.charset import Charset from email.contentmanager import ContentManager from email.errors import MessageDefect +from email.header import Header from email.policy import Policy -from typing import Any, TypeVar, overload -from typing_extensions import Self, TypeAlias +from typing import Any, Protocol, TypeVar, overload +from typing_extensions import Literal, Self, TypeAlias __all__ = ["Message", "EmailMessage"] _T = TypeVar("_T") - -_PayloadType: TypeAlias = list[Message] | str | bytes | bytearray +_PayloadType: TypeAlias = Message | str +_EncodedPayloadType: TypeAlias = Message | bytes +_MultipartPayloadType: TypeAlias = list[_PayloadType] _CharsetType: TypeAlias = Charset | str | None +# Type returned by Policy.header_fetch_parse, AnyOf[str | Header] _HeaderType: TypeAlias = Any +_HeaderTypeParam: TypeAlias = str | Header + +class _SupportsEncodeToPayload(Protocol): + def encode(self, __encoding: str) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload: ... + +class _SupportsDecodeToPayload(Protocol): + def decode(self, __encoding: str, __errors: str) -> _PayloadType | _MultipartPayloadType: ... class Message: policy: Policy # undocumented @@ -23,16 +33,43 @@ class Message: def is_multipart(self) -> bool: ... def set_unixfrom(self, unixfrom: str) -> None: ... def get_unixfrom(self) -> str | None: ... - def attach(self, payload: Message) -> None: ... - def get_payload(self, i: int | None = None, decode: bool = False) -> Any: ... # returns _PayloadType | None - def set_payload(self, payload: _PayloadType, charset: _CharsetType = None) -> None: ... + def attach(self, payload: _PayloadType) -> None: ... + # `i: int` without a multipart payload results in an error + # `| Any`: can be None for cleared or unset payload, but annoying to check + @overload # multipart + def get_payload(self, i: int, decode: Literal[True]) -> None: ... + @overload # multipart + def get_payload(self, i: int, decode: Literal[False] = False) -> _PayloadType | Any: ... + @overload # either + def get_payload(self, i: None = None, decode: Literal[False] = False) -> _PayloadType | _MultipartPayloadType | Any: ... + @overload # not multipart + def get_payload(self, i: None = None, *, decode: Literal[True]) -> _EncodedPayloadType | Any: ... + @overload # not multipart, IDEM but w/o kwarg + def get_payload(self, i: None, decode: Literal[True]) -> _EncodedPayloadType | Any: ... + # If `charset=None` and payload supports both `encode` AND `decode`, then an invalid payload could be passed, but this is unlikely + # Not[_SupportsEncodeToPayload] + @overload + def set_payload( + self, payload: _SupportsDecodeToPayload | _PayloadType | _MultipartPayloadType, charset: None = None + ) -> None: ... + @overload + def set_payload( + self, + payload: _SupportsEncodeToPayload | _SupportsDecodeToPayload | _PayloadType | _MultipartPayloadType, + charset: Charset | str, + ) -> None: ... def set_charset(self, charset: _CharsetType) -> None: ... def get_charset(self) -> _CharsetType: ... def __len__(self) -> int: ... def __contains__(self, name: str) -> bool: ... def __iter__(self) -> Iterator[str]: ... + # Same as `get` with `failobj=None`, but with the expectation that it won't return None in most scenarios + # This is important for protocols using __getitem__, like SupportsKeysAndGetItem + # Morally, the return type should be `AnyOf[_HeaderType, None]`, + # which we could spell as `_HeaderType | Any`, + # *but* `_HeaderType` itself is currently an alias to `Any`... def __getitem__(self, name: str) -> _HeaderType: ... - def __setitem__(self, name: str, val: _HeaderType) -> None: ... + def __setitem__(self, name: str, val: _HeaderTypeParam) -> None: ... def __delitem__(self, name: str) -> None: ... def keys(self) -> list[str]: ... def values(self) -> list[_HeaderType]: ... @@ -46,7 +83,7 @@ class Message: @overload def get_all(self, name: str, failobj: _T) -> list[_HeaderType] | _T: ... def add_header(self, _name: str, _value: str, **_params: _ParamsType) -> None: ... - def replace_header(self, _name: str, _value: _HeaderType) -> None: ... + def replace_header(self, _name: str, _value: _HeaderTypeParam) -> None: ... def get_content_type(self) -> str: ... def get_content_maintype(self) -> str: ... def get_content_subtype(self) -> str: ... @@ -100,7 +137,7 @@ class Message: ) -> None: ... def __init__(self, policy: Policy = ...) -> None: ... # The following two methods are undocumented, but a source code comment states that they are public API - def set_raw(self, name: str, value: _HeaderType) -> None: ... + def set_raw(self, name: str, value: _HeaderTypeParam) -> None: ... def raw_items(self) -> Iterator[tuple[str, _HeaderType]]: ... class MIMEPart(Message): diff --git a/mypy/typeshed/stdlib/email/policy.pyi b/mypy/typeshed/stdlib/email/policy.pyi index 804044031fcd..5f1cf934eb3c 100644 --- a/mypy/typeshed/stdlib/email/policy.pyi +++ b/mypy/typeshed/stdlib/email/policy.pyi @@ -1,55 +1,11 @@ -from abc import ABCMeta, abstractmethod from collections.abc import Callable +from email._policybase import Compat32 as Compat32, Policy as Policy, compat32 as compat32 from email.contentmanager import ContentManager -from email.errors import MessageDefect -from email.header import Header from email.message import Message from typing import Any -from typing_extensions import Self __all__ = ["Compat32", "compat32", "Policy", "EmailPolicy", "default", "strict", "SMTP", "HTTP"] -class Policy(metaclass=ABCMeta): - max_line_length: int | None - linesep: str - cte_type: str - raise_on_defect: bool - mangle_from_: bool - message_factory: Callable[[Policy], Message] | None - def __init__( - self, - *, - max_line_length: int | None = ..., - linesep: str = ..., - cte_type: str = ..., - raise_on_defect: bool = ..., - mangle_from_: bool = ..., - message_factory: Callable[[Policy], Message] | None = ..., - ) -> None: ... - def clone(self, **kw: Any) -> Self: ... - def handle_defect(self, obj: Message, defect: MessageDefect) -> None: ... - def register_defect(self, obj: Message, defect: MessageDefect) -> None: ... - def header_max_count(self, name: str) -> int | None: ... - @abstractmethod - def header_source_parse(self, sourcelines: list[str]) -> tuple[str, str]: ... - @abstractmethod - def header_store_parse(self, name: str, value: str) -> tuple[str, str]: ... - @abstractmethod - def header_fetch_parse(self, name: str, value: str) -> str: ... - @abstractmethod - def fold(self, name: str, value: str) -> str: ... - @abstractmethod - def fold_binary(self, name: str, value: str) -> bytes: ... - -class Compat32(Policy): - def header_source_parse(self, sourcelines: list[str]) -> tuple[str, str]: ... - def header_store_parse(self, name: str, value: str) -> tuple[str, str]: ... - def header_fetch_parse(self, name: str, value: str) -> str | Header: ... # type: ignore[override] - def fold(self, name: str, value: str) -> str: ... - def fold_binary(self, name: str, value: str) -> bytes: ... - -compat32: Compat32 - class EmailPolicy(Policy): utf8: bool refold_source: str diff --git a/mypy/typeshed/stdlib/importlib/_abc.pyi b/mypy/typeshed/stdlib/importlib/_abc.pyi new file mode 100644 index 000000000000..1a21b9a72cd8 --- /dev/null +++ b/mypy/typeshed/stdlib/importlib/_abc.pyi @@ -0,0 +1,15 @@ +import sys +import types +from abc import ABCMeta +from importlib.machinery import ModuleSpec + +if sys.version_info >= (3, 10): + class Loader(metaclass=ABCMeta): + def load_module(self, fullname: str) -> types.ModuleType: ... + if sys.version_info < (3, 12): + def module_repr(self, module: types.ModuleType) -> str: ... + + def create_module(self, spec: ModuleSpec) -> types.ModuleType | None: ... + # Not defined on the actual class for backwards-compatibility reasons, + # but expected in new code. + def exec_module(self, module: types.ModuleType) -> None: ... diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index 148e12ec7e3f..eb13240f84ff 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -24,18 +24,19 @@ if sys.version_info >= (3, 11): if sys.version_info < (3, 12): __all__ += ["Finder", "ResourceReader", "Traversable", "TraversableResources"] -if sys.version_info < (3, 12): - class Finder(metaclass=ABCMeta): ... - -class Loader(metaclass=ABCMeta): - def load_module(self, fullname: str) -> types.ModuleType: ... - if sys.version_info < (3, 12): +if sys.version_info >= (3, 10): + from importlib._abc import Loader as Loader +else: + class Loader(metaclass=ABCMeta): + def load_module(self, fullname: str) -> types.ModuleType: ... def module_repr(self, module: types.ModuleType) -> str: ... + def create_module(self, spec: ModuleSpec) -> types.ModuleType | None: ... + # Not defined on the actual class for backwards-compatibility reasons, + # but expected in new code. + def exec_module(self, module: types.ModuleType) -> None: ... - def create_module(self, spec: ModuleSpec) -> types.ModuleType | None: ... - # Not defined on the actual class for backwards-compatibility reasons, - # but expected in new code. - def exec_module(self, module: types.ModuleType) -> None: ... +if sys.version_info < (3, 12): + class Finder(metaclass=ABCMeta): ... class ResourceLoader(Loader): @abstractmethod @@ -62,10 +63,13 @@ class SourceLoader(ResourceLoader, ExecutionLoader, metaclass=ABCMeta): def get_source(self, fullname: str) -> str | None: ... def path_stats(self, path: str) -> Mapping[str, Any]: ... -# The base classes differ on 3.12: -if sys.version_info >= (3, 12): +# The base classes differ starting in 3.10: +if sys.version_info >= (3, 10): # Please keep in sync with sys._MetaPathFinder class MetaPathFinder(metaclass=ABCMeta): + if sys.version_info < (3, 12): + def find_module(self, fullname: str, path: Sequence[str] | None) -> Loader | None: ... + def invalidate_caches(self) -> None: ... # Not defined on the actual class, but expected to exist. def find_spec( @@ -73,6 +77,10 @@ if sys.version_info >= (3, 12): ) -> ModuleSpec | None: ... class PathEntryFinder(metaclass=ABCMeta): + if sys.version_info < (3, 12): + def find_module(self, fullname: str) -> Loader | None: ... + def find_loader(self, fullname: str) -> tuple[Loader | None, Sequence[str]]: ... + def invalidate_caches(self) -> None: ... # Not defined on the actual class, but expected to exist. def find_spec(self, fullname: str, target: types.ModuleType | None = ...) -> ModuleSpec | None: ... @@ -138,10 +146,10 @@ if sys.version_info >= (3, 9): # which is not the case. @overload @abstractmethod - def open(self, __mode: Literal["r", "w"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ... + def open(self, __mode: Literal["r"] = "r", *, encoding: str | None = None, errors: str | None = None) -> IO[str]: ... @overload @abstractmethod - def open(self, __mode: Literal["rb", "wb"]) -> IO[bytes]: ... + def open(self, __mode: Literal["rb"]) -> IO[bytes]: ... @property @abstractmethod def name(self) -> str: ... diff --git a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi index fd470b8f061d..a936eece1d3f 100644 --- a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi @@ -1,16 +1,21 @@ import abc import pathlib import sys +from _collections_abc import dict_keys, dict_values from _typeshed import StrPath -from collections.abc import Iterable, Mapping +from collections.abc import Iterable, Iterator, Mapping from email.message import Message from importlib.abc import MetaPathFinder from os import PathLike from pathlib import Path from re import Pattern -from typing import Any, ClassVar, NamedTuple, overload +from typing import Any, ClassVar, Generic, NamedTuple, TypeVar, overload from typing_extensions import Self +_T = TypeVar("_T") +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + __all__ = [ "Distribution", "DistributionFinder", @@ -35,14 +40,23 @@ class PackageNotFoundError(ModuleNotFoundError): @property def name(self) -> str: ... # type: ignore[override] -class _EntryPointBase(NamedTuple): - name: str - value: str - group: str +if sys.version_info >= (3, 11): + class DeprecatedTuple: + def __getitem__(self, item: int) -> str: ... + _EntryPointBase = DeprecatedTuple +else: + class _EntryPointBase(NamedTuple): + name: str + value: str + group: str class EntryPoint(_EntryPointBase): pattern: ClassVar[Pattern[str]] if sys.version_info >= (3, 11): + name: str + value: str + group: str + def __init__(self, name: str, value: str, group: str) -> None: ... def load(self) -> Any: ... # Callable[[], Any] or an importable module @@ -68,9 +82,33 @@ class EntryPoint(_EntryPointBase): def __hash__(self) -> int: ... def __eq__(self, other: object) -> bool: ... + if sys.version_info >= (3, 11): + def __lt__(self, other: object) -> bool: ... + if sys.version_info < (3, 12): + def __iter__(self) -> Iterator[Any]: ... # result of iter((str, Self)), really -if sys.version_info >= (3, 10): - class EntryPoints(list[EntryPoint]): # use as list is deprecated since 3.10 +if sys.version_info >= (3, 12): + class EntryPoints(tuple[EntryPoint, ...]): + def __getitem__(self, name: str) -> EntryPoint: ... # type: ignore[override] + def select( + self, + *, + name: str = ..., + value: str = ..., + group: str = ..., + module: str = ..., + attr: str = ..., + extras: list[str] = ..., + ) -> EntryPoints: ... + @property + def names(self) -> set[str]: ... + @property + def groups(self) -> set[str]: ... + +elif sys.version_info >= (3, 10): + class DeprecatedList(list[_T]): ... + + class EntryPoints(DeprecatedList[EntryPoint]): # use as list is deprecated since 3.10 # int argument is deprecated since 3.10 def __getitem__(self, name: int | str) -> EntryPoint: ... # type: ignore[override] def select( @@ -89,7 +127,18 @@ if sys.version_info >= (3, 10): def groups(self) -> set[str]: ... if sys.version_info >= (3, 10) and sys.version_info < (3, 12): - class SelectableGroups(dict[str, EntryPoints]): # use as dict is deprecated since 3.10 + class Deprecated(Generic[_KT, _VT]): + def __getitem__(self, name: _KT) -> _VT: ... + @overload + def get(self, name: _KT) -> _VT | None: ... + @overload + def get(self, name: _KT, default: _T) -> _VT | _T: ... + def __iter__(self) -> Iterator[_KT]: ... + def __contains__(self, *args: object) -> bool: ... + def keys(self) -> dict_keys[_KT, _VT]: ... + def values(self) -> dict_values[_KT, _VT]: ... + + class SelectableGroups(Deprecated[str, EntryPoints], dict[str, EntryPoints]): # use as dict is deprecated since 3.10 @classmethod def load(cls, eps: Iterable[EntryPoint]) -> Self: ... @property @@ -124,7 +173,13 @@ class FileHash: value: str def __init__(self, spec: str) -> None: ... -class Distribution: +if sys.version_info >= (3, 12): + class DeprecatedNonAbstract: ... + _distribution_parent = DeprecatedNonAbstract +else: + _distribution_parent = object + +class Distribution(_distribution_parent): @abc.abstractmethod def read_text(self, filename: str) -> str | None: ... @abc.abstractmethod diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index 16270b948f35..ee4eda1b4eb0 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -33,6 +33,9 @@ __all__ = [ if sys.version_info >= (3, 8): __all__ += ["open_code"] +if sys.version_info >= (3, 11): + __all__ += ["DEFAULT_BUFFER_SIZE", "IncrementalNewlineDecoder", "text_encoding"] + _T = TypeVar("_T") DEFAULT_BUFFER_SIZE: Literal[8192] diff --git a/mypy/typeshed/stdlib/lzma.pyi b/mypy/typeshed/stdlib/lzma.pyi index 8e296bb5b357..be61cac08139 100644 --- a/mypy/typeshed/stdlib/lzma.pyi +++ b/mypy/typeshed/stdlib/lzma.pyi @@ -1,4 +1,4 @@ -import io +from _compression import BaseStream from _typeshed import ReadableBuffer, StrOrBytesPath from collections.abc import Mapping, Sequence from typing import IO, Any, TextIO, overload @@ -104,7 +104,7 @@ class LZMACompressor: class LZMAError(Exception): ... -class LZMAFile(io.BufferedIOBase, IO[bytes]): # type: ignore[misc] # incompatible definitions of writelines in the base classes +class LZMAFile(BaseStream, IO[bytes]): # type: ignore[misc] # incompatible definitions of writelines in the base classes def __init__( self, filename: _PathOrFile | None = None, diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 45eaf2a66e80..7d4b8adcd00a 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -26,7 +26,7 @@ from contextlib import AbstractContextManager from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper as _TextIOWrapper from subprocess import Popen from typing import IO, Any, AnyStr, BinaryIO, Generic, NoReturn, Protocol, TypeVar, overload, runtime_checkable -from typing_extensions import Final, Literal, Self, TypeAlias, final +from typing_extensions import Final, Literal, Self, TypeAlias, Unpack, final from . import path as _path @@ -847,8 +847,12 @@ def execl(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: StrOrBytesPath) - def execlp(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: StrOrBytesPath) -> NoReturn: ... # These are: execle(file, *args, env) but env is pulled from the last element of the args. -def execle(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: Any) -> NoReturn: ... -def execlpe(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: Any) -> NoReturn: ... +def execle( + file: StrOrBytesPath, *args: Unpack[tuple[StrOrBytesPath, Unpack[tuple[StrOrBytesPath, ...]], _ExecEnv]] +) -> NoReturn: ... +def execlpe( + file: StrOrBytesPath, *args: Unpack[tuple[StrOrBytesPath, Unpack[tuple[StrOrBytesPath, ...]], _ExecEnv]] +) -> NoReturn: ... # The docs say `args: tuple or list of strings` # The implementation enforces tuple or list so we can't use Sequence. diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index 5d25d1bb3641..44ce33469ff9 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -1,8 +1,7 @@ import sys -from _typeshed import StrOrBytesPath +from _typeshed import StrEnum, StrOrBytesPath from collections.abc import Iterable from cProfile import Profile as _cProfile -from enum import Enum from profile import Profile from typing import IO, Any, overload from typing_extensions import Literal, Self, TypeAlias @@ -14,7 +13,7 @@ else: _Selector: TypeAlias = str | float | int -class SortKey(str, Enum): +class SortKey(StrEnum): CALLS: str CUMULATIVE: str FILENAME: str diff --git a/mypy/typeshed/stdlib/pyclbr.pyi b/mypy/typeshed/stdlib/pyclbr.pyi index 38658a03139c..504a5d5f115a 100644 --- a/mypy/typeshed/stdlib/pyclbr.pyi +++ b/mypy/typeshed/stdlib/pyclbr.pyi @@ -1,20 +1,35 @@ import sys -from collections.abc import Sequence +from collections.abc import Mapping, Sequence __all__ = ["readmodule", "readmodule_ex", "Class", "Function"] -class Class: +class _Object: module: str name: str - super: list[Class | str] | None - methods: dict[str, int] file: int lineno: int if sys.version_info >= (3, 10): end_lineno: int | None - parent: Class | None + parent: _Object | None + + # This is a dict at runtime, but we're typing it as Mapping to + # avoid variance issues in the subclasses + children: Mapping[str, _Object] + + if sys.version_info >= (3, 10): + def __init__( + self, module: str, name: str, file: str, lineno: int, end_lineno: int | None, parent: _Object | None + ) -> None: ... + else: + def __init__(self, module: str, name: str, file: str, lineno: int, parent: _Object | None) -> None: ... + +class Function(_Object): + if sys.version_info >= (3, 10): + is_async: bool + + parent: Function | Class | None children: dict[str, Class | Function] if sys.version_info >= (3, 10): @@ -22,29 +37,20 @@ class Class: self, module: str, name: str, - super_: list[Class | str] | None, file: str, lineno: int, - parent: Class | None = None, + parent: Function | Class | None = None, + is_async: bool = False, *, end_lineno: int | None = None, ) -> None: ... else: - def __init__( - self, module: str, name: str, super: list[Class | str] | None, file: str, lineno: int, parent: Class | None = None - ) -> None: ... - -class Function: - module: str - name: str - file: int - lineno: int - - if sys.version_info >= (3, 10): - end_lineno: int | None - is_async: bool + def __init__(self, module: str, name: str, file: str, lineno: int, parent: Function | Class | None = None) -> None: ... - parent: Function | Class | None +class Class(_Object): + super: list[Class | str] | None + methods: dict[str, int] + parent: Class | None children: dict[str, Class | Function] if sys.version_info >= (3, 10): @@ -52,15 +58,17 @@ class Function: self, module: str, name: str, + super_: list[Class | str] | None, file: str, lineno: int, - parent: Function | Class | None = None, - is_async: bool = False, + parent: Class | None = None, *, end_lineno: int | None = None, ) -> None: ... else: - def __init__(self, module: str, name: str, file: str, lineno: int, parent: Function | Class | None = None) -> None: ... + def __init__( + self, module: str, name: str, super: list[Class | str] | None, file: str, lineno: int, parent: Class | None = None + ) -> None: ... def readmodule(module: str, path: Sequence[str] | None = None) -> dict[str, Class]: ... def readmodule_ex(module: str, path: Sequence[str] | None = None) -> dict[str, Class | Function | list[str]]: ... diff --git a/mypy/typeshed/stdlib/socketserver.pyi b/mypy/typeshed/stdlib/socketserver.pyi index 6a932f66cd09..5753d1d661b9 100644 --- a/mypy/typeshed/stdlib/socketserver.pyi +++ b/mypy/typeshed/stdlib/socketserver.pyi @@ -86,7 +86,7 @@ class UDPServer(TCPServer): def get_request(self) -> tuple[tuple[bytes, _socket], _RetAddress]: ... # type: ignore[override] if sys.platform != "win32": - class UnixStreamServer(BaseServer): + class UnixStreamServer(TCPServer): server_address: _AfUnixAddress # type: ignore[assignment] def __init__( self, @@ -95,7 +95,7 @@ if sys.platform != "win32": bind_and_activate: bool = True, ) -> None: ... - class UnixDatagramServer(BaseServer): + class UnixDatagramServer(UDPServer): server_address: _AfUnixAddress # type: ignore[assignment] def __init__( self, diff --git a/mypy/typeshed/stdlib/sre_parse.pyi b/mypy/typeshed/stdlib/sre_parse.pyi index 8ef65223dc34..2c10bf7e7c3b 100644 --- a/mypy/typeshed/stdlib/sre_parse.pyi +++ b/mypy/typeshed/stdlib/sre_parse.pyi @@ -19,6 +19,9 @@ FLAGS: dict[str, int] TYPE_FLAGS: int GLOBAL_FLAGS: int +if sys.version_info >= (3, 11): + MAXWIDTH: int + if sys.version_info < (3, 11): class Verbose(Exception): ... diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index a73b1e275f11..5f7c3cb4527d 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -1,13 +1,12 @@ import _tkinter import sys -from _typeshed import Incomplete, StrOrBytesPath +from _typeshed import Incomplete, StrEnum, StrOrBytesPath from collections.abc import Callable, Mapping, Sequence -from enum import Enum from tkinter.constants import * from tkinter.font import _FontDescription from types import TracebackType from typing import Any, Generic, NamedTuple, TypeVar, overload, type_check_only -from typing_extensions import Literal, TypeAlias, TypedDict, deprecated +from typing_extensions import Literal, TypeAlias, TypedDict, TypeVarTuple, Unpack, deprecated if sys.version_info >= (3, 9): __all__ = [ @@ -195,7 +194,7 @@ if sys.version_info >= (3, 11): releaselevel: str serial: int -class EventType(str, Enum): +class EventType(StrEnum): Activate: str ButtonPress: str Button = ButtonPress @@ -315,6 +314,8 @@ getdouble: Incomplete def getboolean(s): ... +_Ts = TypeVarTuple("_Ts") + class _GridIndexInfo(TypedDict, total=False): minsize: _ScreenUnits pad: _ScreenUnits @@ -350,9 +351,9 @@ class Misc: def tk_focusPrev(self) -> Misc | None: ... # .after() can be called without the "func" argument, but it is basically never what you want. # It behaves like time.sleep() and freezes the GUI app. - def after(self, ms: int | Literal["idle"], func: Callable[..., object], *args: Any) -> str: ... + def after(self, ms: int | Literal["idle"], func: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> str: ... # after_idle is essentially partialmethod(after, "idle") - def after_idle(self, func: Callable[..., object], *args: Any) -> str: ... + def after_idle(self, func: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> str: ... def after_cancel(self, id: str) -> None: ... def bell(self, displayof: Literal[0] | Misc | None = 0) -> None: ... def clipboard_get(self, *, displayof: Misc = ..., type: str = ...) -> str: ... diff --git a/mypy/typeshed/stdlib/trace.pyi b/mypy/typeshed/stdlib/trace.pyi index 3764a5b06024..14a921c5e6cc 100644 --- a/mypy/typeshed/stdlib/trace.pyi +++ b/mypy/typeshed/stdlib/trace.pyi @@ -1,7 +1,7 @@ import sys import types -from _typeshed import StrPath, TraceFunction -from collections.abc import Callable, Mapping, Sequence +from _typeshed import Incomplete, StrPath, TraceFunction +from collections.abc import Callable, Iterable, Mapping, Sequence from typing import Any, TypeVar from typing_extensions import ParamSpec, TypeAlias @@ -12,6 +12,12 @@ _P = ParamSpec("_P") _FileModuleFunction: TypeAlias = tuple[str, str | None, str] class CoverageResults: + counts: dict[tuple[str, int], int] + counter: dict[tuple[str, int], int] + calledfuncs: dict[_FileModuleFunction, int] + callers: dict[tuple[_FileModuleFunction, _FileModuleFunction], int] + inifile: StrPath | None + outfile: StrPath | None def __init__( self, counts: dict[tuple[str, int], int] | None = None, @@ -27,7 +33,21 @@ class CoverageResults: ) -> tuple[int, int]: ... def is_ignored_filename(self, filename: str) -> bool: ... # undocumented +class _Ignore: + def __init__(self, modules: Iterable[str] | None = None, dirs: Iterable[StrPath] | None = None) -> None: ... + def names(self, filename: str, modulename: str) -> int: ... + class Trace: + inifile: StrPath | None + outfile: StrPath | None + ignore: _Ignore + counts: dict[str, int] + pathtobasename: dict[Incomplete, Incomplete] + donothing: int + trace: int + start_time: int | None + globaltrace: TraceFunction + localtrace: TraceFunction def __init__( self, count: int = 1, diff --git a/mypy/typeshed/stdlib/unittest/case.pyi b/mypy/typeshed/stdlib/unittest/case.pyi index cc5d683e245a..7efe6cdc9662 100644 --- a/mypy/typeshed/stdlib/unittest/case.pyi +++ b/mypy/typeshed/stdlib/unittest/case.pyi @@ -249,6 +249,8 @@ class TestCase: def assertListEqual(self, list1: list[Any], list2: list[Any], msg: Any = None) -> None: ... def assertTupleEqual(self, tuple1: tuple[Any, ...], tuple2: tuple[Any, ...], msg: Any = None) -> None: ... def assertSetEqual(self, set1: AbstractSet[object], set2: AbstractSet[object], msg: Any = None) -> None: ... + # assertDictEqual accepts only true dict instances. We can't use that here, since that would make + # assertDictEqual incompatible with TypedDict. def assertDictEqual(self, d1: Mapping[Any, object], d2: Mapping[Any, object], msg: Any = None) -> None: ... def fail(self, msg: Any = None) -> NoReturn: ... def countTestCases(self) -> int: ... diff --git a/mypy/typeshed/stdlib/urllib/response.pyi b/mypy/typeshed/stdlib/urllib/response.pyi index 61ba687076b2..bbec4cacc750 100644 --- a/mypy/typeshed/stdlib/urllib/response.pyi +++ b/mypy/typeshed/stdlib/urllib/response.pyi @@ -1,39 +1,23 @@ import sys +import tempfile from _typeshed import ReadableBuffer from collections.abc import Callable, Iterable from email.message import Message from types import TracebackType -from typing import IO, Any, BinaryIO -from typing_extensions import Self +from typing import IO, Any __all__ = ["addbase", "addclosehook", "addinfo", "addinfourl"] -class addbase(BinaryIO): +class addbase(tempfile._TemporaryFileWrapper[bytes]): fp: IO[bytes] def __init__(self, fp: IO[bytes]) -> None: ... - def __enter__(self) -> Self: ... def __exit__( self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... - def __iter__(self) -> Self: ... - def __next__(self) -> bytes: ... - def close(self) -> None: ... # These methods don't actually exist, but the class inherits at runtime from # tempfile._TemporaryFileWrapper, which uses __getattr__ to delegate to the # underlying file object. To satisfy the BinaryIO interface, we pretend that this # class has these additional methods. - def fileno(self) -> int: ... - def flush(self) -> None: ... - def isatty(self) -> bool: ... - def read(self, n: int = ...) -> bytes: ... - def readable(self) -> bool: ... - def readline(self, limit: int = ...) -> bytes: ... - def readlines(self, hint: int = ...) -> list[bytes]: ... - def seek(self, offset: int, whence: int = ...) -> int: ... - def seekable(self) -> bool: ... - def tell(self) -> int: ... - def truncate(self, size: int | None = ...) -> int: ... - def writable(self) -> bool: ... def write(self, s: ReadableBuffer) -> int: ... def writelines(self, lines: Iterable[ReadableBuffer]) -> None: ... diff --git a/mypy/typeshed/stdlib/xml/sax/__init__.pyi b/mypy/typeshed/stdlib/xml/sax/__init__.pyi index f726eae0516f..d2d6f12d474a 100644 --- a/mypy/typeshed/stdlib/xml/sax/__init__.pyi +++ b/mypy/typeshed/stdlib/xml/sax/__init__.pyi @@ -1,10 +1,17 @@ import sys from _typeshed import ReadableBuffer, StrPath, SupportsRead, _T_co from collections.abc import Iterable -from typing import Any, NoReturn, Protocol +from typing import Protocol from typing_extensions import TypeAlias +from xml.sax._exceptions import ( + SAXException as SAXException, + SAXNotRecognizedException as SAXNotRecognizedException, + SAXNotSupportedException as SAXNotSupportedException, + SAXParseException as SAXParseException, + SAXReaderNotAvailable as SAXReaderNotAvailable, +) from xml.sax.handler import ContentHandler as ContentHandler, ErrorHandler as ErrorHandler -from xml.sax.xmlreader import Locator, XMLReader +from xml.sax.xmlreader import XMLReader class _SupportsReadClose(SupportsRead[_T_co], Protocol[_T_co]): def close(self) -> None: ... @@ -14,23 +21,6 @@ if sys.version_info >= (3, 8): else: _Source: TypeAlias = str | _SupportsReadClose[bytes] | _SupportsReadClose[str] -class SAXException(Exception): - def __init__(self, msg: str, exception: Exception | None = None) -> None: ... - def getMessage(self) -> str: ... - def getException(self) -> Exception: ... - def __getitem__(self, ix: Any) -> NoReturn: ... - -class SAXParseException(SAXException): - def __init__(self, msg: str, exception: Exception | None, locator: Locator) -> None: ... - def getColumnNumber(self) -> int: ... - def getLineNumber(self) -> int: ... - def getPublicId(self): ... - def getSystemId(self): ... - -class SAXNotRecognizedException(SAXException): ... -class SAXNotSupportedException(SAXException): ... -class SAXReaderNotAvailable(SAXNotSupportedException): ... - default_parser_list: list[str] if sys.version_info >= (3, 8): diff --git a/mypy/typeshed/stdlib/xml/sax/_exceptions.pyi b/mypy/typeshed/stdlib/xml/sax/_exceptions.pyi new file mode 100644 index 000000000000..8a437a971f13 --- /dev/null +++ b/mypy/typeshed/stdlib/xml/sax/_exceptions.pyi @@ -0,0 +1,19 @@ +from typing import NoReturn +from xml.sax.xmlreader import Locator + +class SAXException(Exception): + def __init__(self, msg: str, exception: Exception | None = None) -> None: ... + def getMessage(self) -> str: ... + def getException(self) -> Exception: ... + def __getitem__(self, ix: object) -> NoReturn: ... + +class SAXParseException(SAXException): + def __init__(self, msg: str, exception: Exception | None, locator: Locator) -> None: ... + def getColumnNumber(self) -> int: ... + def getLineNumber(self) -> int: ... + def getPublicId(self): ... + def getSystemId(self): ... + +class SAXNotRecognizedException(SAXException): ... +class SAXNotSupportedException(SAXException): ... +class SAXReaderNotAvailable(SAXNotSupportedException): ... diff --git a/mypy/typeshed/stdlib/xxlimited.pyi b/mypy/typeshed/stdlib/xxlimited.pyi index d4f41bbaf22a..7fc39138fec5 100644 --- a/mypy/typeshed/stdlib/xxlimited.pyi +++ b/mypy/typeshed/stdlib/xxlimited.pyi @@ -2,7 +2,7 @@ import sys from typing import Any from typing_extensions import final -class Str: ... +class Str(str): ... @final class Xxo: @@ -14,10 +14,10 @@ def foo(__i: int, __j: int) -> Any: ... def new() -> Xxo: ... if sys.version_info >= (3, 10): - class Error: ... + class Error(Exception): ... else: - class error: ... + class error(Exception): ... class Null: ... def roj(__b: Any) -> None: ... From 1dd8e7fe654991b01bd80ef7f1f675d9e3910c3a Mon Sep 17 00:00:00 2001 From: Kouroche Bouchiat Date: Sun, 17 Dec 2023 21:32:57 +0100 Subject: [PATCH 13/69] Substitute type variables in return type of static methods (#16670) `add_class_tvars` correctly instantiates type variables in the return type for class methods but not for static methods. Check if the analyzed member is a static method in `analyze_class_attribute_access` and substitute the type variable in the return type in `add_class_tvars` accordingly. Fixes #16668. --- mypy/checkmember.py | 15 +++++++++++++-- test-data/unit/check-generics.test | 13 +++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 5a4f3875ad04..c24edacf0ee1 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -1063,11 +1063,14 @@ def analyze_class_attribute_access( is_classmethod = (is_decorated and cast(Decorator, node.node).func.is_class) or ( isinstance(node.node, FuncBase) and node.node.is_class ) + is_staticmethod = (is_decorated and cast(Decorator, node.node).func.is_static) or ( + isinstance(node.node, FuncBase) and node.node.is_static + ) t = get_proper_type(t) if isinstance(t, FunctionLike) and is_classmethod: t = check_self_arg(t, mx.self_type, False, mx.context, name, mx.msg) result = add_class_tvars( - t, isuper, is_classmethod, mx.self_type, original_vars=original_vars + t, isuper, is_classmethod, is_staticmethod, mx.self_type, original_vars=original_vars ) if not mx.is_lvalue: result = analyze_descriptor_access(result, mx) @@ -1177,6 +1180,7 @@ def add_class_tvars( t: ProperType, isuper: Instance | None, is_classmethod: bool, + is_staticmethod: bool, original_type: Type, original_vars: Sequence[TypeVarLikeType] | None = None, ) -> Type: @@ -1195,6 +1199,7 @@ class B(A[str]): pass isuper: Current instance mapped to the superclass where method was defined, this is usually done by map_instance_to_supertype() is_classmethod: True if this method is decorated with @classmethod + is_staticmethod: True if this method is decorated with @staticmethod original_type: The value of the type B in the expression B.foo() or the corresponding component in case of a union (this is used to bind the self-types) original_vars: Type variables of the class callable on which the method was accessed @@ -1220,6 +1225,7 @@ class B(A[str]): pass t = freshen_all_functions_type_vars(t) if is_classmethod: t = bind_self(t, original_type, is_classmethod=True) + if is_classmethod or is_staticmethod: assert isuper is not None t = expand_type_by_instance(t, isuper) freeze_all_type_vars(t) @@ -1230,7 +1236,12 @@ class B(A[str]): pass cast( CallableType, add_class_tvars( - item, isuper, is_classmethod, original_type, original_vars=original_vars + item, + isuper, + is_classmethod, + is_staticmethod, + original_type, + original_vars=original_vars, ), ) for item in t.items diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index ef3f359e4989..e2f65ed39c1e 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -2297,6 +2297,19 @@ def func(x: S) -> S: return C[S].get() [builtins fixtures/classmethod.pyi] +[case testGenericStaticMethodInGenericFunction] +from typing import Generic, TypeVar +T = TypeVar('T') +S = TypeVar('S') + +class C(Generic[T]): + @staticmethod + def get() -> T: ... + +def func(x: S) -> S: + return C[S].get() +[builtins fixtures/staticmethod.pyi] + [case testMultipleAssignmentFromAnyIterable] from typing import Any class A: From 08cd371e1a286045139e94622b28e3e9e11b6e63 Mon Sep 17 00:00:00 2001 From: Wesley Collin Wright Date: Thu, 21 Dec 2023 07:09:52 -0600 Subject: [PATCH 14/69] changelog: add release notes for 1.8 (#16689) --- CHANGELOG.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f28cdb1ccc25..a63ad3693597 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,86 @@ ## Next release -Stubgen will now include `__all__` in its output if it is in the input file (PR [16356](https://github.com/python/mypy/pull/16356)). +## Mypy 1.8 + +We’ve just uploaded mypy 1.8 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)). Mypy is a static type checker for Python. This release includes new features, performance improvements and bug fixes. You can install it as follows: + + python3 -m pip install -U mypy + +You can read the full documentation for this release on [Read the Docs](http://mypy.readthedocs.io). + +#### Typechecking Improvements + * Do not intersect types in isinstance checks if at least one is final (Christoph Tyralla, PR [16330](https://github.com/python/mypy/pull/16330)) + * Detect that @final class without __bool__ cannot have falsey instances (Ilya Priven, PR [16566](https://github.com/python/mypy/pull/16566)) + * Do not allow `TypedDict` classes with extra keywords (Nikita Sobolev, PR [16438](https://github.com/python/mypy/pull/16438)) + * Do not allow class-level keywords for `NamedTuple` (Nikita Sobolev, PR [16526](https://github.com/python/mypy/pull/16526)) + * Make imprecise constraints handling more robust (Ivan Levkivskyi, PR [16502](https://github.com/python/mypy/pull/16502)) + * Fix strict-optional in extending generic TypedDict (Ivan Levkivskyi, PR [16398](https://github.com/python/mypy/pull/16398)) + * Allow type ignores of PEP 695 constructs (Shantanu, PR [16608](https://github.com/python/mypy/pull/16608)) + * Refactor class decorator: this enables `type_check_only` support for `TypedDict` and `NamedTuple` (Nikita Sobolev, PR [16469](https://github.com/python/mypy/pull/16469)) + +#### Performance Improvements + * Add fast path to analyzing special form assignments (Jukka Lehtosalo, PR [16561](https://github.com/python/mypy/pull/16561)) + +#### Improvements to Error Reporting + * Don't show docs links for plugin error codes (Ivan Levkivskyi, PR [16383](https://github.com/python/mypy/pull/16383)) + * Improve error messages for `super` checks and add more tests (Nikita Sobolev, PR [16393](https://github.com/python/mypy/pull/16393)) + * Add error code for mutable covariant override (Ivan Levkivskyi, PR [16399](https://github.com/python/mypy/pull/16399)) + +#### Stubgen Improvements + * Preserve simple defaults in function signatures (Ali Hamdan, PR [15355](https://github.com/python/mypy/pull/15355)) + * Include __all__ in output (Jelle Zijlstra, PR [16356](https://github.com/python/mypy/pull/16356)) + * Fix stubgen regressions with pybind11 and mypy 1.7 (Chad Dombrova, PR [16504](https://github.com/python/mypy/pull/16504)) + +#### Stubtest Improvements + * Improve handling of unrepresentable defaults (Jelle Zijlstra, PR [16433](https://github.com/python/mypy/pull/16433)) + * Print more helpful errors if a function is missing from stub (Alex Waygood, PR [16517](https://github.com/python/mypy/pull/16517)) + * Support `@type_check_only` decorator (Nikita Sobolev, PR [16422](https://github.com/python/mypy/pull/16422)) + * Warn about missing __del__ (Shantanu, PR [16456](https://github.com/python/mypy/pull/16456)) + * Fix crashes with some uses of final and deprecated (Shantanu, PR [16457](https://github.com/python/mypy/pull/16457)) + +#### Fixes to Crashes + * Fix crash with type alias to `Callable[[Unpack[Tuple[Any, ...]]], Any]` (Alex Waygood, PR [16541](https://github.com/python/mypy/pull/16541)) + * Fix crash on TypeGuard in __call__ (Ivan Levkivskyi, PR [16516](https://github.com/python/mypy/pull/16516)) + * Fix crash on invalid enum in method (Ivan Levkivskyi, PR [16511](https://github.com/python/mypy/pull/16511)) + * Fix crash on unimported Any in TypedDict (Ivan Levkivskyi, PR [16510](https://github.com/python/mypy/pull/16510)) + +#### Documentation Updates + * Update soft-error-limit default value to -1 (Sveinung Gundersen, PR [16542](https://github.com/python/mypy/pull/16542)) + * Support Sphinx 7.x (Michael R. Crusoe, PR [16460](https://github.com/python/mypy/pull/16460)) + +#### Other Notable Changes and Fixes + * Allow mypy to output a junit file with per-file results (Matthew Wright, PR [16388](https://github.com/python/mypy/pull/16388)) + +#### Typeshed Updates + +Please see [git log](https://github.com/python/typeshed/commits/main?after=4a854366e03dee700109f8e758a08b2457ea2f51+0&branch=main&path=stdlib) for full list of standard library typeshed stub changes. + +#### Acknowledgements + +​Thanks to all mypy contributors who contributed to this release: + +- Alex Waygood +- Ali Hamdan +- Chad Dombrova +- Christoph Tyralla +- Ilya Priven +- Ivan Levkivskyi +- Jelle Zijlstra +- Jukka Lehtosalo +- Marcel Telka +- Matthew Wright +- Michael R. Crusoe +- Nikita Sobolev +- Ole Peder Brandtzæg +- robjhornby +- Shantanu +- Sveinung Gundersen +- Valentin Stanciu + +I’d also like to thank my employer, Dropbox, for supporting mypy development. + +Posted by Wesley Collin Wright ## Mypy 1.7 From 7d842e865331b3b6f44a116a886ea3c24eb67461 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 21 Dec 2023 14:50:12 +0000 Subject: [PATCH 15/69] Minor updates to mypy 1.8 changelog entries (#16692) --- CHANGELOG.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a63ad3693597..82d79b415f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,39 +10,39 @@ We’ve just uploaded mypy 1.8 to the Python Package Index ([PyPI](https://pypi. You can read the full documentation for this release on [Read the Docs](http://mypy.readthedocs.io). -#### Typechecking Improvements +#### Type-checking Improvements * Do not intersect types in isinstance checks if at least one is final (Christoph Tyralla, PR [16330](https://github.com/python/mypy/pull/16330)) - * Detect that @final class without __bool__ cannot have falsey instances (Ilya Priven, PR [16566](https://github.com/python/mypy/pull/16566)) + * Detect that `@final` class without `__bool__` cannot have falsey instances (Ilya Priven, PR [16566](https://github.com/python/mypy/pull/16566)) * Do not allow `TypedDict` classes with extra keywords (Nikita Sobolev, PR [16438](https://github.com/python/mypy/pull/16438)) * Do not allow class-level keywords for `NamedTuple` (Nikita Sobolev, PR [16526](https://github.com/python/mypy/pull/16526)) * Make imprecise constraints handling more robust (Ivan Levkivskyi, PR [16502](https://github.com/python/mypy/pull/16502)) * Fix strict-optional in extending generic TypedDict (Ivan Levkivskyi, PR [16398](https://github.com/python/mypy/pull/16398)) * Allow type ignores of PEP 695 constructs (Shantanu, PR [16608](https://github.com/python/mypy/pull/16608)) - * Refactor class decorator: this enables `type_check_only` support for `TypedDict` and `NamedTuple` (Nikita Sobolev, PR [16469](https://github.com/python/mypy/pull/16469)) + * Enable `type_check_only` support for `TypedDict` and `NamedTuple` (Nikita Sobolev, PR [16469](https://github.com/python/mypy/pull/16469)) #### Performance Improvements * Add fast path to analyzing special form assignments (Jukka Lehtosalo, PR [16561](https://github.com/python/mypy/pull/16561)) #### Improvements to Error Reporting - * Don't show docs links for plugin error codes (Ivan Levkivskyi, PR [16383](https://github.com/python/mypy/pull/16383)) + * Don't show documentation links for plugin error codes (Ivan Levkivskyi, PR [16383](https://github.com/python/mypy/pull/16383)) * Improve error messages for `super` checks and add more tests (Nikita Sobolev, PR [16393](https://github.com/python/mypy/pull/16393)) * Add error code for mutable covariant override (Ivan Levkivskyi, PR [16399](https://github.com/python/mypy/pull/16399)) #### Stubgen Improvements * Preserve simple defaults in function signatures (Ali Hamdan, PR [15355](https://github.com/python/mypy/pull/15355)) - * Include __all__ in output (Jelle Zijlstra, PR [16356](https://github.com/python/mypy/pull/16356)) + * Include `__all__` in output (Jelle Zijlstra, PR [16356](https://github.com/python/mypy/pull/16356)) * Fix stubgen regressions with pybind11 and mypy 1.7 (Chad Dombrova, PR [16504](https://github.com/python/mypy/pull/16504)) #### Stubtest Improvements * Improve handling of unrepresentable defaults (Jelle Zijlstra, PR [16433](https://github.com/python/mypy/pull/16433)) * Print more helpful errors if a function is missing from stub (Alex Waygood, PR [16517](https://github.com/python/mypy/pull/16517)) * Support `@type_check_only` decorator (Nikita Sobolev, PR [16422](https://github.com/python/mypy/pull/16422)) - * Warn about missing __del__ (Shantanu, PR [16456](https://github.com/python/mypy/pull/16456)) - * Fix crashes with some uses of final and deprecated (Shantanu, PR [16457](https://github.com/python/mypy/pull/16457)) + * Warn about missing `__del__` (Shantanu, PR [16456](https://github.com/python/mypy/pull/16456)) + * Fix crashes with some uses of `final` and `deprecated` (Shantanu, PR [16457](https://github.com/python/mypy/pull/16457)) #### Fixes to Crashes * Fix crash with type alias to `Callable[[Unpack[Tuple[Any, ...]]], Any]` (Alex Waygood, PR [16541](https://github.com/python/mypy/pull/16541)) - * Fix crash on TypeGuard in __call__ (Ivan Levkivskyi, PR [16516](https://github.com/python/mypy/pull/16516)) + * Fix crash on TypeGuard in `__call__` (Ivan Levkivskyi, PR [16516](https://github.com/python/mypy/pull/16516)) * Fix crash on invalid enum in method (Ivan Levkivskyi, PR [16511](https://github.com/python/mypy/pull/16511)) * Fix crash on unimported Any in TypedDict (Ivan Levkivskyi, PR [16510](https://github.com/python/mypy/pull/16510)) From 3338c574b92a6eae10e28e1546f4f3f8ba4c20f0 Mon Sep 17 00:00:00 2001 From: zipperer <47086307+zipperer@users.noreply.github.com> Date: Sun, 24 Dec 2023 01:06:54 -0600 Subject: [PATCH 16/69] Fix typo in getting_started.rst (#16700) --- docs/source/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 7ea4ddd148ea..049d7af003b5 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -66,7 +66,7 @@ This is the case even if you misuse the function! def greeting(name): return 'Hello ' + name - # These calls will fail when the program run, but mypy does not report an error + # These calls will fail when the program runs, but mypy does not report an error # because "greeting" does not have type annotations. greeting(123) greeting(b"Alice") From 92fa54822588ef2af453f1623d4dda48f4f2712b Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sun, 24 Dec 2023 11:57:06 -0800 Subject: [PATCH 17/69] Fix a single-letter typo in a comment (#16699) --- mypy/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/types.py b/mypy/types.py index d19766c1de34..fcdb61f9719b 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -56,7 +56,7 @@ # 1. types.LiteralType's serialize and deserialize methods: this method # needs to make sure it can convert the below types into JSON and back. # -# 2. types.LiteralType's 'alue_repr` method: this method is ultimately used +# 2. types.LiteralType's 'value_repr` method: this method is ultimately used # by TypeStrVisitor's visit_literal_type to generate a reasonable # repr-able output. # From f79ae69be1b0c920eec6bf181e6f8c7689cbae20 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Mon, 25 Dec 2023 07:41:30 +0000 Subject: [PATCH 18/69] Speed up pythoneval tests (#16559) Skip slow and unnecessary overload checks in stdlib stubs in these tests. These checks already seem to be skipped in most other contexts, but because pythoneval tests use `--no-silence-site-packages`, the checks were enabled. This makes pythoneval tests about 13% faster on my Linux desktop, and it should also speed up CI a bit. --- mypy/checker.py | 4 +++- mypy/main.py | 2 ++ mypy/options.py | 4 ++++ mypy/test/testpythoneval.py | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mypy/checker.py b/mypy/checker.py index 979a55b223c9..0ac8f6904973 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -709,7 +709,9 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None: # At this point we should have set the impl already, and all remaining # items are decorators - if self.msg.errors.file in self.msg.errors.ignored_files: + if self.msg.errors.file in self.msg.errors.ignored_files or ( + self.is_typeshed_stub and self.options.test_env + ): # This is a little hacky, however, the quadratic check here is really expensive, this # method has no side effects, so we should skip it if we aren't going to report # anything. In some other places we swallow errors in stubs, but this error is very diff --git a/mypy/main.py b/mypy/main.py index ee090a03d3cf..2c68466ec977 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -1135,6 +1135,8 @@ def add_invertible_flag( parser.add_argument("--dump-graph", action="store_true", help=argparse.SUPPRESS) # --semantic-analysis-only does exactly that. parser.add_argument("--semantic-analysis-only", action="store_true", help=argparse.SUPPRESS) + # Some tests use this to tell mypy that we are running a test. + parser.add_argument("--test-env", action="store_true", help=argparse.SUPPRESS) # --local-partial-types disallows partial types spanning module top level and a function # (implicitly defined in fine-grained incremental mode) parser.add_argument("--local-partial-types", action="store_true", help=argparse.SUPPRESS) diff --git a/mypy/options.py b/mypy/options.py index 38a87e423766..bf9c09f1bf4b 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -321,6 +321,10 @@ def __init__(self) -> None: # Use stub builtins fixtures to speed up tests self.use_builtins_fixtures = False + # This should only be set when running certain mypy tests. + # Use this sparingly to avoid tests diverging from non-test behavior. + self.test_env = False + # -- experimental options -- self.shadow_file: list[list[str]] | None = None self.show_column_numbers: bool = False diff --git a/mypy/test/testpythoneval.py b/mypy/test/testpythoneval.py index 17baec96cfbc..baeea1853ded 100644 --- a/mypy/test/testpythoneval.py +++ b/mypy/test/testpythoneval.py @@ -53,6 +53,7 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None "--hide-error-codes", "--allow-empty-bodies", "--force-uppercase-builtins", + "--test-env", # Speeds up some checks ] interpreter = python3_path mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}") From 761965d260e54f8e150d8bd7ac3ab3efd6503b93 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 28 Dec 2023 11:27:30 +0000 Subject: [PATCH 19/69] Speed up finding function type variables (#16562) Merge two visitors into a single visitor that is a bit more optimized than the old visitors. This speeds ups tests, in particular -- `mypy/test/testcheck.py` is about 4% faster and `mypy/test/testpythoneval.py` is about 3% faster. Also self-check is about 1% faster, both interpreted and compiled. This adds more code, but the new code is largely boilerplate, so the difficulty of maintenance seems roughly the same. --- mypy/semanal.py | 13 ++- mypy/typeanal.py | 252 +++++++++++++++++++++++++++++++---------------- 2 files changed, 176 insertions(+), 89 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 4128369ace5d..48be004daf76 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -224,9 +224,9 @@ from mypy.tvar_scope import TypeVarLikeScope from mypy.typeanal import ( SELF_TYPE_NAMES, + FindTypeVarVisitor, TypeAnalyser, TypeVarLikeList, - TypeVarLikeQuery, analyze_type_alias, check_for_explicit_any, detect_diverging_alias, @@ -2034,6 +2034,11 @@ def analyze_unbound_tvar_impl( assert isinstance(sym.node, TypeVarExpr) return t.name, sym.node + def find_type_var_likes(self, t: Type) -> TypeVarLikeList: + visitor = FindTypeVarVisitor(self, self.tvar_scope) + t.accept(visitor) + return visitor.type_var_likes + def get_all_bases_tvars( self, base_type_exprs: list[Expression], removed: list[int] ) -> TypeVarLikeList: @@ -2046,7 +2051,7 @@ def get_all_bases_tvars( except TypeTranslationError: # This error will be caught later. continue - base_tvars = base.accept(TypeVarLikeQuery(self, self.tvar_scope)) + base_tvars = self.find_type_var_likes(base) tvars.extend(base_tvars) return remove_dups(tvars) @@ -2064,7 +2069,7 @@ def get_and_bind_all_tvars(self, type_exprs: list[Expression]) -> list[TypeVarLi except TypeTranslationError: # This error will be caught later. continue - base_tvars = base.accept(TypeVarLikeQuery(self, self.tvar_scope)) + base_tvars = self.find_type_var_likes(base) tvars.extend(base_tvars) tvars = remove_dups(tvars) # Variables are defined in order of textual appearance. tvar_defs = [] @@ -3490,7 +3495,7 @@ def analyze_alias( ) return None, [], set(), [], False - found_type_vars = typ.accept(TypeVarLikeQuery(self, self.tvar_scope)) + found_type_vars = self.find_type_var_likes(typ) tvar_defs: list[TypeVarLikeType] = [] namespace = self.qualified_name(name) with self.tvar_scope_frame(self.tvar_scope.class_frame(namespace)): diff --git a/mypy/typeanal.py b/mypy/typeanal.py index d238a452e7a9..4d916315bddd 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1570,32 +1570,32 @@ def tvar_scope_frame(self) -> Iterator[None]: yield self.tvar_scope = old_scope - def find_type_var_likes(self, t: Type, include_callables: bool = True) -> TypeVarLikeList: - return t.accept( - TypeVarLikeQuery(self.api, self.tvar_scope, include_callables=include_callables) - ) - - def infer_type_variables(self, type: CallableType) -> list[tuple[str, TypeVarLikeExpr]]: - """Return list of unique type variables referred to in a callable.""" - names: list[str] = [] - tvars: list[TypeVarLikeExpr] = [] + def find_type_var_likes(self, t: Type) -> TypeVarLikeList: + visitor = FindTypeVarVisitor(self.api, self.tvar_scope) + t.accept(visitor) + return visitor.type_var_likes + + def infer_type_variables( + self, type: CallableType + ) -> tuple[list[tuple[str, TypeVarLikeExpr]], bool]: + """Infer type variables from a callable. + + Return tuple with these items: + - list of unique type variables referred to in a callable + - whether there is a reference to the Self type + """ + visitor = FindTypeVarVisitor(self.api, self.tvar_scope) for arg in type.arg_types: - for name, tvar_expr in self.find_type_var_likes(arg): - if name not in names: - names.append(name) - tvars.append(tvar_expr) + arg.accept(visitor) + # When finding type variables in the return type of a function, don't # look inside Callable types. Type variables only appearing in # functions in the return type belong to those functions, not the # function we're currently analyzing. - for name, tvar_expr in self.find_type_var_likes(type.ret_type, include_callables=False): - if name not in names: - names.append(name) - tvars.append(tvar_expr) + visitor.include_callables = False + type.ret_type.accept(visitor) - if not names: - return [] # Fast path - return list(zip(names, tvars)) + return visitor.type_var_likes, visitor.has_self_type def bind_function_type_variables( self, fun_type: CallableType, defn: Context @@ -1615,10 +1615,7 @@ def bind_function_type_variables( binding = self.tvar_scope.bind_new(var.name, var_expr) defs.append(binding) return defs, has_self_type - typevars = self.infer_type_variables(fun_type) - has_self_type = find_self_type( - fun_type, lambda name: self.api.lookup_qualified(name, defn, suppress_errors=True) - ) + typevars, has_self_type = self.infer_type_variables(fun_type) # Do not define a new type variable if already defined in scope. typevars = [ (name, tvar) for name, tvar in typevars if not self.is_defined_type_var(name, defn) @@ -2062,67 +2059,6 @@ def flatten_tvars(lists: list[list[T]]) -> list[T]: return result -class TypeVarLikeQuery(TypeQuery[TypeVarLikeList]): - """Find TypeVar and ParamSpec references in an unbound type.""" - - def __init__( - self, - api: SemanticAnalyzerCoreInterface, - scope: TypeVarLikeScope, - *, - include_callables: bool = True, - ) -> None: - super().__init__(flatten_tvars) - self.api = api - self.scope = scope - self.include_callables = include_callables - # Only include type variables in type aliases args. This would be anyway - # that case if we expand (as target variables would be overridden with args) - # and it may cause infinite recursion on invalid (diverging) recursive aliases. - self.skip_alias_target = True - - def _seems_like_callable(self, type: UnboundType) -> bool: - if not type.args: - return False - return isinstance(type.args[0], (EllipsisType, TypeList, ParamSpecType)) - - def visit_unbound_type(self, t: UnboundType) -> TypeVarLikeList: - name = t.name - node = None - # Special case P.args and P.kwargs for ParamSpecs only. - if name.endswith("args"): - if name.endswith(".args") or name.endswith(".kwargs"): - base = ".".join(name.split(".")[:-1]) - n = self.api.lookup_qualified(base, t) - if n is not None and isinstance(n.node, ParamSpecExpr): - node = n - name = base - if node is None: - node = self.api.lookup_qualified(name, t) - if ( - node - and isinstance(node.node, TypeVarLikeExpr) - and self.scope.get_binding(node) is None - ): - assert isinstance(node.node, TypeVarLikeExpr) - return [(name, node.node)] - elif not self.include_callables and self._seems_like_callable(t): - return [] - elif node and node.fullname in LITERAL_TYPE_NAMES: - return [] - elif node and node.fullname in ANNOTATED_TYPE_NAMES and t.args: - # Don't query the second argument to Annotated for TypeVars - return self.query_types([t.args[0]]) - else: - return super().visit_unbound_type(t) - - def visit_callable_type(self, t: CallableType) -> TypeVarLikeList: - if self.include_callables: - return super().visit_callable_type(t) - else: - return [] - - class DivergingAliasDetector(TrivialSyntheticTypeTranslator): """See docstring of detect_diverging_alias() for details.""" @@ -2359,3 +2295,149 @@ def unknown_unpack(t: Type) -> bool: if isinstance(unpacked, AnyType) and unpacked.type_of_any == TypeOfAny.special_form: return True return False + + +class FindTypeVarVisitor(SyntheticTypeVisitor[None]): + """Type visitor that looks for type variable types and self types.""" + + def __init__(self, api: SemanticAnalyzerCoreInterface, scope: TypeVarLikeScope) -> None: + self.api = api + self.scope = scope + self.type_var_likes: list[tuple[str, TypeVarLikeExpr]] = [] + self.has_self_type = False + self.seen_aliases: set[TypeAliasType] | None = None + self.include_callables = True + + def _seems_like_callable(self, type: UnboundType) -> bool: + if not type.args: + return False + return isinstance(type.args[0], (EllipsisType, TypeList, ParamSpecType)) + + def visit_unbound_type(self, t: UnboundType) -> None: + name = t.name + node = None + + # Special case P.args and P.kwargs for ParamSpecs only. + if name.endswith("args"): + if name.endswith(".args") or name.endswith(".kwargs"): + base = ".".join(name.split(".")[:-1]) + n = self.api.lookup_qualified(base, t) + if n is not None and isinstance(n.node, ParamSpecExpr): + node = n + name = base + if node is None: + node = self.api.lookup_qualified(name, t) + if node and node.fullname in SELF_TYPE_NAMES: + self.has_self_type = True + if ( + node + and isinstance(node.node, TypeVarLikeExpr) + and self.scope.get_binding(node) is None + ): + if (name, node.node) not in self.type_var_likes: + self.type_var_likes.append((name, node.node)) + elif not self.include_callables and self._seems_like_callable(t): + if find_self_type( + t, lambda name: self.api.lookup_qualified(name, t, suppress_errors=True) + ): + self.has_self_type = True + return + elif node and node.fullname in LITERAL_TYPE_NAMES: + return + elif node and node.fullname in ANNOTATED_TYPE_NAMES and t.args: + # Don't query the second argument to Annotated for TypeVars + self.process_types([t.args[0]]) + elif t.args: + self.process_types(t.args) + + def visit_type_list(self, t: TypeList) -> None: + self.process_types(t.items) + + def visit_callable_argument(self, t: CallableArgument) -> None: + t.typ.accept(self) + + def visit_any(self, t: AnyType) -> None: + pass + + def visit_uninhabited_type(self, t: UninhabitedType) -> None: + pass + + def visit_none_type(self, t: NoneType) -> None: + pass + + def visit_erased_type(self, t: ErasedType) -> None: + pass + + def visit_deleted_type(self, t: DeletedType) -> None: + pass + + def visit_type_var(self, t: TypeVarType) -> None: + self.process_types([t.upper_bound, t.default] + t.values) + + def visit_param_spec(self, t: ParamSpecType) -> None: + self.process_types([t.upper_bound, t.default]) + + def visit_type_var_tuple(self, t: TypeVarTupleType) -> None: + self.process_types([t.upper_bound, t.default]) + + def visit_unpack_type(self, t: UnpackType) -> None: + self.process_types([t.type]) + + def visit_parameters(self, t: Parameters) -> None: + self.process_types(t.arg_types) + + def visit_partial_type(self, t: PartialType) -> None: + pass + + def visit_instance(self, t: Instance) -> None: + self.process_types(t.args) + + def visit_callable_type(self, t: CallableType) -> None: + # FIX generics + self.process_types(t.arg_types) + t.ret_type.accept(self) + + def visit_tuple_type(self, t: TupleType) -> None: + self.process_types(t.items) + + def visit_typeddict_type(self, t: TypedDictType) -> None: + self.process_types(list(t.items.values())) + + def visit_raw_expression_type(self, t: RawExpressionType) -> None: + pass + + def visit_literal_type(self, t: LiteralType) -> None: + pass + + def visit_union_type(self, t: UnionType) -> None: + self.process_types(t.items) + + def visit_overloaded(self, t: Overloaded) -> None: + self.process_types(t.items) # type: ignore[arg-type] + + def visit_type_type(self, t: TypeType) -> None: + t.item.accept(self) + + def visit_ellipsis_type(self, t: EllipsisType) -> None: + pass + + def visit_placeholder_type(self, t: PlaceholderType) -> None: + return self.process_types(t.args) + + def visit_type_alias_type(self, t: TypeAliasType) -> None: + # Skip type aliases in already visited types to avoid infinite recursion. + if self.seen_aliases is None: + self.seen_aliases = set() + elif t in self.seen_aliases: + return + self.seen_aliases.add(t) + self.process_types(t.args) + + def process_types(self, types: list[Type] | tuple[Type, ...]) -> None: + # Redundant type check helps mypyc. + if isinstance(types, list): + for t in types: + t.accept(self) + else: + for t in types: + t.accept(self) From b08c8b5737b3d4aa6f5f1e45c49dc1a5316679fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 15:58:56 -0800 Subject: [PATCH 20/69] Sync typeshed (#16721) Source commit: https://github.com/python/typeshed/commit/1d3c3265180ae4421be4ce6508810708ccd617f0 Co-authored-by: mypybot <> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: AlexWaygood --- mypy/typeshed/stdlib/VERSIONS | 445 +++++++++--------- mypy/typeshed/stdlib/_ast.pyi | 4 +- mypy/typeshed/stdlib/_thread.pyi | 5 + mypy/typeshed/stdlib/asyncore.pyi | 1 + mypy/typeshed/stdlib/base64.pyi | 4 +- .../stdlib/concurrent/futures/process.pyi | 59 ++- .../stdlib/concurrent/futures/thread.pyi | 31 +- mypy/typeshed/stdlib/http/client.pyi | 18 + mypy/typeshed/stdlib/os/__init__.pyi | 7 +- mypy/typeshed/stdlib/selectors.pyi | 38 +- mypy/typeshed/stdlib/threading.pyi | 9 +- mypy/typeshed/stdlib/unittest/_log.pyi | 5 +- mypy/typeshed/stdlib/unittest/case.pyi | 23 +- .../{zipfile.pyi => zipfile/__init__.pyi} | 5 +- mypy/typeshed/stdlib/zipfile/_path.pyi | 95 ++++ 15 files changed, 470 insertions(+), 279 deletions(-) rename mypy/typeshed/stdlib/{zipfile.pyi => zipfile/__init__.pyi} (98%) create mode 100644 mypy/typeshed/stdlib/zipfile/_path.pyi diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index f5e30c4602b4..5099a94c93bc 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -1,7 +1,7 @@ # The structure of this file is as follows: # - Blank lines and comments starting with `#` are ignored. # - Lines contain the name of a module, followed by a colon, -# a space, and a version range (for example: `symbol: 2.7-3.9`). +# a space, and a version range (for example: `symbol: 3.0-3.9`). # # Version ranges may be of the form "X.Y-A.B" or "X.Y-". The # first form means that a module was introduced in version X.Y and last @@ -12,57 +12,57 @@ # If a submodule is not listed separately, it has the same lifetime as # its parent module. # -# Python versions before 2.7 are ignored, so any module that was already -# present in 2.7 will have "2.7" as its minimum version. Version ranges +# Python versions before 3.0 are ignored, so any module that was already +# present in 3.0 will have "3.0" as its minimum version. Version ranges # for unsupported versions of Python 3 are generally accurate but we do # not guarantee their correctness. -__future__: 2.7- -__main__: 2.7- -_ast: 2.7- -_bisect: 2.7- +__future__: 3.0- +__main__: 3.0- +_ast: 3.0- +_bisect: 3.0- _bootlocale: 3.4-3.9 -_codecs: 2.7- +_codecs: 3.0- _collections_abc: 3.3- _compat_pickle: 3.1- _compression: 3.5- -_csv: 2.7- -_ctypes: 2.7- -_curses: 2.7- +_csv: 3.0- +_ctypes: 3.0- +_curses: 3.0- _decimal: 3.3- _dummy_thread: 3.0-3.8 -_dummy_threading: 2.7-3.8 -_heapq: 2.7- +_dummy_threading: 3.0-3.8 +_heapq: 3.0- _imp: 3.0- -_json: 2.7- -_locale: 2.7- -_markupbase: 2.7- -_msi: 2.7- +_json: 3.0- +_locale: 3.0- +_markupbase: 3.0- +_msi: 3.0- _operator: 3.4- -_osx_support: 2.7- +_osx_support: 3.0- _posixsubprocess: 3.2- _py_abc: 3.7- _pydecimal: 3.5- -_random: 2.7- +_random: 3.0- _sitebuiltins: 3.4- -_socket: 3.0- # present in 2.7 at runtime, but not in typeshed +_socket: 3.0- # present in 3.0 at runtime, but not in typeshed _stat: 3.4- -_thread: 2.7- -_threading_local: 2.7- -_tkinter: 2.7- +_thread: 3.0- +_threading_local: 3.0- +_tkinter: 3.0- _tracemalloc: 3.4- -_typeshed: 2.7- # not present at runtime, only for type checking -_warnings: 2.7- -_weakref: 2.7- -_weakrefset: 2.7- +_typeshed: 3.0- # not present at runtime, only for type checking +_warnings: 3.0- +_weakref: 3.0- +_weakrefset: 3.0- _winapi: 3.3- -abc: 2.7- -aifc: 2.7- -antigravity: 2.7- -argparse: 2.7- -array: 2.7- -ast: 2.7- -asynchat: 2.7-3.11 +abc: 3.0- +aifc: 3.0-3.12 +antigravity: 3.0- +argparse: 3.0- +array: 3.0- +ast: 3.0- +asynchat: 3.0-3.11 asyncio: 3.4- asyncio.mixins: 3.10- asyncio.exceptions: 3.8- @@ -73,83 +73,83 @@ asyncio.taskgroups: 3.11- asyncio.threads: 3.9- asyncio.timeouts: 3.11- asyncio.trsock: 3.8- -asyncore: 2.7-3.11 -atexit: 2.7- -audioop: 2.7- -base64: 2.7- -bdb: 2.7- -binascii: 2.7- -binhex: 2.7-3.10 -bisect: 2.7- +asyncore: 3.0-3.11 +atexit: 3.0- +audioop: 3.0-3.12 +base64: 3.0- +bdb: 3.0- +binascii: 3.0- +binhex: 3.0-3.10 +bisect: 3.0- builtins: 3.0- -bz2: 2.7- -cProfile: 2.7- -calendar: 2.7- -cgi: 2.7- -cgitb: 2.7- -chunk: 2.7- -cmath: 2.7- -cmd: 2.7- -code: 2.7- -codecs: 2.7- -codeop: 2.7- -collections: 2.7- +bz2: 3.0- +cProfile: 3.0- +calendar: 3.0- +cgi: 3.0-3.12 +cgitb: 3.0-3.12 +chunk: 3.0-3.12 +cmath: 3.0- +cmd: 3.0- +code: 3.0- +codecs: 3.0- +codeop: 3.0- +collections: 3.0- collections.abc: 3.3- -colorsys: 2.7- -compileall: 2.7- +colorsys: 3.0- +compileall: 3.0- concurrent: 3.2- configparser: 3.0- -contextlib: 2.7- +contextlib: 3.0- contextvars: 3.7- -copy: 2.7- -copyreg: 2.7- -crypt: 2.7- -csv: 2.7- -ctypes: 2.7- -curses: 2.7- +copy: 3.0- +copyreg: 3.0- +crypt: 3.0-3.12 +csv: 3.0- +ctypes: 3.0- +curses: 3.0- dataclasses: 3.7- -datetime: 2.7- -dbm: 2.7- -decimal: 2.7- -difflib: 2.7- -dis: 2.7- -distutils: 2.7-3.11 -distutils.command.bdist_msi: 2.7-3.10 -distutils.command.bdist_wininst: 2.7-3.9 -doctest: 2.7- -dummy_threading: 2.7-3.8 -email: 2.7- -encodings: 2.7- -ensurepip: 2.7- +datetime: 3.0- +dbm: 3.0- +decimal: 3.0- +difflib: 3.0- +dis: 3.0- +distutils: 3.0-3.11 +distutils.command.bdist_msi: 3.0-3.10 +distutils.command.bdist_wininst: 3.0-3.9 +doctest: 3.0- +dummy_threading: 3.0-3.8 +email: 3.0- +encodings: 3.0- +ensurepip: 3.0- enum: 3.4- -errno: 2.7- +errno: 3.0- faulthandler: 3.3- -fcntl: 2.7- -filecmp: 2.7- -fileinput: 2.7- -fnmatch: 2.7- -formatter: 2.7-3.9 -fractions: 2.7- -ftplib: 2.7- -functools: 2.7- -gc: 2.7- -genericpath: 2.7- -getopt: 2.7- -getpass: 2.7- -gettext: 2.7- -glob: 2.7- +fcntl: 3.0- +filecmp: 3.0- +fileinput: 3.0- +fnmatch: 3.0- +formatter: 3.0-3.9 +fractions: 3.0- +ftplib: 3.0- +functools: 3.0- +gc: 3.0- +genericpath: 3.0- +getopt: 3.0- +getpass: 3.0- +gettext: 3.0- +glob: 3.0- graphlib: 3.9- -grp: 2.7- -gzip: 2.7- -hashlib: 2.7- -heapq: 2.7- -hmac: 2.7- +grp: 3.0- +gzip: 3.0- +hashlib: 3.0- +heapq: 3.0- +hmac: 3.0- html: 3.0- http: 3.0- -imaplib: 2.7- -imghdr: 2.7- -imp: 2.7-3.11 -importlib: 2.7- +imaplib: 3.0- +imghdr: 3.0-3.12 +imp: 3.0-3.11 +importlib: 3.0- importlib._abc: 3.10- importlib.metadata: 3.8- importlib.metadata._meta: 3.10- @@ -159,150 +159,151 @@ importlib.resources.abc: 3.11- importlib.resources.readers: 3.11- importlib.resources.simple: 3.11- importlib.simple: 3.11- -inspect: 2.7- -io: 2.7- +inspect: 3.0- +io: 3.0- ipaddress: 3.3- -itertools: 2.7- -json: 2.7- -keyword: 2.7- -lib2to3: 2.7- -linecache: 2.7- -locale: 2.7- -logging: 2.7- +itertools: 3.0- +json: 3.0- +keyword: 3.0- +lib2to3: 3.0- +linecache: 3.0- +locale: 3.0- +logging: 3.0- lzma: 3.3- -macpath: 2.7-3.7 -mailbox: 2.7- -mailcap: 2.7- -marshal: 2.7- -math: 2.7- -mimetypes: 2.7- -mmap: 2.7- -modulefinder: 2.7- -msilib: 2.7- -msvcrt: 2.7- -multiprocessing: 2.7- +macpath: 3.0-3.7 +mailbox: 3.0- +mailcap: 3.0-3.12 +marshal: 3.0- +math: 3.0- +mimetypes: 3.0- +mmap: 3.0- +modulefinder: 3.0- +msilib: 3.0-3.12 +msvcrt: 3.0- +multiprocessing: 3.0- multiprocessing.resource_tracker: 3.8- multiprocessing.shared_memory: 3.8- -netrc: 2.7- -nis: 2.7- -nntplib: 2.7- -nt: 2.7- -ntpath: 2.7- -nturl2path: 2.7- -numbers: 2.7- -opcode: 2.7- -operator: 2.7- -optparse: 2.7- -os: 2.7- -ossaudiodev: 2.7- -parser: 2.7-3.9 +netrc: 3.0- +nis: 3.0-3.12 +nntplib: 3.0-3.12 +nt: 3.0- +ntpath: 3.0- +nturl2path: 3.0- +numbers: 3.0- +opcode: 3.0- +operator: 3.0- +optparse: 3.0- +os: 3.0- +ossaudiodev: 3.0-3.12 +parser: 3.0-3.9 pathlib: 3.4- -pdb: 2.7- -pickle: 2.7- -pickletools: 2.7- -pipes: 2.7- -pkgutil: 2.7- -platform: 2.7- -plistlib: 2.7- -poplib: 2.7- -posix: 2.7- -posixpath: 2.7- -pprint: 2.7- -profile: 2.7- -pstats: 2.7- -pty: 2.7- -pwd: 2.7- -py_compile: 2.7- -pyclbr: 2.7- -pydoc: 2.7- -pydoc_data: 2.7- -pyexpat: 2.7- +pdb: 3.0- +pickle: 3.0- +pickletools: 3.0- +pipes: 3.0-3.12 +pkgutil: 3.0- +platform: 3.0- +plistlib: 3.0- +poplib: 3.0- +posix: 3.0- +posixpath: 3.0- +pprint: 3.0- +profile: 3.0- +pstats: 3.0- +pty: 3.0- +pwd: 3.0- +py_compile: 3.0- +pyclbr: 3.0- +pydoc: 3.0- +pydoc_data: 3.0- +pyexpat: 3.0- queue: 3.0- -quopri: 2.7- -random: 2.7- -re: 2.7- -readline: 2.7- +quopri: 3.0- +random: 3.0- +re: 3.0- +readline: 3.0- reprlib: 3.0- -resource: 2.7- -rlcompleter: 2.7- -runpy: 2.7- -sched: 2.7- +resource: 3.0- +rlcompleter: 3.0- +runpy: 3.0- +sched: 3.0- secrets: 3.6- -select: 2.7- +select: 3.0- selectors: 3.4- -shelve: 2.7- -shlex: 2.7- -shutil: 2.7- -signal: 2.7- -site: 2.7- -smtpd: 2.7-3.11 -smtplib: 2.7- -sndhdr: 2.7- -socket: 2.7- +shelve: 3.0- +shlex: 3.0- +shutil: 3.0- +signal: 3.0- +site: 3.0- +smtpd: 3.0-3.11 +smtplib: 3.0- +sndhdr: 3.0-3.12 +socket: 3.0- socketserver: 3.0- -spwd: 2.7- -sqlite3: 2.7- -sre_compile: 2.7- -sre_constants: 2.7- -sre_parse: 2.7- -ssl: 2.7- -stat: 2.7- +spwd: 3.0-3.12 +sqlite3: 3.0- +sre_compile: 3.0- +sre_constants: 3.0- +sre_parse: 3.0- +ssl: 3.0- +stat: 3.0- statistics: 3.4- -string: 2.7- -stringprep: 2.7- -struct: 2.7- -subprocess: 2.7- -sunau: 2.7- -symbol: 2.7-3.9 -symtable: 2.7- -sys: 2.7- +string: 3.0- +stringprep: 3.0- +struct: 3.0- +subprocess: 3.0- +sunau: 3.0-3.12 +symbol: 3.0-3.9 +symtable: 3.0- +sys: 3.0- sys._monitoring: 3.12- # Doesn't actually exist. See comments in the stub. -sysconfig: 2.7- -syslog: 2.7- -tabnanny: 2.7- -tarfile: 2.7- -telnetlib: 2.7- -tempfile: 2.7- -termios: 2.7- -textwrap: 2.7- -this: 2.7- -threading: 2.7- -time: 2.7- -timeit: 2.7- +sysconfig: 3.0- +syslog: 3.0- +tabnanny: 3.0- +tarfile: 3.0- +telnetlib: 3.0-3.12 +tempfile: 3.0- +termios: 3.0- +textwrap: 3.0- +this: 3.0- +threading: 3.0- +time: 3.0- +timeit: 3.0- tkinter: 3.0- -token: 2.7- -tokenize: 2.7- +token: 3.0- +tokenize: 3.0- tomllib: 3.11- -trace: 2.7- -traceback: 2.7- +trace: 3.0- +traceback: 3.0- tracemalloc: 3.4- -tty: 2.7- -turtle: 2.7- -types: 2.7- +tty: 3.0- +turtle: 3.0- +types: 3.0- typing: 3.5- -typing_extensions: 2.7- -unicodedata: 2.7- -unittest: 2.7- +typing_extensions: 3.0- +unicodedata: 3.0- +unittest: 3.0- unittest._log: 3.9- unittest.async_case: 3.8- -urllib: 2.7- -uu: 2.7- -uuid: 2.7- +urllib: 3.0- +uu: 3.0-3.12 +uuid: 3.0- venv: 3.3- -warnings: 2.7- -wave: 2.7- -weakref: 2.7- -webbrowser: 2.7- +warnings: 3.0- +wave: 3.0- +weakref: 3.0- +webbrowser: 3.0- winreg: 3.0- -winsound: 2.7- -wsgiref: 2.7- +winsound: 3.0- +wsgiref: 3.0- wsgiref.types: 3.11- -xdrlib: 2.7- -xml: 2.7- +xdrlib: 3.0-3.12 +xml: 3.0- xmlrpc: 3.0- xxlimited: 3.2- zipapp: 3.5- -zipfile: 2.7- -zipimport: 2.7- -zlib: 2.7- +zipfile: 3.0- +zipfile._path: 3.12- +zipimport: 3.0- +zlib: 3.0- zoneinfo: 3.9- diff --git a/mypy/typeshed/stdlib/_ast.pyi b/mypy/typeshed/stdlib/_ast.pyi index 0302133fc6f9..0fbf66f7feda 100644 --- a/mypy/typeshed/stdlib/_ast.pyi +++ b/mypy/typeshed/stdlib/_ast.pyi @@ -586,7 +586,9 @@ if sys.version_info >= (3, 10): patterns: list[pattern] if sys.version_info >= (3, 12): - class type_param(AST): ... + class type_param(AST): + end_lineno: int + end_col_offset: int class TypeVar(type_param): __match_args__ = ("name", "bound") diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index dba8664fbf13..8bd0b179607b 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -46,3 +46,8 @@ if sys.version_info >= (3, 8): if sys.version_info >= (3, 12): def daemon_threads_allowed() -> bool: ... + +class _local: + def __getattribute__(self, __name: str) -> Any: ... + def __setattr__(self, __name: str, __value: Any) -> None: ... + def __delattr__(self, __name: str) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncore.pyi b/mypy/typeshed/stdlib/asyncore.pyi index 47c8e2207022..36d1862fdda7 100644 --- a/mypy/typeshed/stdlib/asyncore.pyi +++ b/mypy/typeshed/stdlib/asyncore.pyi @@ -83,6 +83,7 @@ if sys.platform != "win32": def write(self, data: bytes, flags: int = ...) -> int: ... def close(self) -> None: ... def fileno(self) -> int: ... + def __del__(self) -> None: ... class file_dispatcher(dispatcher): def __init__(self, fd: FileDescriptorLike, map: _MapType | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/base64.pyi b/mypy/typeshed/stdlib/base64.pyi index 24830cbfba04..4629c95d0949 100644 --- a/mypy/typeshed/stdlib/base64.pyi +++ b/mypy/typeshed/stdlib/base64.pyi @@ -27,13 +27,13 @@ if sys.version_info >= (3, 10): __all__ += ["b32hexencode", "b32hexdecode"] def b64encode(s: ReadableBuffer, altchars: ReadableBuffer | None = None) -> bytes: ... -def b64decode(s: str | ReadableBuffer, altchars: ReadableBuffer | None = None, validate: bool = False) -> bytes: ... +def b64decode(s: str | ReadableBuffer, altchars: str | ReadableBuffer | None = None, validate: bool = False) -> bytes: ... def standard_b64encode(s: ReadableBuffer) -> bytes: ... def standard_b64decode(s: str | ReadableBuffer) -> bytes: ... def urlsafe_b64encode(s: ReadableBuffer) -> bytes: ... def urlsafe_b64decode(s: str | ReadableBuffer) -> bytes: ... def b32encode(s: ReadableBuffer) -> bytes: ... -def b32decode(s: str | ReadableBuffer, casefold: bool = False, map01: bytes | None = None) -> bytes: ... +def b32decode(s: str | ReadableBuffer, casefold: bool = False, map01: str | ReadableBuffer | None = None) -> bytes: ... def b16encode(s: ReadableBuffer) -> bytes: ... def b16decode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/process.pyi b/mypy/typeshed/stdlib/concurrent/futures/process.pyi index 000e7a43503a..d3706a9c15a6 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/process.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/process.pyi @@ -5,12 +5,14 @@ from multiprocessing.context import BaseContext, Process from multiprocessing.queues import Queue, SimpleQueue from threading import Lock, Semaphore, Thread from types import TracebackType -from typing import Any, Generic, TypeVar +from typing import Any, Generic, TypeVar, overload +from typing_extensions import TypeVarTuple, Unpack from weakref import ref from ._base import BrokenExecutor, Executor, Future _T = TypeVar("_T") +_Ts = TypeVarTuple("_Ts") _threads_wakeups: MutableMapping[Any, Any] _global_shutdown: bool @@ -109,8 +111,8 @@ if sys.version_info >= (3, 11): def _process_worker( call_queue: Queue[_CallItem], result_queue: SimpleQueue[_ResultItem], - initializer: Callable[..., object] | None, - initargs: tuple[Any, ...], + initializer: Callable[[Unpack[_Ts]], object] | None, + initargs: tuple[Unpack[_Ts]], max_tasks: int | None = None, ) -> None: ... @@ -118,8 +120,8 @@ else: def _process_worker( call_queue: Queue[_CallItem], result_queue: SimpleQueue[_ResultItem], - initializer: Callable[..., object] | None, - initargs: tuple[Any, ...], + initializer: Callable[[Unpack[_Ts]], object] | None, + initargs: tuple[Unpack[_Ts]], ) -> None: ... if sys.version_info >= (3, 9): @@ -169,22 +171,61 @@ class ProcessPoolExecutor(Executor): _result_queue: SimpleQueue[Any] _work_ids: Queue[Any] if sys.version_info >= (3, 11): + @overload def __init__( self, max_workers: int | None = None, mp_context: BaseContext | None = None, - initializer: Callable[..., object] | None = None, - initargs: tuple[Any, ...] = (), + initializer: Callable[[], object] | None = None, + initargs: tuple[()] = (), + *, + max_tasks_per_child: int | None = None, + ) -> None: ... + @overload + def __init__( + self, + max_workers: int | None = None, + mp_context: BaseContext | None = None, + *, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], + max_tasks_per_child: int | None = None, + ) -> None: ... + @overload + def __init__( + self, + max_workers: int | None, + mp_context: BaseContext | None, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], *, max_tasks_per_child: int | None = None, ) -> None: ... else: + @overload + def __init__( + self, + max_workers: int | None = None, + mp_context: BaseContext | None = None, + initializer: Callable[[], object] | None = None, + initargs: tuple[()] = (), + ) -> None: ... + @overload def __init__( self, max_workers: int | None = None, mp_context: BaseContext | None = None, - initializer: Callable[..., object] | None = None, - initargs: tuple[Any, ...] = (), + *, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], + ) -> None: ... + @overload + def __init__( + self, + max_workers: int | None, + mp_context: BaseContext | None, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], ) -> None: ... if sys.version_info >= (3, 9): def _start_executor_manager_thread(self) -> None: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/thread.pyi b/mypy/typeshed/stdlib/concurrent/futures/thread.pyi index 0b00d524aa3d..f38cf2c57963 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/thread.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/thread.pyi @@ -2,11 +2,14 @@ import queue import sys from collections.abc import Callable, Iterable, Mapping, Set as AbstractSet from threading import Lock, Semaphore, Thread -from typing import Any, Generic, TypeVar +from typing import Any, Generic, TypeVar, overload +from typing_extensions import TypeVarTuple, Unpack from weakref import ref from ._base import BrokenExecutor, Executor, Future +_Ts = TypeVarTuple("_Ts") + _threads_queues: Mapping[Any, Any] _shutdown: bool _global_shutdown_lock: Lock @@ -31,8 +34,8 @@ class _WorkItem(Generic[_S]): def _worker( executor_reference: ref[Any], work_queue: queue.SimpleQueue[Any], - initializer: Callable[..., object], - initargs: tuple[Any, ...], + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], ) -> None: ... class BrokenThreadPool(BrokenExecutor): ... @@ -48,12 +51,30 @@ class ThreadPoolExecutor(Executor): _initializer: Callable[..., None] | None _initargs: tuple[Any, ...] _work_queue: queue.SimpleQueue[_WorkItem[Any]] + @overload def __init__( self, max_workers: int | None = None, thread_name_prefix: str = "", - initializer: Callable[..., object] | None = None, - initargs: tuple[Any, ...] = (), + initializer: Callable[[], object] | None = None, + initargs: tuple[()] = (), + ) -> None: ... + @overload + def __init__( + self, + max_workers: int | None = None, + thread_name_prefix: str = "", + *, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], + ) -> None: ... + @overload + def __init__( + self, + max_workers: int | None, + thread_name_prefix: str, + initializer: Callable[[Unpack[_Ts]], object], + initargs: tuple[Unpack[_Ts]], ) -> None: ... def _adjust_thread_count(self) -> None: ... def _initializer_failed(self) -> None: ... diff --git a/mypy/typeshed/stdlib/http/client.pyi b/mypy/typeshed/stdlib/http/client.pyi index 20223695a1a8..fb5450730f60 100644 --- a/mypy/typeshed/stdlib/http/client.pyi +++ b/mypy/typeshed/stdlib/http/client.pyi @@ -99,6 +99,24 @@ responses: dict[int, str] class HTTPMessage(email.message.Message): def getallmatchingheaders(self, name: str) -> list[str]: ... # undocumented + # override below all of Message's methods that use `_HeaderType` / `_HeaderTypeParam` with `str` + # `HTTPMessage` breaks the Liskov substitution principle by only intending for `str` headers + # This is easier than making `Message` generic + def __getitem__(self, name: str) -> str | None: ... + def __setitem__(self, name: str, val: str) -> None: ... # type: ignore[override] + def values(self) -> list[str]: ... + def items(self) -> list[tuple[str, str]]: ... + @overload + def get(self, name: str, failobj: None = None) -> str | None: ... + @overload + def get(self, name: str, failobj: _T) -> str | _T: ... + @overload + def get_all(self, name: str, failobj: None = None) -> list[str] | None: ... + @overload + def get_all(self, name: str, failobj: _T) -> list[str] | _T: ... + def replace_header(self, _name: str, _value: str) -> None: ... # type: ignore[override] + def set_raw(self, name: str, value: str) -> None: ... # type: ignore[override] + def raw_items(self) -> Iterator[tuple[str, str]]: ... def parse_headers(fp: io.BufferedIOBase, _class: Callable[[], email.message.Message] = ...) -> HTTPMessage: ... diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 7d4b8adcd00a..e92dd7a095d6 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -33,6 +33,9 @@ from . import path as _path if sys.version_info >= (3, 9): from types import GenericAlias +if sys.platform != "win32": + from resource import struct_rusage + # This unnecessary alias is to work around various errors path = _path @@ -962,8 +965,8 @@ else: def waitid(__idtype: int, __ident: int, __options: int) -> waitid_result | None: ... - def wait3(options: int) -> tuple[int, int, Any]: ... - def wait4(pid: int, options: int) -> tuple[int, int, Any]: ... + def wait3(options: int) -> tuple[int, int, struct_rusage]: ... + def wait4(pid: int, options: int) -> tuple[int, int, struct_rusage]: ... def WCOREDUMP(__status: int) -> bool: ... def WIFCONTINUED(status: int) -> bool: ... def WIFSTOPPED(status: int) -> bool: ... diff --git a/mypy/typeshed/stdlib/selectors.pyi b/mypy/typeshed/stdlib/selectors.pyi index 043df9253316..a857d0e242ab 100644 --- a/mypy/typeshed/stdlib/selectors.pyi +++ b/mypy/typeshed/stdlib/selectors.pyi @@ -31,49 +31,37 @@ class BaseSelector(metaclass=ABCMeta): def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... -class SelectSelector(BaseSelector): +class _BaseSelectorImpl(BaseSelector, metaclass=ABCMeta): def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... - def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... + def modify(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... +class SelectSelector(_BaseSelectorImpl): + def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... + +class _PollLikeSelector(_BaseSelectorImpl): + def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... + if sys.platform != "win32": - class PollSelector(BaseSelector): - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... - def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... + class PollSelector(_PollLikeSelector): ... if sys.platform == "linux": - class EpollSelector(BaseSelector): + class EpollSelector(_PollLikeSelector): def fileno(self) -> int: ... - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... - def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... -class DevpollSelector(BaseSelector): +class DevpollSelector(_PollLikeSelector): def fileno(self) -> int: ... - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = ...) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... - def select(self, timeout: float | None = ...) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... if sys.platform != "win32": - class KqueueSelector(BaseSelector): + class KqueueSelector(_BaseSelectorImpl): def fileno(self) -> int: ... - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... # Not a real class at runtime, it is just a conditional alias to other real selectors. # The runtime logic is more fine-grained than a `sys.platform` check; # not really expressible in the stubs -class DefaultSelector(BaseSelector): - def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ... - def unregister(self, fileobj: FileDescriptorLike) -> SelectorKey: ... +class DefaultSelector(_BaseSelectorImpl): def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ... - def get_map(self) -> Mapping[FileDescriptorLike, SelectorKey]: ... if sys.platform != "win32": def fileno(self) -> int: ... diff --git a/mypy/typeshed/stdlib/threading.pyi b/mypy/typeshed/stdlib/threading.pyi index badd09cae051..bcd73823c63f 100644 --- a/mypy/typeshed/stdlib/threading.pyi +++ b/mypy/typeshed/stdlib/threading.pyi @@ -1,3 +1,4 @@ +import _thread import sys from _typeshed import ProfileFunction, TraceFunction from collections.abc import Callable, Iterable, Mapping @@ -68,12 +69,8 @@ def stack_size(size: int = ...) -> int: ... TIMEOUT_MAX: float -class ThreadError(Exception): ... - -class local: - def __getattribute__(self, __name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... - def __delattr__(self, __name: str) -> None: ... +ThreadError = _thread.error +local = _thread._local class Thread: name: str diff --git a/mypy/typeshed/stdlib/unittest/_log.pyi b/mypy/typeshed/stdlib/unittest/_log.pyi index 4de5d502e004..011a970d8bbc 100644 --- a/mypy/typeshed/stdlib/unittest/_log.pyi +++ b/mypy/typeshed/stdlib/unittest/_log.pyi @@ -2,7 +2,7 @@ import logging import sys from types import TracebackType from typing import ClassVar, Generic, NamedTuple, TypeVar -from unittest.case import TestCase +from unittest.case import TestCase, _BaseTestCaseContext _L = TypeVar("_L", None, _LoggingWatcher) @@ -10,9 +10,8 @@ class _LoggingWatcher(NamedTuple): records: list[logging.LogRecord] output: list[str] -class _AssertLogsContext(Generic[_L]): +class _AssertLogsContext(_BaseTestCaseContext, Generic[_L]): LOGGING_FORMAT: ClassVar[str] - test_case: TestCase logger_name: str level: int msg: None diff --git a/mypy/typeshed/stdlib/unittest/case.pyi b/mypy/typeshed/stdlib/unittest/case.pyi index 7efe6cdc9662..d66f027324f1 100644 --- a/mypy/typeshed/stdlib/unittest/case.pyi +++ b/mypy/typeshed/stdlib/unittest/case.pyi @@ -25,8 +25,26 @@ _P = ParamSpec("_P") DIFF_OMITTED: str class _BaseTestCaseContext: + test_case: TestCase def __init__(self, test_case: TestCase) -> None: ... +class _AssertRaisesBaseContext(_BaseTestCaseContext): + expected: type[BaseException] | tuple[type[BaseException], ...] + expected_regex: Pattern[str] | None + obj_name: str | None + msg: str | None + + def __init__( + self, + expected: type[BaseException] | tuple[type[BaseException], ...], + test_case: TestCase, + expected_regex: str | Pattern[str] | None = None, + ) -> None: ... + + # This returns Self if args is the empty list, and None otherwise. + # but it's not possible to construct an overload which expresses that + def handle(self, name: str, args: list[Any], kwargs: dict[str, Any]) -> Any: ... + if sys.version_info >= (3, 9): from unittest._log import _AssertLogsContext, _LoggingWatcher else: @@ -41,7 +59,6 @@ else: class _AssertLogsContext(_BaseTestCaseContext, Generic[_L]): LOGGING_FORMAT: ClassVar[str] - test_case: TestCase logger_name: str level: int msg: None @@ -310,7 +327,7 @@ class FunctionTestCase(TestCase): def __hash__(self) -> int: ... def __eq__(self, other: object) -> bool: ... -class _AssertRaisesContext(Generic[_E]): +class _AssertRaisesContext(_AssertRaisesBaseContext, Generic[_E]): exception: _E def __enter__(self) -> Self: ... def __exit__( @@ -319,7 +336,7 @@ class _AssertRaisesContext(Generic[_E]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... -class _AssertWarnsContext: +class _AssertWarnsContext(_AssertRaisesBaseContext): warning: WarningMessage filename: str lineno: int diff --git a/mypy/typeshed/stdlib/zipfile.pyi b/mypy/typeshed/stdlib/zipfile/__init__.pyi similarity index 98% rename from mypy/typeshed/stdlib/zipfile.pyi rename to mypy/typeshed/stdlib/zipfile/__init__.pyi index 5483b84fe6f6..83982be3be08 100644 --- a/mypy/typeshed/stdlib/zipfile.pyi +++ b/mypy/typeshed/stdlib/zipfile/__init__.pyi @@ -227,7 +227,10 @@ class ZipInfo: def is_dir(self) -> bool: ... def FileHeader(self, zip64: bool | None = None) -> bytes: ... -if sys.version_info >= (3, 8): +if sys.version_info >= (3, 12): + from zipfile._path import CompleteDirs as CompleteDirs, Path as Path + +elif sys.version_info >= (3, 8): class CompleteDirs(ZipFile): def resolve_dir(self, name: str) -> str: ... @overload diff --git a/mypy/typeshed/stdlib/zipfile/_path.pyi b/mypy/typeshed/stdlib/zipfile/_path.pyi new file mode 100644 index 000000000000..3cf034aec8f4 --- /dev/null +++ b/mypy/typeshed/stdlib/zipfile/_path.pyi @@ -0,0 +1,95 @@ +import sys +from _typeshed import StrPath +from collections.abc import Iterator, Sequence +from io import TextIOWrapper +from os import PathLike +from typing import IO, overload +from typing_extensions import Literal, Self, TypeAlias +from zipfile import ZipFile + +_ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] + +if sys.version_info >= (3, 12): + class InitializedState: + def __init__(self, *args: object, **kwargs: object) -> None: ... + def __getstate__(self) -> tuple[list[object], dict[object, object]]: ... + def __setstate__(self, state: Sequence[tuple[list[object], dict[object, object]]]) -> None: ... + + class CompleteDirs(InitializedState, ZipFile): + def resolve_dir(self, name: str) -> str: ... + @overload + @classmethod + def make(cls, source: ZipFile) -> CompleteDirs: ... + @overload + @classmethod + def make(cls, source: StrPath | IO[bytes]) -> Self: ... + + class Path: + root: CompleteDirs + def __init__(self, root: ZipFile | StrPath | IO[bytes], at: str = "") -> None: ... + @property + def name(self) -> str: ... + @property + def parent(self) -> PathLike[str]: ... # undocumented + if sys.version_info >= (3, 10): + @property + def filename(self) -> PathLike[str]: ... # undocumented + if sys.version_info >= (3, 11): + @property + def suffix(self) -> str: ... + @property + def suffixes(self) -> list[str]: ... + @property + def stem(self) -> str: ... + + if sys.version_info >= (3, 9): + @overload + def open( + self, + mode: Literal["r", "w"] = "r", + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + line_buffering: bool = ..., + write_through: bool = ..., + *, + pwd: bytes | None = None, + ) -> TextIOWrapper: ... + @overload + def open(self, mode: Literal["rb", "wb"], *, pwd: bytes | None = None) -> IO[bytes]: ... + else: + def open( + self, mode: _ReadWriteBinaryMode = "r", pwd: bytes | None = None, *, force_zip64: bool = False + ) -> IO[bytes]: ... + + if sys.version_info >= (3, 10): + def iterdir(self) -> Iterator[Self]: ... + else: + def iterdir(self) -> Iterator[Path]: ... + + def is_dir(self) -> bool: ... + def is_file(self) -> bool: ... + def exists(self) -> bool: ... + def read_text( + self, + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., + line_buffering: bool = ..., + write_through: bool = ..., + ) -> str: ... + def read_bytes(self) -> bytes: ... + if sys.version_info >= (3, 10): + def joinpath(self, *other: StrPath) -> Path: ... + else: + def joinpath(self, add: StrPath) -> Path: ... # undocumented + if sys.version_info >= (3, 12): + def glob(self, pattern: str) -> Iterator[Self]: ... + def rglob(self, pattern: str) -> Iterator[Self]: ... + def is_symlink(self) -> Literal[False]: ... + def relative_to(self, other: Path, *extra: StrPath) -> str: ... + def match(self, path_pattern: str) -> bool: ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self) -> int: ... + + def __truediv__(self, add: StrPath) -> Path: ... From 4aba5ca8450ad3f06805f2bd6dfcd06048a3f1d2 Mon Sep 17 00:00:00 2001 From: Fabian Lewis <49647154+frobian21@users.noreply.github.com> Date: Tue, 2 Jan 2024 02:26:30 +0100 Subject: [PATCH 21/69] Fix xml writing bug introduced in #16388 (#16713) #16388 introduced a bug where invalid xml could be produced by `write_junit_xml`, as special characters were no longer being escaped. The fix is to revert the removal of `from xml.sax.saxutils import escape` and `escape("\n".join(messages))` in the `write_junit_xml` function. I've added a small test case which checks that the `<`, `>`, `&` are escaped correctly in the xml. --- mypy/test/testutil.py | 22 ++++++++++++++++++++++ mypy/util.py | 6 ++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mypy/test/testutil.py b/mypy/test/testutil.py index d0d54ffec8c6..a7c3f1c00fee 100644 --- a/mypy/test/testutil.py +++ b/mypy/test/testutil.py @@ -31,6 +31,28 @@ def test_junit_pass(self) -> None: +""" + result = _generate_junit_contents( + dt=1.23, + serious=serious, + messages_by_file=messages_by_file, + version="3.14", + platform="test-plat", + ) + assert result == expected + + def test_junit_fail_escape_xml_chars(self) -> None: + serious = False + messages_by_file: dict[str | None, list[str]] = { + "file1.py": ["Test failed", "another line < > &"] + } + expected = """ + + + Test failed +another line < > & + + """ result = _generate_junit_contents( dt=1.23, diff --git a/mypy/util.py b/mypy/util.py index be8a22d08a27..0277a96a6885 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -263,6 +263,8 @@ def _generate_junit_contents( version: str, platform: str, ) -> str: + from xml.sax.saxutils import escape + if serious: failures = 0 errors = len(messages_by_file) @@ -284,7 +286,7 @@ def _generate_junit_contents( for filename, messages in messages_by_file.items(): if filename is not None: xml += JUNIT_TESTCASE_FAIL_TEMPLATE.format( - text="\n".join(messages), + text=escape("\n".join(messages)), filename=filename, time=dt, name="mypy-py{ver}-{platform} {filename}".format( @@ -293,7 +295,7 @@ def _generate_junit_contents( ) else: xml += JUNIT_TESTCASE_FAIL_TEMPLATE.format( - text="\n".join(messages), + text=escape("\n".join(messages)), filename="mypy", time=dt, name="mypy-py{ver}-{platform}".format(ver=version, platform=platform), From d0d5876d876272c56a339c628197935906c57e3c Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Mon, 1 Jan 2024 19:47:02 -0800 Subject: [PATCH 22/69] Fix various lint (#16726) --- .pre-commit-config.yaml | 2 +- mypy/binder.py | 2 +- mypy/build.py | 10 ++++------ mypy/checker.py | 7 +++---- mypy/checkexpr.py | 6 ++---- mypy/checkpattern.py | 2 +- mypy/checkstrformat.py | 4 ++-- mypy/dmypy_server.py | 2 +- mypy/dmypy_util.py | 2 +- mypy/errors.py | 2 +- mypy/main.py | 6 +++--- mypy/message_registry.py | 2 +- mypy/messages.py | 2 +- mypy/nodes.py | 6 +++--- mypy/patterns.py | 14 ++++++++------ mypy/plugins/enums.py | 4 ++-- mypy/renaming.py | 2 +- mypy/semanal.py | 10 ++++------ mypy/semanal_enum.py | 2 +- mypy/semanal_namedtuple.py | 2 +- mypy/semanal_typeddict.py | 2 +- mypy/server/astmerge.py | 4 ++-- mypy/stubdoc.py | 2 +- mypy/stubgenc.py | 8 ++++---- mypy/stubtest.py | 16 ++++++---------- mypy/stubutil.py | 2 +- mypy/test/helpers.py | 4 ++-- mypy/test/testcheck.py | 5 ++++- mypy/test/testformatter.py | 4 ++-- mypy/test/teststubtest.py | 4 ++-- mypy/typeanal.py | 2 +- mypy/types.py | 2 +- mypy/typestate.py | 4 ++-- mypy/util.py | 2 +- mypyc/codegen/emitmodule.py | 2 +- mypyc/codegen/emitwrapper.py | 4 ++-- mypyc/irbuild/prepare.py | 6 +++--- mypyc/primitives/registry.py | 20 +++++++++++++++----- pyproject.toml | 9 +++++++-- test-requirements.in | 2 +- test-requirements.txt | 2 +- 41 files changed, 102 insertions(+), 93 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bd2a09b7a8cf..4090bf0ecb4c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.0 # must match test-requirements.txt + rev: v0.1.4 # must match test-requirements.txt hooks: - id: ruff args: [--exit-non-zero-on-fix] diff --git a/mypy/binder.py b/mypy/binder.py index 3b67d09f16c3..9d0a33b54bc2 100644 --- a/mypy/binder.py +++ b/mypy/binder.py @@ -291,7 +291,7 @@ def assign_type( self.type_assignments[expr].append((type, declared_type)) return if not isinstance(expr, (IndexExpr, MemberExpr, NameExpr)): - return None + return if not literal(expr): return self.invalidate_dependencies(expr) diff --git a/mypy/build.py b/mypy/build.py index b3ca8d06916d..8049fa2d0c3f 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -682,9 +682,7 @@ def __init__( # for efficient lookup self.shadow_map: dict[str, str] = {} if self.options.shadow_file is not None: - self.shadow_map = { - source_file: shadow_file for (source_file, shadow_file) in self.options.shadow_file - } + self.shadow_map = dict(self.options.shadow_file) # a mapping from each file being typechecked to its possible shadow file self.shadow_equivalence_map: dict[str, str | None] = {} self.plugin = plugin @@ -1120,7 +1118,7 @@ def read_deps_cache(manager: BuildManager, graph: Graph) -> dict[str, FgDepMeta] module_deps_metas = deps_meta["deps_meta"] assert isinstance(module_deps_metas, dict) if not manager.options.skip_cache_mtime_checks: - for id, meta in module_deps_metas.items(): + for meta in module_deps_metas.values(): try: matched = manager.getmtime(meta["path"]) == meta["mtime"] except FileNotFoundError: @@ -2093,7 +2091,7 @@ def load_tree(self, temporary: bool = False) -> None: self.meta.data_json, self.manager, "Load tree ", "Could not load tree: " ) if data is None: - return None + return t0 = time.time() # TODO: Assert data file wasn't changed. @@ -3383,7 +3381,7 @@ def order_ascc(graph: Graph, ascc: AbstractSet[str], pri_max: int = PRI_ALL) -> strongly_connected_components() below for a reference. """ if len(ascc) == 1: - return [s for s in ascc] + return list(ascc) pri_spread = set() for id in ascc: state = graph[id] diff --git a/mypy/checker.py b/mypy/checker.py index 0ac8f6904973..1b57ef780104 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -632,7 +632,7 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: if not defn.items: # In this case we have already complained about none of these being # valid overloads. - return None + return if len(defn.items) == 1: self.fail(message_registry.MULTIPLE_OVERLOADS_REQUIRED, defn) @@ -676,7 +676,6 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None: self.msg.no_overridable_method(defn.name, defn) self.check_explicit_override_decorator(defn, found_method_base_classes, defn.impl) self.check_inplace_operator_method(defn) - return None def extract_callable_type(self, inner_type: Type | None, ctx: Context) -> CallableType | None: """Get type as seen by an overload item caller.""" @@ -1838,7 +1837,7 @@ def check_match_args(self, var: Var, typ: Type, context: Context) -> None: return typ = get_proper_type(typ) if not isinstance(typ, TupleType) or not all( - [is_string_literal(item) for item in typ.items] + is_string_literal(item) for item in typ.items ): self.msg.note( "__match_args__ must be a tuple containing string literals for checking " @@ -5045,7 +5044,7 @@ def visit_break_stmt(self, s: BreakStmt) -> None: def visit_continue_stmt(self, s: ContinueStmt) -> None: self.binder.handle_continue() - return None + return def visit_match_stmt(self, s: MatchStmt) -> None: with self.binder.frame_context(can_skip=False, fall_through=0): diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 626584bc3a20..3af8d70e78c9 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -739,7 +739,7 @@ def check_typeddict_call( context: Context, orig_callee: Type | None, ) -> Type: - if args and all([ak in (ARG_NAMED, ARG_STAR2) for ak in arg_kinds]): + if args and all(ak in (ARG_NAMED, ARG_STAR2) for ak in arg_kinds): # ex: Point(x=42, y=1337, **extras) # This is a bit ugly, but this is a price for supporting all possible syntax # variants for TypedDict constructors. @@ -4017,9 +4017,7 @@ def check_op( left_variants = [base_type] base_type = get_proper_type(base_type) if isinstance(base_type, UnionType): - left_variants = [ - item for item in flatten_nested_unions(base_type.relevant_items()) - ] + left_variants = list(flatten_nested_unions(base_type.relevant_items())) right_type = self.accept(arg) # Step 1: We first try leaving the right arguments alone and destructure diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index c0061f1c3e72..3210dcc3b7ac 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -187,7 +187,7 @@ def visit_or_pattern(self, o: OrPattern) -> PatternType: capture_types[node].append((expr, typ)) captures: dict[Expression, Type] = {} - for var, capture_list in capture_types.items(): + for capture_list in capture_types.values(): typ = UninhabitedType() for _, other in capture_list: typ = join_types(typ, other) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index 39d44e84a9c1..c63210a96c44 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -372,7 +372,7 @@ def check_specs_in_format_call( ): # TODO: add support for some custom specs like datetime? self.msg.fail( - "Unrecognized format" ' specification "{}"'.format(spec.format_spec[1:]), + f'Unrecognized format specification "{spec.format_spec[1:]}"', call, code=codes.STRING_FORMATTING, ) @@ -482,7 +482,7 @@ def find_replacements_in_call(self, call: CallExpr, keys: list[str]) -> list[Exp expr = self.get_expr_by_name(key, call) if not expr: self.msg.fail( - "Cannot find replacement for named" ' format specifier "{}"'.format(key), + f'Cannot find replacement for named format specifier "{key}"', call, code=codes.STRING_FORMATTING, ) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 42236497f275..b4c3fe8fe0dc 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -1055,7 +1055,7 @@ def fix_module_deps(graph: mypy.build.Graph) -> None: This can make some suppressed dependencies non-suppressed, and vice versa (if modules have been added to or removed from the build). """ - for module, state in graph.items(): + for state in graph.values(): new_suppressed = [] new_dependencies = [] for dep in state.dependencies + state.suppressed: diff --git a/mypy/dmypy_util.py b/mypy/dmypy_util.py index d95cba9f40b5..fe949e8fc294 100644 --- a/mypy/dmypy_util.py +++ b/mypy/dmypy_util.py @@ -43,7 +43,7 @@ def send(connection: IPCBase, data: Any) -> None: class WriteToConn: """Helper class to write to a connection instead of standard output.""" - def __init__(self, server: IPCBase, output_key: str = "stdout"): + def __init__(self, server: IPCBase, output_key: str = "stdout") -> None: self.server = server self.output_key = output_key diff --git a/mypy/errors.py b/mypy/errors.py index 6e90c28d9c03..eabe96a2dc73 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -170,7 +170,7 @@ def __init__( *, filter_errors: bool | Callable[[str, ErrorInfo], bool] = False, save_filtered_errors: bool = False, - ): + ) -> None: self.errors = errors self._has_new_errors = False self._filter = filter_errors diff --git a/mypy/main.py b/mypy/main.py index 2c68466ec977..b32624456ce0 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -145,7 +145,7 @@ def main( sys.exit(code) # HACK: keep res alive so that mypyc won't free it before the hard_exit - list([res]) + list([res]) # noqa: C410 def run_build( @@ -349,7 +349,7 @@ class CapturableArgumentParser(argparse.ArgumentParser): yet output must be captured to properly support mypy.api.run. """ - def __init__(self, *args: Any, **kwargs: Any): + def __init__(self, *args: Any, **kwargs: Any) -> None: self.stdout = kwargs.pop("stdout", sys.stdout) self.stderr = kwargs.pop("stderr", sys.stderr) super().__init__(*args, **kwargs) @@ -415,7 +415,7 @@ def __init__( default: str = argparse.SUPPRESS, help: str = "show program's version number and exit", stdout: IO[str] | None = None, - ): + ) -> None: super().__init__( option_strings=option_strings, dest=dest, default=default, nargs=0, help=help ) diff --git a/mypy/message_registry.py b/mypy/message_registry.py index 8dc14e158d90..fb430b63c74b 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -52,7 +52,7 @@ def with_additional_msg(self, info: str) -> ErrorMessage: '"return" with value in async generator is not allowed' ) INVALID_RETURN_TYPE_FOR_GENERATOR: Final = ErrorMessage( - 'The return type of a generator function should be "Generator"' " or one of its supertypes" + 'The return type of a generator function should be "Generator" or one of its supertypes' ) INVALID_RETURN_TYPE_FOR_ASYNC_GENERATOR: Final = ErrorMessage( 'The return type of an async generator function should be "AsyncGenerator" or one of its ' diff --git a/mypy/messages.py b/mypy/messages.py index 069c4d51e281..450faf4c1688 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -3099,7 +3099,7 @@ def append_invariance_notes( ): invariant_type = "Dict" covariant_suggestion = ( - 'Consider using "Mapping" instead, ' "which is covariant in the value type" + 'Consider using "Mapping" instead, which is covariant in the value type' ) if invariant_type and covariant_suggestion: notes.append( diff --git a/mypy/nodes.py b/mypy/nodes.py index 17e06613d1e3..fe41777c55f7 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -3137,7 +3137,7 @@ def protocol_members(self) -> list[str]: if name in EXCLUDED_PROTOCOL_ATTRIBUTES: continue members.add(name) - return sorted(list(members)) + return sorted(members) def __getitem__(self, name: str) -> SymbolTableNode: n = self.get(name) @@ -3296,7 +3296,7 @@ def serialize(self) -> JsonDict: else self.typeddict_type.serialize(), "flags": get_flags(self, TypeInfo.FLAGS), "metadata": self.metadata, - "slots": list(sorted(self.slots)) if self.slots is not None else None, + "slots": sorted(self.slots) if self.slots is not None else None, "deletable_attributes": self.deletable_attributes, "self_type": self.self_type.serialize() if self.self_type is not None else None, "dataclass_transform_spec": ( @@ -3966,7 +3966,7 @@ def __init__( # frozen_default was added to CPythonin https://github.com/python/cpython/pull/99958 citing # positive discussion in typing-sig frozen_default: bool | None = None, - ): + ) -> None: self.eq_default = eq_default if eq_default is not None else True self.order_default = order_default if order_default is not None else False self.kw_only_default = kw_only_default if kw_only_default is not None else False diff --git a/mypy/patterns.py b/mypy/patterns.py index 839864ef5879..a01bf6acc876 100644 --- a/mypy/patterns.py +++ b/mypy/patterns.py @@ -60,7 +60,7 @@ class ValuePattern(Pattern): expr: Expression - def __init__(self, expr: Expression): + def __init__(self, expr: Expression) -> None: super().__init__() self.expr = expr @@ -72,7 +72,7 @@ class SingletonPattern(Pattern): # This can be exactly True, False or None value: bool | None - def __init__(self, value: bool | None): + def __init__(self, value: bool | None) -> None: super().__init__() self.value = value @@ -85,7 +85,7 @@ class SequencePattern(Pattern): patterns: list[Pattern] - def __init__(self, patterns: list[Pattern]): + def __init__(self, patterns: list[Pattern]) -> None: super().__init__() self.patterns = patterns @@ -98,7 +98,7 @@ class StarredPattern(Pattern): # a name. capture: NameExpr | None - def __init__(self, capture: NameExpr | None): + def __init__(self, capture: NameExpr | None) -> None: super().__init__() self.capture = capture @@ -111,7 +111,9 @@ class MappingPattern(Pattern): values: list[Pattern] rest: NameExpr | None - def __init__(self, keys: list[Expression], values: list[Pattern], rest: NameExpr | None): + def __init__( + self, keys: list[Expression], values: list[Pattern], rest: NameExpr | None + ) -> None: super().__init__() assert len(keys) == len(values) self.keys = keys @@ -136,7 +138,7 @@ def __init__( positionals: list[Pattern], keyword_keys: list[str], keyword_values: list[Pattern], - ): + ) -> None: super().__init__() assert len(keyword_keys) == len(keyword_values) self.class_ref = class_ref diff --git a/mypy/plugins/enums.py b/mypy/plugins/enums.py index 7869a8b5cdfa..2c568f66c62d 100644 --- a/mypy/plugins/enums.py +++ b/mypy/plugins/enums.py @@ -166,11 +166,11 @@ class SomeEnum: for n in stnodes if n is None or not n.implicit ) - proper_types = list( + proper_types = [ _infer_value_type_with_auto_fallback(ctx, t) for t in node_types if t is None or not isinstance(t, CallableType) - ) + ] underlying_type = _first(proper_types) if underlying_type is None: return ctx.default_attr_type diff --git a/mypy/renaming.py b/mypy/renaming.py index c960eb4b1ce8..8db336205960 100644 --- a/mypy/renaming.py +++ b/mypy/renaming.py @@ -270,7 +270,7 @@ def flush_refs(self) -> None: This will be called at the end of a scope. """ is_func = self.scope_kinds[-1] == FUNCTION - for name, refs in self.refs[-1].items(): + for refs in self.refs[-1].values(): if len(refs) == 1: # Only one definition -- no renaming needed. continue diff --git a/mypy/semanal.py b/mypy/semanal.py index 48be004daf76..e0a3db2bff1b 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -4153,7 +4153,7 @@ def check_typevarlike_name(self, call: CallExpr, name: str, context: Context) -> if len(call.args) < 1: self.fail(f"Too few arguments for {typevarlike_type}()", context) return False - if not isinstance(call.args[0], StrExpr) or not call.arg_kinds[0] == ARG_POS: + if not isinstance(call.args[0], StrExpr) or call.arg_kinds[0] != ARG_POS: self.fail(f"{typevarlike_type}() expects a string literal as first argument", context) return False elif call.args[0].value != name: @@ -4961,9 +4961,7 @@ def visit_name_expr(self, expr: NameExpr) -> None: def bind_name_expr(self, expr: NameExpr, sym: SymbolTableNode) -> None: """Bind name expression to a symbol table node.""" if isinstance(sym.node, TypeVarExpr) and self.tvar_scope.get_binding(sym): - self.fail( - '"{}" is a type variable and only valid in type ' "context".format(expr.name), expr - ) + self.fail(f'"{expr.name}" is a type variable and only valid in type context', expr) elif isinstance(sym.node, PlaceholderNode): self.process_placeholder(expr.name, "name", expr) else: @@ -6809,13 +6807,13 @@ def parse_dataclass_transform_spec(self, call: CallExpr) -> DataclassTransformSp def parse_dataclass_transform_field_specifiers(self, arg: Expression) -> tuple[str, ...]: if not isinstance(arg, TupleExpr): self.fail('"field_specifiers" argument must be a tuple literal', arg) - return tuple() + return () names = [] for specifier in arg.items: if not isinstance(specifier, RefExpr): self.fail('"field_specifiers" must only contain identifiers', specifier) - return tuple() + return () names.append(specifier.fullname) return tuple(names) diff --git a/mypy/semanal_enum.py b/mypy/semanal_enum.py index 528b0519cca1..21576ab47a84 100644 --- a/mypy/semanal_enum.py +++ b/mypy/semanal_enum.py @@ -148,7 +148,7 @@ def parse_enum_call_args( Return a tuple of fields, values, was there an error. """ args = call.args - if not all([arg_kind in [ARG_POS, ARG_NAMED] for arg_kind in call.arg_kinds]): + if not all(arg_kind in [ARG_POS, ARG_NAMED] for arg_kind in call.arg_kinds): return self.fail_enum_call_arg(f"Unexpected arguments to {class_name}()", call) if len(args) < 2: return self.fail_enum_call_arg(f"Too few arguments for {class_name}()", call) diff --git a/mypy/semanal_namedtuple.py b/mypy/semanal_namedtuple.py index bc3c5dd61894..9a0be9d9c14c 100644 --- a/mypy/semanal_namedtuple.py +++ b/mypy/semanal_namedtuple.py @@ -85,7 +85,7 @@ ) NAMEDTUP_CLASS_ERROR: Final = ( - "Invalid statement in NamedTuple definition; " 'expected "field_name: field_type [= default]"' + 'Invalid statement in NamedTuple definition; expected "field_name: field_type [= default]"' ) SELF_TVAR_NAME: Final = "_NT" diff --git a/mypy/semanal_typeddict.py b/mypy/semanal_typeddict.py index 13aab4de65e4..67c05fd74273 100644 --- a/mypy/semanal_typeddict.py +++ b/mypy/semanal_typeddict.py @@ -50,7 +50,7 @@ ) TPDICT_CLASS_ERROR: Final = ( - "Invalid statement in TypedDict definition; " 'expected "field_name: field_type"' + 'Invalid statement in TypedDict definition; expected "field_name: field_type"' ) diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py index 862c3898a383..174c2922c767 100644 --- a/mypy/server/astmerge.py +++ b/mypy/server/astmerge.py @@ -394,7 +394,7 @@ def process_synthetic_type_info(self, info: TypeInfo) -> None: # have bodies in the AST so we need to iterate over their symbol # tables separately, unlike normal classes. self.process_type_info(info) - for name, node in info.names.items(): + for node in info.names.values(): if node.node: node.node.accept(self) @@ -549,7 +549,7 @@ def fixup(self, node: SN) -> SN: def replace_nodes_in_symbol_table( symbols: SymbolTable, replacements: dict[SymbolNode, SymbolNode] ) -> None: - for name, node in symbols.items(): + for node in symbols.values(): if node.node: if node.node in replacements: new = replacements[node.node] diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index 86ff6e2bb540..8c0a4dab696f 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -325,7 +325,7 @@ def args_kwargs(signature: FunctionSig) -> bool: return has_arg("*args", signature) and has_arg("**kwargs", signature) # Move functions with (*args, **kwargs) in their signature to last place. - return list(sorted(self.signatures, key=lambda x: 1 if args_kwargs(x) else 0)) + return sorted(self.signatures, key=lambda x: 1 if args_kwargs(x) else 0) def infer_sig_from_docstring(docstr: str | None, name: str) -> list[FunctionSig] | None: diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 39288197f477..55e46fe0ec25 100755 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -41,7 +41,7 @@ class ExternalSignatureGenerator(SignatureGenerator): def __init__( self, func_sigs: dict[str, str] | None = None, class_sigs: dict[str, str] | None = None - ): + ) -> None: """ Takes a mapping of function/method names to signatures and class name to class signatures (usually corresponds to __init__). @@ -187,7 +187,7 @@ class CFunctionStub: Class that mimics a C function in order to provide parseable docstrings. """ - def __init__(self, name: str, doc: str, is_abstract: bool = False): + def __init__(self, name: str, doc: str, is_abstract: bool = False) -> None: self.__name__ = name self.__doc__ = doc self.__abstractmethod__ = is_abstract @@ -404,7 +404,7 @@ def generate_module(self) -> None: if self.should_reexport(name, obj_module_name, name_is_alias=False): self.import_tracker.reexport(name) - self.set_defined_names(set([name for name, obj in all_items if not inspect.ismodule(obj)])) + self.set_defined_names({name for name, obj in all_items if not inspect.ismodule(obj)}) if self.resort_members: functions: list[str] = [] @@ -765,7 +765,7 @@ def generate_class_stub(self, class_name: str, cls: type, output: list[str]) -> items = self.get_members(cls) if self.resort_members: items = sorted(items, key=lambda x: method_name_sort_key(x[0])) - names = set(x[0] for x in items) + names = {x[0] for x in items} methods: list[str] = [] types: list[str] = [] static_properties: list[str] = [] diff --git a/mypy/stubtest.py b/mypy/stubtest.py index c02a3efd8dc0..e7cc24f33d18 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -303,11 +303,9 @@ def _verify_exported_names( # desirable in at least the `names_in_runtime_not_stub` case stub_object=MISSING, runtime_object=MISSING, - stub_desc=( - f"Names exported in the stub but not at runtime: " f"{names_in_stub_not_runtime}" - ), + stub_desc=(f"Names exported in the stub but not at runtime: {names_in_stub_not_runtime}"), runtime_desc=( - f"Names exported at runtime but not in the stub: " f"{names_in_runtime_not_stub}" + f"Names exported at runtime but not in the stub: {names_in_runtime_not_stub}" ), ) @@ -677,7 +675,7 @@ def _verify_arg_default_value( runtime_type is not None and stub_type is not None # Avoid false positives for marker objects - and type(runtime_arg.default) != object + and type(runtime_arg.default) is not object # And ellipsis and runtime_arg.default is not ... and not is_subtype_helper(runtime_type, stub_type) @@ -897,7 +895,7 @@ def _verify_signature( runtime_arg.kind == inspect.Parameter.POSITIONAL_ONLY and not stub_arg.pos_only and not stub_arg.variable.name.startswith("__") - and not stub_arg.variable.name.strip("_") == "self" + and stub_arg.variable.name.strip("_") != "self" and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( @@ -1812,10 +1810,8 @@ def get_importable_stdlib_modules() -> set[str]: # test.* modules do weird things like raising exceptions in __del__ methods, # leading to unraisable exceptions being logged to the terminal # as a warning at the end of the stubtest run - if ( - submodule_name.endswith(".__main__") - or submodule_name.startswith("idlelib.") - or submodule_name.startswith("test.") + if submodule_name.endswith(".__main__") or submodule_name.startswith( + ("idlelib.", "test.") ): continue diff --git a/mypy/stubutil.py b/mypy/stubutil.py index b8d601ed3c6b..e4a97964c547 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -558,7 +558,7 @@ def __init__( include_private: bool = False, export_less: bool = False, include_docstrings: bool = False, - ): + ) -> None: # Best known value of __all__. self._all_ = _all_ self._include_private = include_private diff --git a/mypy/test/helpers.py b/mypy/test/helpers.py index dc34931427ec..bae4f6e81ad1 100644 --- a/mypy/test/helpers.py +++ b/mypy/test/helpers.py @@ -145,7 +145,7 @@ def assert_module_equivalence(name: str, expected: Iterable[str], actual: Iterab assert_string_arrays_equal( expected_normalized, actual_normalized, - ("Actual modules ({}) do not match expected modules ({}) " 'for "[{} ...]"').format( + ('Actual modules ({}) do not match expected modules ({}) for "[{} ...]"').format( ", ".join(actual_normalized), ", ".join(expected_normalized), name ), ) @@ -156,7 +156,7 @@ def assert_target_equivalence(name: str, expected: list[str], actual: list[str]) assert_string_arrays_equal( expected, actual, - ("Actual targets ({}) do not match expected targets ({}) " 'for "[{} ...]"').format( + ('Actual targets ({}) do not match expected targets ({}) for "[{} ...]"').format( ", ".join(actual), ", ".join(expected), name ), ) diff --git a/mypy/test/testcheck.py b/mypy/test/testcheck.py index 3ad97ced61f2..5fba6192dcaf 100644 --- a/mypy/test/testcheck.py +++ b/mypy/test/testcheck.py @@ -29,6 +29,7 @@ except ImportError: lxml = None + import pytest # List of files that contain test case descriptions. @@ -99,9 +100,11 @@ def _filename(_msg: str) -> str: def run_case_once( self, testcase: DataDrivenTestCase, - operations: list[FileOperation] = [], + operations: list[FileOperation] | None = None, incremental_step: int = 0, ) -> None: + if operations is None: + operations = [] original_program_text = "\n".join(testcase.input) module_data = self.parse_module(original_program_text, incremental_step) diff --git a/mypy/test/testformatter.py b/mypy/test/testformatter.py index f64527e7804a..9f8bb5d82408 100644 --- a/mypy/test/testformatter.py +++ b/mypy/test/testformatter.py @@ -52,14 +52,14 @@ def test_trim_source(self) -> None: def test_split_words(self) -> None: assert split_words("Simple message") == ["Simple", "message"] - assert split_words('Message with "Some[Long, Types]"' " in it") == [ + assert split_words('Message with "Some[Long, Types]" in it') == [ "Message", "with", '"Some[Long, Types]"', "in", "it", ] - assert split_words('Message with "Some[Long, Types]"' " and [error-code]") == [ + assert split_words('Message with "Some[Long, Types]" and [error-code]') == [ "Message", "with", '"Some[Long, Types]"', diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 34b266115166..72b6f6620f83 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -173,7 +173,7 @@ def run_stubtest( class Case: - def __init__(self, stub: str, runtime: str, error: str | None): + def __init__(self, stub: str, runtime: str, error: str | None) -> None: self.stub = stub self.runtime = runtime self.error = error @@ -2226,7 +2226,7 @@ def also_bad(asdf): pass options=["--allowlist", allowlist.name, "--generate-allowlist"], ) assert output == ( - f"note: unused allowlist entry unused.*\n" f"{TEST_MODULE_NAME}.also_bad\n" + f"note: unused allowlist entry unused.*\n{TEST_MODULE_NAME}.also_bad\n" ) finally: os.unlink(allowlist.name) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 4d916315bddd..8a840424f76f 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -2319,7 +2319,7 @@ def visit_unbound_type(self, t: UnboundType) -> None: # Special case P.args and P.kwargs for ParamSpecs only. if name.endswith("args"): - if name.endswith(".args") or name.endswith(".kwargs"): + if name.endswith((".args", ".kwargs")): base = ".".join(name.split(".")[:-1]) n = self.api.lookup_qualified(base, t) if n is not None and isinstance(n.node, ParamSpecExpr): diff --git a/mypy/types.py b/mypy/types.py index fcdb61f9719b..f02e56a677ae 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -441,7 +441,7 @@ class TypeGuardedType(Type): __slots__ = ("type_guard",) - def __init__(self, type_guard: Type): + def __init__(self, type_guard: Type) -> None: super().__init__(line=type_guard.line, column=type_guard.column) self.type_guard = type_guard diff --git a/mypy/typestate.py b/mypy/typestate.py index b32fb0ef6df1..c5a5da03eae5 100644 --- a/mypy/typestate.py +++ b/mypy/typestate.py @@ -192,7 +192,7 @@ def record_subtype_cache_entry( # These are unlikely to match, due to the large space of # possible values. Avoid uselessly increasing cache sizes. return - cache = self._subtype_caches.setdefault(right.type, dict()) + cache = self._subtype_caches.setdefault(right.type, {}) cache.setdefault(kind, set()).add((left, right)) def record_negative_subtype_cache_entry( @@ -204,7 +204,7 @@ def record_negative_subtype_cache_entry( return if len(self._negative_subtype_caches) > MAX_NEGATIVE_CACHE_TYPES: self._negative_subtype_caches.clear() - cache = self._negative_subtype_caches.setdefault(right.type, dict()) + cache = self._negative_subtype_caches.setdefault(right.type, {}) subcache = cache.setdefault(kind, set()) if len(subcache) > MAX_NEGATIVE_CACHE_ENTRIES: subcache.clear() diff --git a/mypy/util.py b/mypy/util.py index 0277a96a6885..968774ee7c98 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -451,7 +451,7 @@ def get_unique_redefinition_name(name: str, existing: Container[str]) -> str: def check_python_version(program: str) -> None: """Report issues with the Python used to run mypy, dmypy, or stubgen""" # Check for known bad Python versions. - if sys.version_info[:2] < (3, 8): + if sys.version_info[:2] < (3, 8): # noqa: UP036 sys.exit( "Running {name} with Python 3.7 or lower is not supported; " "please upgrade to 3.8 or newer".format(name=program) diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index caf2058ea7c4..6c0dfd43b9af 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -993,7 +993,7 @@ def _toposort_visit(name: str) -> None: result.append(decl.declaration) decl.mark = True - for name, marked_declaration in marked_declarations.items(): + for name in marked_declarations: _toposort_visit(name) return result diff --git a/mypyc/codegen/emitwrapper.py b/mypyc/codegen/emitwrapper.py index 791e856c274a..45c6c7a05867 100644 --- a/mypyc/codegen/emitwrapper.py +++ b/mypyc/codegen/emitwrapper.py @@ -145,7 +145,7 @@ def generate_wrapper_function( real_args = list(fn.args) if fn.sig.num_bitmap_args: real_args = real_args[: -fn.sig.num_bitmap_args] - if fn.class_name and not fn.decl.kind == FUNC_STATICMETHOD: + if fn.class_name and fn.decl.kind != FUNC_STATICMETHOD: arg = real_args.pop(0) emitter.emit_line(f"PyObject *obj_{arg.name} = self;") @@ -238,7 +238,7 @@ def generate_legacy_wrapper_function( real_args = list(fn.args) if fn.sig.num_bitmap_args: real_args = real_args[: -fn.sig.num_bitmap_args] - if fn.class_name and not fn.decl.kind == FUNC_STATICMETHOD: + if fn.class_name and fn.decl.kind != FUNC_STATICMETHOD: arg = real_args.pop(0) emitter.emit_line(f"PyObject *obj_{arg.name} = self;") diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index 5e6520048197..29e06439abdd 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -139,7 +139,7 @@ def is_from_module(node: SymbolNode, module: MypyFile) -> bool: def load_type_map(mapper: Mapper, modules: list[MypyFile], deser_ctx: DeserMaps) -> None: """Populate a Mapper with deserialized IR from a list of modules.""" for module in modules: - for name, node in module.names.items(): + for node in module.names.values(): if isinstance(node.node, TypeInfo) and is_from_module(node.node, module): ir = deser_ctx.classes[node.node.fullname] mapper.type_to_ir[node.node] = ir @@ -153,7 +153,7 @@ def load_type_map(mapper: Mapper, modules: list[MypyFile], deser_ctx: DeserMaps) def get_module_func_defs(module: MypyFile) -> Iterable[FuncDef]: """Collect all of the (non-method) functions declared in a module.""" - for name, node in module.names.items(): + for node in module.names.values(): # We need to filter out functions that are imported or # aliases. The best way to do this seems to be by # checking that the fullname matches. @@ -468,7 +468,7 @@ def prepare_non_ext_class_def( ir = mapper.type_to_ir[cdef.info] info = cdef.info - for name, node in info.names.items(): + for node in info.names.values(): if isinstance(node.node, (FuncDef, Decorator)): prepare_method_def(ir, module_name, cdef, mapper, node.node) elif isinstance(node.node, OverloadedFuncDef): diff --git a/mypyc/primitives/registry.py b/mypyc/primitives/registry.py index aa96b35aec56..11fca7dc2c70 100644 --- a/mypyc/primitives/registry.py +++ b/mypyc/primitives/registry.py @@ -93,7 +93,7 @@ def method_op( var_arg_type: RType | None = None, truncated_type: RType | None = None, ordering: list[int] | None = None, - extra_int_constants: list[tuple[int, RType]] = [], + extra_int_constants: list[tuple[int, RType]] | None = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1, @@ -122,6 +122,8 @@ def method_op( is_borrowed: if True, returned value is borrowed (no need to decrease refcount) priority: if multiple ops match, the one with the highest priority is picked """ + if extra_int_constants is None: + extra_int_constants = [] ops = method_call_ops.setdefault(name, []) desc = CFunctionDescription( name, @@ -150,7 +152,7 @@ def function_op( var_arg_type: RType | None = None, truncated_type: RType | None = None, ordering: list[int] | None = None, - extra_int_constants: list[tuple[int, RType]] = [], + extra_int_constants: list[tuple[int, RType]] | None = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1, @@ -165,6 +167,8 @@ def function_op( name: full name of the function arg_types: positional argument types for which this applies """ + if extra_int_constants is None: + extra_int_constants = [] ops = function_ops.setdefault(name, []) desc = CFunctionDescription( name, @@ -193,7 +197,7 @@ def binary_op( var_arg_type: RType | None = None, truncated_type: RType | None = None, ordering: list[int] | None = None, - extra_int_constants: list[tuple[int, RType]] = [], + extra_int_constants: list[tuple[int, RType]] | None = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1, @@ -205,6 +209,8 @@ def binary_op( Most arguments are similar to method_op(), but exactly two argument types are expected. """ + if extra_int_constants is None: + extra_int_constants = [] ops = binary_ops.setdefault(name, []) desc = CFunctionDescription( name, @@ -232,7 +238,7 @@ def custom_op( var_arg_type: RType | None = None, truncated_type: RType | None = None, ordering: list[int] | None = None, - extra_int_constants: list[tuple[int, RType]] = [], + extra_int_constants: list[tuple[int, RType]] | None = None, steals: StealsDescription = False, is_borrowed: bool = False, ) -> CFunctionDescription: @@ -240,6 +246,8 @@ def custom_op( Most arguments are similar to method_op(). """ + if extra_int_constants is None: + extra_int_constants = [] return CFunctionDescription( "", arg_types, @@ -264,7 +272,7 @@ def unary_op( error_kind: int, truncated_type: RType | None = None, ordering: list[int] | None = None, - extra_int_constants: list[tuple[int, RType]] = [], + extra_int_constants: list[tuple[int, RType]] | None = None, steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1, @@ -276,6 +284,8 @@ def unary_op( Most arguments are similar to method_op(), but exactly one argument type is expected. """ + if extra_int_constants is None: + extra_int_constants = [] ops = unary_ops.setdefault(name, []) desc = CFunctionDescription( name, diff --git a/pyproject.toml b/pyproject.toml index c43253fed982..5fc0cee3f65c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,24 +33,29 @@ fix = true select = [ "E", # pycodestyle (error) "F", # pyflakes + "W", # pycodestyle (warning) "B", # flake8-bugbear "I", # isort "RUF100", # Unused noqa comments "PGH004", # blanket noqa comments "UP", # pyupgrade + "C4", # flake8-comprehensions + "SIM201", "SIM202", # simplify comparisons involving not + "ISC001", # implicitly concatenated string + "RET501", "RET502", # better return None handling ] ignore = [ - "B006", # use of mutable defaults in function signatures "B007", # Loop control variable not used within the loop body. "B011", # Don't use assert False "B023", # Function definition does not bind loop variable - "E203", # conflicts with black + "E2", # conflicts with black "E402", # module level import not at top of file "E501", # conflicts with black "E731", # Do not assign a `lambda` expression, use a `def` "E741", # Ambiguous variable name "UP032", # 'f-string always preferable to format' is controversial + "C416", # There are a few cases where it's nice to have names for the dict items ] unfixable = [ diff --git a/test-requirements.in b/test-requirements.in index bab3ece29c02..2bf8de0aa2f5 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -14,6 +14,6 @@ psutil>=4.0 pytest>=7.4.0 pytest-xdist>=1.34.0 pytest-cov>=2.10.0 -ruff==0.1.0 # must match version in .pre-commit-config.yaml +ruff==0.1.4 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 tomli>=1.1.0 # needed even on py311+ so the self check passes with --python-version 3.7 diff --git a/test-requirements.txt b/test-requirements.txt index 3bb9cf29635f..57607c1bae57 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -67,7 +67,7 @@ ruamel-yaml==0.17.40 # via pre-commit-hooks ruamel-yaml-clib==0.2.8 # via ruamel-yaml -ruff==0.1.0 +ruff==0.1.4 # via -r test-requirements.in tomli==2.0.1 # via -r test-requirements.in From f9e8e0bda5cfbb54d6a8f9e482aa25da28a1a635 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Mon, 1 Jan 2024 20:15:15 -0800 Subject: [PATCH 23/69] Allow unary + in Literal (#16729) Implements python/typing#1550 Fixes #16727 (a trivial bug I found while implementing this feature) --- mypy/fastparse.py | 16 +++++++++++----- test-data/unit/check-literal.test | 11 ++++++++--- test-data/unit/fixtures/ops.pyi | 4 ++-- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index cba01eab2e4e..13b9b5c8a871 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -126,7 +126,7 @@ import ast as ast3 # TODO: Index, ExtSlice are deprecated in 3.9. -from ast import AST, Attribute, Call, FunctionType, Index, Name, Starred, UnaryOp, USub +from ast import AST, Attribute, Call, FunctionType, Index, Name, Starred, UAdd, UnaryOp, USub def ast3_parse( @@ -1940,13 +1940,19 @@ def visit_Constant(self, n: Constant) -> Type: # UnaryOp(op, operand) def visit_UnaryOp(self, n: UnaryOp) -> Type: - # We support specifically Literal[-4] and nothing else. - # For example, Literal[+4] or Literal[~6] is not supported. + # We support specifically Literal[-4], Literal[+4], and nothing else. + # For example, Literal[~6] or Literal[not False] is not supported. typ = self.visit(n.operand) - if isinstance(typ, RawExpressionType) and isinstance(n.op, USub): - if isinstance(typ.literal_value, int): + if ( + isinstance(typ, RawExpressionType) + # Use type() because we do not want to allow bools. + and type(typ.literal_value) is int # noqa: E721 + ): + if isinstance(n.op, USub): typ.literal_value *= -1 return typ + if isinstance(n.op, UAdd): + return typ return self.invalid_type(n) def numeric_type(self, value: object, n: AST) -> Type: diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index d9ad68385ad1..ea2aa5068e85 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -591,7 +591,6 @@ from typing_extensions import Literal def dummy() -> int: return 3 a: Literal[3 + 4] # E: Invalid type: Literal[...] cannot contain arbitrary expressions b: Literal[" foo ".trim()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions -c: Literal[+42] # E: Invalid type: Literal[...] cannot contain arbitrary expressions d: Literal[~12] # E: Invalid type: Literal[...] cannot contain arbitrary expressions e: Literal[dummy()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions [builtins fixtures/tuple.pyi] @@ -2739,7 +2738,7 @@ def test() -> None: ... [builtins fixtures/bool.pyi] -[case testNegativeIntLiteral] +[case testUnaryOpLiteral] from typing_extensions import Literal a: Literal[-2] = -2 @@ -2747,8 +2746,14 @@ b: Literal[-1] = -1 c: Literal[0] = 0 d: Literal[1] = 1 e: Literal[2] = 2 +f: Literal[+1] = 1 +g: Literal[+2] = 2 + +x: Literal[+True] = True # E: Invalid type: Literal[...] cannot contain arbitrary expressions +y: Literal[-True] = -1 # E: Invalid type: Literal[...] cannot contain arbitrary expressions +z: Literal[~0] = 0 # E: Invalid type: Literal[...] cannot contain arbitrary expressions [out] -[builtins fixtures/float.pyi] +[builtins fixtures/ops.pyi] [case testNegativeIntLiteralWithFinal] from typing_extensions import Literal, Final diff --git a/test-data/unit/fixtures/ops.pyi b/test-data/unit/fixtures/ops.pyi index 9cc4d22eb0a7..df3b163166ad 100644 --- a/test-data/unit/fixtures/ops.pyi +++ b/test-data/unit/fixtures/ops.pyi @@ -24,8 +24,6 @@ class tuple(Sequence[Tco]): class function: pass -class bool: pass - class str: def __init__(self, x: 'int') -> None: pass def __add__(self, x: 'str') -> 'str': pass @@ -54,6 +52,8 @@ class int: def __gt__(self, x: 'int') -> bool: pass def __ge__(self, x: 'int') -> bool: pass +class bool(int): pass + class float: def __add__(self, x: 'float') -> 'float': pass def __radd__(self, x: 'float') -> 'float': pass From a1b4e32785b69291748579d97cb9456e1198ec21 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Tue, 2 Jan 2024 13:02:15 -0800 Subject: [PATCH 24/69] Document how evil `--no-strict-optional` is (#16731) On multiple occasions, I've encountered folks using this, running into issues and then being perplexed when they figure out what `--no-strict-optional` actually does. Most recently in https://github.com/python/mypy/issues/16718#issuecomment-1873374058 This is a non-standard, dangerous option that should not be used in modern typed Python. It's been five and a half years since it was the default behaviour in mypy, so we should deemphasise and warn about its existence. --- docs/source/command_line.rst | 16 ++++---- docs/source/common_issues.rst | 2 +- docs/source/config_file.rst | 9 ++++- docs/source/kinds_of_types.rst | 68 ---------------------------------- 4 files changed, 17 insertions(+), 78 deletions(-) diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index c8e0ef3df11f..4a7ead3e8724 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -415,7 +415,6 @@ None and Optional handling ************************** The following flags adjust how mypy handles values of type ``None``. -For more details, see :ref:`no_strict_optional`. .. _implicit-optional: @@ -435,16 +434,19 @@ For more details, see :ref:`no_strict_optional`. **Note:** This was disabled by default starting in mypy 0.980. +.. _no_strict_optional: + .. option:: --no-strict-optional - This flag disables strict checking of :py:data:`~typing.Optional` + This flag effectively disables checking of :py:data:`~typing.Optional` types and ``None`` values. With this option, mypy doesn't - generally check the use of ``None`` values -- they are valid - everywhere. See :ref:`no_strict_optional` for more about this feature. + generally check the use of ``None`` values -- it is treated + as compatible with every type. + + .. warning:: - **Note:** Strict optional checking was enabled by default starting in - mypy 0.600, and in previous versions it had to be explicitly enabled - using ``--strict-optional`` (which is still accepted). + ``--no-strict-optional`` is evil. Avoid using it and definitely do + not use it without understanding what it does. .. _configuring-warnings: diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index e6570b7eef5b..8cc18c863e45 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -119,7 +119,7 @@ and mypy doesn't complain**. return None # No error! You may have disabled strict optional checking (see -:ref:`no_strict_optional` for more). +:ref:`--no-strict-optional ` for more). .. _silencing_checker: diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index de769200bf2b..910b015df658 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -580,10 +580,15 @@ section of the command line docs. :type: boolean :default: True - Enables or disables strict Optional checks. If False, mypy treats ``None`` + Effectively disables checking of :py:data:`~typing.Optional` + types and ``None`` values. With this option, mypy doesn't + generally check the use of ``None`` values -- it is treated as compatible with every type. - **Note:** This was False by default in mypy versions earlier than 0.600. + .. warning:: + + ``strict_optional = false`` is evil. Avoid using it and definitely do + not use it without understanding what it does. Configuring warnings diff --git a/docs/source/kinds_of_types.rst b/docs/source/kinds_of_types.rst index c3180850f119..d07eb40753f3 100644 --- a/docs/source/kinds_of_types.rst +++ b/docs/source/kinds_of_types.rst @@ -429,74 +429,6 @@ the runtime with some limitations (see :ref:`runtime_troubles`). t2: int | None # equivalent to Optional[int] -.. _no_strict_optional: - -Disabling strict optional checking -********************************** - -Mypy also has an option to treat ``None`` as a valid value for every -type (in case you know Java, it's useful to think of it as similar to -the Java ``null``). In this mode ``None`` is also valid for primitive -types such as ``int`` and ``float``, and :py:data:`~typing.Optional` types are -not required. - -The mode is enabled through the :option:`--no-strict-optional ` command-line -option. In mypy versions before 0.600 this was the default mode. You -can enable this option explicitly for backward compatibility with -earlier mypy versions, in case you don't want to introduce optional -types to your codebase yet. - -It will cause mypy to silently accept some buggy code, such as -this example -- it's not recommended if you can avoid it: - -.. code-block:: python - - def inc(x: int) -> int: - return x + 1 - - x = inc(None) # No error reported by mypy if strict optional mode disabled! - -However, making code "optional clean" can take some work! You can also use -:ref:`the mypy configuration file ` to migrate your code -to strict optional checking one file at a time, since there exists -the per-module flag -:confval:`strict_optional` to control strict optional mode. - -Often it's still useful to document whether a variable can be -``None``. For example, this function accepts a ``None`` argument, -but it's not obvious from its signature: - -.. code-block:: python - - def greeting(name: str) -> str: - if name: - return f'Hello, {name}' - else: - return 'Hello, stranger' - - print(greeting('Python')) # Okay! - print(greeting(None)) # Also okay! - -You can still use :py:data:`Optional[t] ` to document that ``None`` is a -valid argument type, even if strict ``None`` checking is not -enabled: - -.. code-block:: python - - from typing import Optional - - def greeting(name: Optional[str]) -> str: - if name: - return f'Hello, {name}' - else: - return 'Hello, stranger' - -Mypy treats this as semantically equivalent to the previous example -if strict optional checking is disabled, since ``None`` is implicitly -valid for any type, but it's much more -useful for a programmer who is reading the code. This also makes -it easier to migrate to strict ``None`` checking in the future. - .. _type-aliases: Type aliases From fbb738a4626976f83a7412df73533d87483a31b7 Mon Sep 17 00:00:00 2001 From: Ihor <31508183+nautics889@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:40:24 +0200 Subject: [PATCH 25/69] [minor] Fix arg name in classmethod (#16741) --- mypy/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index fe41777c55f7..6c23c51dfcd3 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -1155,7 +1155,7 @@ def serialize(self) -> JsonDict: } @classmethod - def deserialize(self, data: JsonDict) -> ClassDef: + def deserialize(cls, data: JsonDict) -> ClassDef: assert data[".class"] == "ClassDef" res = ClassDef( data["name"], From 35f402c74205d373b81076ea82f507eb85161a25 Mon Sep 17 00:00:00 2001 From: WeilerMarcel Date: Mon, 8 Jan 2024 10:08:32 +0100 Subject: [PATCH 26/69] Support type stub generation for `staticmethod` (#14934) Fixes #13574 This PR fixes the generation of type hints for static methods of pybind11 classes. The code changes are based on the suggestions in #13574. The fix introduces an additional check if the property under inspection is of type `staticmethod`. If it is, the type information is read from the staticmethod's `__func__` attribute, instead of the staticmethod instance itself. I added a test for C++ classes with static methods bound using pybind11. Both, an overloaded and a non-overloaded static method are tested. --- mypy/stubgenc.py | 16 ++++++---- test-data/pybind11_mypy_demo/src/main.cpp | 15 ++++++++++ .../pybind11_mypy_demo/basics.pyi | 30 +++++++++++++++++++ .../stubgen/pybind11_mypy_demo/basics.pyi | 11 +++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 55e46fe0ec25..3bec0c246d9a 100755 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -530,12 +530,14 @@ def is_classmethod(self, class_info: ClassInfo, name: str, obj: object) -> bool: return inspect.ismethod(obj) def is_staticmethod(self, class_info: ClassInfo | None, name: str, obj: object) -> bool: - if self.is_c_module: + if class_info is None: return False + elif self.is_c_module: + raw_lookup: Mapping[str, Any] = getattr(class_info.cls, "__dict__") # noqa: B009 + raw_value = raw_lookup.get(name, obj) + return isinstance(raw_value, staticmethod) else: - return class_info is not None and isinstance( - inspect.getattr_static(class_info.cls, name), staticmethod - ) + return isinstance(inspect.getattr_static(class_info.cls, name), staticmethod) @staticmethod def is_abstract_method(obj: object) -> bool: @@ -761,7 +763,7 @@ def generate_class_stub(self, class_name: str, cls: type, output: list[str]) -> The result lines will be appended to 'output'. If necessary, any required names will be added to 'imports'. """ - raw_lookup = getattr(cls, "__dict__") # noqa: B009 + raw_lookup: Mapping[str, Any] = getattr(cls, "__dict__") # noqa: B009 items = self.get_members(cls) if self.resort_members: items = sorted(items, key=lambda x: method_name_sort_key(x[0])) @@ -793,7 +795,9 @@ def generate_class_stub(self, class_name: str, cls: type, output: list[str]) -> continue attr = "__init__" # FIXME: make this nicer - if self.is_classmethod(class_info, attr, value): + if self.is_staticmethod(class_info, attr, value): + class_info.self_var = "" + elif self.is_classmethod(class_info, attr, value): class_info.self_var = "cls" else: class_info.self_var = "self" diff --git a/test-data/pybind11_mypy_demo/src/main.cpp b/test-data/pybind11_mypy_demo/src/main.cpp index 192a90cf8e30..8be759d51671 100644 --- a/test-data/pybind11_mypy_demo/src/main.cpp +++ b/test-data/pybind11_mypy_demo/src/main.cpp @@ -118,6 +118,13 @@ const Point Point::y_axis = Point(0, 1); Point::LengthUnit Point::length_unit = Point::LengthUnit::mm; Point::AngleUnit Point::angle_unit = Point::AngleUnit::radian; +struct Foo +{ + static int some_static_method(int a, int b) { return a * 42 + b; } + static int overloaded_static_method(int value) { return value * 42; } + static double overloaded_static_method(double value) { return value * 42; } +}; + } // namespace: basics void bind_basics(py::module& basics) { @@ -166,6 +173,14 @@ void bind_basics(py::module& basics) { .value("radian", Point::AngleUnit::radian) .value("degree", Point::AngleUnit::degree); + // Static methods + py::class_ pyFoo(basics, "Foo"); + + pyFoo + .def_static("some_static_method", &Foo::some_static_method, R"#(None)#", py::arg("a"), py::arg("b")) + .def_static("overloaded_static_method", py::overload_cast(&Foo::overloaded_static_method), py::arg("value")) + .def_static("overloaded_static_method", py::overload_cast(&Foo::overloaded_static_method), py::arg("value")); + // Module-level attributes basics.attr("PI") = std::acos(-1); basics.attr("__version__") = "0.0.1"; diff --git a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi index b761291e11f3..3047da622a3e 100644 --- a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi +++ b/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi @@ -3,6 +3,36 @@ from typing import ClassVar, List, overload PI: float __version__: str +class Foo: + def __init__(self, *args, **kwargs) -> None: + """Initialize self. See help(type(self)) for accurate signature.""" + @overload + @staticmethod + def overloaded_static_method(value: int) -> int: + """overloaded_static_method(*args, **kwargs) + Overloaded function. + + 1. overloaded_static_method(value: int) -> int + + 2. overloaded_static_method(value: float) -> float + """ + @overload + @staticmethod + def overloaded_static_method(value: float) -> float: + """overloaded_static_method(*args, **kwargs) + Overloaded function. + + 1. overloaded_static_method(value: int) -> int + + 2. overloaded_static_method(value: float) -> float + """ + @staticmethod + def some_static_method(a: int, b: int) -> int: + """some_static_method(a: int, b: int) -> int + + None + """ + class Point: class AngleUnit: __members__: ClassVar[dict] = ... # read-only diff --git a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi index 6f164a03edcc..f3acb1677e68 100644 --- a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi +++ b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi @@ -3,6 +3,17 @@ from typing import ClassVar, List, overload PI: float __version__: str +class Foo: + def __init__(self, *args, **kwargs) -> None: ... + @overload + @staticmethod + def overloaded_static_method(value: int) -> int: ... + @overload + @staticmethod + def overloaded_static_method(value: float) -> float: ... + @staticmethod + def some_static_method(a: int, b: int) -> int: ... + class Point: class AngleUnit: __members__: ClassVar[dict] = ... # read-only From edebe024cbe8406cdf191cefe111683d0c2849ea Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:08:49 -0800 Subject: [PATCH 27/69] Accept multiline quoted annotations (#16765) See discussion in https://discuss.python.org/t/newlines-within-triple-quoted-type-expressions/42833 --- mypy/fastparse.py | 2 +- test-data/unit/check-basic.test | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 13b9b5c8a871..b3e0fc70a9d6 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -318,7 +318,7 @@ def parse_type_string( string expression "blah" using this function. """ try: - _, node = parse_type_comment(expr_string.strip(), line=line, column=column, errors=None) + _, node = parse_type_comment(f"({expr_string})", line=line, column=column, errors=None) if isinstance(node, UnboundType) and node.original_str_expr is None: node.original_str_expr = expr_string node.original_str_fallback = expr_fallback_name diff --git a/test-data/unit/check-basic.test b/test-data/unit/check-basic.test index 61a7160ce4f4..7a426c3eca9f 100644 --- a/test-data/unit/check-basic.test +++ b/test-data/unit/check-basic.test @@ -502,3 +502,19 @@ s2: str = 42 # E: Incompatible types in assignment (expression has type "int", s3: str = 42 # E: Incompatible types in assignment (expression has type "int", variable has type "str") [file c.py] s3: str = 'foo' + +[case testMultilineQuotedAnnotation] +x: """ + + int | + str + +""" +reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" + +y: """( + int | + str +) +""" +reveal_type(y) # N: Revealed type is "Union[builtins.int, builtins.str]" From 1fd29ac54a2135ec1d1d30289c625d12e6198eac Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:27:46 -0800 Subject: [PATCH 28/69] stubtest: fix pos-only handling in overload resolution (#16750) --- mypy/stubtest.py | 7 ++++- mypy/test/teststubtest.py | 58 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index e7cc24f33d18..6061e98bd7cd 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -826,7 +826,10 @@ def from_overloadedfuncdef(stub: nodes.OverloadedFuncDef) -> Signature[nodes.Arg # argument. To accomplish this, we just make up a fake index-based name. name = ( f"__{index}" - if arg.variable.name.startswith("__") or assume_positional_only + if arg.variable.name.startswith("__") + or arg.pos_only + or assume_positional_only + or arg.variable.name.strip("_") == "self" else arg.variable.name ) all_args.setdefault(name, []).append((arg, index)) @@ -870,6 +873,7 @@ def get_kind(arg_name: str) -> nodes.ArgKind: type_annotation=None, initializer=None, kind=get_kind(arg_name), + pos_only=all(arg.pos_only for arg, _ in all_args[arg_name]), ) if arg.kind.is_positional(): sig.pos.append(arg) @@ -905,6 +909,7 @@ def _verify_signature( if ( runtime_arg.kind != inspect.Parameter.POSITIONAL_ONLY and (stub_arg.pos_only or stub_arg.variable.name.startswith("__")) + and stub_arg.variable.name.strip("_") != "self" and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 72b6f6620f83..c0bb2eb6f9da 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -210,7 +210,13 @@ def test(*args: Any, **kwargs: Any) -> None: ) actual_errors = set(output.splitlines()) - assert actual_errors == expected_errors, output + if actual_errors != expected_errors: + output = run_stubtest( + stub="\n\n".join(textwrap.dedent(c.stub.lstrip("\n")) for c in cases), + runtime="\n\n".join(textwrap.dedent(c.runtime.lstrip("\n")) for c in cases), + options=[], + ) + assert actual_errors == expected_errors, output return test @@ -660,6 +666,56 @@ def f6(self, x, /): pass """, error=None, ) + yield Case( + stub=""" + @overload + def f7(a: int, /) -> int: ... + @overload + def f7(b: str, /) -> str: ... + """, + runtime="def f7(x, /): pass", + error=None, + ) + yield Case( + stub=""" + @overload + def f8(a: int, c: int = 0, /) -> int: ... + @overload + def f8(b: str, d: int, /) -> str: ... + """, + runtime="def f8(x, y, /): pass", + error="f8", + ) + yield Case( + stub=""" + @overload + def f9(a: int, c: int = 0, /) -> int: ... + @overload + def f9(b: str, d: int, /) -> str: ... + """, + runtime="def f9(x, y=0, /): pass", + error=None, + ) + yield Case( + stub=""" + class Bar: + @overload + def f1(self) -> int: ... + @overload + def f1(self, a: int, /) -> int: ... + + @overload + def f2(self, a: int, /) -> int: ... + @overload + def f2(self, a: str, /) -> int: ... + """, + runtime=""" + class Bar: + def f1(self, *a) -> int: ... + def f2(self, *a) -> int: ... + """, + error=None, + ) @collect_cases def test_property(self) -> Iterator[Case]: From a8741d8fda2695e189add60b1cfc4adebd2c3e1e Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Sat, 13 Jan 2024 16:14:16 +0100 Subject: [PATCH 29/69] Improve stubgen tests (#16760) Improve test cases around #16486 This PR does not change any actual mypy behavior, only hardens the stubgen tests. The specific changes are: - **dedicated test cases**: The existing pybind11 test cases originate from a pybind11 demo. They cover a specific topic involving geometry types and semi-implemented logic related to it. This somehow distracts from the aspects we are trying to test here from the mypy stubgen perspective, because it hides the actual intent of the bindings. I've simply started adding new test cases that clearly express via their name what the test case is addressing. I've kept the original demo stuff for now, so that the new cases are just an addition (overhead is negligible). - **running mypy on the generated stubs**: In general it is crucial that the output produced by the stubgen can actually be type checked by mypy (this was the regression in #18486). This wasn't covered by the CI check so far. I've added check now, which would have avoided the regression. My goal for follow up PRs would be that we can use `mypy --disallow-untyped-defs` or even `mypy --strict` on the output. - **minor directory restructuring**: So far the expected stub outputs were stored in folder names `stubgen` and `stubgen-include-docs`. This was a bit confusing, because the folder `stubgen` suggested it contains _the_ stubgen (implementation). I went for `expected_stubs_no_docs` and `expected_stubs_with_docs` to make the role of the two folders more explicit. - **minor script bugfix**: Fix a bug in `test-stubgen.sh`: The pre-delete functionality was broken, because the `*` was quoted and therefore did not match. --- .github/workflows/test_stubgenc.yml | 2 +- misc/test-stubgenc.sh | 20 ++- .../pybind11_fixtures/__init__.pyi | 27 ++++ .../pybind11_fixtures/demo.pyi} | 11 -- .../pybind11_fixtures/__init__.pyi | 52 +++++++ .../pybind11_fixtures/demo.pyi} | 60 ++------ .../pyproject.toml | 0 .../setup.py | 4 +- .../src/main.cpp | 143 ++++++++++++++---- .../pybind11_mypy_demo/__init__.pyi | 1 - .../stubgen/pybind11_mypy_demo/__init__.pyi | 1 - 11 files changed, 227 insertions(+), 94 deletions(-) create mode 100644 test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi rename test-data/{pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi => pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi} (86%) create mode 100644 test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi rename test-data/{pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi => pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi} (57%) rename test-data/{pybind11_mypy_demo => pybind11_fixtures}/pyproject.toml (100%) rename test-data/{pybind11_mypy_demo => pybind11_fixtures}/setup.py (85%) rename test-data/{pybind11_mypy_demo => pybind11_fixtures}/src/main.cpp (61%) delete mode 100644 test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/__init__.pyi delete mode 100644 test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi diff --git a/.github/workflows/test_stubgenc.yml b/.github/workflows/test_stubgenc.yml index a2fb3e9dce6b..3daf01372d2d 100644 --- a/.github/workflows/test_stubgenc.yml +++ b/.github/workflows/test_stubgenc.yml @@ -1,4 +1,4 @@ -name: Test stubgenc on pybind11-mypy-demo +name: Test stubgenc on pybind11_fixtures on: workflow_dispatch: diff --git a/misc/test-stubgenc.sh b/misc/test-stubgenc.sh index 5cb5140eba76..ad66722628d8 100755 --- a/misc/test-stubgenc.sh +++ b/misc/test-stubgenc.sh @@ -7,7 +7,7 @@ cd "$(dirname "$0")/.." # Install dependencies, demo project and mypy python -m pip install -r test-requirements.txt -python -m pip install ./test-data/pybind11_mypy_demo +python -m pip install ./test-data/pybind11_fixtures python -m pip install . EXIT=0 @@ -17,19 +17,29 @@ EXIT=0 # everything else is passed to stubgen as its arguments function stubgenc_test() { # Remove expected stubs and generate new inplace - STUBGEN_OUTPUT_FOLDER=./test-data/pybind11_mypy_demo/$1 - rm -rf "${STUBGEN_OUTPUT_FOLDER:?}/*" + STUBGEN_OUTPUT_FOLDER=./test-data/pybind11_fixtures/$1 + rm -rf "${STUBGEN_OUTPUT_FOLDER:?}" + stubgen -o "$STUBGEN_OUTPUT_FOLDER" "${@:2}" + # Check if generated stubs can actually be type checked by mypy + if ! mypy "$STUBGEN_OUTPUT_FOLDER"; + then + echo "Stubgen test failed, because generated stubs failed to type check." + EXIT=1 + fi + # Compare generated stubs to expected ones if ! git diff --exit-code "$STUBGEN_OUTPUT_FOLDER"; then + echo "Stubgen test failed, because generated stubs differ from expected outputs." EXIT=1 fi } # create stubs without docstrings -stubgenc_test stubgen -p pybind11_mypy_demo +stubgenc_test expected_stubs_no_docs -p pybind11_fixtures # create stubs with docstrings -stubgenc_test stubgen-include-docs -p pybind11_mypy_demo --include-docstrings +stubgenc_test expected_stubs_with_docs -p pybind11_fixtures --include-docstrings + exit $EXIT diff --git a/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi new file mode 100644 index 000000000000..e113d8a69a5d --- /dev/null +++ b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi @@ -0,0 +1,27 @@ +import os +from . import demo as demo +from typing import List, Optional, Tuple, overload + +class StaticMethods: + def __init__(self, *args, **kwargs) -> None: ... + @overload + @staticmethod + def overloaded_static_method(value: int) -> int: ... + @overload + @staticmethod + def overloaded_static_method(value: float) -> float: ... + @staticmethod + def some_static_method(a: int, b: int) -> int: ... + +class TestStruct: + field_readwrite: int + field_readwrite_docstring: int + def __init__(self, *args, **kwargs) -> None: ... + @property + def field_readonly(self) -> int: ... + +def func_incomplete_signature(*args, **kwargs): ... +def func_returning_optional() -> Optional[int]: ... +def func_returning_pair() -> Tuple[int, float]: ... +def func_returning_path() -> os.PathLike: ... +def func_returning_vector() -> List[float]: ... diff --git a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi similarity index 86% rename from test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi rename to test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi index f3acb1677e68..6f164a03edcc 100644 --- a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi @@ -3,17 +3,6 @@ from typing import ClassVar, List, overload PI: float __version__: str -class Foo: - def __init__(self, *args, **kwargs) -> None: ... - @overload - @staticmethod - def overloaded_static_method(value: int) -> int: ... - @overload - @staticmethod - def overloaded_static_method(value: float) -> float: ... - @staticmethod - def some_static_method(a: int, b: int) -> int: ... - class Point: class AngleUnit: __members__: ClassVar[dict] = ... # read-only diff --git a/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi new file mode 100644 index 000000000000..1dabb0d9a330 --- /dev/null +++ b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi @@ -0,0 +1,52 @@ +import os +from . import demo as demo +from typing import List, Optional, Tuple, overload + +class StaticMethods: + def __init__(self, *args, **kwargs) -> None: + """Initialize self. See help(type(self)) for accurate signature.""" + @overload + @staticmethod + def overloaded_static_method(value: int) -> int: + """overloaded_static_method(*args, **kwargs) + Overloaded function. + + 1. overloaded_static_method(value: int) -> int + + 2. overloaded_static_method(value: float) -> float + """ + @overload + @staticmethod + def overloaded_static_method(value: float) -> float: + """overloaded_static_method(*args, **kwargs) + Overloaded function. + + 1. overloaded_static_method(value: int) -> int + + 2. overloaded_static_method(value: float) -> float + """ + @staticmethod + def some_static_method(a: int, b: int) -> int: + """some_static_method(a: int, b: int) -> int + + None + """ + +class TestStruct: + field_readwrite: int + field_readwrite_docstring: int + def __init__(self, *args, **kwargs) -> None: + """Initialize self. See help(type(self)) for accurate signature.""" + @property + def field_readonly(self) -> int: ... + +def func_incomplete_signature(*args, **kwargs): + """func_incomplete_signature() -> dummy_sub_namespace::HasNoBinding""" +def func_returning_optional() -> Optional[int]: + """func_returning_optional() -> Optional[int]""" +def func_returning_pair() -> Tuple[int, float]: + """func_returning_pair() -> Tuple[int, float]""" +def func_returning_path() -> os.PathLike: + """func_returning_path() -> os.PathLike""" +def func_returning_vector() -> List[float]: + """func_returning_vector() -> List[float]""" diff --git a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi similarity index 57% rename from test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi rename to test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi index 3047da622a3e..1527225ed009 100644 --- a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/basics.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi @@ -3,36 +3,6 @@ from typing import ClassVar, List, overload PI: float __version__: str -class Foo: - def __init__(self, *args, **kwargs) -> None: - """Initialize self. See help(type(self)) for accurate signature.""" - @overload - @staticmethod - def overloaded_static_method(value: int) -> int: - """overloaded_static_method(*args, **kwargs) - Overloaded function. - - 1. overloaded_static_method(value: int) -> int - - 2. overloaded_static_method(value: float) -> float - """ - @overload - @staticmethod - def overloaded_static_method(value: float) -> float: - """overloaded_static_method(*args, **kwargs) - Overloaded function. - - 1. overloaded_static_method(value: int) -> int - - 2. overloaded_static_method(value: float) -> float - """ - @staticmethod - def some_static_method(a: int, b: int) -> int: - """some_static_method(a: int, b: int) -> int - - None - """ - class Point: class AngleUnit: __members__: ClassVar[dict] = ... # read-only @@ -40,15 +10,15 @@ class Point: degree: ClassVar[Point.AngleUnit] = ... radian: ClassVar[Point.AngleUnit] = ... def __init__(self, value: int) -> None: - """__init__(self: pybind11_mypy_demo.basics.Point.AngleUnit, value: int) -> None""" + """__init__(self: pybind11_fixtures.demo.Point.AngleUnit, value: int) -> None""" def __eq__(self, other: object) -> bool: """__eq__(self: object, other: object) -> bool""" def __hash__(self) -> int: """__hash__(self: object) -> int""" def __index__(self) -> int: - """__index__(self: pybind11_mypy_demo.basics.Point.AngleUnit) -> int""" + """__index__(self: pybind11_fixtures.demo.Point.AngleUnit) -> int""" def __int__(self) -> int: - """__int__(self: pybind11_mypy_demo.basics.Point.AngleUnit) -> int""" + """__int__(self: pybind11_fixtures.demo.Point.AngleUnit) -> int""" def __ne__(self, other: object) -> bool: """__ne__(self: object, other: object) -> bool""" @property @@ -63,15 +33,15 @@ class Point: mm: ClassVar[Point.LengthUnit] = ... pixel: ClassVar[Point.LengthUnit] = ... def __init__(self, value: int) -> None: - """__init__(self: pybind11_mypy_demo.basics.Point.LengthUnit, value: int) -> None""" + """__init__(self: pybind11_fixtures.demo.Point.LengthUnit, value: int) -> None""" def __eq__(self, other: object) -> bool: """__eq__(self: object, other: object) -> bool""" def __hash__(self) -> int: """__hash__(self: object) -> int""" def __index__(self) -> int: - """__index__(self: pybind11_mypy_demo.basics.Point.LengthUnit) -> int""" + """__index__(self: pybind11_fixtures.demo.Point.LengthUnit) -> int""" def __int__(self) -> int: - """__int__(self: pybind11_mypy_demo.basics.Point.LengthUnit) -> int""" + """__int__(self: pybind11_fixtures.demo.Point.LengthUnit) -> int""" def __ne__(self, other: object) -> bool: """__ne__(self: object, other: object) -> bool""" @property @@ -90,38 +60,38 @@ class Point: """__init__(*args, **kwargs) Overloaded function. - 1. __init__(self: pybind11_mypy_demo.basics.Point) -> None + 1. __init__(self: pybind11_fixtures.demo.Point) -> None - 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None + 2. __init__(self: pybind11_fixtures.demo.Point, x: float, y: float) -> None """ @overload def __init__(self, x: float, y: float) -> None: """__init__(*args, **kwargs) Overloaded function. - 1. __init__(self: pybind11_mypy_demo.basics.Point) -> None + 1. __init__(self: pybind11_fixtures.demo.Point) -> None - 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None + 2. __init__(self: pybind11_fixtures.demo.Point, x: float, y: float) -> None """ def as_list(self) -> List[float]: - """as_list(self: pybind11_mypy_demo.basics.Point) -> List[float]""" + """as_list(self: pybind11_fixtures.demo.Point) -> List[float]""" @overload def distance_to(self, x: float, y: float) -> float: """distance_to(*args, **kwargs) Overloaded function. - 1. distance_to(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> float + 1. distance_to(self: pybind11_fixtures.demo.Point, x: float, y: float) -> float - 2. distance_to(self: pybind11_mypy_demo.basics.Point, other: pybind11_mypy_demo.basics.Point) -> float + 2. distance_to(self: pybind11_fixtures.demo.Point, other: pybind11_fixtures.demo.Point) -> float """ @overload def distance_to(self, other: Point) -> float: """distance_to(*args, **kwargs) Overloaded function. - 1. distance_to(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> float + 1. distance_to(self: pybind11_fixtures.demo.Point, x: float, y: float) -> float - 2. distance_to(self: pybind11_mypy_demo.basics.Point, other: pybind11_mypy_demo.basics.Point) -> float + 2. distance_to(self: pybind11_fixtures.demo.Point, other: pybind11_fixtures.demo.Point) -> float """ @property def length(self) -> float: ... diff --git a/test-data/pybind11_mypy_demo/pyproject.toml b/test-data/pybind11_fixtures/pyproject.toml similarity index 100% rename from test-data/pybind11_mypy_demo/pyproject.toml rename to test-data/pybind11_fixtures/pyproject.toml diff --git a/test-data/pybind11_mypy_demo/setup.py b/test-data/pybind11_fixtures/setup.py similarity index 85% rename from test-data/pybind11_mypy_demo/setup.py rename to test-data/pybind11_fixtures/setup.py index 0da1cfbcef19..e227b49935ea 100644 --- a/test-data/pybind11_mypy_demo/setup.py +++ b/test-data/pybind11_fixtures/setup.py @@ -5,14 +5,14 @@ # Documentation: https://pybind11.readthedocs.io/en/stable/compiling.html ext_modules = [ Pybind11Extension( - "pybind11_mypy_demo", + "pybind11_fixtures", ["src/main.cpp"], cxx_std=17, ), ] setup( - name="pybind11-mypy-demo", + name="pybind11_fixtures", version="0.0.1", ext_modules=ext_modules, ) diff --git a/test-data/pybind11_mypy_demo/src/main.cpp b/test-data/pybind11_fixtures/src/main.cpp similarity index 61% rename from test-data/pybind11_mypy_demo/src/main.cpp rename to test-data/pybind11_fixtures/src/main.cpp index 8be759d51671..4d275ab1fd70 100644 --- a/test-data/pybind11_mypy_demo/src/main.cpp +++ b/test-data/pybind11_fixtures/src/main.cpp @@ -43,12 +43,106 @@ */ #include +#include +#include +#include +#include + #include #include +#include namespace py = pybind11; -namespace basics { +// ---------------------------------------------------------------------------- +// Dedicated test cases +// ---------------------------------------------------------------------------- + +std::vector funcReturningVector() +{ + return std::vector{1.0, 2.0, 3.0}; +} + +std::pair funcReturningPair() +{ + return std::pair{42, 1.0}; +} + +std::optional funcReturningOptional() +{ + return std::nullopt; +} + +std::filesystem::path funcReturningPath() +{ + return std::filesystem::path{"foobar"}; +} + +namespace dummy_sub_namespace { + struct HasNoBinding{}; +} + +// We can enforce the case of an incomplete signature by referring to a type in +// some namespace that doesn't have a pybind11 binding. +dummy_sub_namespace::HasNoBinding funcIncompleteSignature() +{ + return dummy_sub_namespace::HasNoBinding{}; +} + +struct TestStruct +{ + int field_readwrite; + int field_readwrite_docstring; + int field_readonly; +}; + +struct StaticMethods +{ + static int some_static_method(int a, int b) { return 42; } + static int overloaded_static_method(int value) { return 42; } + static double overloaded_static_method(double value) { return 1.0; } +}; + +// Bindings + +void bind_test_cases(py::module& m) { + m.def("func_returning_vector", &funcReturningVector); + m.def("func_returning_pair", &funcReturningPair); + m.def("func_returning_optional", &funcReturningOptional); + m.def("func_returning_path", &funcReturningPath); + + m.def("func_incomplete_signature", &funcIncompleteSignature); + + py::class_(m, "TestStruct") + .def_readwrite("field_readwrite", &TestStruct::field_readwrite) + .def_readwrite("field_readwrite_docstring", &TestStruct::field_readwrite_docstring, "some docstring") + .def_property_readonly( + "field_readonly", + [](const TestStruct& x) { + return x.field_readonly; + }, + "some docstring"); + + // Static methods + py::class_ pyStaticMethods(m, "StaticMethods"); + + pyStaticMethods + .def_static( + "some_static_method", + &StaticMethods::some_static_method, R"#(None)#", py::arg("a"), py::arg("b")) + .def_static( + "overloaded_static_method", + py::overload_cast(&StaticMethods::overloaded_static_method), py::arg("value")) + .def_static( + "overloaded_static_method", + py::overload_cast(&StaticMethods::overloaded_static_method), py::arg("value")); +} + +// ---------------------------------------------------------------------------- +// Original demo +// ---------------------------------------------------------------------------- + +namespace demo { int answer() { return 42; @@ -118,27 +212,22 @@ const Point Point::y_axis = Point(0, 1); Point::LengthUnit Point::length_unit = Point::LengthUnit::mm; Point::AngleUnit Point::angle_unit = Point::AngleUnit::radian; -struct Foo -{ - static int some_static_method(int a, int b) { return a * 42 + b; } - static int overloaded_static_method(int value) { return value * 42; } - static double overloaded_static_method(double value) { return value * 42; } -}; +} // namespace: demo -} // namespace: basics +// Bindings -void bind_basics(py::module& basics) { +void bind_demo(py::module& m) { - using namespace basics; + using namespace demo; // Functions - basics.def("answer", &answer, "answer docstring, with end quote\""); // tests explicit docstrings - basics.def("sum", &sum, "multiline docstring test, edge case quotes \"\"\"'''"); - basics.def("midpoint", &midpoint, py::arg("left"), py::arg("right")); - basics.def("weighted_midpoint", weighted_midpoint, py::arg("left"), py::arg("right"), py::arg("alpha")=0.5); + m.def("answer", &answer, "answer docstring, with end quote\""); // tests explicit docstrings + m.def("sum", &sum, "multiline docstring test, edge case quotes \"\"\"'''"); + m.def("midpoint", &midpoint, py::arg("left"), py::arg("right")); + m.def("weighted_midpoint", weighted_midpoint, py::arg("left"), py::arg("right"), py::arg("alpha")=0.5); // Classes - py::class_ pyPoint(basics, "Point"); + py::class_ pyPoint(m, "Point"); py::enum_ pyLengthUnit(pyPoint, "LengthUnit"); py::enum_ pyAngleUnit(pyPoint, "AngleUnit"); @@ -173,20 +262,18 @@ void bind_basics(py::module& basics) { .value("radian", Point::AngleUnit::radian) .value("degree", Point::AngleUnit::degree); - // Static methods - py::class_ pyFoo(basics, "Foo"); - - pyFoo - .def_static("some_static_method", &Foo::some_static_method, R"#(None)#", py::arg("a"), py::arg("b")) - .def_static("overloaded_static_method", py::overload_cast(&Foo::overloaded_static_method), py::arg("value")) - .def_static("overloaded_static_method", py::overload_cast(&Foo::overloaded_static_method), py::arg("value")); - // Module-level attributes - basics.attr("PI") = std::acos(-1); - basics.attr("__version__") = "0.0.1"; + m.attr("PI") = std::acos(-1); + m.attr("__version__") = "0.0.1"; } -PYBIND11_MODULE(pybind11_mypy_demo, m) { - auto basics = m.def_submodule("basics"); - bind_basics(basics); +// ---------------------------------------------------------------------------- +// Module entry point +// ---------------------------------------------------------------------------- + +PYBIND11_MODULE(pybind11_fixtures, m) { + bind_test_cases(m); + + auto demo = m.def_submodule("demo"); + bind_demo(demo); } diff --git a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/__init__.pyi b/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/__init__.pyi deleted file mode 100644 index 0cb252f00259..000000000000 --- a/test-data/pybind11_mypy_demo/stubgen-include-docs/pybind11_mypy_demo/__init__.pyi +++ /dev/null @@ -1 +0,0 @@ -from . import basics as basics diff --git a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi deleted file mode 100644 index 0cb252f00259..000000000000 --- a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi +++ /dev/null @@ -1 +0,0 @@ -from . import basics as basics From e28925ddd34fd128d509b5b4741789578462cbe0 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sat, 13 Jan 2024 16:58:37 +0100 Subject: [PATCH 30/69] stubgen: use PEP 604 unions everywhere (#16519) Fixes #12920 --- mypy/stubgen.py | 22 ++++++++++------------ mypy/stubutil.py | 25 +++++++++++++++++-------- test-data/unit/stubgen.test | 30 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 7ec3d7069fb2..e753fd1e73d5 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -22,7 +22,7 @@ => Generate out/urllib/parse.pyi. $ stubgen -p urllib - => Generate stubs for whole urlib package (recursively). + => Generate stubs for whole urllib package (recursively). For C modules, you can get more precise function signatures by parsing .rst (Sphinx) documentation for extra information. For this, use the --doc-dir option: @@ -306,6 +306,13 @@ def visit_str_expr(self, node: StrExpr) -> str: return repr(node.value) def visit_index_expr(self, node: IndexExpr) -> str: + base_fullname = self.stubgen.get_fullname(node.base) + if base_fullname == "typing.Union": + if isinstance(node.index, TupleExpr): + return " | ".join([item.accept(self) for item in node.index.items]) + return node.index.accept(self) + if base_fullname == "typing.Optional": + return f"{node.index.accept(self)} | None" base = node.base.accept(self) index = node.index.accept(self) if len(index) > 2 and index.startswith("(") and index.endswith(")"): @@ -682,7 +689,7 @@ def process_decorator(self, o: Decorator) -> None: self.add_decorator(qualname, require_name=False) def get_fullname(self, expr: Expression) -> str: - """Return the full name resolving imports and import aliases.""" + """Return the expression's full name.""" if ( self.analyzed and isinstance(expr, (NameExpr, MemberExpr)) @@ -691,16 +698,7 @@ def get_fullname(self, expr: Expression) -> str: ): return expr.fullname name = get_qualified_name(expr) - if "." not in name: - real_module = self.import_tracker.module_for.get(name) - real_short = self.import_tracker.reverse_alias.get(name, name) - if real_module is None and real_short not in self.defined_names: - real_module = "builtins" # not imported and not defined, must be a builtin - else: - name_module, real_short = name.split(".", 1) - real_module = self.import_tracker.reverse_alias.get(name_module, name_module) - resolved_name = real_short if real_module is None else f"{real_module}.{real_short}" - return resolved_name + return self.resolve_name(name) def visit_class_def(self, o: ClassDef) -> None: self._current_class = o diff --git a/mypy/stubutil.py b/mypy/stubutil.py index e4a97964c547..b7f6131c003d 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -226,6 +226,11 @@ def visit_any(self, t: AnyType) -> str: def visit_unbound_type(self, t: UnboundType) -> str: s = t.name + fullname = self.stubgen.resolve_name(s) + if fullname == "typing.Union": + return " | ".join([item.accept(self) for item in t.args]) + if fullname == "typing.Optional": + return f"{t.args[0].accept(self)} | None" if self.known_modules is not None and "." in s: # see if this object is from any of the modules that we're currently processing. # reverse sort so that subpackages come before parents: e.g. "foo.bar" before "foo". @@ -588,14 +593,18 @@ def __init__( def get_sig_generators(self) -> list[SignatureGenerator]: return [] - def refers_to_fullname(self, name: str, fullname: str | tuple[str, ...]) -> bool: - """Return True if the variable name identifies the same object as the given fullname(s).""" - if isinstance(fullname, tuple): - return any(self.refers_to_fullname(name, fname) for fname in fullname) - module, short = fullname.rsplit(".", 1) - return self.import_tracker.module_for.get(name) == module and ( - name == short or self.import_tracker.reverse_alias.get(name) == short - ) + def resolve_name(self, name: str) -> str: + """Return the full name resolving imports and import aliases.""" + if "." not in name: + real_module = self.import_tracker.module_for.get(name) + real_short = self.import_tracker.reverse_alias.get(name, name) + if real_module is None and real_short not in self.defined_names: + real_module = "builtins" # not imported and not defined, must be a builtin + else: + name_module, real_short = name.split(".", 1) + real_module = self.import_tracker.reverse_alias.get(name_module, name_module) + resolved_name = real_short if real_module is None else f"{real_module}.{real_short}" + return resolved_name def add_name(self, fullname: str, require: bool = True) -> str: """Add a name to be imported and return the name reference. diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index cd38242ce031..50437c903530 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4139,3 +4139,33 @@ from dataclasses import dataclass class X(missing.Base): a: int def __init__(self, *selfa_, a, **selfa__) -> None: ... + +[case testAlwaysUsePEP604Union] +import typing +import typing as t +from typing import Optional, Union, Optional as O, Union as U +import x + +union = Union[int, str] +bad_union = Union[int] +nested_union = Optional[Union[int, str]] +not_union = x.Union[int, str] +u = U[int, str] +o = O[int] + +def f1(a: Union["int", Optional[tuple[int, t.Optional[int]]]]) -> int: ... +def f2(a: typing.Union[int | x.Union[int, int], O[float]]) -> int: ... + +[out] +import x +from _typeshed import Incomplete + +union = int | str +bad_union = int +nested_union = int | str | None +not_union: Incomplete +u = int | str +o = int | None + +def f1(a: int | tuple[int, int | None] | None) -> int: ... +def f2(a: int | x.Union[int, int] | float | None) -> int: ... From e64fb9f7fe75d5e5aa722f80576bd2b67b442a4e Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sat, 13 Jan 2024 21:19:44 +0100 Subject: [PATCH 31/69] Fix failing stubgen tests (#16779) --- .github/workflows/test_stubgenc.yml | 1 + .pre-commit-config.yaml | 1 + .../expected_stubs_no_docs/pybind11_fixtures/__init__.pyi | 4 ++-- .../expected_stubs_with_docs/pybind11_fixtures/__init__.pyi | 4 ++-- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test_stubgenc.yml b/.github/workflows/test_stubgenc.yml index 3daf01372d2d..7bdcfdb305bb 100644 --- a/.github/workflows/test_stubgenc.yml +++ b/.github/workflows/test_stubgenc.yml @@ -10,6 +10,7 @@ on: - 'misc/test-stubgenc.sh' - 'mypy/stubgenc.py' - 'mypy/stubdoc.py' + - 'mypy/stubutil.py' - 'test-data/stubgen/**' permissions: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4090bf0ecb4c..0bbd7b3ce382 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,7 @@ repos: rev: 23.9.1 # must match test-requirements.txt hooks: - id: black + exclude: '^(test-data/)' - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.1.4 # must match test-requirements.txt hooks: diff --git a/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi index e113d8a69a5d..bb939aa5a5e7 100644 --- a/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/__init__.pyi @@ -1,6 +1,6 @@ import os from . import demo as demo -from typing import List, Optional, Tuple, overload +from typing import List, Tuple, overload class StaticMethods: def __init__(self, *args, **kwargs) -> None: ... @@ -21,7 +21,7 @@ class TestStruct: def field_readonly(self) -> int: ... def func_incomplete_signature(*args, **kwargs): ... -def func_returning_optional() -> Optional[int]: ... +def func_returning_optional() -> int | None: ... def func_returning_pair() -> Tuple[int, float]: ... def func_returning_path() -> os.PathLike: ... def func_returning_vector() -> List[float]: ... diff --git a/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi index 1dabb0d9a330..622e5881a147 100644 --- a/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/__init__.pyi @@ -1,6 +1,6 @@ import os from . import demo as demo -from typing import List, Optional, Tuple, overload +from typing import List, Tuple, overload class StaticMethods: def __init__(self, *args, **kwargs) -> None: @@ -42,7 +42,7 @@ class TestStruct: def func_incomplete_signature(*args, **kwargs): """func_incomplete_signature() -> dummy_sub_namespace::HasNoBinding""" -def func_returning_optional() -> Optional[int]: +def func_returning_optional() -> int | None: """func_returning_optional() -> Optional[int]""" def func_returning_pair() -> Tuple[int, float]: """func_returning_pair() -> Tuple[int, float]""" From 186ace34432014e668de2ed1449f9262c1e7f056 Mon Sep 17 00:00:00 2001 From: Makonnen Makonnen Date: Sat, 13 Jan 2024 22:05:38 -0500 Subject: [PATCH 32/69] Improve mypy daemon documentation note about local partial types (#16782) The existing documentation almost makes it seem like the user has the option to toggle this. --- docs/source/mypy_daemon.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/mypy_daemon.rst b/docs/source/mypy_daemon.rst index 7586026b6c81..6c511e14eb95 100644 --- a/docs/source/mypy_daemon.rst +++ b/docs/source/mypy_daemon.rst @@ -61,7 +61,7 @@ you have a large codebase.) .. note:: - The mypy daemon automatically enables ``--local-partial-types`` by default. + The mypy daemon requires ``--local-partial-types`` and automatically enables it. Daemon client commands From b1fe23f5a3a4457cae3430acca6e99a36e3efd00 Mon Sep 17 00:00:00 2001 From: anniel-stripe <97691964+anniel-stripe@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:09:24 -0800 Subject: [PATCH 33/69] Support TypedDict functional syntax as class base type (#16703) Fixes https://github.com/python/mypy/issues/16701 This PR allows `TypedDict(...)` calls to be used as a base class. This fixes the error emitted by mypy described in https://github.com/python/mypy/issues/16701 . --- mypy/semanal.py | 8 ++++++++ mypy/semanal_typeddict.py | 19 +++++++++++++++---- test-data/unit/check-typeddict.test | 10 ++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index e0a3db2bff1b..4bf9f0c3eabb 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -2169,8 +2169,16 @@ def analyze_base_classes( if ( isinstance(base_expr, RefExpr) and base_expr.fullname in TYPED_NAMEDTUPLE_NAMES + TPDICT_NAMES + ) or ( + isinstance(base_expr, CallExpr) + and isinstance(base_expr.callee, RefExpr) + and base_expr.callee.fullname in TPDICT_NAMES ): # Ignore magic bases for now. + # For example: + # class Foo(TypedDict): ... # RefExpr + # class Foo(NamedTuple): ... # RefExpr + # class Foo(TypedDict("Foo", {"a": int})): ... # CallExpr continue try: diff --git a/mypy/semanal_typeddict.py b/mypy/semanal_typeddict.py index 67c05fd74273..dbec981bdc96 100644 --- a/mypy/semanal_typeddict.py +++ b/mypy/semanal_typeddict.py @@ -79,6 +79,8 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> tuple[bool, TypeInfo | N """ possible = False for base_expr in defn.base_type_exprs: + if isinstance(base_expr, CallExpr): + base_expr = base_expr.callee if isinstance(base_expr, IndexExpr): base_expr = base_expr.base if isinstance(base_expr, RefExpr): @@ -117,7 +119,13 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> tuple[bool, TypeInfo | N typeddict_bases: list[Expression] = [] typeddict_bases_set = set() for expr in defn.base_type_exprs: - if isinstance(expr, RefExpr) and expr.fullname in TPDICT_NAMES: + ok, maybe_type_info, _ = self.check_typeddict(expr, None, False) + if ok and maybe_type_info is not None: + # expr is a CallExpr + info = maybe_type_info + typeddict_bases_set.add(info.fullname) + typeddict_bases.append(expr) + elif isinstance(expr, RefExpr) and expr.fullname in TPDICT_NAMES: if "TypedDict" not in typeddict_bases_set: typeddict_bases_set.add("TypedDict") else: @@ -176,12 +184,11 @@ def add_keys_and_types_from_base( required_keys: set[str], ctx: Context, ) -> None: + base_args: list[Type] = [] if isinstance(base, RefExpr): assert isinstance(base.node, TypeInfo) info = base.node - base_args: list[Type] = [] - else: - assert isinstance(base, IndexExpr) + elif isinstance(base, IndexExpr): assert isinstance(base.base, RefExpr) assert isinstance(base.base.node, TypeInfo) info = base.base.node @@ -189,6 +196,10 @@ def add_keys_and_types_from_base( if args is None: return base_args = args + else: + assert isinstance(base, CallExpr) + assert isinstance(base.analyzed, TypedDictExpr) + info = base.analyzed.info assert info.typeddict_type is not None base_typed_dict = info.typeddict_type diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index d8022f85574c..625b82936e8c 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -3438,3 +3438,13 @@ class TotalInTheMiddle(TypedDict, a=1, total=True, b=2, c=3): # E: Unexpected k ... [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi] + +[case testCanCreateClassWithFunctionBasedTypedDictBase] +from mypy_extensions import TypedDict + +class Params(TypedDict("Params", {'x': int})): + pass + +p: Params = {'x': 2} +reveal_type(p) # N: Revealed type is "TypedDict('__main__.Params', {'x': builtins.int})" +[builtins fixtures/dict.pyi] From 261e569e2c256451692dd57c05295ef0bcfb34fd Mon Sep 17 00:00:00 2001 From: Christoph Tyralla Date: Sun, 14 Jan 2024 04:15:33 +0100 Subject: [PATCH 34/69] Support narrowing unions that include type[None] (#16315) Fixes #16279 See my comment in the referenced issue. --- mypy/checker.py | 18 +++++--- mypy/checkexpr.py | 19 +++++--- test-data/unit/check-narrowing.test | 70 +++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 12 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 1b57ef780104..cd23e74a8dac 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -7121,9 +7121,10 @@ def conditional_types_with_intersection( possible_target_types = [] for tr in type_ranges: item = get_proper_type(tr.item) - if not isinstance(item, Instance) or tr.is_upper_bound: - return yes_type, no_type - possible_target_types.append(item) + if isinstance(item, (Instance, NoneType)): + possible_target_types.append(item) + if not possible_target_types: + return yes_type, no_type out = [] errors: list[tuple[str, str]] = [] @@ -7131,6 +7132,9 @@ def conditional_types_with_intersection( if not isinstance(v, Instance): return yes_type, no_type for t in possible_target_types: + if isinstance(t, NoneType): + errors.append((f'"{v.type.name}" and "NoneType"', '"NoneType" is final')) + continue intersection = self.intersect_instances((v, t), errors) if intersection is None: continue @@ -7174,7 +7178,11 @@ def get_isinstance_type(self, expr: Expression) -> list[TypeRange] | None: elif isinstance(typ, TypeType): # Type[A] means "any type that is a subtype of A" rather than "precisely type A" # we indicate this by setting is_upper_bound flag - types.append(TypeRange(typ.item, is_upper_bound=True)) + is_upper_bound = True + if isinstance(typ.item, NoneType): + # except for Type[None], because "'NoneType' is not an acceptable base type" + is_upper_bound = False + types.append(TypeRange(typ.item, is_upper_bound=is_upper_bound)) elif isinstance(typ, Instance) and typ.type.fullname == "builtins.type": object_type = Instance(typ.type.mro[-1], []) types.append(TypeRange(object_type, is_upper_bound=True)) @@ -7627,7 +7635,7 @@ def convert_to_typetype(type_map: TypeMap) -> TypeMap: if isinstance(t, TypeVarType): t = t.upper_bound # TODO: should we only allow unions of instances as per PEP 484? - if not isinstance(get_proper_type(t), (UnionType, Instance)): + if not isinstance(get_proper_type(t), (UnionType, Instance, NoneType)): # unknown type; error was likely reported earlier return {} converted_type_map[expr] = TypeType.make_normalized(typ) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 3af8d70e78c9..fbedd95e8fd2 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -385,6 +385,9 @@ def analyze_ref_expr(self, e: RefExpr, lvalue: bool = False) -> Type: if node.typeddict_type: # We special-case TypedDict, because they don't define any constructor. result = self.typeddict_callable(node) + elif node.fullname == "types.NoneType": + # We special case NoneType, because its stub definition is not related to None. + result = TypeType(NoneType()) else: result = type_object_type(node, self.named_type) if isinstance(result, CallableType) and isinstance( # type: ignore[misc] @@ -511,13 +514,13 @@ def visit_call_expr_inner(self, e: CallExpr, allow_none_return: bool = False) -> if is_expr_literal_type(typ): self.msg.cannot_use_function_with_type(e.callee.name, "Literal", e) continue - if ( - node - and isinstance(node.node, TypeAlias) - and isinstance(get_proper_type(node.node.target), AnyType) - ): - self.msg.cannot_use_function_with_type(e.callee.name, "Any", e) - continue + if node and isinstance(node.node, TypeAlias): + target = get_proper_type(node.node.target) + if isinstance(target, AnyType): + self.msg.cannot_use_function_with_type(e.callee.name, "Any", e) + continue + if isinstance(target, NoneType): + continue if ( isinstance(typ, IndexExpr) and isinstance(typ.analyzed, (TypeApplication, TypeAliasExpr)) @@ -4731,6 +4734,8 @@ class LongName(Generic[T]): ... return type_object_type(tuple_fallback(item).type, self.named_type) elif isinstance(item, TypedDictType): return self.typeddict_callable_from_context(item) + elif isinstance(item, NoneType): + return TypeType(item, line=item.line, column=item.column) elif isinstance(item, AnyType): return AnyType(TypeOfAny.from_another_any, source_any=item) else: diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index a2859dfffa3a..d50d1f508b85 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -2022,3 +2022,73 @@ def f(x: Union[int, Sequence[int]]) -> None: ): reveal_type(x) # N: Revealed type is "Tuple[builtins.int, builtins.int]" [builtins fixtures/len.pyi] + +[case testNarrowingIsSubclassNoneType1] +from typing import Type, Union + +def f(cls: Type[Union[None, int]]) -> None: + if issubclass(cls, int): + reveal_type(cls) # N: Revealed type is "Type[builtins.int]" + else: + reveal_type(cls) # N: Revealed type is "Type[None]" +[builtins fixtures/isinstance.pyi] + +[case testNarrowingIsSubclassNoneType2] +from typing import Type, Union + +def f(cls: Type[Union[None, int]]) -> None: + if issubclass(cls, type(None)): + reveal_type(cls) # N: Revealed type is "Type[None]" + else: + reveal_type(cls) # N: Revealed type is "Type[builtins.int]" +[builtins fixtures/isinstance.pyi] + +[case testNarrowingIsSubclassNoneType3] +from typing import Type, Union + +NoneType_ = type(None) + +def f(cls: Type[Union[None, int]]) -> None: + if issubclass(cls, NoneType_): + reveal_type(cls) # N: Revealed type is "Type[None]" + else: + reveal_type(cls) # N: Revealed type is "Type[builtins.int]" +[builtins fixtures/isinstance.pyi] + +[case testNarrowingIsSubclassNoneType4] +# flags: --python-version 3.10 + +from types import NoneType +from typing import Type, Union + +def f(cls: Type[Union[None, int]]) -> None: + if issubclass(cls, NoneType): + reveal_type(cls) # N: Revealed type is "Type[None]" + else: + reveal_type(cls) # N: Revealed type is "Type[builtins.int]" +[builtins fixtures/isinstance.pyi] + +[case testNarrowingIsInstanceNoIntersectionWithFinalTypeAndNoneType] +# flags: --warn-unreachable --python-version 3.10 + +from types import NoneType +from typing import final + +class X: ... +class Y: ... +@final +class Z: ... + +x: X + +if isinstance(x, (Y, Z)): + reveal_type(x) # N: Revealed type is "__main__." +if isinstance(x, (Y, NoneType)): + reveal_type(x) # N: Revealed type is "__main__.1" +if isinstance(x, (Y, Z, NoneType)): + reveal_type(x) # N: Revealed type is "__main__.2" +if isinstance(x, (Z, NoneType)): # E: Subclass of "X" and "Z" cannot exist: "Z" is final \ + # E: Subclass of "X" and "NoneType" cannot exist: "NoneType" is final + reveal_type(x) # E: Statement is unreachable + +[builtins fixtures/isinstance.pyi] From 75b68fa2c0d32bd08b98b00aece20c22d82b1b15 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 14 Jan 2024 18:19:12 +0100 Subject: [PATCH 35/69] stubgen: Do not ignore property deleter (#16781) Fixes #16690 --- mypy/stubgen.py | 2 +- test-data/unit/stubgen.test | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index e753fd1e73d5..1f7a01e6ae3c 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -685,7 +685,7 @@ def process_decorator(self, o: Decorator) -> None: elif fullname in OVERLOAD_NAMES: self.add_decorator(qualname, require_name=True) o.func.is_overload = True - elif qualname.endswith(".setter"): + elif qualname.endswith((".setter", ".deleter")): self.add_decorator(qualname, require_name=False) def get_fullname(self, expr: Expression) -> str: diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 50437c903530..751a1a7fbbcf 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -368,6 +368,8 @@ class A: return 1 @f.setter def f(self, x): ... + @f.deleter + def f(self): ... def h(self): self.f = 1 @@ -377,6 +379,8 @@ class A: def f(self): ... @f.setter def f(self, x) -> None: ... + @f.deleter + def f(self) -> None: ... def h(self) -> None: ... [case testProperty_semanal] @@ -386,6 +390,8 @@ class A: return 1 @f.setter def f(self, x): ... + @f.deleter + def f(self): ... def h(self): self.f = 1 @@ -395,6 +401,8 @@ class A: def f(self): ... @f.setter def f(self, x) -> None: ... + @f.deleter + def f(self) -> None: ... def h(self) -> None: ... -- a read/write property is treated the same as an attribute @@ -2338,10 +2346,12 @@ class B: @property def x(self): return 'x' - @x.setter def x(self, value): self.y = 'y' + @x.deleter + def x(self): + del self.y [out] class A: @@ -2355,6 +2365,8 @@ class B: y: str @x.setter def x(self, value) -> None: ... + @x.deleter + def x(self) -> None: ... [case testMisplacedTypeComment] def f(): From 7eab8a429187ffd2b64bbb9ca29f7d24b262d269 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 21 Jan 2024 21:31:53 -0800 Subject: [PATCH 36/69] stubtest: Add support for setting enum members to "..." (#16807) Unblock python/typeshed#11299 --- mypy/stubtest.py | 7 +++++++ mypy/test/teststubtest.py | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 6061e98bd7cd..9a038105dc82 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1093,6 +1093,13 @@ def verify_var( runtime_type = get_mypy_type_of_runtime_value(runtime.value) if runtime_type is not None and is_subtype_helper(runtime_type, stub.type): should_error = False + # We always allow setting the stub value to ... + proper_type = mypy.types.get_proper_type(stub.type) + if ( + isinstance(proper_type, mypy.types.Instance) + and proper_type.type.fullname == "builtins.ellipsis" + ): + should_error = False if should_error: yield Error( diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index c0bb2eb6f9da..3f231d8afbcc 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1139,6 +1139,25 @@ def baz(x=Flags3(0)): pass """, error=None, ) + yield Case( + runtime=""" + import enum + class SomeObject: ... + + class WeirdEnum(enum.Enum): + a = SomeObject() + b = SomeObject() + """, + stub=""" + import enum + class SomeObject: ... + class WeirdEnum(enum.Enum): + _value_: SomeObject + a = ... + b = ... + """, + error=None, + ) yield Case( stub=""" class Flags4(enum.Flag): From ec06e004426d92637cd0ddd266a464cea723f952 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 24 Jan 2024 19:30:30 +0100 Subject: [PATCH 37/69] Use TypeVar defaults instead of Any when fixing instance types (PEP 696) (#16812) Start using TypeVar defaults when fixing instance types, instead of filling those with `Any`. This PR preserves the way an invalid amount of args is handled. I.e. filling all with `Any` / defaults, instead of cutting off additional args. Thus preserving full backwards compatibility. This can be easily changed later if necessary. `TypeVarTuple` defaults aren't handled correctly yet. Those will require additional logic which would have complicated the change here and made it more difficult to review. Ref: https://github.com/python/mypy/issues/14851 --- mypy/messages.py | 15 ++- mypy/typeanal.py | 87 ++++++++++----- test-data/unit/check-typevar-defaults.test | 123 +++++++++++++++++++++ 3 files changed, 189 insertions(+), 36 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 450faf4c1688..75b8eeb3174c 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -3017,12 +3017,15 @@ def for_function(callee: CallableType) -> str: return "" -def wrong_type_arg_count(n: int, act: str, name: str) -> str: - s = f"{n} type arguments" - if n == 0: - s = "no type arguments" - elif n == 1: - s = "1 type argument" +def wrong_type_arg_count(low: int, high: int, act: str, name: str) -> str: + if low == high: + s = f"{low} type arguments" + if low == 0: + s = "no type arguments" + elif low == 1: + s = "1 type argument" + else: + s = f"between {low} and {high} type arguments" if act == "0": act = "none" return f'"{name}" expects {s}, but {act} given' diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 8a840424f76f..d10f26f5199a 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -9,6 +9,7 @@ from mypy import errorcodes as codes, message_registry, nodes from mypy.errorcodes import ErrorCode +from mypy.expandtype import expand_type from mypy.messages import MessageBuilder, format_type_bare, quote_type_string, wrong_type_arg_count from mypy.nodes import ( ARG_NAMED, @@ -75,6 +76,7 @@ TypeOfAny, TypeQuery, TypeType, + TypeVarId, TypeVarLikeType, TypeVarTupleType, TypeVarType, @@ -1834,14 +1836,14 @@ def get_omitted_any( return any_type -def fix_type_var_tuple_argument(any_type: Type, t: Instance) -> None: +def fix_type_var_tuple_argument(t: Instance) -> None: if t.type.has_type_var_tuple_type: args = list(t.args) assert t.type.type_var_tuple_prefix is not None tvt = t.type.defn.type_vars[t.type.type_var_tuple_prefix] assert isinstance(tvt, TypeVarTupleType) args[t.type.type_var_tuple_prefix] = UnpackType( - Instance(tvt.tuple_fallback.type, [any_type]) + Instance(tvt.tuple_fallback.type, [args[t.type.type_var_tuple_prefix]]) ) t.args = tuple(args) @@ -1855,26 +1857,42 @@ def fix_instance( use_generic_error: bool = False, unexpanded_type: Type | None = None, ) -> None: - """Fix a malformed instance by replacing all type arguments with Any. + """Fix a malformed instance by replacing all type arguments with TypeVar default or Any. Also emit a suitable error if this is not due to implicit Any's. """ - if len(t.args) == 0: - if use_generic_error: - fullname: str | None = None - else: - fullname = t.type.fullname - any_type = get_omitted_any(disallow_any, fail, note, t, options, fullname, unexpanded_type) - t.args = (any_type,) * len(t.type.type_vars) - fix_type_var_tuple_argument(any_type, t) - return - # Construct the correct number of type arguments, as - # otherwise the type checker may crash as it expects - # things to be right. - any_type = AnyType(TypeOfAny.from_error) - t.args = tuple(any_type for _ in t.type.type_vars) - fix_type_var_tuple_argument(any_type, t) - t.invalid = True + arg_count = len(t.args) + min_tv_count = sum(not tv.has_default() for tv in t.type.defn.type_vars) + max_tv_count = len(t.type.type_vars) + if arg_count < min_tv_count or arg_count > max_tv_count: + # Don't use existing args if arg_count doesn't match + t.args = () + + args: list[Type] = [*(t.args[:max_tv_count])] + any_type: AnyType | None = None + env: dict[TypeVarId, Type] = {} + + for tv, arg in itertools.zip_longest(t.type.defn.type_vars, t.args, fillvalue=None): + if tv is None: + continue + if arg is None: + if tv.has_default(): + arg = tv.default + else: + if any_type is None: + fullname = None if use_generic_error else t.type.fullname + any_type = get_omitted_any( + disallow_any, fail, note, t, options, fullname, unexpanded_type + ) + arg = any_type + args.append(arg) + env[tv.id] = arg + t.args = tuple(args) + fix_type_var_tuple_argument(t) + if not t.type.has_type_var_tuple_type: + fixed = expand_type(t, env) + assert isinstance(fixed, Instance) + t.args = fixed.args def instantiate_type_alias( @@ -1963,7 +1981,7 @@ def instantiate_type_alias( if use_standard_error: # This is used if type alias is an internal representation of another type, # for example a generic TypedDict or NamedTuple. - msg = wrong_type_arg_count(exp_len, str(act_len), node.name) + msg = wrong_type_arg_count(exp_len, exp_len, str(act_len), node.name) else: if node.tvar_tuple_index is not None: exp_len_str = f"at least {exp_len - 1}" @@ -2217,24 +2235,27 @@ def validate_instance(t: Instance, fail: MsgCallback, empty_tuple_index: bool) - # TODO: is it OK to fill with TypeOfAny.from_error instead of special form? return False if t.type.has_type_var_tuple_type: - correct = len(t.args) >= len(t.type.type_vars) - 1 + min_tv_count = sum( + not tv.has_default() and not isinstance(tv, TypeVarTupleType) + for tv in t.type.defn.type_vars + ) + correct = len(t.args) >= min_tv_count if any( isinstance(a, UnpackType) and isinstance(get_proper_type(a.type), Instance) for a in t.args ): correct = True - if not correct: - exp_len = f"at least {len(t.type.type_vars) - 1}" + if not t.args: + if not (empty_tuple_index and len(t.type.type_vars) == 1): + # The Any arguments should be set by the caller. + return False + elif not correct: fail( - f"Bad number of arguments, expected: {exp_len}, given: {len(t.args)}", + f"Bad number of arguments, expected: at least {min_tv_count}, given: {len(t.args)}", t, code=codes.TYPE_ARG, ) return False - elif not t.args: - if not (empty_tuple_index and len(t.type.type_vars) == 1): - # The Any arguments should be set by the caller. - return False else: # We also need to check if we are not performing a type variable tuple split. unpack = find_unpack_in_list(t.args) @@ -2254,15 +2275,21 @@ def validate_instance(t: Instance, fail: MsgCallback, empty_tuple_index: bool) - elif any(isinstance(a, UnpackType) for a in t.args): # A variadic unpack in fixed size instance (fixed unpacks must be flattened by the caller) fail(message_registry.INVALID_UNPACK_POSITION, t, code=codes.VALID_TYPE) + t.args = () return False elif len(t.args) != len(t.type.type_vars): # Invalid number of type parameters. - if t.args: + arg_count = len(t.args) + min_tv_count = sum(not tv.has_default() for tv in t.type.defn.type_vars) + max_tv_count = len(t.type.type_vars) + if arg_count and (arg_count < min_tv_count or arg_count > max_tv_count): fail( - wrong_type_arg_count(len(t.type.type_vars), str(len(t.args)), t.type.name), + wrong_type_arg_count(min_tv_count, max_tv_count, str(arg_count), t.type.name), t, code=codes.TYPE_ARG, ) + t.args = () + t.invalid = True return False return True diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 9015d353fa08..c4d258d50ee5 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -116,3 +116,126 @@ def func_c1(x: Union[int, Callable[[Unpack[Ts1]], None]]) -> Tuple[Unpack[Ts1]]: # reveal_type(func_c1(callback1)) # Revealed type is "builtins.tuple[str]" # TODO # reveal_type(func_c1(2)) # Revealed type is "builtins.tuple[builtins.int, builtins.str]" # TODO [builtins fixtures/tuple.pyi] + +[case testTypeVarDefaultsClass1] +from typing import Generic, TypeVar + +T1 = TypeVar("T1") +T2 = TypeVar("T2", default=int) +T3 = TypeVar("T3", default=str) + +class ClassA1(Generic[T2, T3]): ... + +def func_a1( + a: ClassA1, + b: ClassA1[float], + c: ClassA1[float, float], + d: ClassA1[float, float, float], # E: "ClassA1" expects between 0 and 2 type arguments, but 3 given +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassA1[builtins.int, builtins.str]" + reveal_type(b) # N: Revealed type is "__main__.ClassA1[builtins.float, builtins.str]" + reveal_type(c) # N: Revealed type is "__main__.ClassA1[builtins.float, builtins.float]" + reveal_type(d) # N: Revealed type is "__main__.ClassA1[builtins.int, builtins.str]" + +class ClassA2(Generic[T1, T2, T3]): ... + +def func_a2( + a: ClassA2, + b: ClassA2[float], + c: ClassA2[float, float], + d: ClassA2[float, float, float], + e: ClassA2[float, float, float, float], # E: "ClassA2" expects between 1 and 3 type arguments, but 4 given +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassA2[Any, builtins.int, builtins.str]" + reveal_type(b) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.int, builtins.str]" + reveal_type(c) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.float, builtins.str]" + reveal_type(d) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.float, builtins.float]" + reveal_type(e) # N: Revealed type is "__main__.ClassA2[Any, builtins.int, builtins.str]" + +[case testTypeVarDefaultsClass2] +from typing import Generic, ParamSpec + +P1 = ParamSpec("P1") +P2 = ParamSpec("P2", default=[int, str]) +P3 = ParamSpec("P3", default=...) + +class ClassB1(Generic[P2, P3]): ... + +def func_b1( + a: ClassB1, + b: ClassB1[[float]], + c: ClassB1[[float], [float]], + d: ClassB1[[float], [float], [float]], # E: "ClassB1" expects between 0 and 2 type arguments, but 3 given +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], ...]" + reveal_type(b) # N: Revealed type is "__main__.ClassB1[[builtins.float], ...]" + reveal_type(c) # N: Revealed type is "__main__.ClassB1[[builtins.float], [builtins.float]]" + reveal_type(d) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], ...]" + +class ClassB2(Generic[P1, P2]): ... + +def func_b2( + a: ClassB2, + b: ClassB2[[float]], + c: ClassB2[[float], [float]], + d: ClassB2[[float], [float], [float]], # E: "ClassB2" expects between 1 and 2 type arguments, but 3 given +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" + reveal_type(b) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.int, builtins.str]]" + reveal_type(c) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.float]]" + reveal_type(d) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" + +[case testTypeVarDefaultsClass3] +from typing import Generic, Tuple, TypeVar +from typing_extensions import TypeVarTuple, Unpack + +T1 = TypeVar("T1") +T3 = TypeVar("T3", default=str) + +Ts1 = TypeVarTuple("Ts1") +Ts2 = TypeVarTuple("Ts2", default=Unpack[Tuple[int, str]]) +Ts3 = TypeVarTuple("Ts3", default=Unpack[Tuple[float, ...]]) +Ts4 = TypeVarTuple("Ts4", default=Unpack[Tuple[()]]) + +class ClassC1(Generic[Unpack[Ts2]]): ... + +def func_c1( + a: ClassC1, + b: ClassC1[float], +) -> None: + # reveal_type(a) # Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" # TODO + reveal_type(b) # N: Revealed type is "__main__.ClassC1[builtins.float]" + +class ClassC2(Generic[T3, Unpack[Ts3]]): ... + +def func_c2( + a: ClassC2, + b: ClassC2[int], + c: ClassC2[int, Unpack[Tuple[()]]], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassC2[builtins.str, Unpack[builtins.tuple[builtins.float, ...]]]" + # reveal_type(b) # Revealed type is "__main__.ClassC2[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + reveal_type(c) # N: Revealed type is "__main__.ClassC2[builtins.int]" + +class ClassC3(Generic[T3, Unpack[Ts4]]): ... + +def func_c3( + a: ClassC3, + b: ClassC3[int], + c: ClassC3[int, Unpack[Tuple[float]]] +) -> None: + # reveal_type(a) # Revealed type is "__main__.ClassC3[builtins.str]" # TODO + reveal_type(b) # N: Revealed type is "__main__.ClassC3[builtins.int]" + reveal_type(c) # N: Revealed type is "__main__.ClassC3[builtins.int, builtins.float]" + +class ClassC4(Generic[T1, Unpack[Ts1], T3]): ... + +def func_c4( + a: ClassC4, + b: ClassC4[int], + c: ClassC4[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassC4[Any, Unpack[builtins.tuple[Any, ...]], builtins.str]" + # reveal_type(b) # Revealed type is "__main__.ClassC4[builtins.int, builtins.str]" # TODO + reveal_type(c) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" +[builtins fixtures/tuple.pyi] From 3838bff555de4237cb77ef2a191a6791a4d0ae7a Mon Sep 17 00:00:00 2001 From: Aleksi Tarvainen Date: Thu, 25 Jan 2024 15:24:09 +0200 Subject: [PATCH 38/69] Docs: Add missing class instantiation to cheat sheet (#16817) --- docs/source/cheat_sheet_py3.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/cheat_sheet_py3.rst b/docs/source/cheat_sheet_py3.rst index fe5761ca6187..7ae8eeb59d66 100644 --- a/docs/source/cheat_sheet_py3.rst +++ b/docs/source/cheat_sheet_py3.rst @@ -209,6 +209,7 @@ Classes # This will allow access to any A.x, if x is compatible with the return type def __getattr__(self, name: str) -> int: ... + a = A() a.foo = 42 # Works a.bar = 'Ex-parrot' # Fails type checking From 717a263fcb594689ff48b1d1a88a8bc4f10c2652 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sat, 27 Jan 2024 01:20:24 -0800 Subject: [PATCH 39/69] stubtest: adjust symtable logic (#16823) Fixes https://github.com/python/typeshed/issues/11318 --- mypy/stubtest.py | 59 ++++++++++++++++++++------------------- mypy/test/teststubtest.py | 18 ++++++++++++ 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 9a038105dc82..7ab3a2b1e5d0 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -10,6 +10,7 @@ import collections.abc import copy import enum +import functools import importlib import importlib.machinery import inspect @@ -310,35 +311,23 @@ def _verify_exported_names( ) -def _get_imported_symbol_names(runtime: types.ModuleType) -> frozenset[str] | None: - """Retrieve the names in the global namespace which are known to be imported. +@functools.lru_cache +def _module_symbol_table(runtime: types.ModuleType) -> symtable.SymbolTable | None: + """Retrieve the symbol table for the module (or None on failure). - 1). Use inspect to retrieve the source code of the module - 2). Use symtable to parse the source and retrieve names that are known to be imported - from other modules. - - If either of the above steps fails, return `None`. - - Note that if a set of names is returned, - it won't include names imported via `from foo import *` imports. + 1) Use inspect to retrieve the source code of the module + 2) Use symtable to parse the source (and use what symtable knows for its purposes) """ try: source = inspect.getsource(runtime) except (OSError, TypeError, SyntaxError): return None - if not source.strip(): - # The source code for the module was an empty file, - # no point in parsing it with symtable - return frozenset() - try: - module_symtable = symtable.symtable(source, runtime.__name__, "exec") + return symtable.symtable(source, runtime.__name__, "exec") except SyntaxError: return None - return frozenset(sym.get_name() for sym in module_symtable.get_symbols() if sym.is_imported()) - @verify.register(nodes.MypyFile) def verify_mypyfile( @@ -369,25 +358,37 @@ def verify_mypyfile( if not o.module_hidden and (not is_probably_private(m) or hasattr(runtime, m)) } - imported_symbols = _get_imported_symbol_names(runtime) - def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool: """Heuristics to determine whether a name originates from another module.""" obj = getattr(r, attr) if isinstance(obj, types.ModuleType): return False - if callable(obj): - # It's highly likely to be a class or a function if it's callable, - # so the __module__ attribute will give a good indication of which module it comes from + + symbol_table = _module_symbol_table(r) + if symbol_table is not None: try: - obj_mod = obj.__module__ - except Exception: + symbol = symbol_table.lookup(attr) + except KeyError: pass else: - if isinstance(obj_mod, str): - return bool(obj_mod == r.__name__) - if imported_symbols is not None: - return attr not in imported_symbols + if symbol.is_imported(): + # symtable says we got this from another module + return False + # But we can't just return True here, because symtable doesn't know about symbols + # that come from `from module import *` + if symbol.is_assigned(): + # symtable knows we assigned this symbol in the module + return True + + # The __module__ attribute is unreliable for anything except functions and classes, + # but it's our best guess at this point + try: + obj_mod = obj.__module__ + except Exception: + pass + else: + if isinstance(obj_mod, str): + return bool(obj_mod == r.__name__) return True runtime_public_contents = ( diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 3f231d8afbcc..55f35200a7f5 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -1285,6 +1285,24 @@ def test_missing_no_runtime_all(self) -> Iterator[Case]: yield Case(stub="", runtime="from json.scanner import NUMBER_RE", error=None) yield Case(stub="", runtime="from string import ascii_letters", error=None) + @collect_cases + def test_missing_no_runtime_all_terrible(self) -> Iterator[Case]: + yield Case( + stub="", + runtime=""" +import sys +import types +import __future__ +_m = types.SimpleNamespace() +_m.annotations = __future__.annotations +sys.modules["_terrible_stubtest_test_module"] = _m + +from _terrible_stubtest_test_module import * +assert annotations +""", + error=None, + ) + @collect_cases def test_non_public_1(self) -> Iterator[Case]: yield Case( From 09490c890590d1ead414b06a332c7570fd589342 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sun, 28 Jan 2024 02:37:14 +0100 Subject: [PATCH 40/69] Use TypeVar defaults instead of Any when fixing TypeAlias types (PEP 696) (#16825) This PR applies the TypeVar defaults to `TypeAlias` types instead of using `Any` exclusively, similar to https://github.com/python/mypy/pull/16812. Again `TypeVarTuple` defaults aren't handled correctly yet. Ref: https://github.com/python/mypy/issues/14851 --- mypy/checkexpr.py | 1 + mypy/typeanal.py | 104 ++++++++----- test-data/unit/check-typevar-defaults.test | 161 +++++++++++++++++++++ 3 files changed, 232 insertions(+), 34 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index fbedd95e8fd2..a4b66bb9932c 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4711,6 +4711,7 @@ class LongName(Generic[T]): ... item = get_proper_type( set_any_tvars( alias, + [], ctx.line, ctx.column, self.chk.options, diff --git a/mypy/typeanal.py b/mypy/typeanal.py index d10f26f5199a..678407acc3ac 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1927,18 +1927,19 @@ def instantiate_type_alias( if any(unknown_unpack(a) for a in args): # This type is not ready to be validated, because of unknown total count. # Note that we keep the kind of Any for consistency. - return set_any_tvars(node, ctx.line, ctx.column, options, special_form=True) + return set_any_tvars(node, [], ctx.line, ctx.column, options, special_form=True) - exp_len = len(node.alias_tvars) + max_tv_count = len(node.alias_tvars) act_len = len(args) if ( - exp_len > 0 + max_tv_count > 0 and act_len == 0 and not (empty_tuple_index and node.tvar_tuple_index is not None) ): # Interpret bare Alias same as normal generic, i.e., Alias[Any, Any, ...] return set_any_tvars( node, + args, ctx.line, ctx.column, options, @@ -1946,7 +1947,7 @@ def instantiate_type_alias( fail=fail, unexpanded_type=unexpanded_type, ) - if exp_len == 0 and act_len == 0: + if max_tv_count == 0 and act_len == 0: if no_args: assert isinstance(node.target, Instance) # type: ignore[misc] # Note: this is the only case where we use an eager expansion. See more info about @@ -1954,7 +1955,7 @@ def instantiate_type_alias( return Instance(node.target.type, [], line=ctx.line, column=ctx.column) return TypeAliasType(node, [], line=ctx.line, column=ctx.column) if ( - exp_len == 0 + max_tv_count == 0 and act_len > 0 and isinstance(node.target, Instance) # type: ignore[misc] and no_args @@ -1967,32 +1968,48 @@ def instantiate_type_alias( if any(isinstance(a, UnpackType) for a in args): # A variadic unpack in fixed size alias (fixed unpacks must be flattened by the caller) fail(message_registry.INVALID_UNPACK_POSITION, ctx, code=codes.VALID_TYPE) - return set_any_tvars(node, ctx.line, ctx.column, options, from_error=True) - correct = act_len == exp_len + return set_any_tvars(node, [], ctx.line, ctx.column, options, from_error=True) + min_tv_count = sum(not tv.has_default() for tv in node.alias_tvars) + fill_typevars = act_len != max_tv_count + correct = min_tv_count <= act_len <= max_tv_count else: - correct = act_len >= exp_len - 1 + min_tv_count = sum( + not tv.has_default() and not isinstance(tv, TypeVarTupleType) + for tv in node.alias_tvars + ) + correct = act_len >= min_tv_count for a in args: if isinstance(a, UnpackType): unpacked = get_proper_type(a.type) if isinstance(unpacked, Instance) and unpacked.type.fullname == "builtins.tuple": # Variadic tuple is always correct. correct = True - if not correct: - if use_standard_error: - # This is used if type alias is an internal representation of another type, - # for example a generic TypedDict or NamedTuple. - msg = wrong_type_arg_count(exp_len, exp_len, str(act_len), node.name) - else: - if node.tvar_tuple_index is not None: - exp_len_str = f"at least {exp_len - 1}" + fill_typevars = not correct + if fill_typevars: + if not correct: + if use_standard_error: + # This is used if type alias is an internal representation of another type, + # for example a generic TypedDict or NamedTuple. + msg = wrong_type_arg_count(max_tv_count, max_tv_count, str(act_len), node.name) else: - exp_len_str = str(exp_len) - msg = ( - "Bad number of arguments for type alias," - f" expected: {exp_len_str}, given: {act_len}" - ) - fail(msg, ctx, code=codes.TYPE_ARG) - return set_any_tvars(node, ctx.line, ctx.column, options, from_error=True) + if node.tvar_tuple_index is not None: + msg = ( + "Bad number of arguments for type alias," + f" expected: at least {min_tv_count}, given: {act_len}" + ) + elif min_tv_count != max_tv_count: + msg = ( + "Bad number of arguments for type alias," + f" expected between {min_tv_count} and {max_tv_count}, given: {act_len}" + ) + else: + msg = ( + "Bad number of arguments for type alias," + f" expected: {min_tv_count}, given: {act_len}" + ) + fail(msg, ctx, code=codes.TYPE_ARG) + args = [] + return set_any_tvars(node, args, ctx.line, ctx.column, options, from_error=True) elif node.tvar_tuple_index is not None: # We also need to check if we are not performing a type variable tuple split. unpack = find_unpack_in_list(args) @@ -2006,7 +2023,7 @@ def instantiate_type_alias( act_suffix = len(args) - unpack - 1 if act_prefix < exp_prefix or act_suffix < exp_suffix: fail("TypeVarTuple cannot be split", ctx, code=codes.TYPE_ARG) - return set_any_tvars(node, ctx.line, ctx.column, options, from_error=True) + return set_any_tvars(node, [], ctx.line, ctx.column, options, from_error=True) # TODO: we need to check args validity w.r.t alias.alias_tvars. # Otherwise invalid instantiations will be allowed in runtime context. # Note: in type context, these will be still caught by semanal_typeargs. @@ -2025,6 +2042,7 @@ def instantiate_type_alias( def set_any_tvars( node: TypeAlias, + args: list[Type], newline: int, newcolumn: int, options: Options, @@ -2041,7 +2059,33 @@ def set_any_tvars( type_of_any = TypeOfAny.special_form else: type_of_any = TypeOfAny.from_omitted_generics - if disallow_any and node.alias_tvars: + any_type = AnyType(type_of_any, line=newline, column=newcolumn) + + env: dict[TypeVarId, Type] = {} + used_any_type = False + has_type_var_tuple_type = False + for tv, arg in itertools.zip_longest(node.alias_tvars, args, fillvalue=None): + if tv is None: + continue + if arg is None: + if tv.has_default(): + arg = tv.default + else: + arg = any_type + used_any_type = True + if isinstance(tv, TypeVarTupleType): + # TODO Handle TypeVarTuple defaults + has_type_var_tuple_type = True + arg = UnpackType(Instance(tv.tuple_fallback.type, [any_type])) + args.append(arg) + env[tv.id] = arg + t = TypeAliasType(node, args, newline, newcolumn) + if not has_type_var_tuple_type: + fixed = expand_type(t, env) + assert isinstance(fixed, TypeAliasType) + t.args = fixed.args + + if used_any_type and disallow_any and node.alias_tvars: assert fail is not None if unexpanded_type: type_str = ( @@ -2057,15 +2101,7 @@ def set_any_tvars( Context(newline, newcolumn), code=codes.TYPE_ARG, ) - any_type = AnyType(type_of_any, line=newline, column=newcolumn) - - args: list[Type] = [] - for tv in node.alias_tvars: - if isinstance(tv, TypeVarTupleType): - args.append(UnpackType(Instance(tv.tuple_fallback.type, [any_type]))) - else: - args.append(any_type) - return TypeAliasType(node, args, newline, newcolumn) + return t def flatten_tvars(lists: list[list[T]]) -> list[T]: diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index c4d258d50ee5..0c531dd3f18b 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -239,3 +239,164 @@ def func_c4( # reveal_type(b) # Revealed type is "__main__.ClassC4[builtins.int, builtins.str]" # TODO reveal_type(c) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" [builtins fixtures/tuple.pyi] + +[case testTypeVarDefaultsTypeAlias1] +# flags: --disallow-any-generics +from typing import Any, Dict, List, Tuple, TypeVar, Union + +T1 = TypeVar("T1") +T2 = TypeVar("T2", default=int) +T3 = TypeVar("T3", default=str) +T4 = TypeVar("T4") + +TA1 = Dict[T2, T3] + +def func_a1( + a: TA1, + b: TA1[float], + c: TA1[float, float], + d: TA1[float, float, float], # E: Bad number of arguments for type alias, expected between 0 and 2, given: 3 +) -> None: + reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" + reveal_type(b) # N: Revealed type is "builtins.dict[builtins.float, builtins.str]" + reveal_type(c) # N: Revealed type is "builtins.dict[builtins.float, builtins.float]" + reveal_type(d) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" + +TA2 = Tuple[T1, T2, T3] + +def func_a2( + a: TA2, # E: Missing type parameters for generic type "TA2" + b: TA2[float], + c: TA2[float, float], + d: TA2[float, float, float], + e: TA2[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given: 4 +) -> None: + reveal_type(a) # N: Revealed type is "Tuple[Any, builtins.int, builtins.str]" + reveal_type(b) # N: Revealed type is "Tuple[builtins.float, builtins.int, builtins.str]" + reveal_type(c) # N: Revealed type is "Tuple[builtins.float, builtins.float, builtins.str]" + reveal_type(d) # N: Revealed type is "Tuple[builtins.float, builtins.float, builtins.float]" + reveal_type(e) # N: Revealed type is "Tuple[Any, builtins.int, builtins.str]" + +TA3 = Union[Dict[T1, T2], List[T3]] + +def func_a3( + a: TA3, # E: Missing type parameters for generic type "TA3" + b: TA3[float], + c: TA3[float, float], + d: TA3[float, float, float], + e: TA3[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given: 4 +) -> None: + reveal_type(a) # N: Revealed type is "Union[builtins.dict[Any, builtins.int], builtins.list[builtins.str]]" + reveal_type(b) # N: Revealed type is "Union[builtins.dict[builtins.float, builtins.int], builtins.list[builtins.str]]" + reveal_type(c) # N: Revealed type is "Union[builtins.dict[builtins.float, builtins.float], builtins.list[builtins.str]]" + reveal_type(d) # N: Revealed type is "Union[builtins.dict[builtins.float, builtins.float], builtins.list[builtins.float]]" + reveal_type(e) # N: Revealed type is "Union[builtins.dict[Any, builtins.int], builtins.list[builtins.str]]" + +TA4 = Tuple[T1, T4, T2] + +def func_a4( + a: TA4, # E: Missing type parameters for generic type "TA4" + b: TA4[float], # E: Bad number of arguments for type alias, expected between 2 and 3, given: 1 + c: TA4[float, float], + d: TA4[float, float, float], + e: TA4[float, float, float, float], # E: Bad number of arguments for type alias, expected between 2 and 3, given: 4 +) -> None: + reveal_type(a) # N: Revealed type is "Tuple[Any, Any, builtins.int]" + reveal_type(b) # N: Revealed type is "Tuple[Any, Any, builtins.int]" + reveal_type(c) # N: Revealed type is "Tuple[builtins.float, builtins.float, builtins.int]" + reveal_type(d) # N: Revealed type is "Tuple[builtins.float, builtins.float, builtins.float]" + reveal_type(e) # N: Revealed type is "Tuple[Any, Any, builtins.int]" +[builtins fixtures/dict.pyi] + +[case testTypeVarDefaultsTypeAlias2] +# flags: --disallow-any-generics +from typing import Any, Generic, ParamSpec + +P1 = ParamSpec("P1") +P2 = ParamSpec("P2", default=[int, str]) +P3 = ParamSpec("P3", default=...) + +class ClassB1(Generic[P2, P3]): ... +TB1 = ClassB1[P2, P3] + +def func_b1( + a: TB1, + b: TB1[[float]], + c: TB1[[float], [float]], + d: TB1[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 0 and 2, given: 3 +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]" + reveal_type(b) # N: Revealed type is "__main__.ClassB1[[builtins.float], [*Any, **Any]]" + reveal_type(c) # N: Revealed type is "__main__.ClassB1[[builtins.float], [builtins.float]]" + reveal_type(d) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]" + +class ClassB2(Generic[P1, P2]): ... +TB2 = ClassB2[P1, P2] + +def func_b2( + a: TB2, # E: Missing type parameters for generic type "TB2" + b: TB2[[float]], + c: TB2[[float], [float]], + d: TB2[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 1 and 2, given: 3 +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" + reveal_type(b) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.int, builtins.str]]" + reveal_type(c) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.float]]" + reveal_type(d) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" +[builtins fixtures/tuple.pyi] + +[case testTypeVarDefaultsTypeAlias3] +# flags: --disallow-any-generics +from typing import Tuple, TypeVar +from typing_extensions import TypeVarTuple, Unpack + +T1 = TypeVar("T1") +T3 = TypeVar("T3", default=str) + +Ts1 = TypeVarTuple("Ts1") +Ts2 = TypeVarTuple("Ts2", default=Unpack[Tuple[int, str]]) +Ts3 = TypeVarTuple("Ts3", default=Unpack[Tuple[float, ...]]) +Ts4 = TypeVarTuple("Ts4", default=Unpack[Tuple[()]]) + +TC1 = Tuple[Unpack[Ts2]] + +def func_c1( + a: TC1, + b: TC1[float], +) -> None: + # reveal_type(a) # Revealed type is "Tuple[builtins.int, builtins.str]" # TODO + reveal_type(b) # N: Revealed type is "Tuple[builtins.float]" + +TC2 = Tuple[T3, Unpack[Ts3]] + +def func_c2( + a: TC2, + b: TC2[int], + c: TC2[int, Unpack[Tuple[()]]], +) -> None: + # reveal_type(a) # Revealed type is "Tuple[builtins.str, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + # reveal_type(b) # Revealed type is "Tuple[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + reveal_type(c) # N: Revealed type is "Tuple[builtins.int]" + +TC3 = Tuple[T3, Unpack[Ts4]] + +def func_c3( + a: TC3, + b: TC3[int], + c: TC3[int, Unpack[Tuple[float]]], +) -> None: + # reveal_type(a) # Revealed type is "Tuple[builtins.str]" # TODO + reveal_type(b) # N: Revealed type is "Tuple[builtins.int]" + reveal_type(c) # N: Revealed type is "Tuple[builtins.int, builtins.float]" + +TC4 = Tuple[T1, Unpack[Ts1], T3] + +def func_c4( + a: TC4, # E: Missing type parameters for generic type "TC4" + b: TC4[int], + c: TC4[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "Tuple[Any, Unpack[builtins.tuple[Any, ...]], builtins.str]" + # reveal_type(b) # Revealed type is "Tuple[builtins.int, builtins.str]" # TODO + reveal_type(c) # N: Revealed type is "Tuple[builtins.int, builtins.float]" +[builtins fixtures/tuple.pyi] From 1da0ebe5ab96cb4982184e405260822a18b3502c Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Mon, 29 Jan 2024 21:27:19 -0800 Subject: [PATCH 41/69] Various docs improvements (#16836) Recommend `--disable-error-code=import-untyped`. It's probably strictly better than `--ignore-missing-imports` for most users. Remove the displaying error codes section, since it's on by default. Some more advice and discoverability for "using mypy with an existing codebase". --- docs/source/config_file.rst | 4 ++++ docs/source/error_codes.rst | 23 +++++++---------------- docs/source/existing_code.rst | 21 ++++++++++++++------- docs/source/running_mypy.rst | 18 +++++++++++------- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 910b015df658..ac110cbed9f1 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -3,6 +3,10 @@ The mypy configuration file =========================== +Mypy is very configurable. This is most useful when introducing typing to +an existing codebase. See :ref:`existing-code` for concrete advice for +that situation. + Mypy supports reading configuration settings from a file with the following precedence order: 1. ``./mypy.ini`` diff --git a/docs/source/error_codes.rst b/docs/source/error_codes.rst index a71168cadf30..35fad161f8a2 100644 --- a/docs/source/error_codes.rst +++ b/docs/source/error_codes.rst @@ -19,22 +19,6 @@ Most error codes are shared between multiple related error messages. Error codes may change in future mypy releases. - -Displaying error codes ----------------------- - -Error codes are displayed by default. Use :option:`--hide-error-codes ` -or config ``hide_error_codes = True`` to hide error codes. Error codes are shown inside square brackets: - -.. code-block:: text - - $ mypy prog.py - prog.py:1: error: "str" has no attribute "trim" [attr-defined] - -It's also possible to require error codes for ``type: ignore`` comments. -See :ref:`ignore-without-code` for more information. - - .. _silence-error-codes: Silencing errors based on error codes @@ -121,3 +105,10 @@ Similar logic works for disabling error codes globally. If a given error code is a subcode of another one, it will be mentioned in the documentation for the narrower code. This hierarchy is not nested: there cannot be subcodes of other subcodes. + + +Requiring error codes +--------------------- + +It's possible to require error codes be specified in ``type: ignore`` comments. +See :ref:`ignore-without-code` for more information. diff --git a/docs/source/existing_code.rst b/docs/source/existing_code.rst index c66008f4b782..0a5ac2bfa8f6 100644 --- a/docs/source/existing_code.rst +++ b/docs/source/existing_code.rst @@ -31,8 +31,8 @@ invocation to your codebase, or adding your mypy invocation to existing tools you use to run tests, like ``tox``. * Make sure everyone runs mypy with the same options. Checking a mypy - :ref:`configuration file ` into your codebase can help - with this. + :ref:`configuration file ` into your codebase is the + easiest way to do this. * Make sure everyone type checks the same set of files. See :ref:`specifying-code-to-be-checked` for details. @@ -48,7 +48,7 @@ A simple CI script could look something like this: .. code-block:: text - python3 -m pip install mypy==0.971 + python3 -m pip install mypy==1.8 # Run your standardised mypy invocation, e.g. mypy my_project # This could also look like `scripts/run_mypy.sh`, `tox run -e mypy`, `make mypy`, etc @@ -74,6 +74,11 @@ You could even invert this, by setting ``ignore_errors = True`` in your global config section and only enabling error reporting with ``ignore_errors = False`` for the set of modules you are ready to type check. +The per-module configuration that mypy's configuration file allows can be +extremely useful. Many configuration options can be enabled or disabled +only for specific modules. In particular, you can also enable or disable +various error codes on a per-module basis, see :ref:`error-codes`. + Fixing errors related to imports -------------------------------- @@ -89,7 +94,7 @@ that it can't find, that don't have types, or don't have stub files: Sometimes these can be fixed by installing the relevant packages or stub libraries in the environment you're running ``mypy`` in. -See :ref:`ignore-missing-imports` for a complete reference on these errors +See :ref:`fix-missing-imports` for a complete reference on these errors and the ways in which you can fix them. You'll likely find that you want to suppress all errors from importing @@ -118,13 +123,15 @@ codebase, use a config like this: ignore_missing_imports = True If you get a large number of errors, you may want to ignore all errors -about missing imports, for instance by setting :confval:`ignore_missing_imports` -to true globally. This can hide errors later on, so we recommend avoiding this +about missing imports, for instance by setting +:option:`--disable-error-code=import-untyped `. +or setting :confval:`ignore_missing_imports` to true globally. +This can hide errors later on, so we recommend avoiding this if possible. Finally, mypy allows fine-grained control over specific import following behaviour. It's very easy to silently shoot yourself in the foot when playing -around with these, so it's mostly recommended as a last resort. For more +around with these, so this should be a last resort. For more details, look :ref:`here `. Prioritise annotating widely imported modules diff --git a/docs/source/running_mypy.rst b/docs/source/running_mypy.rst index b0cefec9dafa..f959e9af2391 100644 --- a/docs/source/running_mypy.rst +++ b/docs/source/running_mypy.rst @@ -305,16 +305,20 @@ not catch errors in its use. The ``.*`` after ``foobar`` will ignore imports of ``foobar`` modules and subpackages in addition to the ``foobar`` top-level package namespace. -3. To suppress *all* missing import errors for *all* libraries in your codebase, - invoke mypy with the :option:`--ignore-missing-imports ` command line flag or set - the :confval:`ignore_missing_imports` - config file option to True - in the *global* section of your mypy config file:: +3. To suppress *all* missing import errors for *all* untyped libraries + in your codebase, use :option:`--disable-error-code=import-untyped `. + See :ref:`code-import-untyped` for more details on this error code. + + You can also set :confval:`disable_error_code`, like so:: [mypy] - ignore_missing_imports = True + disable_error_code = import-untyped + - We recommend using this approach only as a last resort: it's equivalent + You can also set the :option:`--ignore-missing-imports ` + command line flag or set the :confval:`ignore_missing_imports` config file + option to True in the *global* section of your mypy config file. We + recommend avoiding ``--ignore-missing-imports`` if possible: it's equivalent to adding a ``# type: ignore`` to all unresolved imports in your codebase. From 418377892f3220958f0d71c3429a9e7e638b8ca0 Mon Sep 17 00:00:00 2001 From: Stefanie Molin <24376333+stefmolin@users.noreply.github.com> Date: Tue, 30 Jan 2024 00:27:56 -0500 Subject: [PATCH 42/69] Fix numbering error in docs (#16838) --- docs/source/running_mypy.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/running_mypy.rst b/docs/source/running_mypy.rst index f959e9af2391..25b34b247b4b 100644 --- a/docs/source/running_mypy.rst +++ b/docs/source/running_mypy.rst @@ -391,11 +391,11 @@ this error, try: installing into the environment you expect by running pip like ``python -m pip ...``. -2. Reading the :ref:`finding-imports` section below to make sure you +3. Reading the :ref:`finding-imports` section below to make sure you understand how exactly mypy searches for and finds modules and modify how you're invoking mypy accordingly. -3. Directly specifying the directory containing the module you want to +4. Directly specifying the directory containing the module you want to type check from the command line, by using the :confval:`mypy_path` or :confval:`files` config file options, or by using the ``MYPYPATH`` environment variable. From 7a746c4dbd8a0d35e9a3889c9fc861b63aec66cc Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 30 Jan 2024 06:42:46 +0100 Subject: [PATCH 43/69] Consider TypeVarTuple to be invariant (#16759) The TypeVarTuple equality checks mentioned in PEP 646 assume TypeVarTuple to be `invariant`. https://peps.python.org/pep-0646/#type-variable-tuple-equality Fixes: #16739 --- mypy/constraints.py | 5 +++-- mypy/test/testconstraints.py | 24 +++++++++++++++++----- test-data/unit/check-typevar-tuple.test | 27 +++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/mypy/constraints.py b/mypy/constraints.py index d6a4b28799e5..c4eba2ca1ede 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -894,8 +894,9 @@ def visit_instance(self, template: Instance) -> list[Constraint]: res.append(Constraint(template_arg, SUBTYPE_OF, suffix)) res.append(Constraint(template_arg, SUPERTYPE_OF, suffix)) elif isinstance(tvar, TypeVarTupleType): - # Handle variadic type variables covariantly for consistency. - res.extend(infer_constraints(template_arg, mapped_arg, self.direction)) + # Consider variadic type variables to be invariant. + res.extend(infer_constraints(template_arg, mapped_arg, SUBTYPE_OF)) + res.extend(infer_constraints(template_arg, mapped_arg, SUPERTYPE_OF)) return res if ( template.type.is_protocol diff --git a/mypy/test/testconstraints.py b/mypy/test/testconstraints.py index 5ec292f07056..a701a173cbaa 100644 --- a/mypy/test/testconstraints.py +++ b/mypy/test/testconstraints.py @@ -30,13 +30,18 @@ def test_basic_type_var_tuple_subtype(self) -> None: def test_basic_type_var_tuple(self) -> None: fx = self.fx - assert infer_constraints( - Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUPERTYPE_OF - ) == [ + assert set( + infer_constraints( + Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUPERTYPE_OF + ) + ) == { Constraint( type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple) - ) - ] + ), + Constraint( + type_var=fx.ts, op=SUBTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple) + ), + } def test_type_var_tuple_with_prefix_and_suffix(self) -> None: fx = self.fx @@ -51,6 +56,9 @@ def test_type_var_tuple_with_prefix_and_suffix(self) -> None: Constraint( type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.b, fx.c], fx.std_tuple) ), + Constraint( + type_var=fx.ts, op=SUBTYPE_OF, target=TupleType([fx.b, fx.c], fx.std_tuple) + ), Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.d), } @@ -64,7 +72,9 @@ def test_unpack_homogenous_tuple(self) -> None: ) ) == { Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), + Constraint(type_var=fx.t, op=SUBTYPE_OF, target=fx.a), Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.b), + Constraint(type_var=fx.t, op=SUBTYPE_OF, target=fx.b), } def test_unpack_homogenous_tuple_with_prefix_and_suffix(self) -> None: @@ -78,7 +88,9 @@ def test_unpack_homogenous_tuple_with_prefix_and_suffix(self) -> None: ) == { Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.b), + Constraint(type_var=fx.s, op=SUBTYPE_OF, target=fx.b), Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.c), + Constraint(type_var=fx.s, op=SUBTYPE_OF, target=fx.c), Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.d), } @@ -93,7 +105,9 @@ def test_unpack_with_prefix_and_suffix(self) -> None: ) == { Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.a), Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.b), + Constraint(type_var=fx.t, op=SUBTYPE_OF, target=fx.b), Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.c), + Constraint(type_var=fx.s, op=SUBTYPE_OF, target=fx.c), Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.d), } diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 9c8d21114d4c..70229f5d9a62 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2277,3 +2277,30 @@ higher_order(bad2) # E: Argument 1 to "higher_order" has incompatible type "Cal higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Callable[[NamedArg(str, 'd')], int]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" higher_order(bad4) # E: Argument 1 to "higher_order" has incompatible type "Callable[[KwArg(None)], None]"; expected "Callable[[int, str, VarArg(Unpack[Tuple[Unpack[Tuple[Any, ...]], int]])], Any]" [builtins fixtures/tuple.pyi] + +[case testTypeVarTupleInvariant] +from typing import Generic, Tuple +from typing_extensions import Unpack, TypeVarTuple +Ts = TypeVarTuple("Ts") + +class Array(Generic[Unpack[Ts]]): ... + +def pointwise_multiply(x: Array[Unpack[Ts]], y: Array[Unpack[Ts]]) -> Array[Unpack[Ts]]: ... + +def a1(x: Array[int], y: Array[str], z: Array[int, str]) -> None: + reveal_type(pointwise_multiply(x, x)) # N: Revealed type is "__main__.Array[builtins.int]" + reveal_type(pointwise_multiply(x, y)) # E: Cannot infer type argument 1 of "pointwise_multiply" \ + # N: Revealed type is "__main__.Array[Unpack[builtins.tuple[Any, ...]]]" + reveal_type(pointwise_multiply(x, z)) # E: Cannot infer type argument 1 of "pointwise_multiply" \ + # N: Revealed type is "__main__.Array[Unpack[builtins.tuple[Any, ...]]]" + +def func(x: Array[Unpack[Ts]], *args: Unpack[Ts]) -> Tuple[Unpack[Ts]]: + ... + +def a2(x: Array[int, str]) -> None: + reveal_type(func(x, 2, "Hello")) # N: Revealed type is "Tuple[builtins.int, builtins.str]" + reveal_type(func(x, 2)) # E: Cannot infer type argument 1 of "func" \ + # N: Revealed type is "builtins.tuple[Any, ...]" + reveal_type(func(x, 2, "Hello", True)) # E: Cannot infer type argument 1 of "func" \ + # N: Revealed type is "builtins.tuple[Any, ...]" +[builtins fixtures/tuple.pyi] From ed50208055e8c5f99caf7da0cea8c99fcfdc5670 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 30 Jan 2024 06:44:09 +0100 Subject: [PATCH 44/69] Update TypeAlias error messages to remove colon (#16831) Small update to adjust the error messages following the suggestion in https://github.com/python/mypy/pull/16825#discussion_r1468507923. --- mypy/typeanal.py | 6 +++--- test-data/unit/check-generics.test | 9 ++++----- test-data/unit/check-parameter-specification.test | 5 +++-- test-data/unit/check-type-aliases.test | 5 ++--- test-data/unit/check-typevar-defaults.test | 14 +++++++------- test-data/unit/check-typevar-tuple.test | 6 +++--- test-data/unit/fine-grained.test | 8 ++++---- 7 files changed, 26 insertions(+), 27 deletions(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 678407acc3ac..1bcba5f0ca88 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1995,17 +1995,17 @@ def instantiate_type_alias( if node.tvar_tuple_index is not None: msg = ( "Bad number of arguments for type alias," - f" expected: at least {min_tv_count}, given: {act_len}" + f" expected at least {min_tv_count}, given {act_len}" ) elif min_tv_count != max_tv_count: msg = ( "Bad number of arguments for type alias," - f" expected between {min_tv_count} and {max_tv_count}, given: {act_len}" + f" expected between {min_tv_count} and {max_tv_count}, given {act_len}" ) else: msg = ( "Bad number of arguments for type alias," - f" expected: {min_tv_count}, given: {act_len}" + f" expected {min_tv_count}, given {act_len}" ) fail(msg, ctx, code=codes.TYPE_ARG) args = [] diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index e2f65ed39c1e..337e92daf365 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -630,7 +630,7 @@ main:11:5: error: "Node" expects 2 type arguments, but 3 given main:15:10: error: "list" expects 1 type argument, but 2 given main:16:19: error: "list" expects 1 type argument, but 2 given main:17:25: error: "Node" expects 2 type arguments, but 1 given -main:19:5: error: Bad number of arguments for type alias, expected: 1, given: 2 +main:19:5: error: Bad number of arguments for type alias, expected 1, given 2 main:22:13: note: Revealed type is "__main__.Node[builtins.int, builtins.str]" main:24:13: note: Revealed type is "__main__.Node[__main__.Node[builtins.int, builtins.int], builtins.list[builtins.int]]" main:26:5: error: Type variable "__main__.T" is invalid as target for type alias @@ -944,7 +944,7 @@ Transform = Callable[[T, int], Tuple[T, R]] [case testGenericTypeAliasesImportingWithoutTypeVarError] from a import Alias -x: Alias[int, str] # E: Bad number of arguments for type alias, expected: 1, given: 2 +x: Alias[int, str] # E: Bad number of arguments for type alias, expected 1, given 2 reveal_type(x) # N: Revealed type is "builtins.list[builtins.list[Any]]" [file a.py] @@ -953,7 +953,6 @@ T = TypeVar('T') Alias = List[List[T]] [builtins fixtures/list.pyi] -[out] [case testGenericAliasWithTypeVarsFromDifferentModules] from mod import Alias, TypeVar @@ -1000,8 +999,8 @@ reveal_type(x) # N: Revealed type is "Union[builtins.int, None]" reveal_type(y) # N: Revealed type is "builtins.int" U[int] # E: Type application targets a non-generic function or class -O[int] # E: Bad number of arguments for type alias, expected: 0, given: 1 # E: Type application is only supported for generic classes -[out] +O[int] # E: Bad number of arguments for type alias, expected 0, given 1 \ + # E: Type application is only supported for generic classes [case testAliasesInClassBodyNormalVsSubscripted] diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index af2be84f5412..7a5c5934a94e 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1506,9 +1506,10 @@ def g(x: A[P]) -> None: ... # E: Invalid location for ParamSpec "P" \ # N: You can use ParamSpec as the first argument to Callable, e.g., 'Callable[P, int]' C = Callable[P, T] -x: C[int] # E: Bad number of arguments for type alias, expected: 2, given: 1 +x: C[int] # E: Bad number of arguments for type alias, expected 2, given 1 y: C[int, str] # E: Can only replace ParamSpec with a parameter types list or another ParamSpec, got "int" -z: C[int, str, bytes] # E: Bad number of arguments for type alias, expected: 2, given: 3 +z: C[int, str, bytes] # E: Bad number of arguments for type alias, expected 2, given 3 + [builtins fixtures/paramspec.pyi] [case testTrivialParametersHandledCorrectly] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 4364a9bfa9dc..a43233eed973 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -330,10 +330,9 @@ c: C t: T reveal_type(c) # N: Revealed type is "def (*Any, **Any) -> Any" reveal_type(t) # N: Revealed type is "builtins.tuple[Any, ...]" -bad: C[int] # E: Bad number of arguments for type alias, expected: 0, given: 1 -also_bad: T[int] # E: Bad number of arguments for type alias, expected: 0, given: 1 +bad: C[int] # E: Bad number of arguments for type alias, expected 0, given 1 +also_bad: T[int] # E: Bad number of arguments for type alias, expected 0, given 1 [builtins fixtures/tuple.pyi] -[out] [case testAliasRefOnClass] from typing import Generic, TypeVar, Type diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 0c531dd3f18b..4b509cd4fc40 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -255,7 +255,7 @@ def func_a1( a: TA1, b: TA1[float], c: TA1[float, float], - d: TA1[float, float, float], # E: Bad number of arguments for type alias, expected between 0 and 2, given: 3 + d: TA1[float, float, float], # E: Bad number of arguments for type alias, expected between 0 and 2, given 3 ) -> None: reveal_type(a) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" reveal_type(b) # N: Revealed type is "builtins.dict[builtins.float, builtins.str]" @@ -269,7 +269,7 @@ def func_a2( b: TA2[float], c: TA2[float, float], d: TA2[float, float, float], - e: TA2[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given: 4 + e: TA2[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given 4 ) -> None: reveal_type(a) # N: Revealed type is "Tuple[Any, builtins.int, builtins.str]" reveal_type(b) # N: Revealed type is "Tuple[builtins.float, builtins.int, builtins.str]" @@ -284,7 +284,7 @@ def func_a3( b: TA3[float], c: TA3[float, float], d: TA3[float, float, float], - e: TA3[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given: 4 + e: TA3[float, float, float, float], # E: Bad number of arguments for type alias, expected between 1 and 3, given 4 ) -> None: reveal_type(a) # N: Revealed type is "Union[builtins.dict[Any, builtins.int], builtins.list[builtins.str]]" reveal_type(b) # N: Revealed type is "Union[builtins.dict[builtins.float, builtins.int], builtins.list[builtins.str]]" @@ -296,10 +296,10 @@ TA4 = Tuple[T1, T4, T2] def func_a4( a: TA4, # E: Missing type parameters for generic type "TA4" - b: TA4[float], # E: Bad number of arguments for type alias, expected between 2 and 3, given: 1 + b: TA4[float], # E: Bad number of arguments for type alias, expected between 2 and 3, given 1 c: TA4[float, float], d: TA4[float, float, float], - e: TA4[float, float, float, float], # E: Bad number of arguments for type alias, expected between 2 and 3, given: 4 + e: TA4[float, float, float, float], # E: Bad number of arguments for type alias, expected between 2 and 3, given 4 ) -> None: reveal_type(a) # N: Revealed type is "Tuple[Any, Any, builtins.int]" reveal_type(b) # N: Revealed type is "Tuple[Any, Any, builtins.int]" @@ -323,7 +323,7 @@ def func_b1( a: TB1, b: TB1[[float]], c: TB1[[float], [float]], - d: TB1[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 0 and 2, given: 3 + d: TB1[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 0 and 2, given 3 ) -> None: reveal_type(a) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]" reveal_type(b) # N: Revealed type is "__main__.ClassB1[[builtins.float], [*Any, **Any]]" @@ -337,7 +337,7 @@ def func_b2( a: TB2, # E: Missing type parameters for generic type "TB2" b: TB2[[float]], c: TB2[[float], [float]], - d: TB2[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 1 and 2, given: 3 + d: TB2[[float], [float], [float]], # E: Bad number of arguments for type alias, expected between 1 and 2, given 3 ) -> None: reveal_type(a) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" reveal_type(b) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.int, builtins.str]]" diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index 70229f5d9a62..cc3dc4ed9f39 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -769,15 +769,15 @@ Ts = TypeVarTuple("Ts") class G(Generic[Unpack[Ts]]): ... A = List[Tuple[T, Unpack[Ts], S]] -x: A[int] # E: Bad number of arguments for type alias, expected: at least 2, given: 1 +x: A[int] # E: Bad number of arguments for type alias, expected at least 2, given 1 reveal_type(x) # N: Revealed type is "builtins.list[Tuple[Any, Unpack[builtins.tuple[Any, ...]], Any]]" B = Callable[[T, S, Unpack[Ts]], int] -y: B[int] # E: Bad number of arguments for type alias, expected: at least 2, given: 1 +y: B[int] # E: Bad number of arguments for type alias, expected at least 2, given 1 reveal_type(y) # N: Revealed type is "def (Any, Any, *Any) -> builtins.int" C = G[T, Unpack[Ts], S] -z: C[int] # E: Bad number of arguments for type alias, expected: at least 2, given: 1 +z: C[int] # E: Bad number of arguments for type alias, expected at least 2, given 1 reveal_type(z) # N: Revealed type is "__main__.G[Any, Unpack[builtins.tuple[Any, ...]], Any]" [builtins fixtures/tuple.pyi] diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 165a2089b466..266d9a9efd01 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -4032,7 +4032,7 @@ def f(x: a.A[str]): [builtins fixtures/dict.pyi] [out] == -b.py:2: error: Bad number of arguments for type alias, expected: 2, given: 1 +b.py:2: error: Bad number of arguments for type alias, expected 2, given 1 [case testAliasFineAdded] import b @@ -5542,7 +5542,7 @@ main:9: error: Function "a.T" is not valid as a type main:9: note: Perhaps you need "Callable[...]" or a callback protocol? main:12: error: Function "a.T" is not valid as a type main:12: note: Perhaps you need "Callable[...]" or a callback protocol? -main:12: error: Bad number of arguments for type alias, expected: 0, given: 1 +main:12: error: Bad number of arguments for type alias, expected 0, given 1 [case testChangeTypeVarToModule] @@ -5576,7 +5576,7 @@ main:9: error: Module "T" is not valid as a type main:9: note: Perhaps you meant to use a protocol matching the module structure? main:12: error: Module "T" is not valid as a type main:12: note: Perhaps you meant to use a protocol matching the module structure? -main:12: error: Bad number of arguments for type alias, expected: 0, given: 1 +main:12: error: Bad number of arguments for type alias, expected 0, given 1 [case testChangeClassToModule] @@ -5628,7 +5628,7 @@ T = int == main:5: error: Free type variable expected in Generic[...] main:9: error: "C" expects no type arguments, but 1 given -main:12: error: Bad number of arguments for type alias, expected: 0, given: 1 +main:12: error: Bad number of arguments for type alias, expected 0, given 1 [case testChangeTypeAliasToModule] From 06b01c80a1a365cb8af80b9eecfbe4b14f04fc3e Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Tue, 30 Jan 2024 06:39:02 +0000 Subject: [PATCH 45/69] Fix `'WriteToConn' object has no attribute 'flush'` (#16801) `WriteToConn` replaces stdout and stderr to capture output, but causes issues because it doesn't implement the `TextIO` API (as expected of `sys.stdout` and `sys.stderr`). By stubbing the rest of the `TextIO` API we prevent issues with other code which uses more of the API than we had previously accounted for. Fixes https://github.com/python/mypy/issues/16678 --- mypy/dmypy_server.py | 4 +-- mypy/dmypy_util.py | 65 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index b4c3fe8fe0dc..3d337eedbf1c 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -221,8 +221,8 @@ def serve(self) -> None: while True: with server: data = receive(server) - sys.stdout = WriteToConn(server, "stdout") # type: ignore[assignment] - sys.stderr = WriteToConn(server, "stderr") # type: ignore[assignment] + sys.stdout = WriteToConn(server, "stdout", sys.stdout.isatty()) + sys.stderr = WriteToConn(server, "stderr", sys.stderr.isatty()) resp: dict[str, Any] = {} if "command" not in data: resp = {"error": "No command found in request"} diff --git a/mypy/dmypy_util.py b/mypy/dmypy_util.py index fe949e8fc294..0baff863b3c3 100644 --- a/mypy/dmypy_util.py +++ b/mypy/dmypy_util.py @@ -5,8 +5,10 @@ from __future__ import annotations +import io import json -from typing import Any, Final, Iterable +from types import TracebackType +from typing import Any, Final, Iterable, Iterator, TextIO from mypy.ipc import IPCBase @@ -40,12 +42,66 @@ def send(connection: IPCBase, data: Any) -> None: connection.write(json.dumps(data)) -class WriteToConn: +class WriteToConn(TextIO): """Helper class to write to a connection instead of standard output.""" - def __init__(self, server: IPCBase, output_key: str = "stdout") -> None: + def __init__(self, server: IPCBase, output_key: str, isatty: bool) -> None: self.server = server self.output_key = output_key + self._isatty = isatty + + def __enter__(self) -> TextIO: + return self + + def __exit__( + self, + t: type[BaseException] | None, + value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + pass + + def __iter__(self) -> Iterator[str]: + raise io.UnsupportedOperation + + def __next__(self) -> str: + raise io.UnsupportedOperation + + def close(self) -> None: + pass + + def fileno(self) -> int: + raise OSError + + def flush(self) -> None: + pass + + def isatty(self) -> bool: + return self._isatty + + def read(self, n: int = 0) -> str: + raise io.UnsupportedOperation + + def readable(self) -> bool: + return False + + def readline(self, limit: int = 0) -> str: + raise io.UnsupportedOperation + + def readlines(self, hint: int = 0) -> list[str]: + raise io.UnsupportedOperation + + def seek(self, offset: int, whence: int = 0) -> int: + raise io.UnsupportedOperation + + def seekable(self) -> bool: + return False + + def tell(self) -> int: + raise io.UnsupportedOperation + + def truncate(self, size: int | None = 0) -> int: + raise io.UnsupportedOperation def write(self, output: str) -> int: resp: dict[str, Any] = {} @@ -53,6 +109,9 @@ def write(self, output: str) -> int: send(self.server, resp) return len(output) + def writable(self) -> bool: + return True + def writelines(self, lines: Iterable[str]) -> None: for s in lines: self.write(s) From e40935e5e0b55bee9379e35aa27216c3e0287b13 Mon Sep 17 00:00:00 2001 From: thomaswhaley <39359869+thomas-whaley@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:26:22 +1300 Subject: [PATCH 46/69] Update new type system discussion links (#16841) As of the 10th of September 2023 the typing-sig mail list is now replaced with [discuss.python.org](https://discuss.python.org/c/typing/32) as explained [here](https://mail.python.org/archives/list/typing-sig@python.org/thread/BENDBBUDRCRMTTK2B5HJ7RCKENFD6DW2/) and [here](https://discuss.python.org/t/about-the-typing-category/34155) The README.md file was referencing the old link. --------- Co-authored-by: Jelle Zijlstra --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8b1ebbc0f2cb..07c170d46cb3 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ To report a bug or request an enhancement: To discuss a new type system feature: -- discuss at [typing-sig mailing list](https://mail.python.org/archives/list/typing-sig@python.org/) -- there is also some historical discussion [here](https://github.com/python/typing/issues) +- discuss at [discuss.python.org](https://discuss.python.org/c/typing/32) +- there is also some historical discussion at the [typing-sig mailing list](https://mail.python.org/archives/list/typing-sig@python.org/) and the [python/typing repo](https://github.com/python/typing/issues) What is mypy? ------------- From 55247c469077963a389941a2386ff2747abe517a Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 31 Jan 2024 17:09:44 +0100 Subject: [PATCH 47/69] Apply TypeVar defaults to callables (PEP 696) (#16842) Implement type application for callables with TypeVar defaults. Similar to previous PRs, support for TypeVarTuples is still TODO. Ref: https://github.com/python/mypy/issues/14851 --- mypy/applytype.py | 3 +- mypy/checkexpr.py | 24 ++++-- mypy/messages.py | 21 ++--- test-data/unit/check-typevar-defaults.test | 93 +++++++++++++++++++++- 4 files changed, 122 insertions(+), 19 deletions(-) diff --git a/mypy/applytype.py b/mypy/applytype.py index c7da67d6140b..b00372855d9c 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -93,7 +93,8 @@ def apply_generic_arguments( bound or constraints, instead of giving an error. """ tvars = callable.variables - assert len(tvars) == len(orig_types) + min_arg_count = sum(not tv.has_default() for tv in tvars) + assert min_arg_count <= len(orig_types) <= len(tvars) # Check that inferred type variable values are compatible with allowed # values and bounds. Also, promote subtype values to allowed values. # Create a map from type variable id to target type. diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index a4b66bb9932c..e04d413eab8d 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4809,21 +4809,29 @@ def apply_type_arguments_to_callable( tp = get_proper_type(tp) if isinstance(tp, CallableType): - if len(tp.variables) != len(args) and not any( - isinstance(v, TypeVarTupleType) for v in tp.variables - ): + min_arg_count = sum(not v.has_default() for v in tp.variables) + has_type_var_tuple = any(isinstance(v, TypeVarTupleType) for v in tp.variables) + if ( + len(args) < min_arg_count or len(args) > len(tp.variables) + ) and not has_type_var_tuple: if tp.is_type_obj() and tp.type_object().fullname == "builtins.tuple": # TODO: Specialize the callable for the type arguments return tp - self.msg.incompatible_type_application(len(tp.variables), len(args), ctx) + self.msg.incompatible_type_application( + min_arg_count, len(tp.variables), len(args), ctx + ) return AnyType(TypeOfAny.from_error) return self.apply_generic_arguments(tp, self.split_for_callable(tp, args, ctx), ctx) if isinstance(tp, Overloaded): for it in tp.items: - if len(it.variables) != len(args) and not any( - isinstance(v, TypeVarTupleType) for v in it.variables - ): - self.msg.incompatible_type_application(len(it.variables), len(args), ctx) + min_arg_count = sum(not v.has_default() for v in it.variables) + has_type_var_tuple = any(isinstance(v, TypeVarTupleType) for v in it.variables) + if ( + len(args) < min_arg_count or len(args) > len(it.variables) + ) and not has_type_var_tuple: + self.msg.incompatible_type_application( + min_arg_count, len(it.variables), len(args), ctx + ) return AnyType(TypeOfAny.from_error) return Overloaded( [ diff --git a/mypy/messages.py b/mypy/messages.py index 75b8eeb3174c..2f2d346c2c51 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -1347,18 +1347,21 @@ def override_target(self, name: str, name_in_super: str, supertype: str) -> str: return target def incompatible_type_application( - self, expected_arg_count: int, actual_arg_count: int, context: Context + self, min_arg_count: int, max_arg_count: int, actual_arg_count: int, context: Context ) -> None: - if expected_arg_count == 0: + if max_arg_count == 0: self.fail("Type application targets a non-generic function or class", context) - elif actual_arg_count > expected_arg_count: - self.fail( - f"Type application has too many types ({expected_arg_count} expected)", context - ) + return + + if min_arg_count == max_arg_count: + s = f"{max_arg_count} expected" else: - self.fail( - f"Type application has too few types ({expected_arg_count} expected)", context - ) + s = f"expected between {min_arg_count} and {max_arg_count}" + + if actual_arg_count > max_arg_count: + self.fail(f"Type application has too many types ({s})", context) + else: + self.fail(f"Type application has too few types ({s})", context) def could_not_infer_type_arguments( self, callee_type: CallableType, n: int, context: Context diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 4b509cd4fc40..7c748821401a 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -118,7 +118,7 @@ def func_c1(x: Union[int, Callable[[Unpack[Ts1]], None]]) -> Tuple[Unpack[Ts1]]: [builtins fixtures/tuple.pyi] [case testTypeVarDefaultsClass1] -from typing import Generic, TypeVar +from typing import Generic, TypeVar, Union, overload T1 = TypeVar("T1") T2 = TypeVar("T2", default=int) @@ -137,6 +137,15 @@ def func_a1( reveal_type(c) # N: Revealed type is "__main__.ClassA1[builtins.float, builtins.float]" reveal_type(d) # N: Revealed type is "__main__.ClassA1[builtins.int, builtins.str]" + k = ClassA1() + reveal_type(k) # N: Revealed type is "__main__.ClassA1[builtins.int, builtins.str]" + l = ClassA1[float]() + reveal_type(l) # N: Revealed type is "__main__.ClassA1[builtins.float, builtins.str]" + m = ClassA1[float, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassA1[builtins.float, builtins.float]" + n = ClassA1[float, float, float]() # E: Type application has too many types (expected between 0 and 2) + reveal_type(n) # N: Revealed type is "Any" + class ClassA2(Generic[T1, T2, T3]): ... def func_a2( @@ -152,6 +161,44 @@ def func_a2( reveal_type(d) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.float, builtins.float]" reveal_type(e) # N: Revealed type is "__main__.ClassA2[Any, builtins.int, builtins.str]" + k = ClassA2() # E: Need type annotation for "k" + reveal_type(k) # N: Revealed type is "__main__.ClassA2[Any, builtins.int, builtins.str]" + l = ClassA2[float]() + reveal_type(l) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.int, builtins.str]" + m = ClassA2[float, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.float, builtins.str]" + n = ClassA2[float, float, float]() + reveal_type(n) # N: Revealed type is "__main__.ClassA2[builtins.float, builtins.float, builtins.float]" + o = ClassA2[float, float, float, float]() # E: Type application has too many types (expected between 1 and 3) + reveal_type(o) # N: Revealed type is "Any" + +class ClassA3(Generic[T1, T2]): + @overload + def __init__(self) -> None: ... + @overload + def __init__(self, var: int) -> None: ... + def __init__(self, var: Union[int, None] = None) -> None: ... + +def func_a3( + a: ClassA3, + b: ClassA3[float], + c: ClassA3[float, float], + d: ClassA3[float, float, float], # E: "ClassA3" expects between 1 and 2 type arguments, but 3 given +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassA3[Any, builtins.int]" + reveal_type(b) # N: Revealed type is "__main__.ClassA3[builtins.float, builtins.int]" + reveal_type(c) # N: Revealed type is "__main__.ClassA3[builtins.float, builtins.float]" + reveal_type(d) # N: Revealed type is "__main__.ClassA3[Any, builtins.int]" + + k = ClassA3() # E: Need type annotation for "k" + reveal_type(k) # N: Revealed type is "__main__.ClassA3[Any, builtins.int]" + l = ClassA3[float]() + reveal_type(l) # N: Revealed type is "__main__.ClassA3[builtins.float, builtins.int]" + m = ClassA3[float, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassA3[builtins.float, builtins.float]" + n = ClassA3[float, float, float]() # E: Type application has too many types (expected between 1 and 2) + reveal_type(n) # N: Revealed type is "Any" + [case testTypeVarDefaultsClass2] from typing import Generic, ParamSpec @@ -172,6 +219,15 @@ def func_b1( reveal_type(c) # N: Revealed type is "__main__.ClassB1[[builtins.float], [builtins.float]]" reveal_type(d) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], ...]" + k = ClassB1() + reveal_type(k) # N: Revealed type is "__main__.ClassB1[[builtins.int, builtins.str], [*Any, **Any]]" + l = ClassB1[[float]]() + reveal_type(l) # N: Revealed type is "__main__.ClassB1[[builtins.float], [*Any, **Any]]" + m = ClassB1[[float], [float]]() + reveal_type(m) # N: Revealed type is "__main__.ClassB1[[builtins.float], [builtins.float]]" + n = ClassB1[[float], [float], [float]]() # E: Type application has too many types (expected between 0 and 2) + reveal_type(n) # N: Revealed type is "Any" + class ClassB2(Generic[P1, P2]): ... def func_b2( @@ -185,6 +241,15 @@ def func_b2( reveal_type(c) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.float]]" reveal_type(d) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" + k = ClassB2() # E: Need type annotation for "k" + reveal_type(k) # N: Revealed type is "__main__.ClassB2[Any, [builtins.int, builtins.str]]" + l = ClassB2[[float]]() + reveal_type(l) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.int, builtins.str]]" + m = ClassB2[[float], [float]]() + reveal_type(m) # N: Revealed type is "__main__.ClassB2[[builtins.float], [builtins.float]]" + n = ClassB2[[float], [float], [float]]() # E: Type application has too many types (expected between 1 and 2) + reveal_type(n) # N: Revealed type is "Any" + [case testTypeVarDefaultsClass3] from typing import Generic, Tuple, TypeVar from typing_extensions import TypeVarTuple, Unpack @@ -206,6 +271,11 @@ def func_c1( # reveal_type(a) # Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" # TODO reveal_type(b) # N: Revealed type is "__main__.ClassC1[builtins.float]" + # k = ClassC1() # TODO + # reveal_type(k) # Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" # TODO + l = ClassC1[float]() + reveal_type(l) # N: Revealed type is "__main__.ClassC1[builtins.float]" + class ClassC2(Generic[T3, Unpack[Ts3]]): ... def func_c2( @@ -217,6 +287,13 @@ def func_c2( # reveal_type(b) # Revealed type is "__main__.ClassC2[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO reveal_type(c) # N: Revealed type is "__main__.ClassC2[builtins.int]" + # k = ClassC2() # TODO + # reveal_type(k) # Revealed type is "__main__.ClassC2[builtins.str, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + l = ClassC2[int]() + # reveal_type(l) # Revealed type is "__main__.ClassC2[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + m = ClassC2[int, Unpack[Tuple[()]]]() + reveal_type(m) # N: Revealed type is "__main__.ClassC2[builtins.int]" + class ClassC3(Generic[T3, Unpack[Ts4]]): ... def func_c3( @@ -228,6 +305,13 @@ def func_c3( reveal_type(b) # N: Revealed type is "__main__.ClassC3[builtins.int]" reveal_type(c) # N: Revealed type is "__main__.ClassC3[builtins.int, builtins.float]" + # k = ClassC3() # TODO + # reveal_type(k) # Revealed type is "__main__.ClassC3[builtins.str]" # TODO + l = ClassC3[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassC3[builtins.int]" + m = ClassC3[int, Unpack[Tuple[float]]]() + reveal_type(m) # N: Revealed type is "__main__.ClassC3[builtins.int, builtins.float]" + class ClassC4(Generic[T1, Unpack[Ts1], T3]): ... def func_c4( @@ -238,6 +322,13 @@ def func_c4( reveal_type(a) # N: Revealed type is "__main__.ClassC4[Any, Unpack[builtins.tuple[Any, ...]], builtins.str]" # reveal_type(b) # Revealed type is "__main__.ClassC4[builtins.int, builtins.str]" # TODO reveal_type(c) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" + + k = ClassC4() # E: Need type annotation for "k" + reveal_type(k) # N: Revealed type is "__main__.ClassC4[Any, Unpack[builtins.tuple[Any, ...]], builtins.str]" + l = ClassC4[int]() + # reveal_type(l) # Revealed type is "__main__.ClassC4[builtins.int, builtins.str]" # TODO + m = ClassC4[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" [builtins fixtures/tuple.pyi] [case testTypeVarDefaultsTypeAlias1] From 5bf774234da052efffd14e6c3dd26d93a14e3cc8 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 31 Jan 2024 22:41:49 +0100 Subject: [PATCH 48/69] Fix missing type store for overloads (#16803) Add missing call to store inferred types if an overload match is found early. All other code paths already do that. ### Some background on the issue this fixes I recently saw an interesting pattern in `aiohttp` to type values in an `dict[str, Any]` by subclassing dict. ```py T = TypeVar("T") U = TypeVar("U") class Key(Generic[T]): ... class CustomDict(dict[Key[Any] | str, Any]): @overload # type: ignore[override] def get(self, __key: Key[T]) -> T | None: ... @overload def get(self, __key: Key[T], __default: U) -> T | U: ... @overload def get(self, __key: str) -> Any | None: ... @overload def get(self, __key: str, __default: Any) -> Any: ... def get(self, __key: Key[Any] | str, __default: Any = None) -> Any: """Forward to super implementation.""" return super().get(__key, __default) # overloads for __getitem__, setdefault, pop # ... @overload # type: ignore[override] def __setitem__(self, key: Key[T], value: T) -> None: ... @overload def __setitem__(self, key: str, value: Any) -> None: ... def __setitem__(self, key: Key[Any] | str, value: Any) -> None: """Forward to super implementation.""" return super().__setitem__(key, value) ``` With the exception that these overloads aren't technically compatible with the supertype, they do the job. ```py d = CustomDict() key = Key[int]() other_key = "other" assert_type(d.get(key), int | None) assert_type(d.get("other"), Any | None) ``` The issue exists for the `__setitem__` case. Without this PR the following would create an issue. Here `var` would be inferred as `dict[Never, Never]`, even though it should be `dict[Any, Any]` which is the case for non-subclassed dicts. ```py def a2(d: CustomDict) -> None: if (var := d.get("arg")) is None: var = d["arg"] = {} reveal_type(var) ``` --- mypy/checkexpr.py | 1 + test-data/unit/check-generics.test | 24 ++++++++++++++++++++++++ test-data/unit/typexport-basic.test | 21 +++++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index e04d413eab8d..c628a3398b59 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2825,6 +2825,7 @@ def infer_overload_return_type( # Return early if possible; otherwise record info, so we can # check for ambiguity due to 'Any' below. if not args_contain_any: + self.chk.store_types(m) return ret_type, infer_type p_infer_type = get_proper_type(infer_type) if isinstance(p_infer_type, CallableType): diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 337e92daf365..469cedb8f6f7 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -1480,6 +1480,30 @@ if int(): b = f(b) [builtins fixtures/list.pyi] +[case testGenericDictWithOverload] +from typing import Dict, Generic, TypeVar, Any, overload +T = TypeVar("T") + +class Key(Generic[T]): ... +class CustomDict(dict): + @overload # type: ignore[override] + def __setitem__(self, key: Key[T], value: T) -> None: ... + @overload + def __setitem__(self, key: str, value: Any) -> None: ... + def __setitem__(self, key, value): + return super().__setitem__(key, value) + +def a1(d: Dict[str, Any]) -> None: + if (var := d.get("arg")) is None: + var = d["arg"] = {} + reveal_type(var) # N: Revealed type is "builtins.dict[Any, Any]" + +def a2(d: CustomDict) -> None: + if (var := d.get("arg")) is None: + var = d["arg"] = {} + reveal_type(var) # N: Revealed type is "builtins.dict[Any, Any]" +[builtins fixtures/dict.pyi] + -- Type variable scoping -- --------------------- diff --git a/test-data/unit/typexport-basic.test b/test-data/unit/typexport-basic.test index c4c3a1d36f83..d78cf0f179f2 100644 --- a/test-data/unit/typexport-basic.test +++ b/test-data/unit/typexport-basic.test @@ -1236,6 +1236,27 @@ LambdaExpr(10) : def (x: builtins.int) -> builtins.int LambdaExpr(12) : def (y: builtins.str) -> builtins.str LambdaExpr(13) : def (x: builtins.str) -> builtins.str +[case testExportOverloadArgTypeDict] +## DictExpr +from typing import TypeVar, Generic, Any, overload, Dict +T = TypeVar("T") +class Key(Generic[T]): ... +@overload +def f(x: Key[T], y: T) -> T: ... +@overload +def f(x: int, y: Any) -> Any: ... +def f(x, y): ... +d: Dict = {} +d.get( + "", {}) +f( + 2, {}) +[builtins fixtures/dict.pyi] +[out] +DictExpr(10) : builtins.dict[Any, Any] +DictExpr(12) : builtins.dict[Any, Any] +DictExpr(14) : builtins.dict[Any, Any] + -- TODO -- -- test expressions From c3cd83a23dcdbd72e6e2a4c2d6c605eadc7bccf4 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 31 Jan 2024 23:21:57 +0100 Subject: [PATCH 49/69] Fix disallow-any errors for Instance types (PEP 696) (#16832) Similar to TypeAlias types `Missing type parameters for generic type` should not be emitted if too many arguments are given. There is a separate error message for that. Ref: https://github.com/python/mypy/issues/14851 --- mypy/messages.py | 8 ++++---- mypy/typeanal.py | 5 ++++- test-data/unit/check-typevar-defaults.test | 11 +++++++---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index 2f2d346c2c51..c107e874f4fc 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2515,10 +2515,10 @@ def format_literal_value(typ: LiteralType) -> str: else: base_str = itype.type.name if not itype.args: - if not itype.type.has_type_var_tuple_type: - # No type arguments, just return the type name - return base_str - return base_str + "[()]" + if itype.type.has_type_var_tuple_type and len(itype.type.type_vars) == 1: + return base_str + "[()]" + # No type arguments, just return the type name + return base_str elif itype.type.fullname == "builtins.tuple": item_type_str = format(itype.args[0]) return f"{'tuple' if options.use_lowercase_names() else 'Tuple'}[{item_type_str}, ...]" diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 1bcba5f0ca88..601f98e958e2 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1866,7 +1866,11 @@ def fix_instance( max_tv_count = len(t.type.type_vars) if arg_count < min_tv_count or arg_count > max_tv_count: # Don't use existing args if arg_count doesn't match + if arg_count > max_tv_count: + # Already wrong arg count error, don't emit missing type parameters error as well. + disallow_any = False t.args = () + arg_count = 0 args: list[Type] = [*(t.args[:max_tv_count])] any_type: AnyType | None = None @@ -2324,7 +2328,6 @@ def validate_instance(t: Instance, fail: MsgCallback, empty_tuple_index: bool) - t, code=codes.TYPE_ARG, ) - t.args = () t.invalid = True return False return True diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 7c748821401a..6136746cbd0a 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -118,6 +118,7 @@ def func_c1(x: Union[int, Callable[[Unpack[Ts1]], None]]) -> Tuple[Unpack[Ts1]]: [builtins fixtures/tuple.pyi] [case testTypeVarDefaultsClass1] +# flags: --disallow-any-generics from typing import Generic, TypeVar, Union, overload T1 = TypeVar("T1") @@ -149,7 +150,7 @@ def func_a1( class ClassA2(Generic[T1, T2, T3]): ... def func_a2( - a: ClassA2, + a: ClassA2, # E: Missing type parameters for generic type "ClassA2" b: ClassA2[float], c: ClassA2[float, float], d: ClassA2[float, float, float], @@ -180,7 +181,7 @@ class ClassA3(Generic[T1, T2]): def __init__(self, var: Union[int, None] = None) -> None: ... def func_a3( - a: ClassA3, + a: ClassA3, # E: Missing type parameters for generic type "ClassA3" b: ClassA3[float], c: ClassA3[float, float], d: ClassA3[float, float, float], # E: "ClassA3" expects between 1 and 2 type arguments, but 3 given @@ -200,6 +201,7 @@ def func_a3( reveal_type(n) # N: Revealed type is "Any" [case testTypeVarDefaultsClass2] +# flags: --disallow-any-generics from typing import Generic, ParamSpec P1 = ParamSpec("P1") @@ -231,7 +233,7 @@ def func_b1( class ClassB2(Generic[P1, P2]): ... def func_b2( - a: ClassB2, + a: ClassB2, # E: Missing type parameters for generic type "ClassB2" b: ClassB2[[float]], c: ClassB2[[float], [float]], d: ClassB2[[float], [float], [float]], # E: "ClassB2" expects between 1 and 2 type arguments, but 3 given @@ -251,6 +253,7 @@ def func_b2( reveal_type(n) # N: Revealed type is "Any" [case testTypeVarDefaultsClass3] +# flags: --disallow-any-generics from typing import Generic, Tuple, TypeVar from typing_extensions import TypeVarTuple, Unpack @@ -315,7 +318,7 @@ def func_c3( class ClassC4(Generic[T1, Unpack[Ts1], T3]): ... def func_c4( - a: ClassC4, + a: ClassC4, # E: Missing type parameters for generic type "ClassC4" b: ClassC4[int], c: ClassC4[int, float], ) -> None: From 8107e53158d83d30bb04d290ac10d8d3ccd344f8 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:46:07 +0100 Subject: [PATCH 50/69] Update black to 24.1.1 (#16847) --- .pre-commit-config.yaml | 2 +- mypy/build.py | 1 + mypy/checker.py | 42 +++++++++++++++--------------- mypy/checkexpr.py | 16 ++++++------ mypy/checkpattern.py | 9 +++---- mypy/evalexpr.py | 1 + mypy/expandtype.py | 24 ++++++----------- mypy/fastparse.py | 21 +++++++-------- mypy/join.py | 6 ++--- mypy/main.py | 2 -- mypy/metastore.py | 3 +-- mypy/nodes.py | 12 ++++----- mypy/plugins/attrs.py | 16 +++++++----- mypy/plugins/enums.py | 1 + mypy/plugins/functools.py | 1 + mypy/semanal_shared.py | 9 +++---- mypy/semanal_typeddict.py | 9 +++---- mypy/stubtest.py | 8 +++--- mypy/stubutil.py | 6 ++--- mypy/subtypes.py | 8 +++--- mypy/test/meta/test_parse_data.py | 1 + mypy/test/meta/test_update_data.py | 1 + mypy/test/testargs.py | 1 + mypy/test/testerrorstream.py | 1 + mypy/test/testreports.py | 1 + mypy/test/teststubgen.py | 3 +-- mypy/typeanal.py | 3 +-- mypy/typeops.py | 8 +++--- mypy/types.py | 23 +++++++--------- mypyc/analysis/ircheck.py | 1 + mypyc/codegen/emitfunc.py | 4 +-- mypyc/ir/class_ir.py | 6 ++--- mypyc/irbuild/builder.py | 7 +++-- mypyc/irbuild/nonlocalcontrol.py | 3 +-- test-requirements.in | 2 +- test-requirements.txt | 2 +- 36 files changed, 126 insertions(+), 138 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0bbd7b3ce382..6566bb0297d8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.9.1 # must match test-requirements.txt + rev: 24.1.1 # must match test-requirements.txt hooks: - id: black exclude: '^(test-data/)' diff --git a/mypy/build.py b/mypy/build.py index 8049fa2d0c3f..65a06211c87e 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -8,6 +8,7 @@ The function build() is the main interface to this module. """ + # TODO: More consistent terminology, e.g. path/fnam, module/id, state/file from __future__ import annotations diff --git a/mypy/checker.py b/mypy/checker.py index cd23e74a8dac..391f28e93b1d 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -526,12 +526,16 @@ def check_second_pass( # print("XXX in pass %d, class %s, function %s" % # (self.pass_num, type_name, node.fullname or node.name)) done.add(node) - with self.tscope.class_scope( - active_typeinfo - ) if active_typeinfo else nullcontext(): - with self.scope.push_class( - active_typeinfo - ) if active_typeinfo else nullcontext(): + with ( + self.tscope.class_scope(active_typeinfo) + if active_typeinfo + else nullcontext() + ): + with ( + self.scope.push_class(active_typeinfo) + if active_typeinfo + else nullcontext() + ): self.check_partial(node) return True @@ -3802,9 +3806,11 @@ def check_multi_assignment_from_tuple( if star_lv: list_expr = ListExpr( [ - self.temp_node(rv_type, context) - if not isinstance(rv_type, UnpackType) - else StarExpr(self.temp_node(rv_type.type, context)) + ( + self.temp_node(rv_type, context) + if not isinstance(rv_type, UnpackType) + else StarExpr(self.temp_node(rv_type.type, context)) + ) for rv_type in star_rv_types ] ) @@ -6593,8 +6599,7 @@ def check_subtype( notes: list[str] | None = None, code: ErrorCode | None = None, outer_context: Context | None = None, - ) -> bool: - ... + ) -> bool: ... @overload def check_subtype( @@ -6608,8 +6613,7 @@ def check_subtype( *, notes: list[str] | None = None, outer_context: Context | None = None, - ) -> bool: - ... + ) -> bool: ... def check_subtype( self, @@ -7083,14 +7087,12 @@ def conditional_types_with_intersection( type_ranges: list[TypeRange] | None, ctx: Context, default: None = None, - ) -> tuple[Type | None, Type | None]: - ... + ) -> tuple[Type | None, Type | None]: ... @overload def conditional_types_with_intersection( self, expr_type: Type, type_ranges: list[TypeRange] | None, ctx: Context, default: Type - ) -> tuple[Type, Type]: - ... + ) -> tuple[Type, Type]: ... def conditional_types_with_intersection( self, @@ -7348,15 +7350,13 @@ def visit_type_var(self, t: TypeVarType) -> None: @overload def conditional_types( current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: None = None -) -> tuple[Type | None, Type | None]: - ... +) -> tuple[Type | None, Type | None]: ... @overload def conditional_types( current_type: Type, proposed_type_ranges: list[TypeRange] | None, default: Type -) -> tuple[Type, Type]: - ... +) -> tuple[Type, Type]: ... def conditional_types( diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index c628a3398b59..ff7b7fa2ff58 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -2132,11 +2132,13 @@ def infer_function_type_arguments( unknown = UninhabitedType() unknown.ambiguous = True inferred_args = [ - expand_type( - a, {v.id: unknown for v in list(callee_type.variables) + free_vars} + ( + expand_type( + a, {v.id: unknown for v in list(callee_type.variables) + free_vars} + ) + if a is not None + else None ) - if a is not None - else None for a in poly_inferred_args ] else: @@ -6042,14 +6044,12 @@ def bool_type(self) -> Instance: return self.named_type("builtins.bool") @overload - def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type: - ... + def narrow_type_from_binder(self, expr: Expression, known_type: Type) -> Type: ... @overload def narrow_type_from_binder( self, expr: Expression, known_type: Type, skip_non_overlapping: bool - ) -> Type | None: - ... + ) -> Type | None: ... def narrow_type_from_binder( self, expr: Expression, known_type: Type, skip_non_overlapping: bool = False diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 3210dcc3b7ac..7b6a55324741 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -305,11 +305,10 @@ def visit_sequence_pattern(self, o: SequencePattern) -> PatternType: narrowed_inner_types = [] inner_rest_types = [] for inner_type, new_inner_type in zip(inner_types, new_inner_types): - ( - narrowed_inner_type, - inner_rest_type, - ) = self.chk.conditional_types_with_intersection( - new_inner_type, [get_type_range(inner_type)], o, default=new_inner_type + (narrowed_inner_type, inner_rest_type) = ( + self.chk.conditional_types_with_intersection( + new_inner_type, [get_type_range(inner_type)], o, default=new_inner_type + ) ) narrowed_inner_types.append(narrowed_inner_type) inner_rest_types.append(inner_rest_type) diff --git a/mypy/evalexpr.py b/mypy/evalexpr.py index 4b3abb1be3e2..e39c5840d47a 100644 --- a/mypy/evalexpr.py +++ b/mypy/evalexpr.py @@ -6,6 +6,7 @@ put it in a mypyc-compiled file. """ + import ast from typing import Final diff --git a/mypy/expandtype.py b/mypy/expandtype.py index f6aa74add9d8..b4bc1aa9b9a5 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -50,18 +50,15 @@ @overload -def expand_type(typ: CallableType, env: Mapping[TypeVarId, Type]) -> CallableType: - ... +def expand_type(typ: CallableType, env: Mapping[TypeVarId, Type]) -> CallableType: ... @overload -def expand_type(typ: ProperType, env: Mapping[TypeVarId, Type]) -> ProperType: - ... +def expand_type(typ: ProperType, env: Mapping[TypeVarId, Type]) -> ProperType: ... @overload -def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: - ... +def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: ... def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: @@ -72,18 +69,15 @@ def expand_type(typ: Type, env: Mapping[TypeVarId, Type]) -> Type: @overload -def expand_type_by_instance(typ: CallableType, instance: Instance) -> CallableType: - ... +def expand_type_by_instance(typ: CallableType, instance: Instance) -> CallableType: ... @overload -def expand_type_by_instance(typ: ProperType, instance: Instance) -> ProperType: - ... +def expand_type_by_instance(typ: ProperType, instance: Instance) -> ProperType: ... @overload -def expand_type_by_instance(typ: Type, instance: Instance) -> Type: - ... +def expand_type_by_instance(typ: Type, instance: Instance) -> Type: ... def expand_type_by_instance(typ: Type, instance: Instance) -> Type: @@ -470,13 +464,11 @@ def expand_types(self, types: Iterable[Type]) -> list[Type]: @overload -def expand_self_type(var: Var, typ: ProperType, replacement: ProperType) -> ProperType: - ... +def expand_self_type(var: Var, typ: ProperType, replacement: ProperType) -> ProperType: ... @overload -def expand_self_type(var: Var, typ: Type, replacement: Type) -> Type: - ... +def expand_self_type(var: Var, typ: Type, replacement: Type) -> Type: ... def expand_self_type(var: Var, typ: Type, replacement: Type) -> Type: diff --git a/mypy/fastparse.py b/mypy/fastparse.py index b3e0fc70a9d6..a155187992ec 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -608,10 +608,9 @@ def fix_function_overloads(self, stmts: list[Statement]) -> list[Statement]: # Check IfStmt block to determine if function overloads can be merged if_overload_name = self._check_ifstmt_for_overloads(stmt, current_overload_name) if if_overload_name is not None: - ( - if_block_with_overload, - if_unknown_truth_value, - ) = self._get_executable_if_block_with_overloads(stmt) + (if_block_with_overload, if_unknown_truth_value) = ( + self._get_executable_if_block_with_overloads(stmt) + ) if ( current_overload_name is not None @@ -911,9 +910,11 @@ def do_func_def( # PEP 484 disallows both type annotations and type comments self.fail(message_registry.DUPLICATE_TYPE_SIGNATURES, lineno, n.col_offset) arg_types = [ - a.type_annotation - if a.type_annotation is not None - else AnyType(TypeOfAny.unannotated) + ( + a.type_annotation + if a.type_annotation is not None + else AnyType(TypeOfAny.unannotated) + ) for a in args ] else: @@ -1790,12 +1791,10 @@ def invalid_type(self, node: AST, note: str | None = None) -> RawExpressionType: ) @overload - def visit(self, node: ast3.expr) -> ProperType: - ... + def visit(self, node: ast3.expr) -> ProperType: ... @overload - def visit(self, node: AST | None) -> ProperType | None: - ... + def visit(self, node: AST | None) -> ProperType | None: ... def visit(self, node: AST | None) -> ProperType | None: """Modified visit -- keep track of the stack of nodes""" diff --git a/mypy/join.py b/mypy/join.py index d33cbd98726d..bf88f43d88fe 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -237,13 +237,11 @@ def trivial_join(s: Type, t: Type) -> Type: @overload def join_types( s: ProperType, t: ProperType, instance_joiner: InstanceJoiner | None = None -) -> ProperType: - ... +) -> ProperType: ... @overload -def join_types(s: Type, t: Type, instance_joiner: InstanceJoiner | None = None) -> Type: - ... +def join_types(s: Type, t: Type, instance_joiner: InstanceJoiner | None = None) -> Type: ... def join_types(s: Type, t: Type, instance_joiner: InstanceJoiner | None = None) -> Type: diff --git a/mypy/main.py b/mypy/main.py index b32624456ce0..c2df79d51e83 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -342,7 +342,6 @@ def infer_python_executable(options: Options, special_opts: argparse.Namespace) class CapturableArgumentParser(argparse.ArgumentParser): - """Override ArgumentParser methods that use sys.stdout/sys.stderr directly. This is needed because hijacking sys.std* is not thread-safe, @@ -396,7 +395,6 @@ def error(self, message: str) -> NoReturn: class CapturableVersionAction(argparse.Action): - """Supplement CapturableArgumentParser to handle --version. This is nearly identical to argparse._VersionAction except, diff --git a/mypy/metastore.py b/mypy/metastore.py index 0547f94cd671..4caa7d7f0534 100644 --- a/mypy/metastore.py +++ b/mypy/metastore.py @@ -63,8 +63,7 @@ def commit(self) -> None: """ @abstractmethod - def list_all(self) -> Iterable[str]: - ... + def list_all(self) -> Iterable[str]: ... def random_string() -> str: diff --git a/mypy/nodes.py b/mypy/nodes.py index 6c23c51dfcd3..1c781320580a 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -3287,13 +3287,13 @@ def serialize(self) -> JsonDict: "declared_metaclass": ( None if self.declared_metaclass is None else self.declared_metaclass.serialize() ), - "metaclass_type": None - if self.metaclass_type is None - else self.metaclass_type.serialize(), + "metaclass_type": ( + None if self.metaclass_type is None else self.metaclass_type.serialize() + ), "tuple_type": None if self.tuple_type is None else self.tuple_type.serialize(), - "typeddict_type": None - if self.typeddict_type is None - else self.typeddict_type.serialize(), + "typeddict_type": ( + None if self.typeddict_type is None else self.typeddict_type.serialize() + ), "flags": get_flags(self, TypeInfo.FLAGS), "metadata": self.metadata, "slots": sorted(self.slots) if self.slots is not None else None, diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index 19a402492aef..345ea822ed94 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -185,9 +185,11 @@ def serialize(self) -> JsonDict: "init": self.init, "kw_only": self.kw_only, "has_converter": self.converter is not None, - "converter_init_type": self.converter.init_type.serialize() - if self.converter and self.converter.init_type - else None, + "converter_init_type": ( + self.converter.init_type.serialize() + if self.converter and self.converter.init_type + else None + ), "context_line": self.context.line, "context_column": self.context.column, "init_type": self.init_type.serialize() if self.init_type else None, @@ -1073,9 +1075,11 @@ def _meet_fields(types: list[Mapping[str, Type]]) -> Mapping[str, Type]: field_to_types[name].append(typ) return { - name: get_proper_type(reduce(meet_types, f_types)) - if len(f_types) == len(types) - else UninhabitedType() + name: ( + get_proper_type(reduce(meet_types, f_types)) + if len(f_types) == len(types) + else UninhabitedType() + ) for name, f_types in field_to_types.items() } diff --git a/mypy/plugins/enums.py b/mypy/plugins/enums.py index 2c568f66c62d..83350fe2fe11 100644 --- a/mypy/plugins/enums.py +++ b/mypy/plugins/enums.py @@ -10,6 +10,7 @@ we actually bake some of it directly in to the semantic analysis layer (see semanal_enum.py). """ + from __future__ import annotations from typing import Final, Iterable, Sequence, TypeVar, cast diff --git a/mypy/plugins/functools.py b/mypy/plugins/functools.py index 0aa2824c9b51..792ed6669503 100644 --- a/mypy/plugins/functools.py +++ b/mypy/plugins/functools.py @@ -1,4 +1,5 @@ """Plugin for supporting the functools standard library module.""" + from __future__ import annotations from typing import Final, NamedTuple diff --git a/mypy/semanal_shared.py b/mypy/semanal_shared.py index e8edfe65c8d4..b5ec2bb52a0d 100644 --- a/mypy/semanal_shared.py +++ b/mypy/semanal_shared.py @@ -308,8 +308,7 @@ def calculate_tuple_fallback(typ: TupleType) -> None: class _NamedTypeCallback(Protocol): - def __call__(self, fully_qualified_name: str, args: list[Type] | None = None) -> Instance: - ... + def __call__(self, fully_qualified_name: str, args: list[Type] | None = None) -> Instance: ... def paramspec_args( @@ -453,8 +452,7 @@ def require_bool_literal_argument( expression: Expression, name: str, default: Literal[True] | Literal[False], -) -> bool: - ... +) -> bool: ... @overload @@ -463,8 +461,7 @@ def require_bool_literal_argument( expression: Expression, name: str, default: None = None, -) -> bool | None: - ... +) -> bool | None: ... def require_bool_literal_argument( diff --git a/mypy/semanal_typeddict.py b/mypy/semanal_typeddict.py index dbec981bdc96..eee98d4d20fa 100644 --- a/mypy/semanal_typeddict.py +++ b/mypy/semanal_typeddict.py @@ -156,12 +156,9 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> tuple[bool, TypeInfo | N # Iterate over bases in reverse order so that leftmost base class' keys take precedence for base in reversed(typeddict_bases): self.add_keys_and_types_from_base(base, keys, types, required_keys, defn) - ( - new_keys, - new_types, - new_statements, - new_required_keys, - ) = self.analyze_typeddict_classdef_fields(defn, keys) + (new_keys, new_types, new_statements, new_required_keys) = ( + self.analyze_typeddict_classdef_fields(defn, keys) + ) if new_keys is None: return True, None # Defer keys.extend(new_keys) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 7ab3a2b1e5d0..225c1c35c1be 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1519,9 +1519,11 @@ def safe_inspect_signature(runtime: Any) -> inspect.Signature | None: sig = inspect._signature_fromstr(inspect.Signature, runtime, sig) # type: ignore[attr-defined] assert isinstance(sig, inspect.Signature) new_params = [ - parameter.replace(default=UNREPRESENTABLE) - if parameter.default is ... - else parameter + ( + parameter.replace(default=UNREPRESENTABLE) + if parameter.default is ... + else parameter + ) for parameter in sig.parameters.values() ] return sig.replace(parameters=new_params) diff --git a/mypy/stubutil.py b/mypy/stubutil.py index b7f6131c003d..1a9c2357c58e 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -140,13 +140,11 @@ def fail_missing(mod: str, reason: ModuleNotFoundReason) -> None: @overload -def remove_misplaced_type_comments(source: bytes) -> bytes: - ... +def remove_misplaced_type_comments(source: bytes) -> bytes: ... @overload -def remove_misplaced_type_comments(source: str) -> str: - ... +def remove_misplaced_type_comments(source: str) -> str: ... def remove_misplaced_type_comments(source: str | bytes) -> str | bytes: diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 4fd3f8ff98ca..2d536f892a2a 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -693,9 +693,11 @@ def visit_callable_type(self, left: CallableType) -> bool: is_compat=self._is_subtype, is_proper_subtype=self.proper_subtype, ignore_pos_arg_names=self.subtype_context.ignore_pos_arg_names, - strict_concatenate=(self.options.extra_checks or self.options.strict_concatenate) - if self.options - else False, + strict_concatenate=( + (self.options.extra_checks or self.options.strict_concatenate) + if self.options + else False + ), ) elif isinstance(right, Overloaded): return all(self._is_subtype(left, item) for item in right.items) diff --git a/mypy/test/meta/test_parse_data.py b/mypy/test/meta/test_parse_data.py index 797fdd7b2c8c..bff2d6977612 100644 --- a/mypy/test/meta/test_parse_data.py +++ b/mypy/test/meta/test_parse_data.py @@ -2,6 +2,7 @@ A "meta test" which tests the parsing of .test files. This is not meant to become exhaustive but to ensure we maintain a basic level of ergonomics for mypy contributors. """ + from mypy.test.helpers import Suite from mypy.test.meta._pytest import PytestResult, run_pytest_data_suite diff --git a/mypy/test/meta/test_update_data.py b/mypy/test/meta/test_update_data.py index 40b70157a0e3..820fd359893e 100644 --- a/mypy/test/meta/test_update_data.py +++ b/mypy/test/meta/test_update_data.py @@ -3,6 +3,7 @@ Updating the expected output, especially when it's in the form of inline (comment) assertions, can be brittle, which is why we're "meta-testing" here. """ + from mypy.test.helpers import Suite from mypy.test.meta._pytest import PytestResult, dedent_docstring, run_pytest_data_suite diff --git a/mypy/test/testargs.py b/mypy/test/testargs.py index b0cc6b19aa80..7c139902fe90 100644 --- a/mypy/test/testargs.py +++ b/mypy/test/testargs.py @@ -4,6 +4,7 @@ defaults, and that argparse doesn't assign any new members to the Options object it creates. """ + from __future__ import annotations import argparse diff --git a/mypy/test/testerrorstream.py b/mypy/test/testerrorstream.py index 5ed112fd31e7..a54a3495ddb2 100644 --- a/mypy/test/testerrorstream.py +++ b/mypy/test/testerrorstream.py @@ -1,4 +1,5 @@ """Tests for mypy incremental error output.""" + from __future__ import annotations from mypy import build diff --git a/mypy/test/testreports.py b/mypy/test/testreports.py index 5ff315f83ba8..f638756ad819 100644 --- a/mypy/test/testreports.py +++ b/mypy/test/testreports.py @@ -1,4 +1,5 @@ """Test cases for reports generated by mypy.""" + from __future__ import annotations import textwrap diff --git a/mypy/test/teststubgen.py b/mypy/test/teststubgen.py index ace0b4d95573..c138f9953918 100644 --- a/mypy/test/teststubgen.py +++ b/mypy/test/teststubgen.py @@ -1099,8 +1099,7 @@ def test(arg0: str) -> None: assert_equal(gen.get_imports().splitlines(), ["import foo", "import other"]) def test_generate_c_function_no_crash_for_non_str_docstring(self) -> None: - def test(arg0: str) -> None: - ... + def test(arg0: str) -> None: ... test.__doc__ = property(lambda self: "test(arg0: str) -> None") # type: ignore[assignment] diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 601f98e958e2..2b37d10e2aff 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1775,8 +1775,7 @@ def tuple_type(self, items: list[Type], line: int, column: int) -> TupleType: class MsgCallback(Protocol): - def __call__(self, __msg: str, __ctx: Context, *, code: ErrorCode | None = None) -> None: - ... + def __call__(self, __msg: str, __ctx: Context, *, code: ErrorCode | None = None) -> None: ... def get_omitted_any( diff --git a/mypy/typeops.py b/mypy/typeops.py index 2bf8ffbf47ab..5b396308d955 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -915,9 +915,11 @@ def try_contracting_literals_in_union(types: Sequence[Type]) -> list[ProperType] if typ.fallback.type.is_enum or isinstance(typ.value, bool): if fullname not in sum_types: sum_types[fullname] = ( - set(typ.fallback.get_enum_values()) - if typ.fallback.type.is_enum - else {True, False}, + ( + set(typ.fallback.get_enum_values()) + if typ.fallback.type.is_enum + else {True, False} + ), [], ) literals, indexes = sum_types[fullname] diff --git a/mypy/types.py b/mypy/types.py index f02e56a677ae..0e87ec701386 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1490,9 +1490,9 @@ def copy_modified( args if args is not _dummy else self.args, self.line, self.column, - last_known_value=last_known_value - if last_known_value is not _dummy - else self.last_known_value, + last_known_value=( + last_known_value if last_known_value is not _dummy else self.last_known_value + ), ) # We intentionally don't copy the extra_attrs here, so they will be erased. new.can_be_true = self.can_be_true @@ -2834,13 +2834,13 @@ def __eq__(self, other: object) -> bool: @overload @staticmethod - def make_union(items: Sequence[ProperType], line: int = -1, column: int = -1) -> ProperType: - ... + def make_union( + items: Sequence[ProperType], line: int = -1, column: int = -1 + ) -> ProperType: ... @overload @staticmethod - def make_union(items: Sequence[Type], line: int = -1, column: int = -1) -> Type: - ... + def make_union(items: Sequence[Type], line: int = -1, column: int = -1) -> Type: ... @staticmethod def make_union(items: Sequence[Type], line: int = -1, column: int = -1) -> Type: @@ -3052,13 +3052,11 @@ def serialize(self) -> str: @overload -def get_proper_type(typ: None) -> None: - ... +def get_proper_type(typ: None) -> None: ... @overload -def get_proper_type(typ: Type) -> ProperType: - ... +def get_proper_type(typ: Type) -> ProperType: ... def get_proper_type(typ: Type | None) -> ProperType | None: @@ -3088,8 +3086,7 @@ def get_proper_types(types: list[Type] | tuple[Type, ...]) -> list[ProperType]: @overload def get_proper_types( types: list[Type | None] | tuple[Type | None, ...] -) -> list[ProperType | None]: - ... +) -> list[ProperType | None]: ... def get_proper_types( diff --git a/mypyc/analysis/ircheck.py b/mypyc/analysis/ircheck.py index a31b1517b036..127047e02ff5 100644 --- a/mypyc/analysis/ircheck.py +++ b/mypyc/analysis/ircheck.py @@ -1,4 +1,5 @@ """Utilities for checking that internal ir is valid and consistent.""" + from __future__ import annotations from mypyc.ir.func_ir import FUNC_STATICMETHOD, FuncIR diff --git a/mypyc/codegen/emitfunc.py b/mypyc/codegen/emitfunc.py index 3bce84d3ea59..c08f1f840fa4 100644 --- a/mypyc/codegen/emitfunc.py +++ b/mypyc/codegen/emitfunc.py @@ -535,9 +535,7 @@ def visit_method_call(self, op: MethodCall) -> None: obj_args = ( [] if method.decl.kind == FUNC_STATICMETHOD - else [f"(PyObject *)Py_TYPE({obj})"] - if method.decl.kind == FUNC_CLASSMETHOD - else [obj] + else [f"(PyObject *)Py_TYPE({obj})"] if method.decl.kind == FUNC_CLASSMETHOD else [obj] ) args = ", ".join(obj_args + [self.reg(arg) for arg in op.args]) mtype = native_function_type(method, self.emitter) diff --git a/mypyc/ir/class_ir.py b/mypyc/ir/class_ir.py index 61f0fc36e1b3..18f3cbcff987 100644 --- a/mypyc/ir/class_ir.py +++ b/mypyc/ir/class_ir.py @@ -383,9 +383,9 @@ def serialize(self) -> JsonDict: "traits": [cir.fullname for cir in self.traits], "mro": [cir.fullname for cir in self.mro], "base_mro": [cir.fullname for cir in self.base_mro], - "children": [cir.fullname for cir in self.children] - if self.children is not None - else None, + "children": ( + [cir.fullname for cir in self.children] if self.children is not None else None + ), "deletable": self.deletable, "attrs_with_defaults": sorted(self.attrs_with_defaults), "_always_initialized_attrs": sorted(self._always_initialized_attrs), diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 5ed617aa925f..9d160b08505d 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -10,6 +10,7 @@ example, expressions are transformed in mypyc.irbuild.expression and functions are transformed in mypyc.irbuild.function. """ + from __future__ import annotations from contextlib import contextmanager @@ -231,12 +232,10 @@ def set_module(self, module_name: str, module_path: str) -> None: self.builder.set_module(module_name, module_path) @overload - def accept(self, node: Expression, *, can_borrow: bool = False) -> Value: - ... + def accept(self, node: Expression, *, can_borrow: bool = False) -> Value: ... @overload - def accept(self, node: Statement) -> None: - ... + def accept(self, node: Statement) -> None: ... def accept(self, node: Statement | Expression, *, can_borrow: bool = False) -> Value | None: """Transform an expression or a statement. diff --git a/mypyc/irbuild/nonlocalcontrol.py b/mypyc/irbuild/nonlocalcontrol.py index 02dd51283e95..0ac9bd3cee31 100644 --- a/mypyc/irbuild/nonlocalcontrol.py +++ b/mypyc/irbuild/nonlocalcontrol.py @@ -120,8 +120,7 @@ def __init__(self, outer: NonlocalControl) -> None: self.outer = outer @abstractmethod - def gen_cleanup(self, builder: IRBuilder, line: int) -> None: - ... + def gen_cleanup(self, builder: IRBuilder, line: int) -> None: ... def gen_break(self, builder: IRBuilder, line: int) -> None: self.gen_cleanup(builder, line) diff --git a/test-requirements.in b/test-requirements.in index 2bf8de0aa2f5..5971074a00be 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -4,7 +4,7 @@ -r mypy-requirements.txt -r build-requirements.txt attrs>=18.0 -black==23.9.1 # must match version in .pre-commit-config.yaml +black==24.1.1 # must match version in .pre-commit-config.yaml filelock>=3.3.0 # lxml 4.9.3 switched to manylinux_2_28, the wheel builder still uses manylinux2014 lxml>=4.9.1,<4.9.3; (python_version<'3.11' or sys_platform!='win32') and python_version<'3.12' diff --git a/test-requirements.txt b/test-requirements.txt index 57607c1bae57..683efa2a7334 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,7 +6,7 @@ # attrs==23.1.0 # via -r test-requirements.in -black==23.9.1 +black==24.1.1 # via -r test-requirements.in cfgv==3.4.0 # via pre-commit From d94b972ad3a2f61076ce1a70cf7e1dca1c9fe289 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 1 Feb 2024 15:46:29 +0100 Subject: [PATCH 51/69] Update ruff to 0.1.15 (#16846) --- .pre-commit-config.yaml | 2 +- mypy/types.py | 2 +- test-requirements.in | 2 +- test-requirements.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6566bb0297d8..eec410457641 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: black exclude: '^(test-data/)' - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.4 # must match test-requirements.txt + rev: v0.1.15 # must match test-requirements.txt hooks: - id: ruff args: [--exit-non-zero-on-fix] diff --git a/mypy/types.py b/mypy/types.py index 0e87ec701386..b1119c9447e2 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -3108,7 +3108,7 @@ def get_proper_types( # to make it easier to gradually get modules working with mypyc. # Import them here, after the types are defined. # This is intended as a re-export also. -from mypy.type_visitor import ( # noqa: F811 +from mypy.type_visitor import ( ALL_STRATEGY as ALL_STRATEGY, ANY_STRATEGY as ANY_STRATEGY, BoolTypeQuery as BoolTypeQuery, diff --git a/test-requirements.in b/test-requirements.in index 5971074a00be..8f9d2cae0cce 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -14,6 +14,6 @@ psutil>=4.0 pytest>=7.4.0 pytest-xdist>=1.34.0 pytest-cov>=2.10.0 -ruff==0.1.4 # must match version in .pre-commit-config.yaml +ruff==0.1.15 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 tomli>=1.1.0 # needed even on py311+ so the self check passes with --python-version 3.7 diff --git a/test-requirements.txt b/test-requirements.txt index 683efa2a7334..dcd250970a15 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -67,7 +67,7 @@ ruamel-yaml==0.17.40 # via pre-commit-hooks ruamel-yaml-clib==0.2.8 # via ruamel-yaml -ruff==0.1.4 +ruff==0.1.15 # via -r test-requirements.in tomli==2.0.1 # via -r test-requirements.in From 9f510570c703c57f4ad596a4d8df7d9283d18c4c Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 1 Feb 2024 19:06:52 +0100 Subject: [PATCH 52/69] Remove --python-version 3.7 references from tests (#16848) Remove `--python-version 3.7` from tests if not necessary anymore or use `3.8` where it makes sense instead. --- test-data/unit/check-async-await.test | 5 - test-data/unit/check-callable.test | 1 - test-data/unit/check-dataclass-transform.test | 1 - test-data/unit/check-dataclasses.test | 97 +++---------------- test-data/unit/check-errorcodes.test | 4 +- test-data/unit/check-flags.test | 2 +- test-data/unit/check-generic-alias.test | 8 +- test-data/unit/check-incremental.test | 17 +--- test-data/unit/check-literal.test | 1 - test-data/unit/check-modules.test | 15 +-- test-data/unit/check-namedtuple.test | 1 - test-data/unit/check-narrowing.test | 3 - test-data/unit/check-newsemanal.test | 3 +- test-data/unit/check-newtype.test | 1 - test-data/unit/check-union-or-syntax.test | 1 - test-data/unit/check-unreachable-code.test | 10 +- test-data/unit/deps.test | 1 - test-data/unit/fine-grained.test | 21 ++-- test-requirements.in | 2 +- 19 files changed, 38 insertions(+), 156 deletions(-) diff --git a/test-data/unit/check-async-await.test b/test-data/unit/check-async-await.test index f0fa206645dd..713c82c752ce 100644 --- a/test-data/unit/check-async-await.test +++ b/test-data/unit/check-async-await.test @@ -819,8 +819,6 @@ def bar() -> None: [typing fixtures/typing-async.pyi] [case testAsyncForOutsideCoroutine] -# flags: --python-version 3.7 - async def g(): yield 0 @@ -841,8 +839,6 @@ async for x in g(): ... # E: "async for" outside async function [typing fixtures/typing-async.pyi] [case testAsyncWithOutsideCoroutine] -# flags: --python-version 3.7 - class C: async def __aenter__(self): pass async def __aexit__(self, x, y, z): pass @@ -858,7 +854,6 @@ async with C() as x: # E: "async with" outside async function [typing fixtures/typing-async.pyi] [case testAwaitMissingNote] -# flags: --python-version 3.7 from typing import Generic, TypeVar, Generator, Any, Awaitable, Type class C: diff --git a/test-data/unit/check-callable.test b/test-data/unit/check-callable.test index 8a611a689be5..39e6c4fa3ff1 100644 --- a/test-data/unit/check-callable.test +++ b/test-data/unit/check-callable.test @@ -525,7 +525,6 @@ else: [builtins fixtures/callable.pyi] [case testBuiltinsTypeAsCallable] -# flags: --python-version 3.7 from __future__ import annotations reveal_type(type) # N: Revealed type is "def (x: Any) -> builtins.type" diff --git a/test-data/unit/check-dataclass-transform.test b/test-data/unit/check-dataclass-transform.test index 743c7fef8aa9..51b2e186214f 100644 --- a/test-data/unit/check-dataclass-transform.test +++ b/test-data/unit/check-dataclass-transform.test @@ -22,7 +22,6 @@ Person('Jonh', 21, None) # E: Too many arguments for "Person" [builtins fixtures/dataclasses.pyi] [case testDataclassTransformIsFoundInTypingExtensions] -# flags: --python-version 3.7 from typing import Type from typing_extensions import dataclass_transform diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index 107298875761..b57fe8f548c4 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1,5 +1,4 @@ [case testDataclassesBasic] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -18,7 +17,6 @@ Person('Jonh', 21, None) # E: Too many arguments for "Person" [typing fixtures/typing-medium.pyi] [case testDataclassesCustomInit] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -33,7 +31,6 @@ A('1') [builtins fixtures/dataclasses.pyi] [case testDataclassesBasicInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -56,7 +53,6 @@ Person(21, 'Jonh', None) # E: Too many arguments for "Person" [typing fixtures/typing-medium.pyi] [case testDataclassesDeepInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -83,7 +79,6 @@ reveal_type(D) # N: Revealed type is "def (a: builtins.int, b: builtins.int, c: [builtins fixtures/dataclasses.pyi] [case testDataclassesMultipleInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass, field, InitVar @dataclass class A: @@ -106,7 +101,6 @@ reveal_type(C) # N: Revealed type is "def (b: builtins.bool, a: builtins.bool) [builtins fixtures/dataclasses.pyi] [case testDataclassesDeepInitVarInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass, field, InitVar @dataclass class A: @@ -135,7 +129,6 @@ reveal_type(D) # N: Revealed type is "def (b: builtins.bool) -> __main__.D" [builtins fixtures/dataclasses.pyi] [case testDataclassesOverriding] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -169,7 +162,6 @@ ExtraSpecialPerson(21, 'John', 0.5) [case testDataclassesOverridingWithDefaults] # Issue #5681 https://github.com/python/mypy/issues/5681 -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Any @@ -188,7 +180,6 @@ reveal_type(C) # N: Revealed type is "def (some_int: builtins.int, some_str: bu [builtins fixtures/dataclasses.pyi] [case testDataclassIncompatibleOverrides] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -217,7 +208,6 @@ class BadDerived3(Base): [builtins fixtures/dataclasses.pyi] [case testDataclassMultipleInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass class Unrelated: @@ -237,7 +227,6 @@ reveal_type(d.bar) # N: Revealed type is "builtins.int" [builtins fixtures/dataclasses.pyi] [case testDataclassIncompatibleFrozenOverride] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(frozen=True) @@ -252,7 +241,6 @@ class BadDerived(Base): [builtins fixtures/dataclasses.pyi] [case testDataclassesFreezing] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(frozen=True) @@ -265,7 +253,6 @@ john.name = 'Ben' # E: Property "name" defined in "Person" is read-only [builtins fixtures/dataclasses.pyi] [case testDataclassesInconsistentFreezing] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(frozen=True) @@ -287,7 +274,6 @@ class BadFrozenDerived(NormalBase): # E: Cannot inherit frozen dataclass from a [builtins fixtures/dataclasses.pyi] [case testDataclassesFields] -# flags: --python-version 3.7 from dataclasses import dataclass, field @dataclass @@ -303,7 +289,6 @@ john.age = 24 [builtins fixtures/dataclasses.pyi] [case testDataclassesBadInit] -# flags: --python-version 3.7 from dataclasses import dataclass, field @dataclass @@ -318,7 +303,6 @@ class Person: [builtins fixtures/dataclasses.pyi] [case testDataclassesMultiInit] -# flags: --python-version 3.7 from dataclasses import dataclass, field from typing import List @@ -334,7 +318,6 @@ reveal_type(Person) # N: Revealed type is "def (name: builtins.str, friend_name [builtins fixtures/dataclasses.pyi] [case testDataclassesMultiInitDefaults] -# flags: --python-version 3.7 from dataclasses import dataclass, field from typing import List, Optional @@ -351,7 +334,6 @@ reveal_type(Person) # N: Revealed type is "def (name: builtins.str, friend_name [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaults] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -365,7 +347,6 @@ app = Application() [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaultFactories] -# flags: --python-version 3.7 from dataclasses import dataclass, field @dataclass @@ -377,7 +358,6 @@ class Application: [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaultFactoryTypeChecking] -# flags: --python-version 3.7 from dataclasses import dataclass, field @dataclass @@ -388,7 +368,6 @@ class Application: [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaultOrdering] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -533,7 +512,6 @@ class Base: [builtins fixtures/dataclasses.pyi] [case testDataclassesClassmethods] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -549,7 +527,6 @@ app = Application.parse('') [builtins fixtures/dataclasses.pyi] [case testDataclassesOverloadsAndClassmethods] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import overload, Union @@ -582,20 +559,18 @@ reveal_type(A.foo("foo")) # N: Revealed type is "builtins.str" [builtins fixtures/dataclasses.pyi] [case testClassmethodShadowingFieldDoesNotCrash] -# flags: --python-version 3.7 from dataclasses import dataclass # This used to crash -- see #6217 @dataclass class Foo: bar: str - @classmethod # E: Name "bar" already defined on line 7 + @classmethod # E: Name "bar" already defined on line 6 def bar(cls) -> "Foo": return cls('asdf') [builtins fixtures/dataclasses.pyi] [case testDataclassesClassVars] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import ClassVar @@ -613,7 +588,6 @@ Application.COUNTER = 1 [builtins fixtures/dataclasses.pyi] [case testTypeAliasInDataclassDoesNotCrash] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Callable from typing_extensions import TypeAlias @@ -642,7 +616,6 @@ reveal_type(x) # N: Revealed type is "typing._SpecialForm" [typing fixtures/typing-medium.pyi] [case testDataclassOrdering] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(order=True) @@ -673,7 +646,6 @@ app1 >= app3 [builtins fixtures/dataclasses.pyi] [case testDataclassOrderingWithoutEquality] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(eq=False, order=True) # E: "eq" must be True if "order" is True @@ -683,7 +655,6 @@ class Application: [builtins fixtures/dataclasses.pyi] [case testDataclassOrderingWithCustomMethods] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(order=True) @@ -694,7 +665,6 @@ class Application: [builtins fixtures/dataclasses.pyi] [case testDataclassDefaultsInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Optional @@ -712,7 +682,6 @@ reveal_type(SpecializedApplication) # N: Revealed type is "def (id: Union[built [builtins fixtures/dataclasses.pyi] [case testDataclassGenerics] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, List, Optional, TypeVar @@ -757,7 +726,6 @@ class MyDataclass(Generic[T_co]): [builtins fixtures/dataclasses.pyi] [case testDataclassUntypedGenericInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -778,7 +746,6 @@ reveal_type(sub.attr) # N: Revealed type is "Any" [builtins fixtures/dataclasses.pyi] [case testDataclassGenericSubtype] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -805,7 +772,6 @@ reveal_type(sub_str.attr) # N: Revealed type is "builtins.str" [builtins fixtures/dataclasses.pyi] [case testDataclassGenericInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -832,7 +798,6 @@ reveal_type(sub.three) # N: Revealed type is "builtins.float" [builtins fixtures/dataclasses.pyi] [case testDataclassMultiGenericInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -860,7 +825,6 @@ reveal_type(sub.middle_attr) # N: Revealed type is "builtins.str" [builtins fixtures/dataclasses.pyi] [case testDataclassGenericsClassmethod] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -882,7 +846,6 @@ reveal_type(A(0).other) # N: Revealed type is "def (x: builtins.int) -> __main_ [builtins fixtures/dataclasses.pyi] [case testDataclassesForwardRefs] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -901,7 +864,6 @@ A(b=42) # E: Argument "b" to "A" has incompatible type "int"; expected "B" [case testDataclassesInitVars] -# flags: --python-version 3.7 from dataclasses import InitVar, dataclass @dataclass @@ -930,7 +892,6 @@ app.database_name # E: "SpecializedApplication" has no attribute "database_name [builtins fixtures/dataclasses.pyi] [case testDataclassesInitVarsAndDefer] -# flags: --python-version 3.7 from dataclasses import InitVar, dataclass defer: Yes @@ -950,7 +911,6 @@ class Yes: ... [builtins fixtures/dataclasses.pyi] [case testDataclassesNoInitInitVarInheritance] -# flags: --python-version 3.7 from dataclasses import dataclass, field, InitVar @dataclass @@ -967,7 +927,6 @@ sub.bar [builtins fixtures/dataclasses.pyi] [case testDataclassFactory] -# flags: --python-version 3.7 from typing import Type, TypeVar from dataclasses import dataclass @@ -983,7 +942,6 @@ class A: [builtins fixtures/dataclasses.pyi] [case testDataclassesInitVarOverride] -# flags: --python-version 3.7 import dataclasses @dataclasses.dataclass @@ -1006,7 +964,6 @@ class B(A): [builtins fixtures/dataclasses.pyi] [case testDataclassesInitVarNoOverride] -# flags: --python-version 3.7 import dataclasses @dataclasses.dataclass @@ -1032,7 +989,6 @@ B(1, 'a') # E: Argument 2 to "B" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] [case testDataclassesInitVarPostInitOverride] -# flags: --python-version 3.7 import dataclasses @dataclasses.dataclass @@ -1068,7 +1024,6 @@ C(1, 'a') # E: Argument 2 to "C" has incompatible type "str"; expected "int" [builtins fixtures/primitives.pyi] [case testDataclassesInitVarIncremental] -# flags: --python-version 3.7 import a [file a.py] @@ -1114,7 +1069,6 @@ tmp/a.py:12: note: Revealed type is "def (a: builtins.int) -> a.B" [case testNoComplainFieldNone] -# flags: --python-version 3.7 # flags: --no-strict-optional from dataclasses import dataclass, field from typing import Optional @@ -1126,7 +1080,6 @@ class Foo: [out] [case testNoComplainFieldNoneStrict] -# flags: --python-version 3.7 from dataclasses import dataclass, field from typing import Optional @@ -1137,7 +1090,7 @@ class Foo: [out] [case testDisallowUntypedWorksForward] -# flags: --disallow-untyped-defs --python-version 3.7 +# flags: --disallow-untyped-defs from dataclasses import dataclass from typing import List @@ -1152,7 +1105,7 @@ reveal_type(B) # N: Revealed type is "def (x: __main__.C) -> __main__.B" [builtins fixtures/dataclasses.pyi] [case testDisallowUntypedWorksForwardBad] -# flags: --disallow-untyped-defs --python-version 3.7 +# flags: --disallow-untyped-defs from dataclasses import dataclass @dataclass @@ -1164,7 +1117,6 @@ reveal_type(B) # N: Revealed type is "def (x: Any) -> __main__.B" [builtins fixtures/dataclasses.pyi] [case testMemberExprWorksAsField] -# flags: --python-version 3.7 import dataclasses @dataclasses.dataclass @@ -1184,7 +1136,6 @@ class C: [builtins fixtures/dict.pyi] [case testDataclassOrderingDeferred] -# flags: --python-version 3.7 from dataclasses import dataclass defer: Yes @@ -1202,7 +1153,6 @@ class Yes: ... [builtins fixtures/dataclasses.pyi] [case testDataclassFieldDeferred] -# flags: --python-version 3.7 from dataclasses import field, dataclass @dataclass @@ -1214,7 +1164,6 @@ C('no') # E: Argument 1 to "C" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] [case testDataclassFieldDeferredFrozen] -# flags: --python-version 3.7 from dataclasses import field, dataclass @dataclass(frozen=True) @@ -1227,7 +1176,6 @@ c.x = 1 # E: Property "x" defined in "C" is read-only [builtins fixtures/dataclasses.pyi] [case testTypeInDataclassDeferredStar] -# flags: --python-version 3.7 import lib [file lib.py] from dataclasses import dataclass @@ -1246,7 +1194,7 @@ import lib [builtins fixtures/dataclasses.pyi] [case testDeferredDataclassInitSignature] -# flags: --python-version 3.7 --no-strict-optional +# flags: --no-strict-optional from dataclasses import dataclass from typing import Optional, Type @@ -1263,7 +1211,6 @@ class Deferred: pass [builtins fixtures/dataclasses.pyi] [case testDeferredDataclassInitSignatureSubclass] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Optional @@ -1279,7 +1226,6 @@ a = C(None, 'abc') [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaultsIncremental] -# flags: --python-version 3.7 import a [file a.py] @@ -1311,7 +1257,6 @@ class Person: [builtins fixtures/dataclasses.pyi] [case testDataclassesDefaultsMroOtherFile] -# flags: --python-version 3.7 import a [file a.py] @@ -1340,14 +1285,13 @@ class A2: [builtins fixtures/dataclasses.pyi] [case testDataclassesInheritingDuplicateField] -# flags: --python-version 3.7 # see mypy issue #7792 from dataclasses import dataclass @dataclass class A: x: int = 0 - x: int = 0 # E: Name "x" already defined on line 7 + x: int = 0 # E: Name "x" already defined on line 6 @dataclass class B(A): @@ -1356,7 +1300,6 @@ class B(A): [builtins fixtures/dataclasses.pyi] [case testDataclassInheritanceNoAnnotation] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -1373,7 +1316,6 @@ reveal_type(B) # N: Revealed type is "def (foo: builtins.int) -> __main__.B" [builtins fixtures/dataclasses.pyi] [case testDataclassInheritanceNoAnnotation2] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass(frozen=True) @@ -1390,7 +1332,6 @@ reveal_type(B) # N: Revealed type is "def (foo: builtins.int) -> __main__.B" [builtins fixtures/dataclasses.pyi] [case testDataclassHasAttributeWithFields] -# flags: --python-version 3.7 from dataclasses import dataclass @dataclass @@ -1402,7 +1343,6 @@ reveal_type(A.__dataclass_fields__) # N: Revealed type is "builtins.dict[builti [builtins fixtures/dict.pyi] [case testDataclassCallableFieldAccess] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Callable @@ -1420,7 +1360,6 @@ reveal_type(A.y) # N: Revealed type is "def (builtins.int) -> builtins.int" [builtins fixtures/dataclasses.pyi] [case testDataclassCallableFieldAssignment] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Callable @@ -1439,7 +1378,6 @@ a.x = x2 # E: Incompatible types in assignment (expression has type "Callable[[s [builtins fixtures/dataclasses.pyi] [case testDataclassFieldDoesNotFailOnKwargsUnpacking] -# flags: --python-version 3.7 # https://github.com/python/mypy/issues/10879 from dataclasses import dataclass, field @@ -1447,16 +1385,15 @@ from dataclasses import dataclass, field class Foo: bar: float = field(**{"repr": False}) [out] -main:7: error: Unpacking **kwargs in "field()" is not supported -main:7: error: No overload variant of "field" matches argument type "Dict[str, bool]" -main:7: note: Possible overload variants: -main:7: note: def [_T] field(*, default: _T, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T -main:7: note: def [_T] field(*, default_factory: Callable[[], _T], init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T -main:7: note: def field(*, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> Any +main:6: error: Unpacking **kwargs in "field()" is not supported +main:6: error: No overload variant of "field" matches argument type "Dict[str, bool]" +main:6: note: Possible overload variants: +main:6: note: def [_T] field(*, default: _T, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T +main:6: note: def [_T] field(*, default_factory: Callable[[], _T], init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T +main:6: note: def field(*, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> Any [builtins fixtures/dataclasses.pyi] [case testDataclassFieldWithPositionalArguments] -# flags: --python-version 3.7 from dataclasses import dataclass, field @dataclass @@ -1470,7 +1407,6 @@ class C: [builtins fixtures/dataclasses.pyi] [case testDataclassFieldWithTypedDictUnpacking] -# flags: --python-version 3.7 from dataclasses import dataclass, field from typing_extensions import TypedDict @@ -1668,7 +1604,6 @@ class PublishedMessages: [builtins fixtures/dataclasses.pyi] [case testDataclassesAnyInherit] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Any B: Any @@ -1682,7 +1617,6 @@ A(a="foo") # E: Argument "a" to "A" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] [case testDataclassesCallableFrozen] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Any, Callable @dataclass(frozen=True) @@ -1698,7 +1632,6 @@ A(a=func).a = func # E: Property "a" defined in "A" is read-only [builtins fixtures/dataclasses.pyi] [case testDataclassInFunctionDoesNotCrash] -# flags: --python-version 3.7 from dataclasses import dataclass def foo() -> None: @@ -1728,7 +1661,6 @@ class Derived(A, B): [builtins fixtures/dataclasses.pyi] [case testDataclassGenericInheritance2] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Any, Callable, Generic, TypeVar, List @@ -1760,7 +1692,6 @@ reveal_type(Child2[int, A]([A()], [1]).b) # N: Revealed type is "builtins.list[ [builtins fixtures/dataclasses.pyi] [case testDataclassInheritOptionalType] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Any, Callable, Generic, TypeVar, List, Optional @@ -1779,7 +1710,6 @@ Child(x=None, y=None) [builtins fixtures/dataclasses.pyi] [case testDataclassGenericInheritanceSpecialCase1] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar, List @@ -1803,7 +1733,6 @@ def g(c: Child1) -> None: [builtins fixtures/dataclasses.pyi] [case testDataclassGenericInheritanceSpecialCase2] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -1829,7 +1758,6 @@ Child2(y=1, key='') [builtins fixtures/dataclasses.pyi] [case testDataclassGenericWithBound] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import Generic, TypeVar @@ -1845,7 +1773,6 @@ C(x=2) [builtins fixtures/dataclasses.pyi] [case testDataclassGenericBoundToInvalidTypeVarDoesNotCrash] -# flags: --python-version 3.7 import dataclasses from typing import Generic, TypeVar @@ -1857,7 +1784,6 @@ class C(Generic[T]): [builtins fixtures/dataclasses.pyi] [case testDataclassInitVarCannotBeSet] -# flags: --python-version 3.7 from dataclasses import dataclass, InitVar @dataclass @@ -1877,7 +1803,6 @@ c.x # E: "C" has no attribute "x" [builtins fixtures/dataclasses.pyi] [case testDataclassCheckTypeVarBounds] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import ClassVar, Protocol, Dict, TypeVar, Generic diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 1dd058730f28..7f5f05d37595 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -124,10 +124,10 @@ z # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment [unuse # flags: --enable-error-code ignore-without-code # type: ignore # whole file ignore x -y # type: ignore # ignore the lack of error code since we're ignore the whole file +y # type: ignore # ignore the lack of error code since we ignore the whole file [case testErrorCodeMissingMultiple] -# flags: --enable-error-code ignore-without-code --python-version 3.7 +# flags: --enable-error-code ignore-without-code from __future__ import annotations class A: attr: int diff --git a/test-data/unit/check-flags.test b/test-data/unit/check-flags.test index 04adaca317c1..c90c773e320f 100644 --- a/test-data/unit/check-flags.test +++ b/test-data/unit/check-flags.test @@ -1655,7 +1655,7 @@ __all__ = ('b',) [builtins fixtures/tuple.pyi] [case testNoImplicitReexportGetAttr] -# flags: --no-implicit-reexport --python-version 3.7 +# flags: --no-implicit-reexport from other_module_2 import a # E: Module "other_module_2" does not explicitly export attribute "a" reveal_type(a) # N: Revealed type is "builtins.int" from other_module_2 import b # E: Module "other_module_2" does not explicitly export attribute "b" diff --git a/test-data/unit/check-generic-alias.test b/test-data/unit/check-generic-alias.test index 8c90b5adba34..3ae815a5cd48 100644 --- a/test-data/unit/check-generic-alias.test +++ b/test-data/unit/check-generic-alias.test @@ -1,7 +1,7 @@ -- Test cases for generic aliases [case testGenericBuiltinWarning] -# flags: --python-version 3.7 +# flags: --python-version 3.8 t1: list t2: list[int] # E: "list" is not subscriptable, use "typing.List" instead t3: list[str] # E: "list" is not subscriptable, use "typing.List" instead @@ -21,14 +21,14 @@ t11: type[int] # E: "type" expects no type arguments, but 1 given [case testGenericBuiltinSetWarning] -# flags: --python-version 3.7 +# flags: --python-version 3.8 t1: set t2: set[int] # E: "set" is not subscriptable, use "typing.Set" instead [builtins fixtures/set.pyi] [case testGenericCollectionsWarning] -# flags: --python-version 3.7 +# flags: --python-version 3.8 import collections t01: collections.deque @@ -44,7 +44,6 @@ t10: collections.ChainMap[int, str] # E: "ChainMap" is not subscriptable, use " [case testGenericBuiltinFutureAnnotations] -# flags: --python-version 3.7 from __future__ import annotations t1: list t2: list[int] @@ -64,7 +63,6 @@ t11: type[int] [case testGenericCollectionsFutureAnnotations] -# flags: --python-version 3.7 from __future__ import annotations import collections diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 2c7d908c5f5b..69381227ca8e 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -3796,7 +3796,6 @@ import b [rechecked b] [case testIncrementalDataclassesSubclassingCached] -# flags: --python-version 3.7 from a import A from dataclasses import dataclass @@ -3829,7 +3828,6 @@ class A: [out2] [case testIncrementalDataclassesSubclassingCachedType] -# flags: --python-version 3.7 import b [file b.py] @@ -3863,7 +3861,6 @@ class A: tmp/b.py:8: note: Revealed type is "def (x: builtins.int) -> b.B" [case testIncrementalDataclassesArguments] -# flags: --python-version 3.7 import b [file b.py] @@ -3912,7 +3909,6 @@ tmp/b.py:15: error: Unsupported left operand type for > ("NoCmp") tmp/b.py:16: error: Unsupported left operand type for >= ("NoCmp") [case testIncrementalDataclassesDunder] -# flags: --python-version 3.7 import b [file b.py] @@ -3977,7 +3973,6 @@ tmp/b.py:27: error: Unsupported operand types for < ("A" and "int") tmp/b.py:28: error: Unsupported operand types for <= ("A" and "int") [case testIncrementalDataclassesSubclassModified] -# flags: --python-version 3.7 from b import B B(5, 'foo') @@ -4007,11 +4002,10 @@ class B(A): [builtins fixtures/dataclasses.pyi] [out1] [out2] -main:3: error: Argument 2 to "B" has incompatible type "str"; expected "int" +main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int" [rechecked b] [case testIncrementalDataclassesSubclassModifiedErrorFirst] -# flags: --python-version 3.7 from b import B B(5, 'foo') @@ -4040,13 +4034,12 @@ class B(A): [builtins fixtures/dataclasses.pyi] [out1] -main:3: error: Argument 2 to "B" has incompatible type "str"; expected "int" +main:2: error: Argument 2 to "B" has incompatible type "str"; expected "int" [out2] [rechecked b] [case testIncrementalDataclassesThreeFiles] -# flags: --python-version 3.7 from c import C C('foo', 5, True) @@ -4085,10 +4078,9 @@ class C(A, B): [out1] [out2] tmp/c.py:7: error: Incompatible types in assignment (expression has type "bool", base class "B" defined the type as "str") -main:3: error: Argument 2 to "C" has incompatible type "int"; expected "bool" +main:2: error: Argument 2 to "C" has incompatible type "int"; expected "bool" [case testIncrementalDataclassesThreeRuns] -# flags: --python-version 3.7 from a import A A(5) @@ -4116,7 +4108,7 @@ class A: [builtins fixtures/dataclasses.pyi] [out1] [out2] -main:3: error: Argument 1 to "A" has incompatible type "int"; expected "str" +main:2: error: Argument 1 to "A" has incompatible type "int"; expected "str" [out3] [case testParentPatchingMess] @@ -5664,7 +5656,6 @@ A().g() [out2] [case testIncrementalWithDifferentKindsOfNestedTypesWithinMethod] -# flags: --python-version 3.7 import a diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index ea2aa5068e85..de4440ce7f49 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -64,7 +64,6 @@ reveal_type(bar) # N: Revealed type is "def (x: Tuple[Literal [out] [case testLiteralInsideOtherTypesTypeCommentsPython3] -# flags: --python-version 3.7 from typing import Tuple, Optional from typing_extensions import Literal diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 44585fdd8d1a..5fd48577e436 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -2075,9 +2075,7 @@ def __getattr__(name): ... [builtins fixtures/module.pyi] -[case testModuleLevelGetattrNotStub37] -# flags: --python-version 3.7 - +[case testModuleLevelGetattrNotStub] import has_getattr reveal_type(has_getattr.any_attribute) # N: Revealed type is "builtins.str" @@ -2109,8 +2107,7 @@ def __getattr__(name: str) -> int: ... [builtins fixtures/module.pyi] -[case testModuleLevelGetattrImportFromNotStub37] -# flags: --python-version 3.7 +[case testModuleLevelGetattrImportFromNotStub] from non_stub import name reveal_type(name) # N: Revealed type is "Any" @@ -2145,7 +2142,6 @@ def __getattr__(name: str) -> int: ... [case testModuleLevelGetattrAssignedGood] -# flags: --python-version 3.7 import non_stub reveal_type(non_stub.name) # N: Revealed type is "builtins.int" @@ -2156,7 +2152,6 @@ def make_getattr_good() -> Callable[[str], int]: ... __getattr__ = make_getattr_good() # OK [case testModuleLevelGetattrAssignedBad] -# flags: --python-version 3.7 import non_stub reveal_type(non_stub.name) @@ -2168,10 +2163,9 @@ __getattr__ = make_getattr_bad() [out] tmp/non_stub.py:4: error: Invalid signature "Callable[[], int]" for "__getattr__" -main:3: note: Revealed type is "builtins.int" +main:2: note: Revealed type is "builtins.int" [case testModuleLevelGetattrImportedGood] -# flags: --python-version 3.7 import non_stub reveal_type(non_stub.name) # N: Revealed type is "builtins.int" @@ -2182,7 +2176,6 @@ from has_getattr import __getattr__ def __getattr__(name: str) -> int: ... [case testModuleLevelGetattrImportedBad] -# flags: --python-version 3.7 import non_stub reveal_type(non_stub.name) @@ -2194,7 +2187,7 @@ def __getattr__() -> int: ... [out] tmp/has_getattr.py:1: error: Invalid signature "Callable[[], int]" for "__getattr__" -main:3: note: Revealed type is "builtins.int" +main:2: note: Revealed type is "builtins.int" [builtins fixtures/module.pyi] diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 51b02b500bd1..0ce8630e51d9 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -131,7 +131,6 @@ main:6: error: Unexpected keyword argument "unrecognized_arg" for "namedtuple" main:7: error: Too many positional arguments for "namedtuple" [case testNamedTupleDefaults] -# flags: --python-version 3.7 from collections import namedtuple X = namedtuple('X', ['x', 'y'], defaults=(1,)) diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index d50d1f508b85..4d117687554e 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -1,5 +1,4 @@ [case testNarrowingParentWithStrsBasic] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import NamedTuple, Tuple, Union from typing_extensions import Literal, TypedDict @@ -83,7 +82,6 @@ else: [builtins fixtures/primitives.pyi] [case testNarrowingParentWithEnumsBasic] -# flags: --python-version 3.7 from enum import Enum from dataclasses import dataclass from typing import NamedTuple, Tuple, Union @@ -173,7 +171,6 @@ else: [builtins fixtures/narrowing.pyi] [case testNarrowingParentWithIsInstanceBasic] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import NamedTuple, Tuple, Union from typing_extensions import TypedDict diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index f4d3b9df760e..7cbed5637c3a 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -2577,8 +2577,7 @@ import n [file n.pyi] class C: pass -[case testNewAnalyzerModuleGetAttrInPython37] -# flags: --python-version 3.7 +[case testNewAnalyzerModuleGetAttr] import m import n diff --git a/test-data/unit/check-newtype.test b/test-data/unit/check-newtype.test index 99fdf5fe7ca3..a0a30079f062 100644 --- a/test-data/unit/check-newtype.test +++ b/test-data/unit/check-newtype.test @@ -381,7 +381,6 @@ x: List[Union[N, int]] [builtins fixtures/list.pyi] [case testTypingExtensionsNewType] -# flags: --python-version 3.7 from typing_extensions import NewType N = NewType("N", int) x: N diff --git a/test-data/unit/check-union-or-syntax.test b/test-data/unit/check-union-or-syntax.test index f342d0ca34a5..85e268f348f0 100644 --- a/test-data/unit/check-union-or-syntax.test +++ b/test-data/unit/check-union-or-syntax.test @@ -127,7 +127,6 @@ cast(str | int, 'x') # E: Cast target is not a type x = 1 # type: int | str [case testUnionOrSyntaxFutureImport] -# flags: --python-version 3.7 from __future__ import annotations x: int | None [builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index acb5ca6ea609..b8b438b979c6 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -798,7 +798,7 @@ def baz(x: int) -> int: [builtins fixtures/exception.pyi] [case testUnreachableFlagIgnoresSemanticAnalysisUnreachable] -# flags: --warn-unreachable --python-version 3.7 --platform win32 --always-false FOOBAR +# flags: --warn-unreachable --python-version 3.8 --platform win32 --always-false FOOBAR import sys from typing import TYPE_CHECKING @@ -828,7 +828,7 @@ if sys.version_info == (2, 7): else: reveal_type(x) # N: Revealed type is "builtins.int" -if sys.version_info == (3, 7): +if sys.version_info == (3, 8): reveal_type(x) # N: Revealed type is "builtins.int" else: reveal_type(x) @@ -1155,7 +1155,7 @@ def f_suppress() -> int: # E: Missing return statement [builtins fixtures/tuple.pyi] [case testUnreachableFlagContextAsyncManagersNoSuppress] -# flags: --warn-unreachable --python-version 3.7 +# flags: --warn-unreachable from contextlib import asynccontextmanager from typing import Optional, AsyncIterator, Any from typing_extensions import Literal @@ -1221,7 +1221,7 @@ async def f_no_suppress_5() -> int: [builtins fixtures/tuple.pyi] [case testUnreachableFlagContextAsyncManagersSuppressed] -# flags: --warn-unreachable --python-version 3.7 +# flags: --warn-unreachable from contextlib import asynccontextmanager from typing import Optional, AsyncIterator, Any from typing_extensions import Literal @@ -1268,7 +1268,7 @@ async def f_mix() -> int: # E: Missing return statement [builtins fixtures/tuple.pyi] [case testUnreachableFlagContextAsyncManagersAbnormal] -# flags: --warn-unreachable --python-version 3.7 +# flags: --warn-unreachable from contextlib import asynccontextmanager from typing import Optional, AsyncIterator, Any from typing_extensions import Literal diff --git a/test-data/unit/deps.test b/test-data/unit/deps.test index 5e77ff1d85e0..d18b4aae963b 100644 --- a/test-data/unit/deps.test +++ b/test-data/unit/deps.test @@ -1369,7 +1369,6 @@ def h() -> None: -> m.D, m.h [case testDataclassDepsOldVersion] -# flags: --python-version 3.7 from dataclasses import dataclass Z = int diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index 266d9a9efd01..9c379d8f60da 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -652,7 +652,6 @@ class M(type): a.py:4: error: Incompatible types in assignment (expression has type "str", variable has type "int") [case testDataclassUpdate1] -# flags: --python-version 3.7 [file a.py] from dataclasses import dataclass @@ -691,7 +690,6 @@ b.py:8: error: Argument 1 to "B" has incompatible type "int"; expected "str" [builtins fixtures/dataclasses.pyi] [case testDataclassUpdate2] -# flags: --python-version 3.7 [file c.py] Foo = int @@ -722,7 +720,6 @@ b.py:8: error: Argument 1 to "B" has incompatible type "int"; expected "str" [builtins fixtures/dataclasses.pyi] [case testDataclassUpdate3] -# flags: --python-version 3.7 from b import B B(1, 2) [file b.py] @@ -746,10 +743,9 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Missing positional argument "b" in call to "B" +main:2: error: Missing positional argument "b" in call to "B" [case testDataclassUpdate4] -# flags: --python-version 3.7 from b import B B(1, 2) [file b.py] @@ -773,10 +769,9 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Missing positional argument "b" in call to "B" +main:2: error: Missing positional argument "b" in call to "B" [case testDataclassUpdate5] -# flags: --python-version 3.7 from b import B B(1, 2) [file b.py] @@ -807,11 +802,10 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Missing positional argument "b" in call to "B" +main:2: error: Missing positional argument "b" in call to "B" == [case testDataclassUpdate6] -# flags: --python-version 3.7 from b import B B(1, 2) < B(1, 2) [file b.py] @@ -834,10 +828,9 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Unsupported left operand type for < ("B") +main:2: error: Unsupported left operand type for < ("B") [case testDataclassUpdate8] -# flags: --python-version 3.7 from c import C C(1, 2, 3) [file c.py] @@ -867,10 +860,9 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Missing positional argument "c" in call to "C" +main:2: error: Missing positional argument "c" in call to "C" [case testDataclassUpdate9] -# flags: --python-version 3.7 from c import C C(1, 2, 3) [file c.py] @@ -907,7 +899,7 @@ class A: [builtins fixtures/dataclasses.pyi] [out] == -main:3: error: Missing positional argument "c" in call to "C" +main:2: error: Missing positional argument "c" in call to "C" == [case testAttrsUpdate1] @@ -9799,7 +9791,6 @@ class ExampleClass(Generic[T]): == [case testDataclassCheckTypeVarBoundsInReprocess] -# flags: --python-version 3.7 from dataclasses import dataclass from typing import ClassVar, Protocol, Dict, TypeVar, Generic from m import x diff --git a/test-requirements.in b/test-requirements.in index 8f9d2cae0cce..a158f5c05ee1 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -16,4 +16,4 @@ pytest-xdist>=1.34.0 pytest-cov>=2.10.0 ruff==0.1.15 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 -tomli>=1.1.0 # needed even on py311+ so the self check passes with --python-version 3.7 +tomli>=1.1.0 # needed even on py311+ so the self check passes with --python-version 3.8 From e48a0258a4bb61710045b6f2136f8b119b9fd525 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:13:07 +0100 Subject: [PATCH 53/69] Remove unnecessary --python-version 3.8 references from tests (#16850) Remove the `--python-version 3.8` flag where it's used to indicate the min python version requirement. Mypy doesn't support running under Python 3.7 / the tests are only run for 3.8+. --- test-data/unit/check-functools.test | 1 - .../unit/check-parameter-specification.test | 8 +- test-data/unit/check-python38.test | 90 +++++++------------ test-data/unit/check-typeddict.test | 1 - 4 files changed, 32 insertions(+), 68 deletions(-) diff --git a/test-data/unit/check-functools.test b/test-data/unit/check-functools.test index ebfe86f2b241..e721a56850e1 100644 --- a/test-data/unit/check-functools.test +++ b/test-data/unit/check-functools.test @@ -102,7 +102,6 @@ Ord() >= 1 # E: Unsupported left operand type for >= ("Ord") [builtins fixtures/dict.pyi] [case testCachedProperty] -# flags: --python-version 3.8 from functools import cached_property class Parent: @property diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index 7a5c5934a94e..b212c7585993 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -642,7 +642,7 @@ reveal_type(f(n)) # N: Revealed type is "def (builtins.int, builtins.bytes) -> [builtins fixtures/paramspec.pyi] [case testParamSpecConcatenateNamedArgs] -# flags: --python-version 3.8 --extra-checks +# flags: --extra-checks # this is one noticeable deviation from PEP but I believe it is for the better from typing_extensions import ParamSpec, Concatenate from typing import Callable, TypeVar @@ -668,8 +668,6 @@ main:17: error: Incompatible return value type (got "Callable[[Arg(int, 'x'), ** main:17: note: This is likely because "result" has named arguments: "x". Consider marking them positional-only [case testNonStrictParamSpecConcatenateNamedArgs] -# flags: --python-version 3.8 - # this is one noticeable deviation from PEP but I believe it is for the better from typing_extensions import ParamSpec, Concatenate from typing import Callable, TypeVar @@ -710,8 +708,6 @@ reveal_type(n(42)) # N: Revealed type is "None" [builtins fixtures/paramspec.pyi] [case testCallablesAsParameters] -# flags: --python-version 3.8 - # credits to https://github.com/microsoft/pyright/issues/2705 from typing_extensions import ParamSpec, Concatenate from typing import Generic, Callable, Any @@ -729,7 +725,7 @@ reveal_type(abc) bar(abc) [builtins fixtures/paramspec.pyi] [out] -main:16: note: Revealed type is "__main__.Foo[[builtins.int, b: builtins.str]]" +main:14: note: Revealed type is "__main__.Foo[[builtins.int, b: builtins.str]]" [case testSolveParamSpecWithSelfType] from typing_extensions import ParamSpec, Concatenate diff --git a/test-data/unit/check-python38.test b/test-data/unit/check-python38.test index 1e99c760b67a..0f1cbb6e81c4 100644 --- a/test-data/unit/check-python38.test +++ b/test-data/unit/check-python38.test @@ -115,25 +115,21 @@ def g(x: int): ... ) # type: ignore # E: Unused "type: ignore" comment [case testPEP570ArgTypesMissing] -# flags: --python-version 3.8 --disallow-untyped-defs +# flags: --disallow-untyped-defs def f(arg, /) -> None: ... # E: Function is missing a type annotation for one or more arguments [case testPEP570ArgTypesBadDefault] -# flags: --python-version 3.8 def f(arg: int = "ERROR", /) -> None: ... # E: Incompatible default for argument "arg" (default has type "str", argument has type "int") [case testPEP570ArgTypesDefault] -# flags: --python-version 3.8 def f(arg: int = 0, /) -> None: reveal_type(arg) # N: Revealed type is "builtins.int" [case testPEP570ArgTypesRequired] -# flags: --python-version 3.8 def f(arg: int, /) -> None: reveal_type(arg) # N: Revealed type is "builtins.int" [case testPEP570Required] -# flags: --python-version 3.8 def f(arg: int, /) -> None: ... # N: "f" defined here f(1) f("ERROR") # E: Argument 1 to "f" has incompatible type "str"; expected "int" @@ -141,7 +137,6 @@ f(arg=1) # E: Unexpected keyword argument "arg" for "f" f(arg="ERROR") # E: Unexpected keyword argument "arg" for "f" [case testPEP570Default] -# flags: --python-version 3.8 def f(arg: int = 0, /) -> None: ... # N: "f" defined here f() f(1) @@ -150,7 +145,7 @@ f(arg=1) # E: Unexpected keyword argument "arg" for "f" f(arg="ERROR") # E: Unexpected keyword argument "arg" for "f" [case testPEP570Calls] -# flags: --python-version 3.8 --no-strict-optional +# flags: --no-strict-optional from typing import Any, Dict def f(p, /, p_or_kw, *, kw) -> None: ... # N: "f" defined here d = None # type: Dict[Any, Any] @@ -163,7 +158,6 @@ f(**d) # E: Missing positional argument "p_or_kw" in call to "f" [builtins fixtures/dict.pyi] [case testPEP570Signatures1] -# flags: --python-version 3.8 def f(p1: bytes, p2: float, /, p_or_kw: int, *, kw: str) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.float" @@ -171,7 +165,6 @@ def f(p1: bytes, p2: float, /, p_or_kw: int, *, kw: str) -> None: reveal_type(kw) # N: Revealed type is "builtins.str" [case testPEP570Signatures2] -# flags: --python-version 3.8 def f(p1: bytes, p2: float = 0.0, /, p_or_kw: int = 0, *, kw: str) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.float" @@ -179,33 +172,28 @@ def f(p1: bytes, p2: float = 0.0, /, p_or_kw: int = 0, *, kw: str) -> None: reveal_type(kw) # N: Revealed type is "builtins.str" [case testPEP570Signatures3] -# flags: --python-version 3.8 def f(p1: bytes, p2: float = 0.0, /, *, kw: int) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.float" reveal_type(kw) # N: Revealed type is "builtins.int" [case testPEP570Signatures4] -# flags: --python-version 3.8 def f(p1: bytes, p2: int = 0, /) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.int" [case testPEP570Signatures5] -# flags: --python-version 3.8 def f(p1: bytes, p2: float, /, p_or_kw: int) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.float" reveal_type(p_or_kw) # N: Revealed type is "builtins.int" [case testPEP570Signatures6] -# flags: --python-version 3.8 def f(p1: bytes, p2: float, /) -> None: reveal_type(p1) # N: Revealed type is "builtins.bytes" reveal_type(p2) # N: Revealed type is "builtins.float" [case testPEP570Unannotated] -# flags: --python-version 3.8 def f(arg, /): ... # N: "f" defined here g = lambda arg, /: arg def h(arg=0, /): ... # N: "h" defined here @@ -223,7 +211,6 @@ h(arg=0) # E: Unexpected keyword argument "arg" for "h" i(arg=0) # E: Unexpected keyword argument "arg" [case testWalrus] -# flags: --python-version 3.8 from typing import NamedTuple, Optional, List from typing_extensions import Final @@ -399,7 +386,6 @@ reveal_type(z2) # E: Name "z2" is not defined # N: Revealed type is "Any" [builtins fixtures/isinstancelist.pyi] [case testWalrusConditionalTypeBinder] -# flags: --python-version 3.8 from typing import Tuple, Union from typing_extensions import Literal @@ -427,7 +413,6 @@ else: [builtins fixtures/list.pyi] [case testWalrusConditionalTypeCheck] -# flags: --python-version 3.8 from typing import Optional maybe_str: Optional[str] @@ -443,7 +428,6 @@ reveal_type(maybe_str) # N: Revealed type is "Union[builtins.str, None]" [builtins fixtures/bool.pyi] [case testWalrusConditionalTypeCheck2] -# flags: --python-version 3.8 from typing import Optional maybe_str: Optional[str] @@ -459,7 +443,6 @@ reveal_type(maybe_str) # N: Revealed type is "Union[builtins.str, None]" [builtins fixtures/bool.pyi] [case testWalrusPartialTypes] -# flags: --python-version 3.8 from typing import List def check_partial_list() -> None: @@ -476,7 +459,7 @@ def check_partial_list() -> None: [builtins fixtures/list.pyi] [case testWalrusAssignmentAndConditionScopeForLiteral] -# flags: --warn-unreachable --python-version 3.8 +# flags: --warn-unreachable if (x := 0): reveal_type(x) # E: Statement is unreachable @@ -486,7 +469,7 @@ else: reveal_type(x) # N: Revealed type is "builtins.int" [case testWalrusAssignmentAndConditionScopeForProperty] -# flags: --warn-unreachable --python-version 3.8 +# flags: --warn-unreachable from typing_extensions import Literal @@ -514,7 +497,7 @@ reveal_type(y) # N: Revealed type is "Literal[False]" [builtins fixtures/property.pyi] [case testWalrusAssignmentAndConditionScopeForFunction] -# flags: --warn-unreachable --python-version 3.8 +# flags: --warn-unreachable from typing_extensions import Literal @@ -547,7 +530,6 @@ reveal_type(z) # N: Revealed type is "Literal[False]" [builtins fixtures/tuple.pyi] [case testWalrusExpr] -# flags: --python-version 3.8 def func() -> None: foo = Foo() if x := foo.x: @@ -558,7 +540,6 @@ class Foo: self.x = 123 [case testWalrusTypeGuard] -# flags: --python-version 3.8 from typing_extensions import TypeGuard def is_float(a: object) -> TypeGuard[float]: pass def main(a: object) -> None: @@ -568,14 +549,12 @@ def main(a: object) -> None: [builtins fixtures/tuple.pyi] [case testWalrusRedefined] -# flags: --python-version 3.8 def foo() -> None: x = 0 [x := x + y for y in [1, 2, 3]] [builtins fixtures/dict.pyi] [case testWalrusUsedBeforeDef] -# flags: --python-version 3.8 class C: def f(self, c: 'C') -> None: pass @@ -583,7 +562,6 @@ class C: (y := C()).f(y) [case testOverloadWithPositionalOnlySelf] -# flags: --python-version 3.8 from typing import overload, Optional class Foo: @@ -608,7 +586,6 @@ class Bar: [builtins fixtures/bool.pyi] [case testOverloadPositionalOnlyErrorMessage] -# flags: --python-version 3.8 from typing import overload @overload @@ -619,13 +596,12 @@ def foo(a): ... foo(a=1) [out] -main:10: error: No overload variant of "foo" matches argument type "int" -main:10: note: Possible overload variants: -main:10: note: def foo(int, /) -> Any -main:10: note: def foo(a: str) -> Any +main:9: error: No overload variant of "foo" matches argument type "int" +main:9: note: Possible overload variants: +main:9: note: def foo(int, /) -> Any +main:9: note: def foo(a: str) -> Any [case testOverloadPositionalOnlyErrorMessageAllTypes] -# flags: --python-version 3.8 from typing import overload @overload @@ -636,13 +612,12 @@ def foo(a, b, *, c): ... foo(a=1) [out] -main:10: error: No overload variant of "foo" matches argument type "int" -main:10: note: Possible overload variants: -main:10: note: def foo(int, /, b: int, *, c: int) -> Any -main:10: note: def foo(a: str, b: int, *, c: int) -> Any +main:9: error: No overload variant of "foo" matches argument type "int" +main:9: note: Possible overload variants: +main:9: note: def foo(int, /, b: int, *, c: int) -> Any +main:9: note: def foo(a: str, b: int, *, c: int) -> Any [case testOverloadPositionalOnlyErrorMessageMultiplePosArgs] -# flags: --python-version 3.8 from typing import overload @overload @@ -653,13 +628,12 @@ def foo(a, b, c, d): ... foo(a=1) [out] -main:10: error: No overload variant of "foo" matches argument type "int" -main:10: note: Possible overload variants: -main:10: note: def foo(int, int, int, /, d: str) -> Any -main:10: note: def foo(a: str, b: int, c: int, d: str) -> Any +main:9: error: No overload variant of "foo" matches argument type "int" +main:9: note: Possible overload variants: +main:9: note: def foo(int, int, int, /, d: str) -> Any +main:9: note: def foo(a: str, b: int, c: int, d: str) -> Any [case testOverloadPositionalOnlyErrorMessageMethod] -# flags: --python-version 3.8 from typing import overload class Some: @@ -673,14 +647,13 @@ class Some: Some().foo(a=1) [out] -main:13: error: No overload variant of "foo" of "Some" matches argument type "int" -main:13: note: Possible overload variants: -main:13: note: def foo(self, int, /) -> Any -main:13: note: def foo(self, float, /) -> Any -main:13: note: def foo(self, a: str) -> Any +main:12: error: No overload variant of "foo" of "Some" matches argument type "int" +main:12: note: Possible overload variants: +main:12: note: def foo(self, int, /) -> Any +main:12: note: def foo(self, float, /) -> Any +main:12: note: def foo(self, a: str) -> Any [case testOverloadPositionalOnlyErrorMessageClassMethod] -# flags: --python-version 3.8 from typing import overload class Some: @@ -699,14 +672,13 @@ class Some: Some.foo(a=1) [builtins fixtures/classmethod.pyi] [out] -main:17: error: No overload variant of "foo" of "Some" matches argument type "int" -main:17: note: Possible overload variants: -main:17: note: def foo(cls, int, /) -> Any -main:17: note: def foo(cls, float, /) -> Any -main:17: note: def foo(cls, a: str) -> Any +main:16: error: No overload variant of "foo" of "Some" matches argument type "int" +main:16: note: Possible overload variants: +main:16: note: def foo(cls, int, /) -> Any +main:16: note: def foo(cls, float, /) -> Any +main:16: note: def foo(cls, a: str) -> Any [case testUnpackWithDuplicateNamePositionalOnly] -# flags: --python-version 3.8 from typing_extensions import Unpack, TypedDict class Person(TypedDict): @@ -717,7 +689,7 @@ def foo(name: str, /, **kwargs: Unpack[Person]) -> None: # Allowed [builtins fixtures/dict.pyi] [case testPossiblyUndefinedWithAssignmentExpr] -# flags: --python-version 3.8 --enable-error-code possibly-undefined +# flags: --enable-error-code possibly-undefined def f1() -> None: d = {0: 1} if int(): @@ -744,7 +716,6 @@ main:9: note: Revealed type is "builtins.int" main:9: note: Revealed type is "builtins.str" [case testTypeGuardWithPositionalOnlyArg] -# flags: --python-version 3.8 from typing_extensions import TypeGuard def typeguard(x: object, /) -> TypeGuard[int]: @@ -755,10 +726,9 @@ if typeguard(n): reveal_type(n) [builtins fixtures/tuple.pyi] [out] -main:9: note: Revealed type is "builtins.int" +main:8: note: Revealed type is "builtins.int" [case testTypeGuardKeywordFollowingWalrus] -# flags: --python-version 3.8 from typing import cast from typing_extensions import TypeGuard @@ -769,7 +739,7 @@ if typeguard(x=(n := cast(object, "hi"))): reveal_type(n) [builtins fixtures/tuple.pyi] [out] -main:9: note: Revealed type is "builtins.int" +main:8: note: Revealed type is "builtins.int" [case testNoCrashOnAssignmentExprClass] class C: diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 625b82936e8c..adf4d210ed0c 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -1764,7 +1764,6 @@ reveal_type(p) # N: Revealed type is "TypedDict('__main__.Point', {'x': builtin [builtins fixtures/dict.pyi] [case testCanCreateTypedDictWithTypingProper] -# flags: --python-version 3.8 from typing import TypedDict class Point(TypedDict): From ba90dc48fef38e48f0615f1f742a767fcde70fa9 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 1 Feb 2024 18:44:31 -0800 Subject: [PATCH 54/69] Fix duplicated TypeVarTuple test (#16853) https://github.com/python/mypy/pull/15879#discussion_r1475245425 --- test-data/unit/check-generics.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index 469cedb8f6f7..f4b7c14bd053 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -3441,5 +3441,5 @@ def dec(f: Callable[[Unpack[Ts]], Foo[Unpack[Ts]]]) -> Callable[[Unpack[Ts]], Fo g: Callable[[T], Foo[int]] reveal_type(dec(g)) # N: Revealed type is "def (builtins.int) -> __main__.Foo[builtins.int]" h: Callable[[Unpack[Us]], Foo[int]] -reveal_type(dec(g)) # N: Revealed type is "def (builtins.int) -> __main__.Foo[builtins.int]" +reveal_type(dec(h)) # N: Revealed type is "def (builtins.int) -> __main__.Foo[builtins.int]" [builtins fixtures/list.pyi] From 67c396908f71e2d5d6aa942fc0b431b8772d4e45 Mon Sep 17 00:00:00 2001 From: jhance Date: Fri, 2 Feb 2024 06:07:40 -0800 Subject: [PATCH 55/69] Sync Typeshed (for 1.9 release) (#16844) Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: AlexWaygood --- mypy/typeshed/stdlib/VERSIONS | 1 - mypy/typeshed/stdlib/_ast.pyi | 69 +- mypy/typeshed/stdlib/_codecs.pyi | 9 +- mypy/typeshed/stdlib/_collections_abc.pyi | 2 +- mypy/typeshed/stdlib/_csv.pyi | 4 +- mypy/typeshed/stdlib/_ctypes.pyi | 4 +- mypy/typeshed/stdlib/_curses.pyi | 18 +- mypy/typeshed/stdlib/_decimal.pyi | 4 +- mypy/typeshed/stdlib/_dummy_threading.pyi | 19 +- mypy/typeshed/stdlib/_heapq.pyi | 3 +- mypy/typeshed/stdlib/_json.pyi | 3 +- mypy/typeshed/stdlib/_operator.pyi | 4 +- mypy/typeshed/stdlib/_osx_support.pyi | 9 +- mypy/typeshed/stdlib/_posixsubprocess.pyi | 2 +- mypy/typeshed/stdlib/_sitebuiltins.pyi | 3 +- mypy/typeshed/stdlib/_socket.pyi | 677 ++++++++++-------- mypy/typeshed/stdlib/_stat.pyi | 4 +- mypy/typeshed/stdlib/_thread.pyi | 33 +- mypy/typeshed/stdlib/_tkinter.pyi | 37 +- mypy/typeshed/stdlib/_typeshed/__init__.pyi | 24 +- mypy/typeshed/stdlib/_weakref.pyi | 4 +- mypy/typeshed/stdlib/_winapi.pyi | 75 +- mypy/typeshed/stdlib/abc.pyi | 4 +- mypy/typeshed/stdlib/aifc.pyi | 4 +- mypy/typeshed/stdlib/argparse.pyi | 7 +- mypy/typeshed/stdlib/array.pyi | 4 +- mypy/typeshed/stdlib/ast.pyi | 222 +++--- mypy/typeshed/stdlib/asyncio/__init__.pyi | 4 +- mypy/typeshed/stdlib/asyncio/base_events.pyi | 52 +- mypy/typeshed/stdlib/asyncio/base_futures.pyi | 3 +- mypy/typeshed/stdlib/asyncio/constants.pyi | 2 +- mypy/typeshed/stdlib/asyncio/coroutines.pyi | 2 - mypy/typeshed/stdlib/asyncio/events.pyi | 105 +-- mypy/typeshed/stdlib/asyncio/futures.pyi | 19 +- mypy/typeshed/stdlib/asyncio/locks.pyi | 9 +- .../stdlib/asyncio/proactor_events.pyi | 3 +- mypy/typeshed/stdlib/asyncio/runners.pyi | 9 +- mypy/typeshed/stdlib/asyncio/sslproto.pyi | 4 +- mypy/typeshed/stdlib/asyncio/streams.pyi | 58 +- mypy/typeshed/stdlib/asyncio/subprocess.pyi | 20 +- mypy/typeshed/stdlib/asyncio/tasks.pyi | 21 +- mypy/typeshed/stdlib/asyncio/timeouts.pyi | 3 +- mypy/typeshed/stdlib/asyncio/unix_events.pyi | 46 +- .../stdlib/asyncio/windows_events.pyi | 3 +- .../typeshed/stdlib/asyncio/windows_utils.pyi | 4 +- mypy/typeshed/stdlib/bdb.pyi | 14 +- mypy/typeshed/stdlib/binascii.pyi | 12 +- mypy/typeshed/stdlib/binhex.pyi | 4 +- mypy/typeshed/stdlib/builtins.pyi | 360 ++++------ mypy/typeshed/stdlib/bz2.pyi | 4 +- mypy/typeshed/stdlib/cProfile.pyi | 6 +- mypy/typeshed/stdlib/calendar.pyi | 4 +- mypy/typeshed/stdlib/cgi.pyi | 12 - mypy/typeshed/stdlib/cgitb.pyi | 3 +- mypy/typeshed/stdlib/cmath.pyi | 11 +- mypy/typeshed/stdlib/cmd.pyi | 3 +- mypy/typeshed/stdlib/codecs.pyi | 19 +- mypy/typeshed/stdlib/collections/__init__.pyi | 16 +- .../stdlib/concurrent/futures/__init__.pyi | 6 +- .../stdlib/concurrent/futures/_base.pyi | 26 +- mypy/typeshed/stdlib/configparser.pyi | 4 +- mypy/typeshed/stdlib/contextvars.pyi | 4 +- mypy/typeshed/stdlib/csv.pyi | 20 +- mypy/typeshed/stdlib/ctypes/__init__.pyi | 76 +- mypy/typeshed/stdlib/ctypes/_endian.pyi | 19 + mypy/typeshed/stdlib/ctypes/wintypes.pyi | 140 ++-- mypy/typeshed/stdlib/dataclasses.pyi | 21 +- mypy/typeshed/stdlib/datetime.pyi | 74 +- mypy/typeshed/stdlib/dbm/__init__.pyi | 3 +- mypy/typeshed/stdlib/distutils/ccompiler.pyi | 2 +- .../stdlib/distutils/cygwinccompiler.pyi | 2 +- mypy/typeshed/stdlib/distutils/filelist.pyi | 3 +- mypy/typeshed/stdlib/distutils/util.pyi | 8 +- .../stdlib/email/_header_value_parser.pyi | 38 +- mypy/typeshed/stdlib/email/headerregistry.pyi | 21 +- mypy/typeshed/stdlib/email/message.pyi | 4 +- mypy/typeshed/stdlib/enum.pyi | 4 +- mypy/typeshed/stdlib/fcntl.pyi | 17 +- mypy/typeshed/stdlib/filecmp.pyi | 3 +- mypy/typeshed/stdlib/fileinput.pyi | 115 +-- mypy/typeshed/stdlib/fractions.pyi | 34 +- mypy/typeshed/stdlib/ftplib.pyi | 4 +- mypy/typeshed/stdlib/functools.pyi | 82 +-- mypy/typeshed/stdlib/gc.pyi | 12 +- mypy/typeshed/stdlib/genericpath.pyi | 4 +- mypy/typeshed/stdlib/gettext.pyi | 26 +- mypy/typeshed/stdlib/grp.pyi | 3 +- mypy/typeshed/stdlib/gzip.pyi | 19 +- mypy/typeshed/stdlib/hashlib.pyi | 15 +- mypy/typeshed/stdlib/heapq.pyi | 3 +- mypy/typeshed/stdlib/hmac.pyi | 25 +- mypy/typeshed/stdlib/http/__init__.pyi | 5 +- mypy/typeshed/stdlib/http/cookiejar.pyi | 58 +- mypy/typeshed/stdlib/http/server.pyi | 2 +- mypy/typeshed/stdlib/imaplib.pyi | 4 +- mypy/typeshed/stdlib/importlib/abc.pyi | 3 +- mypy/typeshed/stdlib/importlib/machinery.pyi | 10 +- mypy/typeshed/stdlib/importlib/readers.pyi | 4 +- .../stdlib/importlib/resources/simple.pyi | 4 +- mypy/typeshed/stdlib/inspect.pyi | 77 +- mypy/typeshed/stdlib/io.pyi | 11 +- mypy/typeshed/stdlib/ipaddress.pyi | 4 +- mypy/typeshed/stdlib/itertools.pyi | 16 +- mypy/typeshed/stdlib/keyword.pyi | 2 +- mypy/typeshed/stdlib/lib2to3/fixer_base.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_apply.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_asserts.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_basestring.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_buffer.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_dict.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_except.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_exec.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_execfile.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_exitfunc.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_filter.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_funcattrs.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_future.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_getcwdu.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_has_key.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_idioms.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_import.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_imports.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_input.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_intern.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_isinstance.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_itertools.pyi | 3 +- .../lib2to3/fixes/fix_itertools_imports.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_long.pyi | 3 +- .../typeshed/stdlib/lib2to3/fixes/fix_map.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_metaclass.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_methodattrs.pyi | 3 +- mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_next.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_nonzero.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_numliterals.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_operator.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_paren.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_print.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_raise.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_raw_input.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_reduce.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_reload.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_renames.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_repr.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_set_literal.pyi | 3 +- .../lib2to3/fixes/fix_standarderror.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_sys_exc.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_throw.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_tuple_params.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_types.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_unicode.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_urllib.pyi | 2 +- .../stdlib/lib2to3/fixes/fix_ws_comma.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_xrange.pyi | 3 +- .../stdlib/lib2to3/fixes/fix_xreadlines.pyi | 3 +- .../typeshed/stdlib/lib2to3/fixes/fix_zip.pyi | 3 +- mypy/typeshed/stdlib/lib2to3/main.pyi | 3 +- mypy/typeshed/stdlib/lib2to3/pygram.pyi | 5 +- mypy/typeshed/stdlib/lib2to3/pytree.pyi | 3 +- mypy/typeshed/stdlib/lib2to3/refactor.pyi | 3 +- mypy/typeshed/stdlib/logging/__init__.pyi | 622 +++++----------- mypy/typeshed/stdlib/logging/config.pyi | 17 +- mypy/typeshed/stdlib/lzma.pyi | 4 +- mypy/typeshed/stdlib/macpath.pyi | 104 --- mypy/typeshed/stdlib/mailbox.pyi | 4 +- mypy/typeshed/stdlib/math.pyi | 52 +- mypy/typeshed/stdlib/mimetypes.pyi | 14 +- mypy/typeshed/stdlib/mmap.pyi | 52 +- mypy/typeshed/stdlib/modulefinder.pyi | 24 +- mypy/typeshed/stdlib/msilib/__init__.pyi | 3 +- mypy/typeshed/stdlib/msvcrt.pyi | 2 +- .../stdlib/multiprocessing/__init__.pyi | 14 +- .../stdlib/multiprocessing/connection.pyi | 4 +- .../stdlib/multiprocessing/context.pyi | 17 +- .../stdlib/multiprocessing/dummy/__init__.pyi | 3 +- .../stdlib/multiprocessing/managers.pyi | 27 +- mypy/typeshed/stdlib/multiprocessing/pool.pyi | 64 +- .../stdlib/multiprocessing/process.pyi | 10 +- .../stdlib/multiprocessing/reduction.pyi | 13 +- .../stdlib/multiprocessing/sharedctypes.pyi | 3 +- mypy/typeshed/stdlib/nntplib.pyi | 4 +- mypy/typeshed/stdlib/ntpath.pyi | 4 +- mypy/typeshed/stdlib/numbers.pyi | 81 +-- mypy/typeshed/stdlib/opcode.pyi | 8 +- mypy/typeshed/stdlib/os/__init__.pyi | 149 ++-- mypy/typeshed/stdlib/ossaudiodev.pyi | 3 +- mypy/typeshed/stdlib/parser.pyi | 3 +- mypy/typeshed/stdlib/pathlib.pyi | 20 +- mypy/typeshed/stdlib/pickle.pyi | 144 ++-- mypy/typeshed/stdlib/platform.pyi | 33 +- mypy/typeshed/stdlib/plistlib.pyi | 118 +-- mypy/typeshed/stdlib/poplib.pyi | 4 +- mypy/typeshed/stdlib/posix.pyi | 185 +++-- mypy/typeshed/stdlib/posixpath.pyi | 8 +- mypy/typeshed/stdlib/pprint.pyi | 37 +- mypy/typeshed/stdlib/pstats.pyi | 4 +- mypy/typeshed/stdlib/pty.pyi | 3 +- mypy/typeshed/stdlib/pwd.pyi | 3 +- mypy/typeshed/stdlib/py_compile.pyi | 30 +- mypy/typeshed/stdlib/pydoc.pyi | 4 +- mypy/typeshed/stdlib/pyexpat/__init__.pyi | 4 +- mypy/typeshed/stdlib/re.pyi | 4 +- mypy/typeshed/stdlib/resource.pyi | 2 +- mypy/typeshed/stdlib/select.pyi | 4 +- mypy/typeshed/stdlib/shlex.pyi | 11 +- mypy/typeshed/stdlib/shutil.pyi | 63 +- mypy/typeshed/stdlib/signal.pyi | 12 +- mypy/typeshed/stdlib/socket.pyi | 192 +++-- mypy/typeshed/stdlib/spwd.pyi | 3 +- mypy/typeshed/stdlib/sqlite3/dbapi2.pyi | 33 +- mypy/typeshed/stdlib/sre_parse.pyi | 50 +- mypy/typeshed/stdlib/ssl.pyi | 29 +- mypy/typeshed/stdlib/statistics.pyi | 105 ++- mypy/typeshed/stdlib/subprocess.pyi | 20 +- mypy/typeshed/stdlib/sunau.pyi | 4 +- mypy/typeshed/stdlib/symbol.pyi | 14 +- mypy/typeshed/stdlib/symtable.pyi | 15 +- mypy/typeshed/stdlib/sys/__init__.pyi | 41 +- mypy/typeshed/stdlib/sysconfig.pyi | 3 +- mypy/typeshed/stdlib/syslog.pyi | 3 +- mypy/typeshed/stdlib/tarfile.pyi | 120 ++-- mypy/typeshed/stdlib/tempfile.pyi | 450 ++++-------- mypy/typeshed/stdlib/threading.pyi | 27 +- mypy/typeshed/stdlib/time.pyi | 40 +- mypy/typeshed/stdlib/tkinter/__init__.pyi | 54 +- mypy/typeshed/stdlib/tkinter/constants.pyi | 2 +- mypy/typeshed/stdlib/tkinter/filedialog.pyi | 3 +- mypy/typeshed/stdlib/tkinter/font.pyi | 11 +- mypy/typeshed/stdlib/tkinter/tix.pyi | 3 +- mypy/typeshed/stdlib/tkinter/ttk.pyi | 11 +- mypy/typeshed/stdlib/token.pyi | 22 +- mypy/typeshed/stdlib/tokenize.pyi | 15 +- mypy/typeshed/stdlib/traceback.pyi | 7 +- mypy/typeshed/stdlib/tracemalloc.pyi | 4 +- mypy/typeshed/stdlib/types.pyi | 65 +- mypy/typeshed/stdlib/typing.pyi | 129 ++-- mypy/typeshed/stdlib/typing_extensions.pyi | 11 +- mypy/typeshed/stdlib/unicodedata.pyi | 13 +- mypy/typeshed/stdlib/unittest/__init__.pyi | 12 +- mypy/typeshed/stdlib/unittest/case.pyi | 19 +- mypy/typeshed/stdlib/unittest/mock.pyi | 173 ++--- mypy/typeshed/stdlib/urllib/parse.pyi | 4 +- mypy/typeshed/stdlib/urllib/robotparser.pyi | 4 +- mypy/typeshed/stdlib/warnings.pyi | 4 +- mypy/typeshed/stdlib/wave.pyi | 4 +- mypy/typeshed/stdlib/webbrowser.pyi | 2 +- mypy/typeshed/stdlib/winreg.pyi | 4 +- mypy/typeshed/stdlib/winsound.pyi | 3 +- mypy/typeshed/stdlib/xml/dom/minicompat.pyi | 3 +- mypy/typeshed/stdlib/xml/dom/minidom.pyi | 4 +- mypy/typeshed/stdlib/xml/dom/pulldom.pyi | 3 +- mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi | 4 +- .../typeshed/stdlib/xml/etree/ElementTree.pyi | 294 ++++---- mypy/typeshed/stdlib/xml/sax/__init__.pyi | 15 +- mypy/typeshed/stdlib/xmlrpc/client.pyi | 78 +- mypy/typeshed/stdlib/xxlimited.pyi | 3 +- mypy/typeshed/stdlib/zipfile/__init__.pyi | 35 +- mypy/typeshed/stdlib/zipfile/_path.pyi | 4 +- mypy/typeshed/stdlib/zipimport.pyi | 3 +- mypy/typeshed/stdlib/zlib.pyi | 2 +- test-data/unit/pythoneval.test | 40 +- 261 files changed, 2887 insertions(+), 4617 deletions(-) create mode 100644 mypy/typeshed/stdlib/ctypes/_endian.pyi delete mode 100644 mypy/typeshed/stdlib/macpath.pyi diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index 5099a94c93bc..da395f797881 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -170,7 +170,6 @@ linecache: 3.0- locale: 3.0- logging: 3.0- lzma: 3.3- -macpath: 3.0-3.7 mailbox: 3.0- mailcap: 3.0-3.12 marshal: 3.0- diff --git a/mypy/typeshed/stdlib/_ast.pyi b/mypy/typeshed/stdlib/_ast.pyi index 0fbf66f7feda..fc3f035cc779 100644 --- a/mypy/typeshed/stdlib/_ast.pyi +++ b/mypy/typeshed/stdlib/_ast.pyi @@ -1,12 +1,10 @@ import sys import typing_extensions -from typing import Any, ClassVar -from typing_extensions import Literal +from typing import Any, ClassVar, Literal PyCF_ONLY_AST: Literal[1024] -if sys.version_info >= (3, 8): - PyCF_TYPE_COMMENTS: Literal[4096] - PyCF_ALLOW_TOP_LEVEL_AWAIT: Literal[8192] +PyCF_TYPE_COMMENTS: Literal[4096] +PyCF_ALLOW_TOP_LEVEL_AWAIT: Literal[8192] _Identifier: typing_extensions.TypeAlias = str @@ -19,33 +17,29 @@ class AST: # TODO: Not all nodes have all of the following attributes lineno: int col_offset: int - if sys.version_info >= (3, 8): - end_lineno: int | None - end_col_offset: int | None - type_comment: str | None + end_lineno: int | None + end_col_offset: int | None + type_comment: str | None class mod(AST): ... +class type_ignore(AST): ... -if sys.version_info >= (3, 8): - class type_ignore(AST): ... - - class TypeIgnore(type_ignore): - if sys.version_info >= (3, 10): - __match_args__ = ("lineno", "tag") - tag: str +class TypeIgnore(type_ignore): + if sys.version_info >= (3, 10): + __match_args__ = ("lineno", "tag") + tag: str - class FunctionType(mod): - if sys.version_info >= (3, 10): - __match_args__ = ("argtypes", "returns") - argtypes: list[expr] - returns: expr +class FunctionType(mod): + if sys.version_info >= (3, 10): + __match_args__ = ("argtypes", "returns") + argtypes: list[expr] + returns: expr class Module(mod): if sys.version_info >= (3, 10): __match_args__ = ("body", "type_ignores") body: list[stmt] - if sys.version_info >= (3, 8): - type_ignores: list[TypeIgnore] + type_ignores: list[TypeIgnore] class Interactive(mod): if sys.version_info >= (3, 10): @@ -340,21 +334,6 @@ class JoinedStr(expr): __match_args__ = ("values",) values: list[expr] -if sys.version_info < (3, 8): - class Num(expr): # Deprecated in 3.8; use Constant - n: int | float | complex - - class Str(expr): # Deprecated in 3.8; use Constant - s: str - - class Bytes(expr): # Deprecated in 3.8; use Constant - s: bytes - - class NameConstant(expr): # Deprecated in 3.8; use Constant - value: Any - - class Ellipsis(expr): ... # Deprecated in 3.8; use Constant - class Constant(expr): if sys.version_info >= (3, 10): __match_args__ = ("value", "kind") @@ -364,12 +343,11 @@ class Constant(expr): s: Any n: int | float | complex -if sys.version_info >= (3, 8): - class NamedExpr(expr): - if sys.version_info >= (3, 10): - __match_args__ = ("target", "value") - target: Name - value: expr +class NamedExpr(expr): + if sys.version_info >= (3, 10): + __match_args__ = ("target", "value") + target: Name + value: expr class Attribute(expr): if sys.version_info >= (3, 10): @@ -498,8 +476,7 @@ class ExceptHandler(excepthandler): class arguments(AST): if sys.version_info >= (3, 10): __match_args__ = ("posonlyargs", "args", "vararg", "kwonlyargs", "kw_defaults", "kwarg", "defaults") - if sys.version_info >= (3, 8): - posonlyargs: list[arg] + posonlyargs: list[arg] args: list[arg] vararg: arg | None kwonlyargs: list[arg] diff --git a/mypy/typeshed/stdlib/_codecs.pyi b/mypy/typeshed/stdlib/_codecs.pyi index f8141d8bad4b..6de4666e0776 100644 --- a/mypy/typeshed/stdlib/_codecs.pyi +++ b/mypy/typeshed/stdlib/_codecs.pyi @@ -2,8 +2,8 @@ import codecs import sys from _typeshed import ReadableBuffer from collections.abc import Callable -from typing import overload -from typing_extensions import Literal, TypeAlias +from typing import Literal, overload +from typing_extensions import TypeAlias # This type is not exposed; it is defined in unicodeobject.c class _EncodingMap: @@ -99,11 +99,6 @@ else: def unicode_escape_decode(__data: str | ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... def unicode_escape_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... - -if sys.version_info < (3, 8): - def unicode_internal_decode(__obj: str | ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... - def unicode_internal_encode(__obj: str | ReadableBuffer, __errors: str | None = None) -> tuple[bytes, int]: ... - def utf_16_be_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... def utf_16_be_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... def utf_16_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... diff --git a/mypy/typeshed/stdlib/_collections_abc.pyi b/mypy/typeshed/stdlib/_collections_abc.pyi index 8520e9e4ed9b..0aa09967a895 100644 --- a/mypy/typeshed/stdlib/_collections_abc.pyi +++ b/mypy/typeshed/stdlib/_collections_abc.pyi @@ -30,9 +30,9 @@ from typing import ( # noqa: Y022,Y038,Y057 Sized as Sized, TypeVar, ValuesView as ValuesView, + final, runtime_checkable, ) -from typing_extensions import final __all__ = [ "Awaitable", diff --git a/mypy/typeshed/stdlib/_csv.pyi b/mypy/typeshed/stdlib/_csv.pyi index 19ea487e1530..19f2dc9664b1 100644 --- a/mypy/typeshed/stdlib/_csv.pyi +++ b/mypy/typeshed/stdlib/_csv.pyi @@ -1,8 +1,8 @@ import sys from _typeshed import SupportsWrite from collections.abc import Iterable, Iterator -from typing import Any -from typing_extensions import Final, Literal, TypeAlias +from typing import Any, Final, Literal +from typing_extensions import TypeAlias __version__: Final[str] diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 0fa041844028..ec3d86e41687 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import ReadableBuffer, WriteableBuffer from abc import abstractmethod from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence -from ctypes import CDLL +from ctypes import CDLL, ArgumentError as ArgumentError from typing import Any, ClassVar, Generic, TypeVar, overload from typing_extensions import Self, TypeAlias @@ -197,8 +197,6 @@ class Array(_CData, Generic[_CT]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... -class ArgumentError(Exception): ... - def addressof(obj: _CData) -> int: ... def alignment(obj_or_type: _CData | type[_CData]) -> int: ... def get_errno() -> int: ... diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index 3604f7abedb5..adb09a50f47c 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadOnlyBuffer, SupportsRead -from typing import IO, Any, NamedTuple, overload -from typing_extensions import TypeAlias, final +from typing import IO, Any, NamedTuple, final, overload +from typing_extensions import TypeAlias if sys.platform != "win32": # Handled by PyCurses_ConvertToChtype in _cursesmodule.c. @@ -548,10 +548,10 @@ if sys.platform != "win32": def vline(self, ch: _ChType, n: int) -> None: ... @overload def vline(self, y: int, x: int, ch: _ChType, n: int) -> None: ... - if sys.version_info >= (3, 8): - class _ncurses_version(NamedTuple): - major: int - minor: int - patch: int - ncurses_version: _ncurses_version - window = _CursesWindow # undocumented + + class _ncurses_version(NamedTuple): + major: int + minor: int + patch: int + ncurses_version: _ncurses_version + window = _CursesWindow # undocumented diff --git a/mypy/typeshed/stdlib/_decimal.pyi b/mypy/typeshed/stdlib/_decimal.pyi index 9a90760bd2c2..369d04cd2d5d 100644 --- a/mypy/typeshed/stdlib/_decimal.pyi +++ b/mypy/typeshed/stdlib/_decimal.pyi @@ -2,8 +2,8 @@ import numbers import sys from collections.abc import Container, Sequence from types import TracebackType -from typing import Any, ClassVar, NamedTuple, overload -from typing_extensions import Final, Literal, Self, TypeAlias +from typing import Any, ClassVar, Final, Literal, NamedTuple, overload +from typing_extensions import Self, TypeAlias _Decimal: TypeAlias = Decimal | int _DecimalNew: TypeAlias = Decimal | float | str | tuple[int, Sequence[int], int] diff --git a/mypy/typeshed/stdlib/_dummy_threading.pyi b/mypy/typeshed/stdlib/_dummy_threading.pyi index abcf3a13a496..21d1d1921c0e 100644 --- a/mypy/typeshed/stdlib/_dummy_threading.pyi +++ b/mypy/typeshed/stdlib/_dummy_threading.pyi @@ -1,4 +1,5 @@ import sys +from _thread import _excepthook, _ExceptHookArgs from _typeshed import ProfileFunction, TraceFunction from collections.abc import Callable, Iterable, Mapping from types import TracebackType @@ -28,11 +29,10 @@ __all__ = [ "settrace", "local", "stack_size", + "ExceptHookArgs", + "excepthook", ] -if sys.version_info >= (3, 8): - __all__ += ["ExceptHookArgs", "excepthook"] - def active_count() -> int: ... def current_thread() -> Thread: ... def currentThread() -> Thread: ... @@ -72,10 +72,8 @@ class Thread: def join(self, timeout: float | None = None) -> None: ... def getName(self) -> str: ... def setName(self, name: str) -> None: ... - if sys.version_info >= (3, 8): - @property - def native_id(self) -> int | None: ... # only available on some platforms - + @property + def native_id(self) -> int | None: ... # only available on some platforms def is_alive(self) -> bool: ... if sys.version_info < (3, 9): def isAlive(self) -> bool: ... @@ -138,11 +136,8 @@ class Event: def clear(self) -> None: ... def wait(self, timeout: float | None = None) -> bool: ... -if sys.version_info >= (3, 8): - from _thread import _excepthook, _ExceptHookArgs - - excepthook = _excepthook - ExceptHookArgs = _ExceptHookArgs +excepthook = _excepthook +ExceptHookArgs = _ExceptHookArgs class Timer(Thread): def __init__( diff --git a/mypy/typeshed/stdlib/_heapq.pyi b/mypy/typeshed/stdlib/_heapq.pyi index 8d6c3e88103e..28b03a75d4c7 100644 --- a/mypy/typeshed/stdlib/_heapq.pyi +++ b/mypy/typeshed/stdlib/_heapq.pyi @@ -1,5 +1,4 @@ -from typing import Any, TypeVar -from typing_extensions import Final +from typing import Any, Final, TypeVar _T = TypeVar("_T") diff --git a/mypy/typeshed/stdlib/_json.pyi b/mypy/typeshed/stdlib/_json.pyi index 130f7ab92e97..a6a62be184d8 100644 --- a/mypy/typeshed/stdlib/_json.pyi +++ b/mypy/typeshed/stdlib/_json.pyi @@ -1,6 +1,5 @@ from collections.abc import Callable -from typing import Any -from typing_extensions import final +from typing import Any, final @final class make_encoder: diff --git a/mypy/typeshed/stdlib/_operator.pyi b/mypy/typeshed/stdlib/_operator.pyi index 26e69f130728..acc4a6fb59ca 100644 --- a/mypy/typeshed/stdlib/_operator.pyi +++ b/mypy/typeshed/stdlib/_operator.pyi @@ -1,8 +1,8 @@ import sys from _typeshed import SupportsGetItem from collections.abc import Callable, Container, Iterable, MutableMapping, MutableSequence, Sequence -from typing import Any, AnyStr, Generic, Protocol, SupportsAbs, TypeVar, overload -from typing_extensions import ParamSpec, SupportsIndex, TypeAlias, TypeVarTuple, Unpack, final +from typing import Any, AnyStr, Generic, Protocol, SupportsAbs, SupportsIndex, TypeVar, final, overload +from typing_extensions import ParamSpec, TypeAlias, TypeVarTuple, Unpack _R = TypeVar("_R") _T = TypeVar("_T") diff --git a/mypy/typeshed/stdlib/_osx_support.pyi b/mypy/typeshed/stdlib/_osx_support.pyi index 3eb6f4ddc67c..64dbdd24fd40 100644 --- a/mypy/typeshed/stdlib/_osx_support.pyi +++ b/mypy/typeshed/stdlib/_osx_support.pyi @@ -1,4 +1,3 @@ -import sys from collections.abc import Iterable, Sequence from typing import TypeVar @@ -13,13 +12,7 @@ _COMPILER_CONFIG_VARS: tuple[str, ...] # undocumented _INITPRE: str # undocumented def _find_executable(executable: str, path: str | None = None) -> str | None: ... # undocumented - -if sys.version_info >= (3, 8): - def _read_output(commandstring: str, capture_stderr: bool = False) -> str | None: ... # undocumented - -else: - def _read_output(commandstring: str) -> str | None: ... # undocumented - +def _read_output(commandstring: str, capture_stderr: bool = False) -> str | None: ... # undocumented def _find_build_tool(toolname: str) -> str: ... # undocumented _SYSTEM_VERSION: str | None # undocumented diff --git a/mypy/typeshed/stdlib/_posixsubprocess.pyi b/mypy/typeshed/stdlib/_posixsubprocess.pyi index 1708063720ba..6c1782433e45 100644 --- a/mypy/typeshed/stdlib/_posixsubprocess.pyi +++ b/mypy/typeshed/stdlib/_posixsubprocess.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import StrOrBytesPath from collections.abc import Callable, Sequence -from typing_extensions import SupportsIndex +from typing import SupportsIndex if sys.platform != "win32": def cloexec_pipe() -> tuple[int, int]: ... diff --git a/mypy/typeshed/stdlib/_sitebuiltins.pyi b/mypy/typeshed/stdlib/_sitebuiltins.pyi index 94ad701d4a73..49e88a196825 100644 --- a/mypy/typeshed/stdlib/_sitebuiltins.pyi +++ b/mypy/typeshed/stdlib/_sitebuiltins.pyi @@ -1,6 +1,5 @@ from collections.abc import Iterable -from typing import ClassVar, NoReturn -from typing_extensions import Literal +from typing import ClassVar, Literal, NoReturn class Quitter: name: str diff --git a/mypy/typeshed/stdlib/_socket.pyi b/mypy/typeshed/stdlib/_socket.pyi index 7a0ede62838c..6471cae2e72d 100644 --- a/mypy/typeshed/stdlib/_socket.pyi +++ b/mypy/typeshed/stdlib/_socket.pyi @@ -1,16 +1,9 @@ import sys from _typeshed import ReadableBuffer, WriteableBuffer from collections.abc import Iterable -from typing import Any, SupportsInt, overload +from typing import Any, SupportsIndex, overload from typing_extensions import TypeAlias -if sys.version_info >= (3, 8): - from typing import SupportsIndex - - _FD: TypeAlias = SupportsIndex -else: - _FD: TypeAlias = SupportsInt - _CMSG: TypeAlias = tuple[int, int, bytes] _CMSGArg: TypeAlias = tuple[int, int, ReadableBuffer] @@ -20,19 +13,18 @@ _CMSGArg: TypeAlias = tuple[int, int, ReadableBuffer] _Address: TypeAlias = tuple[Any, ...] | str | ReadableBuffer _RetAddress: TypeAlias = Any -# ----- Constants ----- -# Some socket families are listed in the "Socket families" section of the docs, -# but not the "Constants" section. These are listed at the end of the list of -# constants. -# -# Besides those and the first few constants listed, the constants are listed in -# documentation order. +# ===== Constants ===== +# This matches the order in the CPython documentation +# https://docs.python.org/3/library/socket.html#constants -has_ipv6: bool +if sys.platform != "win32": + AF_UNIX: int AF_INET: int AF_INET6: int +AF_UNSPEC: int + SOCK_STREAM: int SOCK_DGRAM: int SOCK_RAW: int @@ -40,162 +32,29 @@ SOCK_RDM: int SOCK_SEQPACKET: int if sys.platform == "linux": + # Availability: Linux >= 2.6.27 SOCK_CLOEXEC: int SOCK_NONBLOCK: int -# Address families not mentioned in the docs -AF_APPLETALK: int -AF_DECnet: int -AF_IPX: int -AF_SNA: int -AF_UNSPEC: int - -if sys.platform != "win32": - AF_ROUTE: int - AF_SYSTEM: int - AF_UNIX: int - -if sys.platform != "darwin": - AF_IRDA: int - -if sys.platform != "darwin" and sys.platform != "win32": - AF_AAL5: int - AF_ASH: int - AF_ATMPVC: int - AF_ATMSVC: int - AF_AX25: int - AF_BRIDGE: int - AF_ECONET: int - AF_KEY: int - AF_LLC: int - AF_NETBEUI: int - AF_NETROM: int - AF_PPPOX: int - AF_ROSE: int - AF_SECURITY: int - AF_WANPIPE: int - AF_X25: int +# -------------------- +# Many constants of these forms, documented in the Unix documentation on +# sockets and/or the IP protocol, are also defined in the socket module. +# SO_* +# socket.SOMAXCONN +# MSG_* +# SOL_* +# SCM_* +# IPPROTO_* +# IPPORT_* +# INADDR_* +# IP_* +# IPV6_* +# EAI_* +# AI_* +# NI_* +# TCP_* +# -------------------- -# The "many constants" referenced by the docs -SOMAXCONN: int -AI_ADDRCONFIG: int -AI_ALL: int -AI_CANONNAME: int -AI_NUMERICHOST: int -AI_NUMERICSERV: int -AI_PASSIVE: int -AI_V4MAPPED: int -EAI_AGAIN: int -EAI_BADFLAGS: int -EAI_FAIL: int -EAI_FAMILY: int -EAI_MEMORY: int -EAI_NODATA: int -EAI_NONAME: int -EAI_SERVICE: int -EAI_SOCKTYPE: int -INADDR_ALLHOSTS_GROUP: int -INADDR_ANY: int -INADDR_BROADCAST: int -INADDR_LOOPBACK: int -INADDR_MAX_LOCAL_GROUP: int -INADDR_NONE: int -INADDR_UNSPEC_GROUP: int -IPPORT_RESERVED: int -IPPORT_USERRESERVED: int - -if sys.platform != "win32" or sys.version_info >= (3, 8): - IPPROTO_AH: int - IPPROTO_DSTOPTS: int - IPPROTO_EGP: int - IPPROTO_ESP: int - IPPROTO_FRAGMENT: int - IPPROTO_GGP: int - IPPROTO_HOPOPTS: int - IPPROTO_ICMPV6: int - IPPROTO_IDP: int - IPPROTO_IGMP: int - IPPROTO_IPV4: int - IPPROTO_IPV6: int - IPPROTO_MAX: int - IPPROTO_ND: int - IPPROTO_NONE: int - IPPROTO_PIM: int - IPPROTO_PUP: int - IPPROTO_ROUTING: int - IPPROTO_SCTP: int - - if sys.platform != "darwin": - IPPROTO_CBT: int - IPPROTO_ICLFXBM: int - IPPROTO_IGP: int - IPPROTO_L2TP: int - IPPROTO_PGM: int - IPPROTO_RDP: int - IPPROTO_ST: int - -IPPROTO_ICMP: int -IPPROTO_IP: int -IPPROTO_RAW: int -IPPROTO_TCP: int -IPPROTO_UDP: int -IPV6_CHECKSUM: int -IPV6_JOIN_GROUP: int -IPV6_LEAVE_GROUP: int -IPV6_MULTICAST_HOPS: int -IPV6_MULTICAST_IF: int -IPV6_MULTICAST_LOOP: int -IPV6_RECVTCLASS: int -IPV6_TCLASS: int -IPV6_UNICAST_HOPS: int -IPV6_V6ONLY: int - -if sys.platform != "darwin" or sys.version_info >= (3, 9): - IPV6_DONTFRAG: int - IPV6_HOPLIMIT: int - IPV6_HOPOPTS: int - IPV6_PKTINFO: int - IPV6_RECVRTHDR: int - IPV6_RTHDR: int - -IP_ADD_MEMBERSHIP: int -IP_DROP_MEMBERSHIP: int -IP_HDRINCL: int -IP_MULTICAST_IF: int -IP_MULTICAST_LOOP: int -IP_MULTICAST_TTL: int -IP_OPTIONS: int -IP_RECVDSTADDR: int -if sys.version_info >= (3, 10): - IP_RECVTOS: int -elif sys.platform != "win32" and sys.platform != "darwin": - IP_RECVTOS: int -IP_TOS: int -IP_TTL: int -MSG_CTRUNC: int -MSG_DONTROUTE: int - -if sys.platform != "darwin": - MSG_ERRQUEUE: int - -MSG_OOB: int -MSG_PEEK: int -MSG_TRUNC: int -MSG_WAITALL: int -NI_DGRAM: int -NI_MAXHOST: int -NI_MAXSERV: int -NI_NAMEREQD: int -NI_NOFQDN: int -NI_NUMERICHOST: int -NI_NUMERICSERV: int -SHUT_RD: int -SHUT_RDWR: int -SHUT_WR: int -SOL_IP: int -SOL_SOCKET: int -SOL_TCP: int -SOL_UDP: int SO_ACCEPTCONN: int SO_BROADCAST: int SO_DEBUG: int @@ -213,39 +72,99 @@ SO_SNDLOWAT: int SO_SNDTIMEO: int SO_TYPE: int SO_USELOOPBACK: int -if sys.platform == "linux" and sys.version_info >= (3, 11): - SO_INCOMING_CPU: int -TCP_FASTOPEN: int -TCP_KEEPCNT: int -TCP_KEEPINTVL: int +if sys.platform == "win32": + SO_EXCLUSIVEADDRUSE: int +if sys.platform != "win32": + SO_REUSEPORT: int +if sys.platform != "win32" and sys.platform != "darwin": + SO_BINDTODEVICE: int + SO_DOMAIN: int + SO_MARK: int + SO_PASSCRED: int + SO_PASSSEC: int + SO_PEERCRED: int + SO_PEERSEC: int + SO_PRIORITY: int + SO_PROTOCOL: int + SO_SETFIB: int -if sys.platform != "darwin": - TCP_KEEPIDLE: int +SOMAXCONN: int -TCP_MAXSEG: int -TCP_NODELAY: int +MSG_CTRUNC: int +MSG_DONTROUTE: int +MSG_OOB: int +MSG_PEEK: int +MSG_TRUNC: int +MSG_WAITALL: int if sys.platform != "win32": - TCP_NOTSENT_LOWAT: int -if sys.version_info >= (3, 10) and sys.platform == "darwin": - TCP_KEEPALIVE: int -if sys.version_info >= (3, 11) and sys.platform == "darwin": - TCP_CONNECTION_INFO: int - + MSG_DONTWAIT: int + MSG_EOF: int + MSG_EOR: int + MSG_NOSIGNAL: int # Sometimes this exists on darwin, sometimes not if sys.platform != "darwin": MSG_BCAST: int + MSG_ERRQUEUE: int MSG_MCAST: int - SO_EXCLUSIVEADDRUSE: int +if sys.platform != "win32" and sys.platform != "darwin": + MSG_BTAG: int + MSG_CMSG_CLOEXEC: int + MSG_CONFIRM: int + MSG_ETAG: int + MSG_FASTOPEN: int + MSG_MORE: int + MSG_NOTIFICATION: int + +SOL_IP: int +SOL_SOCKET: int +SOL_TCP: int +SOL_UDP: int +if sys.platform != "win32" and sys.platform != "darwin": + SOL_ATALK: int + SOL_AX25: int + SOL_HCI: int + SOL_IPX: int + SOL_NETROM: int + SOL_ROSE: int if sys.platform != "win32": - AI_DEFAULT: int - AI_MASK: int - AI_V4MAPPED_CFG: int - EAI_ADDRFAMILY: int - EAI_BADHINTS: int - EAI_MAX: int - EAI_OVERFLOW: int - EAI_PROTOCOL: int - EAI_SYSTEM: int + SCM_CREDS: int + SCM_RIGHTS: int +if sys.platform != "win32" and sys.platform != "darwin": + SCM_CREDENTIALS: int + +IPPROTO_ICMP: int +IPPROTO_IP: int +IPPROTO_RAW: int +IPPROTO_TCP: int +IPPROTO_UDP: int +IPPROTO_AH: int +IPPROTO_DSTOPTS: int +IPPROTO_EGP: int +IPPROTO_ESP: int +IPPROTO_FRAGMENT: int +IPPROTO_GGP: int +IPPROTO_HOPOPTS: int +IPPROTO_ICMPV6: int +IPPROTO_IDP: int +IPPROTO_IGMP: int +IPPROTO_IPV4: int +IPPROTO_IPV6: int +IPPROTO_MAX: int +IPPROTO_ND: int +IPPROTO_NONE: int +IPPROTO_PIM: int +IPPROTO_PUP: int +IPPROTO_ROUTING: int +IPPROTO_SCTP: int +if sys.platform != "darwin": + IPPROTO_CBT: int + IPPROTO_ICLFXBM: int + IPPROTO_IGP: int + IPPROTO_L2TP: int + IPPROTO_PGM: int + IPPROTO_RDP: int + IPPROTO_ST: int +if sys.platform != "win32": IPPROTO_EON: int IPPROTO_GRE: int IPPROTO_HELLO: int @@ -254,24 +173,78 @@ if sys.platform != "win32": IPPROTO_RSVP: int IPPROTO_TP: int IPPROTO_XTP: int - IPV6_RTHDR_TYPE_0: int +if sys.platform != "win32" and sys.platform != "darwin": + IPPROTO_BIP: int + IPPROTO_MOBILE: int + IPPROTO_VRRP: int +if sys.version_info >= (3, 9) and sys.platform == "linux": + # Availability: Linux >= 2.6.20, FreeBSD >= 10.1 + IPPROTO_UDPLITE: int +if sys.version_info >= (3, 10) and sys.platform == "linux": + IPPROTO_MPTCP: int + +IPPORT_RESERVED: int +IPPORT_USERRESERVED: int + +INADDR_ALLHOSTS_GROUP: int +INADDR_ANY: int +INADDR_BROADCAST: int +INADDR_LOOPBACK: int +INADDR_MAX_LOCAL_GROUP: int +INADDR_NONE: int +INADDR_UNSPEC_GROUP: int + +IP_ADD_MEMBERSHIP: int +IP_DROP_MEMBERSHIP: int +IP_HDRINCL: int +IP_MULTICAST_IF: int +IP_MULTICAST_LOOP: int +IP_MULTICAST_TTL: int +IP_OPTIONS: int +IP_RECVDSTADDR: int +if sys.version_info >= (3, 10): + IP_RECVTOS: int +elif sys.platform != "win32" and sys.platform != "darwin": + IP_RECVTOS: int +IP_TOS: int +IP_TTL: int +if sys.platform != "win32": IP_DEFAULT_MULTICAST_LOOP: int IP_DEFAULT_MULTICAST_TTL: int IP_MAX_MEMBERSHIPS: int IP_RECVOPTS: int IP_RECVRETOPTS: int IP_RETOPTS: int - LOCAL_PEERCRED: int - MSG_DONTWAIT: int - MSG_EOF: int - MSG_EOR: int - MSG_NOSIGNAL: int # Sometimes this exists on darwin, sometimes not - SCM_CREDS: int - SCM_RIGHTS: int - SO_REUSEPORT: int +if sys.platform != "win32" and sys.platform != "darwin": + IP_TRANSPARENT: int + IP_BIND_ADDRESS_NO_PORT: int +if sys.version_info >= (3, 12): + IP_ADD_SOURCE_MEMBERSHIP: int + IP_BLOCK_SOURCE: int + IP_DROP_SOURCE_MEMBERSHIP: int + IP_PKTINFO: int + IP_UNBLOCK_SOURCE: int +IPV6_CHECKSUM: int +IPV6_JOIN_GROUP: int +IPV6_LEAVE_GROUP: int +IPV6_MULTICAST_HOPS: int +IPV6_MULTICAST_IF: int +IPV6_MULTICAST_LOOP: int +IPV6_RECVTCLASS: int +IPV6_TCLASS: int +IPV6_UNICAST_HOPS: int +IPV6_V6ONLY: int +if sys.version_info >= (3, 9) or sys.platform != "darwin": + IPV6_DONTFRAG: int + IPV6_HOPLIMIT: int + IPV6_HOPOPTS: int + IPV6_PKTINFO: int + IPV6_RECVRTHDR: int + IPV6_RTHDR: int if sys.platform != "win32": - if sys.platform != "darwin" or sys.version_info >= (3, 9): + IPV6_RTHDR_TYPE_0: int + if sys.version_info >= (3, 9) or sys.platform != "darwin": IPV6_DSTOPTS: int IPV6_NEXTHOP: int IPV6_PATHMTU: int @@ -283,43 +256,74 @@ if sys.platform != "win32": IPV6_RTHDRDSTOPTS: int IPV6_USE_MIN_MTU: int +EAI_AGAIN: int +EAI_BADFLAGS: int +EAI_FAIL: int +EAI_FAMILY: int +EAI_MEMORY: int +EAI_NODATA: int +EAI_NONAME: int +EAI_SERVICE: int +EAI_SOCKTYPE: int +if sys.platform != "win32": + EAI_ADDRFAMILY: int + EAI_BADHINTS: int + EAI_MAX: int + EAI_OVERFLOW: int + EAI_PROTOCOL: int + EAI_SYSTEM: int + +AI_ADDRCONFIG: int +AI_ALL: int +AI_CANONNAME: int +AI_NUMERICHOST: int +AI_NUMERICSERV: int +AI_PASSIVE: int +AI_V4MAPPED: int +if sys.platform != "win32": + AI_DEFAULT: int + AI_MASK: int + AI_V4MAPPED_CFG: int + +NI_DGRAM: int +NI_MAXHOST: int +NI_MAXSERV: int +NI_NAMEREQD: int +NI_NOFQDN: int +NI_NUMERICHOST: int +NI_NUMERICSERV: int + +TCP_FASTOPEN: int +TCP_KEEPCNT: int +TCP_KEEPINTVL: int +TCP_MAXSEG: int +TCP_NODELAY: int +if sys.platform != "win32": + TCP_NOTSENT_LOWAT: int +if sys.platform != "darwin": + TCP_KEEPIDLE: int +if sys.version_info >= (3, 10) and sys.platform == "darwin": + TCP_KEEPALIVE: int +if sys.version_info >= (3, 11) and sys.platform == "darwin": + TCP_CONNECTION_INFO: int + if sys.platform != "win32" and sys.platform != "darwin": - IPPROTO_BIP: int - IPPROTO_MOBILE: int - IPPROTO_VRRP: int - IPX_TYPE: int - IP_TRANSPARENT: int - MSG_BTAG: int - MSG_CMSG_CLOEXEC: int - MSG_CONFIRM: int - MSG_ETAG: int - MSG_FASTOPEN: int - MSG_MORE: int - MSG_NOTIFICATION: int - SCM_CREDENTIALS: int - SOL_ATALK: int - SOL_AX25: int - SOL_HCI: int - SOL_IPX: int - SOL_NETROM: int - SOL_ROSE: int - SO_BINDTODEVICE: int - SO_MARK: int - SO_PASSCRED: int - SO_PEERCRED: int - SO_PRIORITY: int - SO_SETFIB: int + TCP_CONGESTION: int TCP_CORK: int TCP_DEFER_ACCEPT: int TCP_INFO: int TCP_LINGER2: int TCP_QUICKACK: int TCP_SYNCNT: int + TCP_USER_TIMEOUT: int TCP_WINDOW_CLAMP: int -# Specifically-documented constants +# -------------------- +# Specifically documented constants +# -------------------- if sys.platform == "linux": + # Availability: Linux >= 2.6.25, NetBSD >= 8 AF_CAN: int PF_CAN: int SOL_CAN_BASE: int @@ -336,6 +340,8 @@ if sys.platform == "linux": CAN_RTR_FLAG: int CAN_SFF_MASK: int +if sys.platform == "linux": + # Availability: Linux >= 2.6.25 CAN_BCM: int CAN_BCM_TX_SETUP: int CAN_BCM_TX_DELETE: int @@ -349,10 +355,6 @@ if sys.platform == "linux": CAN_BCM_RX_STATUS: int CAN_BCM_RX_TIMEOUT: int CAN_BCM_RX_CHANGED: int - - CAN_RAW_FD_FRAMES: int - -if sys.platform == "linux" and sys.version_info >= (3, 8): CAN_BCM_SETTIMER: int CAN_BCM_STARTTIMER: int CAN_BCM_TX_COUNTEVT: int @@ -367,11 +369,20 @@ if sys.platform == "linux" and sys.version_info >= (3, 8): CAN_BCM_CAN_FD_FRAME: int if sys.platform == "linux": + # Availability: Linux >= 3.6 + CAN_RAW_FD_FRAMES: int + +if sys.platform == "linux" and sys.version_info >= (3, 9): + # Availability: Linux >= 4.1 + CAN_RAW_JOIN_FILTERS: int + +if sys.platform == "linux": + # Availability: Linux >= 2.6.25 CAN_ISOTP: int if sys.platform == "linux" and sys.version_info >= (3, 9): + # Availability: Linux >= 5.4 CAN_J1939: int - CAN_RAW_JOIN_FILTERS: int J1939_MAX_UNICAST_ADDR: int J1939_IDLE_ADDR: int @@ -396,16 +407,17 @@ if sys.platform == "linux" and sys.version_info >= (3, 9): J1939_NLA_PAD: int J1939_NLA_BYTES_ACKED: int - J1939_EE_INFO_NONE: int J1939_EE_INFO_TX_ABORT: int - J1939_FILTER_MAX: int -if sys.platform == "linux" and sys.version_info >= (3, 10): - IPPROTO_MPTCP: int +if sys.version_info >= (3, 12) and sys.platform != "linux" and sys.platform != "win32" and sys.platform != "darwin": + # Availability: FreeBSD >= 14.0 + AF_DIVERT: int + PF_DIVERT: int if sys.platform == "linux": + # Availability: Linux >= 2.2 AF_PACKET: int PF_PACKET: int PACKET_BROADCAST: int @@ -416,7 +428,11 @@ if sys.platform == "linux": PACKET_OTHERHOST: int PACKET_OUTGOING: int +if sys.version_info >= (3, 12) and sys.platform == "linux": + ETH_P_ALL: int + if sys.platform == "linux": + # Availability: Linux >= 2.6.30 AF_RDS: int PF_RDS: int SOL_RDS: int @@ -476,6 +492,7 @@ if sys.platform == "linux": TIPC_ZONE_SCOPE: int if sys.platform == "linux": + # Availability: Linux >= 2.6.38 AF_ALG: int SOL_ALG: int ALG_OP_DECRYPT: int @@ -490,6 +507,7 @@ if sys.platform == "linux": ALG_SET_PUBKEY: int if sys.platform == "linux": + # Availability: Linux >= 4.8 (or maybe 3.9, CPython docs are confusing) AF_VSOCK: int IOCTL_VM_SOCKETS_GET_LOCAL_CID: int VMADDR_CID_ANY: int @@ -498,26 +516,65 @@ if sys.platform == "linux": SO_VM_SOCKETS_BUFFER_MAX_SIZE: int SO_VM_SOCKETS_BUFFER_SIZE: int SO_VM_SOCKETS_BUFFER_MIN_SIZE: int - VM_SOCKETS_INVALID_VERSION: int + VM_SOCKETS_INVALID_VERSION: int # undocumented if sys.platform != "win32" or sys.version_info >= (3, 9): + # Documented as only available on BSD, macOS, but empirically sometimes + # available on Windows AF_LINK: int -# BDADDR_* and HCI_* listed with other bluetooth constants below +has_ipv6: bool + +if sys.platform != "darwin": + if sys.platform != "win32" or sys.version_info >= (3, 9): + BDADDR_ANY: str + BDADDR_LOCAL: str if sys.platform != "win32" and sys.platform != "darwin": - SO_DOMAIN: int - SO_PASSSEC: int - SO_PEERSEC: int - SO_PROTOCOL: int - TCP_CONGESTION: int - TCP_USER_TIMEOUT: int + HCI_FILTER: int # not in NetBSD or DragonFlyBSD + HCI_TIME_STAMP: int # not in FreeBSD, NetBSD, or DragonFlyBSD + HCI_DATA_DIR: int # not in FreeBSD, NetBSD, or DragonFlyBSD + +if sys.platform == "linux": + AF_QIPCRTR: int # Availability: Linux >= 4.7 + +if sys.version_info >= (3, 11) and sys.platform != "linux" and sys.platform != "win32" and sys.platform != "darwin": + # FreeBSD + SCM_CREDS2: int + LOCAL_CREDS: int + LOCAL_CREDS_PERSISTENT: int + +if sys.version_info >= (3, 11) and sys.platform == "linux": + SO_INCOMING_CPU: int # Availability: Linux >= 3.9 + +if sys.version_info >= (3, 12) and sys.platform == "win32": + # Availability: Windows + AF_HYPERV: int + HV_PROTOCOL_RAW: int + HVSOCKET_CONNECT_TIMEOUT: int + HVSOCKET_CONNECT_TIMEOUT_MAX: int + HVSOCKET_CONNECTED_SUSPEND: int + HVSOCKET_ADDRESS_FLAG_PASSTHRU: int + HV_GUID_ZERO: str + HV_GUID_WILDCARD: str + HV_GUID_BROADCAST: str + HV_GUID_CHILDREN: str + HV_GUID_LOOPBACK: str + HV_GUID_PARENT: str -if sys.platform == "linux" and sys.version_info >= (3, 8): - AF_QIPCRTR: int +if sys.version_info >= (3, 12): + if sys.platform != "win32": + # Availability: Linux, FreeBSD, macOS + ETHERTYPE_ARP: int + ETHERTYPE_IP: int + ETHERTYPE_IPV6: int + ETHERTYPE_VLAN: int +# -------------------- # Semi-documented constants -# (Listed under "Socket families" in the docs, but not "Constants") +# These are alluded to under the "Socket families" section in the docs +# https://docs.python.org/3/library/socket.html#socket-families +# -------------------- if sys.platform == "linux": # Netlink is defined by Linux @@ -537,12 +594,13 @@ if sys.platform == "linux": NETLINK_W1: int NETLINK_XFRM: int +if sys.platform == "darwin": + PF_SYSTEM: int + SYSPROTO_CONTROL: int + if sys.platform != "darwin": - if sys.platform != "win32" or sys.version_info >= (3, 9): + if sys.version_info >= (3, 9) or sys.platform != "win32": AF_BLUETOOTH: int - BDADDR_ANY: str - BDADDR_LOCAL: str - BTPROTO_RFCOMM: int if sys.platform != "win32" and sys.platform != "darwin": # Linux and some BSD support is explicit in the docs @@ -550,17 +608,65 @@ if sys.platform != "win32" and sys.platform != "darwin": BTPROTO_HCI: int BTPROTO_L2CAP: int BTPROTO_SCO: int # not in FreeBSD - HCI_FILTER: int # not in NetBSD or DragonFlyBSD - # not in FreeBSD, NetBSD, or DragonFlyBSD - HCI_TIME_STAMP: int - HCI_DATA_DIR: int +if sys.platform != "darwin": + if sys.version_info >= (3, 9) or sys.platform != "win32": + BTPROTO_RFCOMM: int -if sys.platform == "darwin": - # PF_SYSTEM is defined by macOS - PF_SYSTEM: int - SYSPROTO_CONTROL: int +if sys.version_info >= (3, 9) and sys.platform == "linux": + UDPLITE_RECV_CSCOV: int + UDPLITE_SEND_CSCOV: int + +# -------------------- +# Documented under socket.shutdown +# -------------------- +SHUT_RD: int +SHUT_RDWR: int +SHUT_WR: int -# ----- Exceptions ----- +# -------------------- +# Undocumented constants +# -------------------- + +# Undocumented address families +AF_APPLETALK: int +AF_DECnet: int +AF_IPX: int +AF_SNA: int + +if sys.platform != "win32": + AF_ROUTE: int + AF_SYSTEM: int + +if sys.platform != "darwin": + AF_IRDA: int + +if sys.platform != "win32" and sys.platform != "darwin": + AF_AAL5: int + AF_ASH: int + AF_ATMPVC: int + AF_ATMSVC: int + AF_AX25: int + AF_BRIDGE: int + AF_ECONET: int + AF_KEY: int + AF_LLC: int + AF_NETBEUI: int + AF_NETROM: int + AF_PPPOX: int + AF_ROSE: int + AF_SECURITY: int + AF_WANPIPE: int + AF_X25: int + +# Miscellaneous undocumented + +if sys.platform != "win32": + LOCAL_PEERCRED: int + +if sys.platform != "win32" and sys.platform != "darwin": + IPX_TYPE: int + +# ===== Exceptions ===== error = OSError @@ -572,7 +678,7 @@ if sys.version_info >= (3, 10): else: class timeout(error): ... -# ----- Classes ----- +# ===== Classes ===== class socket: @property @@ -584,9 +690,11 @@ class socket: @property def timeout(self) -> float | None: ... if sys.platform == "win32": - def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: _FD | bytes | None = ...) -> None: ... + def __init__( + self, family: int = ..., type: int = ..., proto: int = ..., fileno: SupportsIndex | bytes | None = ... + ) -> None: ... else: - def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: _FD | None = ...) -> None: ... + def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: SupportsIndex | None = ...) -> None: ... def bind(self, __address: _Address) -> None: ... def close(self) -> None: ... @@ -648,10 +756,10 @@ class socket: SocketType = socket -# ----- Functions ----- +# ===== Functions ===== -def close(__fd: _FD) -> None: ... -def dup(__fd: _FD) -> int: ... +def close(__fd: SupportsIndex) -> None: ... +def dup(__fd: SupportsIndex) -> int: ... # the 5th tuple item is an address def getaddrinfo( @@ -687,33 +795,8 @@ if sys.platform != "win32": def CMSG_SPACE(__length: int) -> int: ... def socketpair(__family: int = ..., __type: int = ..., __proto: int = ...) -> tuple[socket, socket]: ... -# Windows added these in 3.8, but didn't have them before -if sys.platform != "win32" or sys.version_info >= (3, 8): - def if_nameindex() -> list[tuple[int, str]]: ... - def if_nametoindex(__name: str) -> int: ... - def if_indextoname(__index: int) -> str: ... +def if_nameindex() -> list[tuple[int, str]]: ... +def if_nametoindex(__name: str) -> int: ... +def if_indextoname(__index: int) -> str: ... -if sys.version_info >= (3, 12): - IP_PKTINFO: int - IP_UNBLOCK_SOURCE: int - IP_BLOCK_SOURCE: int - IP_ADD_SOURCE_MEMBERSHIP: int - IP_DROP_SOURCE_MEMBERSHIP: int - if sys.platform == "win32": - AF_HYPERV: int - HV_PROTOCOL_RAW: int - HVSOCKET_CONNECT_TIMEOUT: int - HVSOCKET_CONNECT_TIMEOUT_MAX: int - HVSOCKET_CONNECTED_SUSPEND: int - HVSOCKET_ADDRESS_FLAG_PASSTHRU: int - HV_GUID_ZERO: str - HV_GUID_WILDCARD: str - HV_GUID_BROADCAST: str - HV_GUID_CHILDREN: str - HV_GUID_LOOPBACK: str - HV_GUID_PARENT: str - else: - ETHERTYPE_ARP: int - ETHERTYPE_IP: int - ETHERTYPE_IPV6: int - ETHERTYPE_VLAN: int +CAPI: object diff --git a/mypy/typeshed/stdlib/_stat.pyi b/mypy/typeshed/stdlib/_stat.pyi index 83d832e4dd8e..347897404edc 100644 --- a/mypy/typeshed/stdlib/_stat.pyi +++ b/mypy/typeshed/stdlib/_stat.pyi @@ -1,5 +1,5 @@ import sys -from typing_extensions import Literal +from typing import Literal SF_APPEND: Literal[0x00040000] SF_ARCHIVED: Literal[0x00010000] @@ -78,7 +78,7 @@ def S_ISSOCK(mode: int) -> bool: ... def S_ISWHT(mode: int) -> bool: ... def filemode(mode: int) -> str: ... -if sys.platform == "win32" and sys.version_info >= (3, 8): +if sys.platform == "win32": IO_REPARSE_TAG_SYMLINK: int IO_REPARSE_TAG_MOUNT_POINT: int IO_REPARSE_TAG_APPEXECLINK: int diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index 8bd0b179607b..8b43a81cac8a 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -3,8 +3,7 @@ from _typeshed import structseq from collections.abc import Callable from threading import Thread from types import TracebackType -from typing import Any, NoReturn -from typing_extensions import Final, final +from typing import Any, Final, NoReturn, final error = RuntimeError @@ -28,21 +27,21 @@ def stack_size(size: int = ...) -> int: ... TIMEOUT_MAX: float -if sys.version_info >= (3, 8): - def get_native_id() -> int: ... # only available on some platforms - @final - class _ExceptHookArgs(structseq[Any], tuple[type[BaseException], BaseException | None, TracebackType | None, Thread | None]): - if sys.version_info >= (3, 10): - __match_args__: Final = ("exc_type", "exc_value", "exc_traceback", "thread") - @property - def exc_type(self) -> type[BaseException]: ... - @property - def exc_value(self) -> BaseException | None: ... - @property - def exc_traceback(self) -> TracebackType | None: ... - @property - def thread(self) -> Thread | None: ... - _excepthook: Callable[[_ExceptHookArgs], Any] +def get_native_id() -> int: ... # only available on some platforms +@final +class _ExceptHookArgs(structseq[Any], tuple[type[BaseException], BaseException | None, TracebackType | None, Thread | None]): + if sys.version_info >= (3, 10): + __match_args__: Final = ("exc_type", "exc_value", "exc_traceback", "thread") + @property + def exc_type(self) -> type[BaseException]: ... + @property + def exc_value(self) -> BaseException | None: ... + @property + def exc_traceback(self) -> TracebackType | None: ... + @property + def thread(self) -> Thread | None: ... + +_excepthook: Callable[[_ExceptHookArgs], Any] if sys.version_info >= (3, 12): def daemon_threads_allowed() -> bool: ... diff --git a/mypy/typeshed/stdlib/_tkinter.pyi b/mypy/typeshed/stdlib/_tkinter.pyi index 89610e21d9e7..67e7e3f696e2 100644 --- a/mypy/typeshed/stdlib/_tkinter.pyi +++ b/mypy/typeshed/stdlib/_tkinter.pyi @@ -1,6 +1,5 @@ import sys -from typing import Any, ClassVar -from typing_extensions import Literal, final +from typing import Any, ClassVar, Literal, final # _tkinter is meant to be only used internally by tkinter, but some tkinter # functions e.g. return _tkinter.Tcl_Obj objects. Tcl_Obj represents a Tcl @@ -107,29 +106,15 @@ TK_VERSION: str class TkttType: def deletetimerhandler(self): ... -if sys.version_info >= (3, 8): - def create( - __screenName: str | None = None, - __baseName: str = "", - __className: str = "Tk", - __interactive: bool = False, - __wantobjects: bool = False, - __wantTk: bool = True, - __sync: bool = False, - __use: str | None = None, - ): ... - -else: - def create( - __screenName: str | None = None, - __baseName: str | None = None, - __className: str = "Tk", - __interactive: bool = False, - __wantobjects: bool = False, - __wantTk: bool = True, - __sync: bool = False, - __use: str | None = None, - ): ... - +def create( + __screenName: str | None = None, + __baseName: str = "", + __className: str = "Tk", + __interactive: bool = False, + __wantobjects: bool = False, + __wantTk: bool = True, + __sync: bool = False, + __use: str | None = None, +): ... def getbusywaitinterval(): ... def setbusywaitinterval(__new_val): ... diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 05892c8aab11..e9a24bab28a9 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -7,8 +7,22 @@ from collections.abc import Awaitable, Callable, Iterable, Sequence, Set as Abst from dataclasses import Field from os import PathLike from types import FrameType, TracebackType -from typing import Any, AnyStr, ClassVar, Generic, Protocol, SupportsFloat, SupportsInt, TypeVar, overload -from typing_extensions import Buffer, Final, Literal, LiteralString, SupportsIndex, TypeAlias, final +from typing import ( + Any, + AnyStr, + ClassVar, + Final, + Generic, + Literal, + Protocol, + SupportsFloat, + SupportsIndex, + SupportsInt, + TypeVar, + final, + overload, +) +from typing_extensions import Buffer, LiteralString, TypeAlias _KT = TypeVar("_KT") _KT_co = TypeVar("_KT_co", covariant=True) @@ -19,8 +33,10 @@ _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) _T_contra = TypeVar("_T_contra", contravariant=True) -# Use for "self" annotations: -# def __enter__(self: Self) -> Self: ... +# Alternative to `typing_extensions.Self`, exclusively for use with `__new__` +# in metaclasses: +# def __new__(cls: type[Self], ...) -> Self: ... +# In other cases, use `typing_extensions.Self`. Self = TypeVar("Self") # noqa: Y001 # covariant version of typing.AnyStr, useful for protocols diff --git a/mypy/typeshed/stdlib/_weakref.pyi b/mypy/typeshed/stdlib/_weakref.pyi index ce0f681248ab..f939aa815bd2 100644 --- a/mypy/typeshed/stdlib/_weakref.pyi +++ b/mypy/typeshed/stdlib/_weakref.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable -from typing import Any, Generic, TypeVar, overload -from typing_extensions import Self, final +from typing import Any, Generic, TypeVar, final, overload +from typing_extensions import Self if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/_winapi.pyi b/mypy/typeshed/stdlib/_winapi.pyi index 1aec6ce50443..21ae149e186e 100644 --- a/mypy/typeshed/stdlib/_winapi.pyi +++ b/mypy/typeshed/stdlib/_winapi.pyi @@ -1,8 +1,7 @@ import sys from _typeshed import ReadableBuffer from collections.abc import Sequence -from typing import Any, NoReturn, overload -from typing_extensions import Literal, final +from typing import Any, Literal, NoReturn, final, overload if sys.platform == "win32": ABOVE_NORMAL_PRIORITY_CLASS: Literal[0x8000] @@ -36,12 +35,11 @@ if sys.platform == "win32": FILE_GENERIC_READ: Literal[1179785] FILE_GENERIC_WRITE: Literal[1179926] - if sys.version_info >= (3, 8): - FILE_MAP_ALL_ACCESS: Literal[983071] - FILE_MAP_COPY: Literal[1] - FILE_MAP_EXECUTE: Literal[32] - FILE_MAP_READ: Literal[4] - FILE_MAP_WRITE: Literal[2] + FILE_MAP_ALL_ACCESS: Literal[983071] + FILE_MAP_COPY: Literal[1] + FILE_MAP_EXECUTE: Literal[32] + FILE_MAP_READ: Literal[4] + FILE_MAP_WRITE: Literal[2] FILE_TYPE_CHAR: Literal[2] FILE_TYPE_DISK: Literal[1] @@ -53,23 +51,21 @@ if sys.platform == "win32": GENERIC_WRITE: Literal[0x40000000] HIGH_PRIORITY_CLASS: Literal[0x80] INFINITE: Literal[0xFFFFFFFF] - if sys.version_info >= (3, 8): - # Ignore the Flake8 error -- flake8-pyi assumes - # most numbers this long will be implementation details, - # but here we can see that it's a power of 2 - INVALID_HANDLE_VALUE: Literal[0xFFFFFFFFFFFFFFFF] # noqa: Y054 + # Ignore the Flake8 error -- flake8-pyi assumes + # most numbers this long will be implementation details, + # but here we can see that it's a power of 2 + INVALID_HANDLE_VALUE: Literal[0xFFFFFFFFFFFFFFFF] # noqa: Y054 IDLE_PRIORITY_CLASS: Literal[0x40] NORMAL_PRIORITY_CLASS: Literal[0x20] REALTIME_PRIORITY_CLASS: Literal[0x100] NMPWAIT_WAIT_FOREVER: Literal[0xFFFFFFFF] - if sys.version_info >= (3, 8): - MEM_COMMIT: Literal[0x1000] - MEM_FREE: Literal[0x10000] - MEM_IMAGE: Literal[0x1000000] - MEM_MAPPED: Literal[0x40000] - MEM_PRIVATE: Literal[0x20000] - MEM_RESERVE: Literal[0x2000] + MEM_COMMIT: Literal[0x1000] + MEM_FREE: Literal[0x10000] + MEM_IMAGE: Literal[0x1000000] + MEM_MAPPED: Literal[0x40000] + MEM_PRIVATE: Literal[0x20000] + MEM_RESERVE: Literal[0x2000] NULL: Literal[0] OPEN_EXISTING: Literal[3] @@ -81,29 +77,27 @@ if sys.platform == "win32": PIPE_UNLIMITED_INSTANCES: Literal[255] PIPE_WAIT: Literal[0] - if sys.version_info >= (3, 8): - PAGE_EXECUTE: Literal[0x10] - PAGE_EXECUTE_READ: Literal[0x20] - PAGE_EXECUTE_READWRITE: Literal[0x40] - PAGE_EXECUTE_WRITECOPY: Literal[0x80] - PAGE_GUARD: Literal[0x100] - PAGE_NOACCESS: Literal[0x1] - PAGE_NOCACHE: Literal[0x200] - PAGE_READONLY: Literal[0x2] - PAGE_READWRITE: Literal[0x4] - PAGE_WRITECOMBINE: Literal[0x400] - PAGE_WRITECOPY: Literal[0x8] + PAGE_EXECUTE: Literal[0x10] + PAGE_EXECUTE_READ: Literal[0x20] + PAGE_EXECUTE_READWRITE: Literal[0x40] + PAGE_EXECUTE_WRITECOPY: Literal[0x80] + PAGE_GUARD: Literal[0x100] + PAGE_NOACCESS: Literal[0x1] + PAGE_NOCACHE: Literal[0x200] + PAGE_READONLY: Literal[0x2] + PAGE_READWRITE: Literal[0x4] + PAGE_WRITECOMBINE: Literal[0x400] + PAGE_WRITECOPY: Literal[0x8] PROCESS_ALL_ACCESS: Literal[0x1FFFFF] PROCESS_DUP_HANDLE: Literal[0x40] - if sys.version_info >= (3, 8): - SEC_COMMIT: Literal[0x8000000] - SEC_IMAGE: Literal[0x1000000] - SEC_LARGE_PAGES: Literal[0x80000000] - SEC_NOCACHE: Literal[0x10000000] - SEC_RESERVE: Literal[0x4000000] - SEC_WRITECOMBINE: Literal[0x40000000] + SEC_COMMIT: Literal[0x8000000] + SEC_IMAGE: Literal[0x1000000] + SEC_LARGE_PAGES: Literal[0x80000000] + SEC_NOCACHE: Literal[0x10000000] + SEC_RESERVE: Literal[0x4000000] + SEC_WRITECOMBINE: Literal[0x40000000] STARTF_USESHOWWINDOW: Literal[0x1] STARTF_USESTDHANDLES: Literal[0x100] @@ -114,8 +108,7 @@ if sys.platform == "win32": STILL_ACTIVE: Literal[259] SW_HIDE: Literal[0] - if sys.version_info >= (3, 8): - SYNCHRONIZE: Literal[0x100000] + SYNCHRONIZE: Literal[0x100000] WAIT_ABANDONED_0: Literal[128] WAIT_OBJECT_0: Literal[0] WAIT_TIMEOUT: Literal[258] diff --git a/mypy/typeshed/stdlib/abc.pyi b/mypy/typeshed/stdlib/abc.pyi index 7fe1d09f7589..c642f8b9f123 100644 --- a/mypy/typeshed/stdlib/abc.pyi +++ b/mypy/typeshed/stdlib/abc.pyi @@ -2,8 +2,8 @@ import _typeshed import sys from _typeshed import SupportsWrite from collections.abc import Callable -from typing import Any, TypeVar -from typing_extensions import Concatenate, Literal, ParamSpec +from typing import Any, Literal, TypeVar +from typing_extensions import Concatenate, ParamSpec _T = TypeVar("_T") _R_co = TypeVar("_R_co", covariant=True) diff --git a/mypy/typeshed/stdlib/aifc.pyi b/mypy/typeshed/stdlib/aifc.pyi index ab0c18ed6623..05bf53986b29 100644 --- a/mypy/typeshed/stdlib/aifc.pyi +++ b/mypy/typeshed/stdlib/aifc.pyi @@ -1,7 +1,7 @@ import sys from types import TracebackType -from typing import IO, Any, NamedTuple, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Literal, NamedTuple, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): __all__ = ["Error", "open"] diff --git a/mypy/typeshed/stdlib/argparse.pyi b/mypy/typeshed/stdlib/argparse.pyi index 0cbbcd242195..489cc6b16634 100644 --- a/mypy/typeshed/stdlib/argparse.pyi +++ b/mypy/typeshed/stdlib/argparse.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import sentinel from collections.abc import Callable, Generator, Iterable, Sequence from re import Pattern -from typing import IO, Any, Generic, NewType, NoReturn, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Generic, Literal, NewType, NoReturn, Protocol, TypeVar, overload +from typing_extensions import Self, TypeAlias __all__ = [ "ArgumentParser", @@ -446,8 +446,7 @@ class _StoreFalseAction(_StoreConstAction): class _AppendAction(Action): ... # undocumented -if sys.version_info >= (3, 8): - class _ExtendAction(_AppendAction): ... +class _ExtendAction(_AppendAction): ... # undocumented class _AppendConstAction(Action): diff --git a/mypy/typeshed/stdlib/array.pyi b/mypy/typeshed/stdlib/array.pyi index 2ef821fcf87a..4b5675d2a76e 100644 --- a/mypy/typeshed/stdlib/array.pyi +++ b/mypy/typeshed/stdlib/array.pyi @@ -3,8 +3,8 @@ from _typeshed import ReadableBuffer, SupportsRead, SupportsWrite from collections.abc import Iterable # pytype crashes if array inherits from collections.abc.MutableSequence instead of typing.MutableSequence -from typing import Any, MutableSequence, TypeVar, overload # noqa: Y022 -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias +from typing import Any, Literal, MutableSequence, SupportsIndex, TypeVar, overload # noqa: Y022 +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 12): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/ast.pyi b/mypy/typeshed/stdlib/ast.pyi index 5c9cafc189be..4ab325b5baa7 100644 --- a/mypy/typeshed/stdlib/ast.pyi +++ b/mypy/typeshed/stdlib/ast.pyi @@ -3,32 +3,34 @@ import sys from _ast import * from _typeshed import ReadableBuffer, Unused from collections.abc import Iterator -from typing import Any, TypeVar as _TypeVar, overload -from typing_extensions import Literal, deprecated +from typing import Any, Literal, TypeVar as _TypeVar, overload +from typing_extensions import deprecated -if sys.version_info >= (3, 8): - class _ABC(type): - if sys.version_info >= (3, 9): - def __init__(cls, *args: Unused) -> None: ... +class _ABC(type): + if sys.version_info >= (3, 9): + def __init__(cls, *args: Unused) -> None: ... - @deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") - class Num(Constant, metaclass=_ABC): - value: int | float | complex - @deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") - class Str(Constant, metaclass=_ABC): - value: str - # Aliases for value, for backwards compatibility - s: str - @deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") - class Bytes(Constant, metaclass=_ABC): - value: bytes - # Aliases for value, for backwards compatibility - s: bytes - @deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") - class NameConstant(Constant, metaclass=_ABC): ... +@deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") +class Num(Constant, metaclass=_ABC): + value: int | float | complex - @deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") - class Ellipsis(Constant, metaclass=_ABC): ... +@deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") +class Str(Constant, metaclass=_ABC): + value: str + # Aliases for value, for backwards compatibility + s: str + +@deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") +class Bytes(Constant, metaclass=_ABC): + value: bytes + # Aliases for value, for backwards compatibility + s: bytes + +@deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") +class NameConstant(Constant, metaclass=_ABC): ... + +@deprecated("Replaced by ast.Constant; removal scheduled for Python 3.14") +class Ellipsis(Constant, metaclass=_ABC): ... if sys.version_info >= (3, 9): class slice(AST): ... @@ -90,10 +92,8 @@ class NodeVisitor: def visit_FormattedValue(self, node: FormattedValue) -> Any: ... def visit_JoinedStr(self, node: JoinedStr) -> Any: ... def visit_Constant(self, node: Constant) -> Any: ... - if sys.version_info >= (3, 8): - def visit_NamedExpr(self, node: NamedExpr) -> Any: ... - def visit_TypeIgnore(self, node: TypeIgnore) -> Any: ... - + def visit_NamedExpr(self, node: NamedExpr) -> Any: ... + def visit_TypeIgnore(self, node: TypeIgnore) -> Any: ... def visit_Attribute(self, node: Attribute) -> Any: ... def visit_Subscript(self, node: Subscript) -> Any: ... def visit_Starred(self, node: Starred) -> Any: ... @@ -181,100 +181,75 @@ class NodeTransformer(NodeVisitor): _T = _TypeVar("_T", bound=AST) -if sys.version_info >= (3, 8): - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any] = "", - mode: Literal["exec"] = "exec", - *, - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> Module: ... - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any], - mode: Literal["eval"], - *, - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> Expression: ... - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any], - mode: Literal["func_type"], - *, - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> FunctionType: ... - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any], - mode: Literal["single"], - *, - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> Interactive: ... - @overload - def parse( - source: str | ReadableBuffer, - *, - mode: Literal["eval"], - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> Expression: ... - @overload - def parse( - source: str | ReadableBuffer, - *, - mode: Literal["func_type"], - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> FunctionType: ... - @overload - def parse( - source: str | ReadableBuffer, - *, - mode: Literal["single"], - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> Interactive: ... - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any] = "", - mode: str = "exec", - *, - type_comments: bool = False, - feature_version: None | int | tuple[int, int] = None, - ) -> AST: ... - -else: - @overload - def parse( - source: str | ReadableBuffer, - filename: str | ReadableBuffer | os.PathLike[Any] = "", - mode: Literal["exec"] = "exec", - ) -> Module: ... - @overload - def parse( - source: str | ReadableBuffer, filename: str | ReadableBuffer | os.PathLike[Any], mode: Literal["eval"] - ) -> Expression: ... - @overload - def parse( - source: str | ReadableBuffer, filename: str | ReadableBuffer | os.PathLike[Any], mode: Literal["single"] - ) -> Interactive: ... - @overload - def parse(source: str | ReadableBuffer, *, mode: Literal["eval"]) -> Expression: ... - @overload - def parse(source: str | ReadableBuffer, *, mode: Literal["single"]) -> Interactive: ... - @overload - def parse( - source: str | ReadableBuffer, filename: str | ReadableBuffer | os.PathLike[Any] = "", mode: str = "exec" - ) -> AST: ... +@overload +def parse( + source: str | ReadableBuffer, + filename: str | ReadableBuffer | os.PathLike[Any] = "", + mode: Literal["exec"] = "exec", + *, + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> Module: ... +@overload +def parse( + source: str | ReadableBuffer, + filename: str | ReadableBuffer | os.PathLike[Any], + mode: Literal["eval"], + *, + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> Expression: ... +@overload +def parse( + source: str | ReadableBuffer, + filename: str | ReadableBuffer | os.PathLike[Any], + mode: Literal["func_type"], + *, + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> FunctionType: ... +@overload +def parse( + source: str | ReadableBuffer, + filename: str | ReadableBuffer | os.PathLike[Any], + mode: Literal["single"], + *, + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> Interactive: ... +@overload +def parse( + source: str | ReadableBuffer, + *, + mode: Literal["eval"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> Expression: ... +@overload +def parse( + source: str | ReadableBuffer, + *, + mode: Literal["func_type"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> FunctionType: ... +@overload +def parse( + source: str | ReadableBuffer, + *, + mode: Literal["single"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> Interactive: ... +@overload +def parse( + source: str | ReadableBuffer, + filename: str | ReadableBuffer | os.PathLike[Any] = "", + mode: str = "exec", + *, + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, +) -> AST: ... if sys.version_info >= (3, 9): def unparse(ast_obj: AST) -> str: ... @@ -295,10 +270,7 @@ def increment_lineno(node: _T, n: int = 1) -> _T: ... def iter_child_nodes(node: AST) -> Iterator[AST]: ... def iter_fields(node: AST) -> Iterator[tuple[str, Any]]: ... def literal_eval(node_or_string: str | AST) -> Any: ... - -if sys.version_info >= (3, 8): - def get_source_segment(source: str, node: AST, *, padded: bool = False) -> str | None: ... - +def get_source_segment(source: str, node: AST, *, padded: bool = False) -> str | None: ... def walk(node: AST) -> Iterator[AST]: ... if sys.version_info >= (3, 9): diff --git a/mypy/typeshed/stdlib/asyncio/__init__.pyi b/mypy/typeshed/stdlib/asyncio/__init__.pyi index c11465184389..d5bbe8cb0642 100644 --- a/mypy/typeshed/stdlib/asyncio/__init__.pyi +++ b/mypy/typeshed/stdlib/asyncio/__init__.pyi @@ -7,6 +7,7 @@ from typing_extensions import TypeAlias from .base_events import * from .coroutines import * from .events import * +from .exceptions import * from .futures import * from .locks import * from .protocols import * @@ -17,9 +18,6 @@ from .subprocess import * from .tasks import * from .transports import * -if sys.version_info >= (3, 8): - from .exceptions import * - if sys.version_info >= (3, 9): from .threads import * diff --git a/mypy/typeshed/stdlib/asyncio/base_events.pyi b/mypy/typeshed/stdlib/asyncio/base_events.pyi index ff6c42c3645a..112cfeefa8f2 100644 --- a/mypy/typeshed/stdlib/asyncio/base_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_events.pyi @@ -10,8 +10,8 @@ from asyncio.transports import BaseTransport, DatagramTransport, ReadTransport, from collections.abc import Callable, Iterable, Sequence from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket -from typing import IO, Any, TypeVar, overload -from typing_extensions import Literal, TypeAlias, TypeVarTuple, Unpack +from typing import IO, Any, Literal, TypeVar, overload +from typing_extensions import TypeAlias, TypeVarTuple, Unpack if sys.version_info >= (3, 9): __all__ = ("BaseEventLoop", "Server") @@ -53,13 +53,8 @@ class Server(AbstractServer): def is_serving(self) -> bool: ... async def start_serving(self) -> None: ... async def serve_forever(self) -> None: ... - if sys.version_info >= (3, 8): - @property - def sockets(self) -> tuple[socket, ...]: ... - else: - @property - def sockets(self) -> list[socket]: ... - + @property + def sockets(self) -> tuple[socket, ...]: ... def close(self) -> None: ... async def wait_closed(self) -> None: ... @@ -87,10 +82,8 @@ class BaseEventLoop(AbstractEventLoop): # Tasks methods if sys.version_info >= (3, 11): def create_task(self, coro: _CoroutineLike[_T], *, name: object = None, context: Context | None = None) -> Task[_T]: ... - elif sys.version_info >= (3, 8): - def create_task(self, coro: _CoroutineLike[_T], *, name: object = None) -> Task[_T]: ... else: - def create_task(self, coro: _CoroutineLike[_T]) -> Task[_T]: ... + def create_task(self, coro: _CoroutineLike[_T], *, name: object = None) -> Task[_T]: ... def set_task_factory(self, factory: _TaskFactory | None) -> None: ... def get_task_factory(self) -> _TaskFactory | None: ... @@ -192,7 +185,7 @@ class BaseEventLoop(AbstractEventLoop): happy_eyeballs_delay: float | None = None, interleave: int | None = None, ) -> tuple[Transport, _ProtocolT]: ... - elif sys.version_info >= (3, 8): + else: @overload async def create_connection( self, @@ -229,39 +222,6 @@ class BaseEventLoop(AbstractEventLoop): happy_eyeballs_delay: float | None = None, interleave: int | None = None, ) -> tuple[Transport, _ProtocolT]: ... - else: - @overload - async def create_connection( - self, - protocol_factory: Callable[[], _ProtocolT], - host: str = ..., - port: int = ..., - *, - ssl: _SSLContext = None, - family: int = 0, - proto: int = 0, - flags: int = 0, - sock: None = None, - local_addr: tuple[str, int] | None = None, - server_hostname: str | None = None, - ssl_handshake_timeout: float | None = None, - ) -> tuple[Transport, _ProtocolT]: ... - @overload - async def create_connection( - self, - protocol_factory: Callable[[], _ProtocolT], - host: None = None, - port: None = None, - *, - ssl: _SSLContext = None, - family: int = 0, - proto: int = 0, - flags: int = 0, - sock: socket, - local_addr: None = None, - server_hostname: str | None = None, - ssl_handshake_timeout: float | None = None, - ) -> tuple[Transport, _ProtocolT]: ... if sys.version_info >= (3, 11): @overload async def create_server( diff --git a/mypy/typeshed/stdlib/asyncio/base_futures.pyi b/mypy/typeshed/stdlib/asyncio/base_futures.pyi index c51174ef23cd..231766200934 100644 --- a/mypy/typeshed/stdlib/asyncio/base_futures.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_futures.pyi @@ -1,7 +1,6 @@ from collections.abc import Callable, Sequence from contextvars import Context -from typing import Any -from typing_extensions import Literal +from typing import Any, Literal from . import futures diff --git a/mypy/typeshed/stdlib/asyncio/constants.pyi b/mypy/typeshed/stdlib/asyncio/constants.pyi index 60d8529209c2..559cc02a0faa 100644 --- a/mypy/typeshed/stdlib/asyncio/constants.pyi +++ b/mypy/typeshed/stdlib/asyncio/constants.pyi @@ -1,6 +1,6 @@ import enum import sys -from typing_extensions import Literal +from typing import Literal LOG_THRESHOLD_FOR_CONNLOST_WRITES: Literal[5] ACCEPT_RETRY_DELAY: Literal[1] diff --git a/mypy/typeshed/stdlib/asyncio/coroutines.pyi b/mypy/typeshed/stdlib/asyncio/coroutines.pyi index 14fb627ae6fe..e92b150875f6 100644 --- a/mypy/typeshed/stdlib/asyncio/coroutines.pyi +++ b/mypy/typeshed/stdlib/asyncio/coroutines.pyi @@ -23,6 +23,4 @@ def iscoroutinefunction(func: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable def iscoroutinefunction(func: Callable[_P, object]) -> TypeGuard[Callable[_P, Coroutine[Any, Any, Any]]]: ... @overload def iscoroutinefunction(func: object) -> TypeGuard[Callable[..., Coroutine[Any, Any, Any]]]: ... - -# Can actually be a generator-style coroutine on Python 3.7 def iscoroutine(obj: object) -> TypeGuard[Coroutine[Any, Any, Any]]: ... diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 0f51c457fc24..649771df8bf1 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -5,8 +5,8 @@ from abc import ABCMeta, abstractmethod from collections.abc import Callable, Coroutine, Generator, Sequence from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket -from typing import IO, Any, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias, TypeVarTuple, Unpack, deprecated +from typing import IO, Any, Literal, Protocol, TypeVar, overload +from typing_extensions import Self, TypeAlias, TypeVarTuple, Unpack, deprecated from . import _AwaitableLike, _CoroutineLike from .base_events import Server @@ -16,44 +16,23 @@ from .tasks import Task from .transports import BaseTransport, DatagramTransport, ReadTransport, SubprocessTransport, Transport, WriteTransport from .unix_events import AbstractChildWatcher -if sys.version_info >= (3, 8): - __all__ = ( - "AbstractEventLoopPolicy", - "AbstractEventLoop", - "AbstractServer", - "Handle", - "TimerHandle", - "get_event_loop_policy", - "set_event_loop_policy", - "get_event_loop", - "set_event_loop", - "new_event_loop", - "get_child_watcher", - "set_child_watcher", - "_set_running_loop", - "get_running_loop", - "_get_running_loop", - ) - -else: - __all__ = ( - "AbstractEventLoopPolicy", - "AbstractEventLoop", - "AbstractServer", - "Handle", - "TimerHandle", - "SendfileNotAvailableError", - "get_event_loop_policy", - "set_event_loop_policy", - "get_event_loop", - "set_event_loop", - "new_event_loop", - "get_child_watcher", - "set_child_watcher", - "_set_running_loop", - "get_running_loop", - "_get_running_loop", - ) +__all__ = ( + "AbstractEventLoopPolicy", + "AbstractEventLoop", + "AbstractServer", + "Handle", + "TimerHandle", + "get_event_loop_policy", + "set_event_loop_policy", + "get_event_loop", + "set_event_loop", + "new_event_loop", + "get_child_watcher", + "set_child_watcher", + "_set_running_loop", + "get_running_loop", + "_get_running_loop", +) _T = TypeVar("_T") _Ts = TypeVarTuple("_Ts") @@ -162,12 +141,9 @@ class AbstractEventLoop: def create_task( self, coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None ) -> Task[_T]: ... - elif sys.version_info >= (3, 8): - @abstractmethod - def create_task(self, coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ... else: @abstractmethod - def create_task(self, coro: _CoroutineLike[_T]) -> Task[_T]: ... + def create_task(self, coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ... @abstractmethod def set_task_factory(self, factory: _TaskFactory | None) -> None: ... @@ -242,7 +218,7 @@ class AbstractEventLoop: happy_eyeballs_delay: float | None = None, interleave: int | None = None, ) -> tuple[Transport, _ProtocolT]: ... - elif sys.version_info >= (3, 8): + else: @overload @abstractmethod async def create_connection( @@ -281,41 +257,6 @@ class AbstractEventLoop: happy_eyeballs_delay: float | None = None, interleave: int | None = None, ) -> tuple[Transport, _ProtocolT]: ... - else: - @overload - @abstractmethod - async def create_connection( - self, - protocol_factory: Callable[[], _ProtocolT], - host: str = ..., - port: int = ..., - *, - ssl: _SSLContext = None, - family: int = 0, - proto: int = 0, - flags: int = 0, - sock: None = None, - local_addr: tuple[str, int] | None = None, - server_hostname: str | None = None, - ssl_handshake_timeout: float | None = None, - ) -> tuple[Transport, _ProtocolT]: ... - @overload - @abstractmethod - async def create_connection( - self, - protocol_factory: Callable[[], _ProtocolT], - host: None = None, - port: None = None, - *, - ssl: _SSLContext = None, - family: int = 0, - proto: int = 0, - flags: int = 0, - sock: socket, - local_addr: None = None, - server_hostname: str | None = None, - ssl_handshake_timeout: float | None = None, - ) -> tuple[Transport, _ProtocolT]: ... if sys.version_info >= (3, 11): @overload @abstractmethod @@ -554,7 +495,6 @@ class AbstractEventLoop: def add_writer(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ... @abstractmethod def remove_writer(self, fd: FileDescriptorLike) -> bool: ... - # Completion based I/O methods returning Futures prior to 3.7 @abstractmethod async def sock_recv(self, sock: socket, nbytes: int) -> bytes: ... @abstractmethod @@ -632,6 +572,3 @@ else: def _set_running_loop(__loop: AbstractEventLoop | None) -> None: ... def _get_running_loop() -> AbstractEventLoop: ... def get_running_loop() -> AbstractEventLoop: ... - -if sys.version_info < (3, 8): - class SendfileNotAvailableError(RuntimeError): ... diff --git a/mypy/typeshed/stdlib/asyncio/futures.pyi b/mypy/typeshed/stdlib/asyncio/futures.pyi index af05425d02a2..44b9528705a5 100644 --- a/mypy/typeshed/stdlib/asyncio/futures.pyi +++ b/mypy/typeshed/stdlib/asyncio/futures.pyi @@ -1,25 +1,16 @@ import sys from collections.abc import Awaitable, Callable, Generator, Iterable -from concurrent.futures._base import Error, Future as _ConcurrentFuture -from typing import Any, TypeVar -from typing_extensions import Literal, Self, TypeGuard +from concurrent.futures._base import Future as _ConcurrentFuture +from contextvars import Context +from typing import Any, Literal, TypeVar +from typing_extensions import Self, TypeGuard from .events import AbstractEventLoop -if sys.version_info < (3, 8): - from concurrent.futures import CancelledError as CancelledError, TimeoutError as TimeoutError - - class InvalidStateError(Error): ... - -from contextvars import Context - if sys.version_info >= (3, 9): from types import GenericAlias -if sys.version_info >= (3, 8): - __all__ = ("Future", "wrap_future", "isfuture") -else: - __all__ = ("CancelledError", "TimeoutError", "InvalidStateError", "Future", "wrap_future", "isfuture") +__all__ = ("Future", "wrap_future", "isfuture") _T = TypeVar("_T") diff --git a/mypy/typeshed/stdlib/asyncio/locks.pyi b/mypy/typeshed/stdlib/asyncio/locks.pyi index 394b82a5b3d9..3aac34b6934f 100644 --- a/mypy/typeshed/stdlib/asyncio/locks.pyi +++ b/mypy/typeshed/stdlib/asyncio/locks.pyi @@ -4,8 +4,8 @@ from _typeshed import Unused from collections import deque from collections.abc import Callable, Generator from types import TracebackType -from typing import Any, TypeVar -from typing_extensions import Literal, Self +from typing import Any, Literal, TypeVar +from typing_extensions import Self from .events import AbstractEventLoop from .futures import Future @@ -47,6 +47,7 @@ else: ) -> None: ... class Lock(_ContextManagerMixin, _LoopBoundMixin): + _waiters: deque[Future[Any]] | None if sys.version_info >= (3, 10): def __init__(self) -> None: ... else: @@ -57,6 +58,7 @@ class Lock(_ContextManagerMixin, _LoopBoundMixin): def release(self) -> None: ... class Event(_LoopBoundMixin): + _waiters: deque[Future[Any]] if sys.version_info >= (3, 10): def __init__(self) -> None: ... else: @@ -68,6 +70,7 @@ class Event(_LoopBoundMixin): async def wait(self) -> Literal[True]: ... class Condition(_ContextManagerMixin, _LoopBoundMixin): + _waiters: deque[Future[Any]] if sys.version_info >= (3, 10): def __init__(self, lock: Lock | None = None) -> None: ... else: @@ -83,7 +86,7 @@ class Condition(_ContextManagerMixin, _LoopBoundMixin): class Semaphore(_ContextManagerMixin, _LoopBoundMixin): _value: int - _waiters: deque[Future[Any]] + _waiters: deque[Future[Any]] | None if sys.version_info >= (3, 10): def __init__(self, value: int = 1) -> None: ... else: diff --git a/mypy/typeshed/stdlib/asyncio/proactor_events.pyi b/mypy/typeshed/stdlib/asyncio/proactor_events.pyi index 4634bbb2b37c..957fdd6ce255 100644 --- a/mypy/typeshed/stdlib/asyncio/proactor_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/proactor_events.pyi @@ -1,8 +1,7 @@ import sys from collections.abc import Mapping from socket import socket -from typing import Any, ClassVar -from typing_extensions import Literal +from typing import Any, ClassVar, Literal from . import base_events, constants, events, futures, streams, transports diff --git a/mypy/typeshed/stdlib/asyncio/runners.pyi b/mypy/typeshed/stdlib/asyncio/runners.pyi index 847072b633ac..37a85b709cdc 100644 --- a/mypy/typeshed/stdlib/asyncio/runners.pyi +++ b/mypy/typeshed/stdlib/asyncio/runners.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import Unused from collections.abc import Callable, Coroutine from contextvars import Context -from typing import Any, TypeVar -from typing_extensions import Self, final +from typing import Any, TypeVar, final +from typing_extensions import Self from .events import AbstractEventLoop @@ -28,8 +28,5 @@ if sys.version_info >= (3, 12): main: Coroutine[Any, Any, _T], *, debug: bool | None = ..., loop_factory: Callable[[], AbstractEventLoop] | None = ... ) -> _T: ... -elif sys.version_info >= (3, 8): - def run(main: Coroutine[Any, Any, _T], *, debug: bool | None = None) -> _T: ... - else: - def run(main: Coroutine[Any, Any, _T], *, debug: bool = False) -> _T: ... + def run(main: Coroutine[Any, Any, _T], *, debug: bool | None = None) -> _T: ... diff --git a/mypy/typeshed/stdlib/asyncio/sslproto.pyi b/mypy/typeshed/stdlib/asyncio/sslproto.pyi index 393a1fbdc468..5dcca950e819 100644 --- a/mypy/typeshed/stdlib/asyncio/sslproto.pyi +++ b/mypy/typeshed/stdlib/asyncio/sslproto.pyi @@ -3,8 +3,8 @@ import sys from collections import deque from collections.abc import Callable from enum import Enum -from typing import Any, ClassVar -from typing_extensions import Literal, TypeAlias +from typing import Any, ClassVar, Literal +from typing_extensions import TypeAlias from . import constants, events, futures, protocols, transports diff --git a/mypy/typeshed/stdlib/asyncio/streams.pyi b/mypy/typeshed/stdlib/asyncio/streams.pyi index 81a94425f8de..4dff8d28b616 100644 --- a/mypy/typeshed/stdlib/asyncio/streams.pyi +++ b/mypy/typeshed/stdlib/asyncio/streams.pyi @@ -2,61 +2,27 @@ import ssl import sys from _typeshed import StrPath from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence -from typing import Any -from typing_extensions import Self, SupportsIndex, TypeAlias +from typing import Any, SupportsIndex +from typing_extensions import Self, TypeAlias from . import events, protocols, transports from .base_events import Server if sys.platform == "win32": - if sys.version_info >= (3, 8): - __all__ = ("StreamReader", "StreamWriter", "StreamReaderProtocol", "open_connection", "start_server") - else: - __all__ = ( - "StreamReader", - "StreamWriter", - "StreamReaderProtocol", - "open_connection", - "start_server", - "IncompleteReadError", - "LimitOverrunError", - ) + __all__ = ("StreamReader", "StreamWriter", "StreamReaderProtocol", "open_connection", "start_server") else: - if sys.version_info >= (3, 8): - __all__ = ( - "StreamReader", - "StreamWriter", - "StreamReaderProtocol", - "open_connection", - "start_server", - "open_unix_connection", - "start_unix_server", - ) - else: - __all__ = ( - "StreamReader", - "StreamWriter", - "StreamReaderProtocol", - "open_connection", - "start_server", - "IncompleteReadError", - "LimitOverrunError", - "open_unix_connection", - "start_unix_server", - ) + __all__ = ( + "StreamReader", + "StreamWriter", + "StreamReaderProtocol", + "open_connection", + "start_server", + "open_unix_connection", + "start_unix_server", + ) _ClientConnectedCallback: TypeAlias = Callable[[StreamReader, StreamWriter], Awaitable[None] | None] -if sys.version_info < (3, 8): - class IncompleteReadError(EOFError): - expected: int | None - partial: bytes - def __init__(self, partial: bytes, expected: int | None) -> None: ... - - class LimitOverrunError(Exception): - consumed: int - def __init__(self, message: str, consumed: int) -> None: ... - if sys.version_info >= (3, 10): async def open_connection( host: str | None = None, diff --git a/mypy/typeshed/stdlib/asyncio/subprocess.pyi b/mypy/typeshed/stdlib/asyncio/subprocess.pyi index 03aea65f6d54..19452d4eb469 100644 --- a/mypy/typeshed/stdlib/asyncio/subprocess.pyi +++ b/mypy/typeshed/stdlib/asyncio/subprocess.pyi @@ -3,16 +3,10 @@ import sys from _typeshed import StrOrBytesPath from asyncio import events, protocols, streams, transports from collections.abc import Callable, Collection -from typing import IO, Any -from typing_extensions import Literal, TypeAlias +from typing import IO, Any, Literal __all__ = ("create_subprocess_exec", "create_subprocess_shell") -if sys.version_info >= (3, 8): - _ExecArg: TypeAlias = StrOrBytesPath -else: - _ExecArg: TypeAlias = str | bytes - PIPE: int STDOUT: int DEVNULL: int @@ -74,8 +68,8 @@ if sys.version_info >= (3, 11): pipesize: int = -1, ) -> Process: ... async def create_subprocess_exec( - program: _ExecArg, - *args: _ExecArg, + program: StrOrBytesPath, + *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, @@ -139,8 +133,8 @@ elif sys.version_info >= (3, 10): pipesize: int = -1, ) -> Process: ... async def create_subprocess_exec( - program: _ExecArg, - *args: _ExecArg, + program: StrOrBytesPath, + *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, @@ -203,8 +197,8 @@ else: # >= 3.9 umask: int = -1, ) -> Process: ... async def create_subprocess_exec( - program: _ExecArg, - *args: _ExecArg, + program: StrOrBytesPath, + *args: StrOrBytesPath, stdin: int | IO[Any] | None = None, stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index 7c76abaf1dca..23447ba27aa5 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -2,8 +2,8 @@ import concurrent.futures import sys from collections.abc import Awaitable, Coroutine, Generator, Iterable, Iterator from types import FrameType -from typing import Any, Protocol, TextIO, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, Literal, Protocol, TextIO, TypeVar, overload +from typing_extensions import TypeAlias from . import _CoroutineLike from .events import AbstractEventLoop @@ -402,16 +402,14 @@ class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportGe name: str | None = ..., context: Context | None = None, ) -> None: ... - elif sys.version_info >= (3, 8): + else: def __init__( self, coro: _TaskCompatibleCoro[_T_co], *, loop: AbstractEventLoop = ..., name: str | None = ... ) -> None: ... - else: - def __init__(self, coro: _TaskCompatibleCoro[_T_co], *, loop: AbstractEventLoop = ...) -> None: ... - if sys.version_info >= (3, 8): - def get_coro(self) -> _TaskCompatibleCoro[_T_co]: ... - def get_name(self) -> str: ... - def set_name(self, __value: object) -> None: ... + + def get_coro(self) -> _TaskCompatibleCoro[_T_co]: ... + def get_name(self) -> str: ... + def set_name(self, __value: object) -> None: ... if sys.version_info >= (3, 12): def get_context(self) -> Context: ... @@ -433,11 +431,8 @@ def all_tasks(loop: AbstractEventLoop | None = None) -> set[Task[Any]]: ... if sys.version_info >= (3, 11): def create_task(coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None) -> Task[_T]: ... -elif sys.version_info >= (3, 8): - def create_task(coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ... - else: - def create_task(coro: _CoroutineLike[_T]) -> Task[_T]: ... + def create_task(coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ... def current_task(loop: AbstractEventLoop | None = None) -> Task[Any] | None: ... def _enter_task(loop: AbstractEventLoop, task: Task[Any]) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/timeouts.pyi b/mypy/typeshed/stdlib/asyncio/timeouts.pyi index 2d31b777b77d..2f0e40e25680 100644 --- a/mypy/typeshed/stdlib/asyncio/timeouts.pyi +++ b/mypy/typeshed/stdlib/asyncio/timeouts.pyi @@ -1,5 +1,6 @@ from types import TracebackType -from typing_extensions import Self, final +from typing import final +from typing_extensions import Self __all__ = ("Timeout", "timeout", "timeout_at") diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index ee16035f86a8..d2a2fef5c33b 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -2,7 +2,8 @@ import sys import types from abc import ABCMeta, abstractmethod from collections.abc import Callable -from typing_extensions import Literal, Self, TypeVarTuple, Unpack, deprecated +from typing import Literal +from typing_extensions import Self, TypeVarTuple, Unpack, deprecated from .events import AbstractEventLoop, BaseDefaultEventLoopPolicy from .selector_events import BaseSelectorEventLoop @@ -29,9 +30,8 @@ if sys.version_info >= (3, 12): def __exit__( self, typ: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None ) -> None: ... - if sys.version_info >= (3, 8): - @abstractmethod - def is_active(self) -> bool: ... + @abstractmethod + def is_active(self) -> bool: ... else: class AbstractChildWatcher: @@ -49,9 +49,8 @@ else: def __exit__( self, typ: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None ) -> None: ... - if sys.version_info >= (3, 8): - @abstractmethod - def is_active(self) -> bool: ... + @abstractmethod + def is_active(self) -> bool: ... if sys.platform != "win32": if sys.version_info >= (3, 9): @@ -65,7 +64,7 @@ if sys.platform != "win32": "ThreadedChildWatcher", "DefaultEventLoopPolicy", ) - elif sys.version_info >= (3, 8): + else: __all__ = ( "SelectorEventLoop", "AbstractChildWatcher", @@ -75,16 +74,12 @@ if sys.platform != "win32": "ThreadedChildWatcher", "DefaultEventLoopPolicy", ) - else: - __all__ = ("SelectorEventLoop", "AbstractChildWatcher", "SafeChildWatcher", "FastChildWatcher", "DefaultEventLoopPolicy") # Doesn't actually have ABCMeta metaclass at runtime, but mypy complains if we don't have it in the stub. # See discussion in #7412 class BaseChildWatcher(AbstractChildWatcher, metaclass=ABCMeta): def close(self) -> None: ... - if sys.version_info >= (3, 8): - def is_active(self) -> bool: ... - + def is_active(self) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... if sys.version_info >= (3, 12): @@ -141,7 +136,7 @@ if sys.platform != "win32": def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... - elif sys.version_info >= (3, 8): + else: class MultiLoopChildWatcher(AbstractChildWatcher): def is_active(self) -> bool: ... def close(self) -> None: ... @@ -153,18 +148,17 @@ if sys.platform != "win32": def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... - if sys.version_info >= (3, 8): - class ThreadedChildWatcher(AbstractChildWatcher): - def is_active(self) -> Literal[True]: ... - def close(self) -> None: ... - def __enter__(self) -> Self: ... - def __exit__( - self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None - ) -> None: ... - def __del__(self) -> None: ... - def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... - def remove_child_handler(self, pid: int) -> bool: ... - def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... + class ThreadedChildWatcher(AbstractChildWatcher): + def is_active(self) -> Literal[True]: ... + def close(self) -> None: ... + def __enter__(self) -> Self: ... + def __exit__( + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None + ) -> None: ... + def __del__(self) -> None: ... + def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def remove_child_handler(self, pid: int) -> bool: ... + def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... if sys.version_info >= (3, 9): class PidfdChildWatcher(AbstractChildWatcher): diff --git a/mypy/typeshed/stdlib/asyncio/windows_events.pyi b/mypy/typeshed/stdlib/asyncio/windows_events.pyi index 8e643dd4a3f2..fdf43d3ea91c 100644 --- a/mypy/typeshed/stdlib/asyncio/windows_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/windows_events.pyi @@ -2,8 +2,7 @@ import socket import sys from _typeshed import Incomplete, ReadableBuffer, WriteableBuffer from collections.abc import Callable -from typing import IO, Any, ClassVar, NoReturn -from typing_extensions import Literal +from typing import IO, Any, ClassVar, Literal, NoReturn from . import events, futures, proactor_events, selector_events, streams, windows_utils diff --git a/mypy/typeshed/stdlib/asyncio/windows_utils.pyi b/mypy/typeshed/stdlib/asyncio/windows_utils.pyi index ed5d8da275c5..6b3589adc3cb 100644 --- a/mypy/typeshed/stdlib/asyncio/windows_utils.pyi +++ b/mypy/typeshed/stdlib/asyncio/windows_utils.pyi @@ -2,8 +2,8 @@ import subprocess import sys from collections.abc import Callable from types import TracebackType -from typing import Any, AnyStr -from typing_extensions import Literal, Self +from typing import Any, AnyStr, Literal +from typing_extensions import Self if sys.platform == "win32": __all__ = ("pipe", "Popen", "PIPE", "PipeHandle") diff --git a/mypy/typeshed/stdlib/bdb.pyi b/mypy/typeshed/stdlib/bdb.pyi index 2a1fdddff7e9..43012a253164 100644 --- a/mypy/typeshed/stdlib/bdb.pyi +++ b/mypy/typeshed/stdlib/bdb.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import ExcInfo, TraceFunction from collections.abc import Callable, Iterable, Mapping from types import CodeType, FrameType, TracebackType -from typing import IO, Any, SupportsInt, TypeVar -from typing_extensions import Literal, ParamSpec +from typing import IO, Any, Literal, SupportsInt, TypeVar +from typing_extensions import ParamSpec __all__ = ["BdbQuit", "Bdb", "Breakpoint"] @@ -50,11 +50,11 @@ class Bdb: def set_quit(self) -> None: ... def set_break( self, filename: str, lineno: int, temporary: bool = False, cond: str | None = None, funcname: str | None = None - ) -> None: ... - def clear_break(self, filename: str, lineno: int) -> None: ... - def clear_bpbynumber(self, arg: SupportsInt) -> None: ... - def clear_all_file_breaks(self, filename: str) -> None: ... - def clear_all_breaks(self) -> None: ... + ) -> str | None: ... + def clear_break(self, filename: str, lineno: int) -> str | None: ... + def clear_bpbynumber(self, arg: SupportsInt) -> str | None: ... + def clear_all_file_breaks(self, filename: str) -> str | None: ... + def clear_all_breaks(self) -> str | None: ... def get_bpbynumber(self, arg: SupportsInt) -> Breakpoint: ... def get_break(self, filename: str, lineno: int) -> bool: ... def get_breaks(self, filename: str, lineno: int) -> list[Breakpoint]: ... diff --git a/mypy/typeshed/stdlib/binascii.pyi b/mypy/typeshed/stdlib/binascii.pyi index 759b6c39399a..d48507b90694 100644 --- a/mypy/typeshed/stdlib/binascii.pyi +++ b/mypy/typeshed/stdlib/binascii.pyi @@ -27,16 +27,8 @@ if sys.version_info < (3, 11): def crc_hqx(__data: ReadableBuffer, __crc: int) -> int: ... def crc32(__data: ReadableBuffer, __crc: int = 0) -> int: ... - -if sys.version_info >= (3, 8): - # sep must be str or bytes, not bytearray or any other buffer - def b2a_hex(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = ...) -> bytes: ... - def hexlify(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = ...) -> bytes: ... - -else: - def b2a_hex(__data: ReadableBuffer) -> bytes: ... - def hexlify(__data: ReadableBuffer) -> bytes: ... - +def b2a_hex(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = ...) -> bytes: ... +def hexlify(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = ...) -> bytes: ... def a2b_hex(__hexstr: _AsciiBuffer) -> bytes: ... def unhexlify(__hexstr: _AsciiBuffer) -> bytes: ... diff --git a/mypy/typeshed/stdlib/binhex.pyi b/mypy/typeshed/stdlib/binhex.pyi index 64ba9f6150b4..d514be3b9b26 100644 --- a/mypy/typeshed/stdlib/binhex.pyi +++ b/mypy/typeshed/stdlib/binhex.pyi @@ -1,6 +1,6 @@ from _typeshed import SizedBuffer -from typing import IO, Any -from typing_extensions import Literal, TypeAlias +from typing import IO, Any, Literal +from typing_extensions import TypeAlias __all__ = ["binhex", "hexbin", "Error"] diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index dca3c2160b5a..1ae1ba03e1ad 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -50,21 +50,23 @@ from typing import ( # noqa: Y022 SupportsBytes, SupportsComplex, SupportsFloat, + SupportsIndex, TypeVar, + final, overload, type_check_only, ) -from typing_extensions import ( + +# we can't import `Literal` from typing or mypy crashes: see #11247 +from typing_extensions import ( # noqa: Y023 Concatenate, Literal, ParamSpec, Self, - SupportsIndex, TypeAlias, TypeGuard, TypeVarTuple, deprecated, - final, ) if sys.version_info >= (3, 9): @@ -115,10 +117,7 @@ class object: # return type of pickle methods is rather hard to express in the current type system # see #6661 and https://docs.python.org/3/library/pickle.html#object.__reduce__ def __reduce__(self) -> str | tuple[Any, ...]: ... - if sys.version_info >= (3, 8): - def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ... - else: - def __reduce_ex__(self, __protocol: int) -> str | tuple[Any, ...]: ... + def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ... if sys.version_info >= (3, 11): def __getstate__(self) -> object: ... @@ -226,9 +225,7 @@ class int: def __new__(cls, __x: ConvertibleToInt = ...) -> Self: ... @overload def __new__(cls, __x: str | bytes | bytearray, base: SupportsIndex) -> Self: ... - if sys.version_info >= (3, 8): - def as_integer_ratio(self) -> tuple[int, Literal[1]]: ... - + def as_integer_ratio(self) -> tuple[int, Literal[1]]: ... @property def real(self) -> int: ... @property @@ -392,22 +389,15 @@ class float: def __bool__(self) -> bool: ... class complex: - if sys.version_info >= (3, 8): - # Python doesn't currently accept SupportsComplex for the second argument - @overload - def __new__( - cls, - real: complex | SupportsComplex | SupportsFloat | SupportsIndex = ..., - imag: complex | SupportsFloat | SupportsIndex = ..., - ) -> Self: ... - @overload - def __new__(cls, real: str | SupportsComplex | SupportsFloat | SupportsIndex | complex) -> Self: ... - else: - @overload - def __new__(cls, real: complex | SupportsComplex | SupportsFloat = ..., imag: complex | SupportsFloat = ...) -> Self: ... - @overload - def __new__(cls, real: str | SupportsComplex | SupportsFloat | complex) -> Self: ... - + # Python doesn't currently accept SupportsComplex for the second argument + @overload + def __new__( + cls, + real: complex | SupportsComplex | SupportsFloat | SupportsIndex = ..., + imag: complex | SupportsFloat | SupportsIndex = ..., + ) -> Self: ... + @overload + def __new__(cls, real: str | SupportsComplex | SupportsFloat | SupportsIndex | complex) -> Self: ... @property def real(self) -> float: ... @property @@ -452,11 +442,10 @@ class str(Sequence[str]): def endswith( self, __suffix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... - if sys.version_info >= (3, 8): - def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] - else: - def expandtabs(self, tabsize: int = 8) -> str: ... # type: ignore[misc] - + @overload + def expandtabs(self: str, tabsize: SupportsIndex = 8) -> str: ... + @overload + def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] def find(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def format(self, *args: object, **kwargs: object) -> str: ... def format_map(self, map: _FormatMapMapping) -> str: ... @@ -546,19 +535,11 @@ class bytes(Sequence[int]): __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ..., ) -> bool: ... - if sys.version_info >= (3, 8): - def expandtabs(self, tabsize: SupportsIndex = 8) -> bytes: ... - else: - def expandtabs(self, tabsize: int = ...) -> bytes: ... - + def expandtabs(self, tabsize: SupportsIndex = 8) -> bytes: ... def find( self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> int: ... - if sys.version_info >= (3, 8): - def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... - else: - def hex(self) -> str: ... - + def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... def index( self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> int: ... @@ -654,20 +635,12 @@ class bytearray(MutableSequence[int]): __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ..., ) -> bool: ... - if sys.version_info >= (3, 8): - def expandtabs(self, tabsize: SupportsIndex = 8) -> bytearray: ... - else: - def expandtabs(self, tabsize: int = ...) -> bytearray: ... - + def expandtabs(self, tabsize: SupportsIndex = 8) -> bytearray: ... def extend(self, __iterable_of_ints: Iterable[SupportsIndex]) -> None: ... def find( self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> int: ... - if sys.version_info >= (3, 8): - def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... - else: - def hex(self) -> str: ... - + def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... def index( self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> int: ... @@ -784,7 +757,7 @@ class memoryview(Sequence[int]): ) -> None: ... def cast(self, format: str, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload - def __getitem__(self, __key: SupportsIndex) -> int: ... + def __getitem__(self, __key: SupportsIndex | tuple[SupportsIndex, ...]) -> int: ... @overload def __getitem__(self, __key: slice) -> memoryview: ... def __contains__(self, __x: object) -> bool: ... @@ -795,24 +768,16 @@ class memoryview(Sequence[int]): @overload def __setitem__(self, __key: slice, __value: ReadableBuffer) -> None: ... @overload - def __setitem__(self, __key: SupportsIndex, __value: SupportsIndex) -> None: ... + def __setitem__(self, __key: SupportsIndex | tuple[SupportsIndex, ...], __value: SupportsIndex) -> None: ... if sys.version_info >= (3, 10): def tobytes(self, order: Literal["C", "F", "A"] | None = "C") -> bytes: ... - elif sys.version_info >= (3, 8): - def tobytes(self, order: Literal["C", "F", "A"] | None = None) -> bytes: ... else: - def tobytes(self) -> bytes: ... + def tobytes(self, order: Literal["C", "F", "A"] | None = None) -> bytes: ... def tolist(self) -> list[int]: ... - if sys.version_info >= (3, 8): - def toreadonly(self) -> memoryview: ... - + def toreadonly(self) -> memoryview: ... def release(self) -> None: ... - if sys.version_info >= (3, 8): - def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... - else: - def hex(self) -> str: ... - + def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... def __buffer__(self, __flags: int) -> memoryview: ... def __release_buffer__(self, __buffer: memoryview) -> None: ... @@ -1026,8 +991,7 @@ class dict(MutableMapping[_KT, _VT]): def __delitem__(self, __key: _KT) -> None: ... def __iter__(self) -> Iterator[_KT]: ... def __eq__(self, __value: object) -> bool: ... - if sys.version_info >= (3, 8): - def __reversed__(self) -> Iterator[_KT]: ... + def __reversed__(self) -> Iterator[_KT]: ... __hash__: ClassVar[None] # type: ignore[assignment] if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... @@ -1204,89 +1168,49 @@ if sys.version_info >= (3, 10): # compile() returns a CodeType, unless the flags argument includes PyCF_ONLY_AST (=1024), # in which case it returns ast.AST. We have overloads for flag 0 (the default) and for # explicitly passing PyCF_ONLY_AST. We fall back to Any for other values of flags. -if sys.version_info >= (3, 8): - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: Literal[0], - dont_inherit: bool = False, - optimize: int = -1, - *, - _feature_version: int = -1, - ) -> CodeType: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - *, - dont_inherit: bool = False, - optimize: int = -1, - _feature_version: int = -1, - ) -> CodeType: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: Literal[1024], - dont_inherit: bool = False, - optimize: int = -1, - *, - _feature_version: int = -1, - ) -> _ast.AST: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: int, - dont_inherit: bool = False, - optimize: int = -1, - *, - _feature_version: int = -1, - ) -> Any: ... - -else: - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: Literal[0], - dont_inherit: bool = False, - optimize: int = -1, - ) -> CodeType: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - *, - dont_inherit: bool = False, - optimize: int = -1, - ) -> CodeType: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: Literal[1024], - dont_inherit: bool = False, - optimize: int = -1, - ) -> _ast.AST: ... - @overload - def compile( - source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, - filename: str | ReadableBuffer | _PathLike[Any], - mode: str, - flags: int, - dont_inherit: bool = False, - optimize: int = -1, - ) -> Any: ... - +@overload +def compile( + source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, + filename: str | ReadableBuffer | _PathLike[Any], + mode: str, + flags: Literal[0], + dont_inherit: bool = False, + optimize: int = -1, + *, + _feature_version: int = -1, +) -> CodeType: ... +@overload +def compile( + source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, + filename: str | ReadableBuffer | _PathLike[Any], + mode: str, + *, + dont_inherit: bool = False, + optimize: int = -1, + _feature_version: int = -1, +) -> CodeType: ... +@overload +def compile( + source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, + filename: str | ReadableBuffer | _PathLike[Any], + mode: str, + flags: Literal[1024], + dont_inherit: bool = False, + optimize: int = -1, + *, + _feature_version: int = -1, +) -> _ast.AST: ... +@overload +def compile( + source: str | ReadableBuffer | _ast.Module | _ast.Expression | _ast.Interactive, + filename: str | ReadableBuffer | _PathLike[Any], + mode: str, + flags: int, + dont_inherit: bool = False, + optimize: int = -1, + *, + _feature_version: int = -1, +) -> Any: ... def copyright() -> None: ... def credits() -> None: ... def delattr(__obj: object, __name: str) -> None: ... @@ -1580,77 +1504,45 @@ _SupportsSomeKindOfPow = ( # noqa: Y026 # TODO: Use TypeAlias once mypy bugs a _SupportsPow2[Any, Any] | _SupportsPow3NoneOnly[Any, Any] | _SupportsPow3[Any, Any, Any] ) -if sys.version_info >= (3, 8): - # TODO: `pow(int, int, Literal[0])` fails at runtime, - # but adding a `NoReturn` overload isn't a good solution for expressing that (see #8566). - @overload - def pow(base: int, exp: int, mod: int) -> int: ... - @overload - def pow(base: int, exp: Literal[0], mod: None = None) -> Literal[1]: ... - @overload - def pow(base: int, exp: _PositiveInteger, mod: None = None) -> int: ... - @overload - def pow(base: int, exp: _NegativeInteger, mod: None = None) -> float: ... - # int base & positive-int exp -> int; int base & negative-int exp -> float - # return type must be Any as `int | float` causes too many false-positive errors - @overload - def pow(base: int, exp: int, mod: None = None) -> Any: ... - @overload - def pow(base: _PositiveInteger, exp: float, mod: None = None) -> float: ... - @overload - def pow(base: _NegativeInteger, exp: float, mod: None = None) -> complex: ... - @overload - def pow(base: float, exp: int, mod: None = None) -> float: ... - # float base & float exp could return float or complex - # return type must be Any (same as complex base, complex exp), - # as `float | complex` causes too many false-positive errors - @overload - def pow(base: float, exp: complex | _SupportsSomeKindOfPow, mod: None = None) -> Any: ... - @overload - def pow(base: complex, exp: complex | _SupportsSomeKindOfPow, mod: None = None) -> complex: ... - @overload - def pow(base: _SupportsPow2[_E, _T_co], exp: _E, mod: None = None) -> _T_co: ... - @overload - def pow(base: _SupportsPow3NoneOnly[_E, _T_co], exp: _E, mod: None = None) -> _T_co: ... - @overload - def pow(base: _SupportsPow3[_E, _M, _T_co], exp: _E, mod: _M) -> _T_co: ... - @overload - def pow(base: _SupportsSomeKindOfPow, exp: float, mod: None = None) -> Any: ... - @overload - def pow(base: _SupportsSomeKindOfPow, exp: complex, mod: None = None) -> complex: ... +# TODO: `pow(int, int, Literal[0])` fails at runtime, +# but adding a `NoReturn` overload isn't a good solution for expressing that (see #8566). +@overload +def pow(base: int, exp: int, mod: int) -> int: ... +@overload +def pow(base: int, exp: Literal[0], mod: None = None) -> Literal[1]: ... +@overload +def pow(base: int, exp: _PositiveInteger, mod: None = None) -> int: ... +@overload +def pow(base: int, exp: _NegativeInteger, mod: None = None) -> float: ... -else: - @overload - def pow(__x: int, __y: int, __z: int) -> int: ... - @overload - def pow(__x: int, __y: Literal[0], __z: None = None) -> Literal[1]: ... - @overload - def pow(__x: int, __y: _PositiveInteger, __z: None = None) -> int: ... - @overload - def pow(__x: int, __y: _NegativeInteger, __z: None = None) -> float: ... - @overload - def pow(__x: int, __y: int, __z: None = None) -> Any: ... - @overload - def pow(__x: _PositiveInteger, __y: float, __z: None = None) -> float: ... - @overload - def pow(__x: _NegativeInteger, __y: float, __z: None = None) -> complex: ... - @overload - def pow(__x: float, __y: int, __z: None = None) -> float: ... - @overload - def pow(__x: float, __y: complex | _SupportsSomeKindOfPow, __z: None = None) -> Any: ... - @overload - def pow(__x: complex, __y: complex | _SupportsSomeKindOfPow, __z: None = None) -> complex: ... - @overload - def pow(__x: _SupportsPow2[_E, _T_co], __y: _E, __z: None = None) -> _T_co: ... - @overload - def pow(__x: _SupportsPow3NoneOnly[_E, _T_co], __y: _E, __z: None = None) -> _T_co: ... - @overload - def pow(__x: _SupportsPow3[_E, _M, _T_co], __y: _E, __z: _M) -> _T_co: ... - @overload - def pow(__x: _SupportsSomeKindOfPow, __y: float, __z: None = None) -> Any: ... - @overload - def pow(__x: _SupportsSomeKindOfPow, __y: complex, __z: None = None) -> complex: ... +# int base & positive-int exp -> int; int base & negative-int exp -> float +# return type must be Any as `int | float` causes too many false-positive errors +@overload +def pow(base: int, exp: int, mod: None = None) -> Any: ... +@overload +def pow(base: _PositiveInteger, exp: float, mod: None = None) -> float: ... +@overload +def pow(base: _NegativeInteger, exp: float, mod: None = None) -> complex: ... +@overload +def pow(base: float, exp: int, mod: None = None) -> float: ... +# float base & float exp could return float or complex +# return type must be Any (same as complex base, complex exp), +# as `float | complex` causes too many false-positive errors +@overload +def pow(base: float, exp: complex | _SupportsSomeKindOfPow, mod: None = None) -> Any: ... +@overload +def pow(base: complex, exp: complex | _SupportsSomeKindOfPow, mod: None = None) -> complex: ... +@overload +def pow(base: _SupportsPow2[_E, _T_co], exp: _E, mod: None = None) -> _T_co: ... +@overload +def pow(base: _SupportsPow3NoneOnly[_E, _T_co], exp: _E, mod: None = None) -> _T_co: ... +@overload +def pow(base: _SupportsPow3[_E, _M, _T_co], exp: _E, mod: _M) -> _T_co: ... +@overload +def pow(base: _SupportsSomeKindOfPow, exp: float, mod: None = None) -> Any: ... +@overload +def pow(base: _SupportsSomeKindOfPow, exp: complex, mod: None = None) -> complex: ... def quit(code: sys._ExitCode = None) -> NoReturn: ... class reversed(Iterator[_T]): @@ -1700,24 +1592,12 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # However, we can't express that in the stub for `sum()` # without creating many false-positive errors (see #7578). # Instead, we special-case the most common examples of this: bool and literal integers. -if sys.version_info >= (3, 8): - @overload - def sum(__iterable: Iterable[bool], start: int = 0) -> int: ... # type: ignore[overload-overlap] - -else: - @overload - def sum(__iterable: Iterable[bool], __start: int = 0) -> int: ... # type: ignore[overload-overlap] - +@overload +def sum(__iterable: Iterable[bool], start: int = 0) -> int: ... # type: ignore[overload-overlap] @overload def sum(__iterable: Iterable[_SupportsSumNoDefaultT]) -> _SupportsSumNoDefaultT | Literal[0]: ... - -if sys.version_info >= (3, 8): - @overload - def sum(__iterable: Iterable[_AddableT1], start: _AddableT2) -> _AddableT1 | _AddableT2: ... - -else: - @overload - def sum(__iterable: Iterable[_AddableT1], __start: _AddableT2) -> _AddableT1 | _AddableT2: ... +@overload +def sum(__iterable: Iterable[_AddableT1], start: _AddableT2) -> _AddableT1 | _AddableT2: ... # The argument to `vars()` has to have a `__dict__` attribute, so the second overload can't be annotated with `object` # (A "SupportsDunderDict" protocol doesn't work) @@ -1821,9 +1701,13 @@ def __import__( def __build_class__(__func: Callable[[], _Cell | Any], __name: str, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... if sys.version_info >= (3, 10): - # In Python 3.10, EllipsisType is exposed publicly in the types module. - @final - class ellipsis: ... + from types import EllipsisType + + # Backwards compatibility hack for folks who relied on the ellipsis type + # existing in typeshed in Python 3.9 and earlier. + ellipsis = EllipsisType + + Ellipsis: EllipsisType else: # Actually the type of Ellipsis is , but since it's @@ -1832,7 +1716,7 @@ else: @type_check_only class ellipsis: ... -Ellipsis: ellipsis + Ellipsis: ellipsis class BaseException: args: tuple[Any, ...] diff --git a/mypy/typeshed/stdlib/bz2.pyi b/mypy/typeshed/stdlib/bz2.pyi index 9ad80ee6f731..620d59a6010c 100644 --- a/mypy/typeshed/stdlib/bz2.pyi +++ b/mypy/typeshed/stdlib/bz2.pyi @@ -3,8 +3,8 @@ import sys from _compression import BaseStream from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer from collections.abc import Iterable -from typing import IO, Any, Protocol, TextIO, overload -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias, final +from typing import IO, Any, Literal, Protocol, SupportsIndex, TextIO, final, overload +from typing_extensions import Self, TypeAlias __all__ = ["BZ2File", "BZ2Compressor", "BZ2Decompressor", "open", "compress", "decompress"] diff --git a/mypy/typeshed/stdlib/cProfile.pyi b/mypy/typeshed/stdlib/cProfile.pyi index 8945b21427ab..7d97fa22c394 100644 --- a/mypy/typeshed/stdlib/cProfile.pyi +++ b/mypy/typeshed/stdlib/cProfile.pyi @@ -1,4 +1,3 @@ -import sys from _typeshed import StrOrBytesPath, Unused from collections.abc import Callable from types import CodeType @@ -30,8 +29,7 @@ class Profile: def run(self, cmd: str) -> Self: ... def runctx(self, cmd: str, globals: dict[str, Any], locals: dict[str, Any]) -> Self: ... def runcall(self, __func: Callable[_P, _T], *args: _P.args, **kw: _P.kwargs) -> _T: ... - if sys.version_info >= (3, 8): - def __enter__(self) -> Self: ... - def __exit__(self, *exc_info: Unused) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *exc_info: Unused) -> None: ... def label(code: str | CodeType) -> _Label: ... # undocumented diff --git a/mypy/typeshed/stdlib/calendar.pyi b/mypy/typeshed/stdlib/calendar.pyi index 3f881393e99f..cac39a498ac9 100644 --- a/mypy/typeshed/stdlib/calendar.pyi +++ b/mypy/typeshed/stdlib/calendar.pyi @@ -4,8 +4,8 @@ import sys from _typeshed import Unused from collections.abc import Iterable, Sequence from time import struct_time -from typing import ClassVar -from typing_extensions import Literal, TypeAlias +from typing import ClassVar, Literal +from typing_extensions import TypeAlias __all__ = [ "IllegalMonthError", diff --git a/mypy/typeshed/stdlib/cgi.pyi b/mypy/typeshed/stdlib/cgi.pyi index 21bf8ca25394..91179c2ed8d5 100644 --- a/mypy/typeshed/stdlib/cgi.pyi +++ b/mypy/typeshed/stdlib/cgi.pyi @@ -1,4 +1,3 @@ -import sys from _typeshed import SupportsGetItem, SupportsItemAccess, Unused from builtins import list as _list, type as _type from collections.abc import Iterable, Iterator, Mapping @@ -22,9 +21,6 @@ __all__ = [ "print_environ_usage", ] -if sys.version_info < (3, 8): - __all__ += ["parse_qs", "parse_qsl", "escape"] - def parse( fp: IO[Any] | None = None, environ: SupportsItemAccess[str, str] = ..., @@ -32,11 +28,6 @@ def parse( strict_parsing: bool = ..., separator: str = "&", ) -> dict[str, list[str]]: ... - -if sys.version_info < (3, 8): - def parse_qs(qs: str, keep_blank_values: bool = ..., strict_parsing: bool = ...) -> dict[str, list[str]]: ... - def parse_qsl(qs: str, keep_blank_values: bool = ..., strict_parsing: bool = ...) -> list[tuple[str, str]]: ... - def parse_multipart( fp: IO[Any], pdict: SupportsGetItem[str, bytes], encoding: str = "utf-8", errors: str = "replace", separator: str = "&" ) -> dict[str, list[Any]]: ... @@ -52,9 +43,6 @@ def print_form(form: dict[str, Any]) -> None: ... def print_directory() -> None: ... def print_environ_usage() -> None: ... -if sys.version_info < (3, 8): - def escape(s: str, quote: bool | None = None) -> str: ... - class MiniFieldStorage: # The first five "Any" attributes here are always None, but mypy doesn't support that filename: Any diff --git a/mypy/typeshed/stdlib/cgitb.pyi b/mypy/typeshed/stdlib/cgitb.pyi index 4c315bf6ca39..565725801159 100644 --- a/mypy/typeshed/stdlib/cgitb.pyi +++ b/mypy/typeshed/stdlib/cgitb.pyi @@ -1,8 +1,7 @@ from _typeshed import OptExcInfo, StrOrBytesPath from collections.abc import Callable from types import FrameType, TracebackType -from typing import IO, Any -from typing_extensions import Final +from typing import IO, Any, Final __UNDEF__: Final[object] # undocumented sentinel diff --git a/mypy/typeshed/stdlib/cmath.pyi b/mypy/typeshed/stdlib/cmath.pyi index 658cfb2d40ed..8aad19dafcfb 100644 --- a/mypy/typeshed/stdlib/cmath.pyi +++ b/mypy/typeshed/stdlib/cmath.pyi @@ -1,10 +1,6 @@ -import sys -from typing import SupportsComplex, SupportsFloat +from typing import SupportsComplex, SupportsFloat, SupportsIndex from typing_extensions import TypeAlias -if sys.version_info >= (3, 8): - from typing import SupportsIndex - e: float pi: float inf: float @@ -13,10 +9,7 @@ nan: float nanj: complex tau: float -if sys.version_info >= (3, 8): - _C: TypeAlias = SupportsFloat | SupportsComplex | SupportsIndex | complex -else: - _C: TypeAlias = SupportsFloat | SupportsComplex | complex +_C: TypeAlias = SupportsFloat | SupportsComplex | SupportsIndex | complex def acos(__z: _C) -> complex: ... def acosh(__z: _C) -> complex: ... diff --git a/mypy/typeshed/stdlib/cmd.pyi b/mypy/typeshed/stdlib/cmd.pyi index b658a873410b..9499847fb153 100644 --- a/mypy/typeshed/stdlib/cmd.pyi +++ b/mypy/typeshed/stdlib/cmd.pyi @@ -1,6 +1,5 @@ from collections.abc import Callable -from typing import IO, Any -from typing_extensions import Literal +from typing import IO, Any, Literal __all__ = ["Cmd"] diff --git a/mypy/typeshed/stdlib/codecs.pyi b/mypy/typeshed/stdlib/codecs.pyi index 985a52702bc8..7e192d91ddc5 100644 --- a/mypy/typeshed/stdlib/codecs.pyi +++ b/mypy/typeshed/stdlib/codecs.pyi @@ -1,11 +1,10 @@ -import sys import types from _codecs import * from _typeshed import ReadableBuffer from abc import abstractmethod from collections.abc import Callable, Generator, Iterable -from typing import Any, BinaryIO, Protocol, TextIO -from typing_extensions import Literal, Self +from typing import Any, BinaryIO, Literal, Protocol, TextIO +from typing_extensions import Self __all__ = [ "register", @@ -129,17 +128,9 @@ def getincrementalencoder(encoding: str) -> _IncrementalEncoder: ... def getincrementaldecoder(encoding: str) -> _IncrementalDecoder: ... def getreader(encoding: str) -> _StreamReader: ... def getwriter(encoding: str) -> _StreamWriter: ... - -if sys.version_info >= (3, 8): - def open( - filename: str, mode: str = "r", encoding: str | None = None, errors: str = "strict", buffering: int = -1 - ) -> StreamReaderWriter: ... - -else: - def open( - filename: str, mode: str = "r", encoding: str | None = None, errors: str = "strict", buffering: int = 1 - ) -> StreamReaderWriter: ... - +def open( + filename: str, mode: str = "r", encoding: str | None = None, errors: str = "strict", buffering: int = -1 +) -> StreamReaderWriter: ... def EncodedFile(file: _Stream, data_encoding: str, file_encoding: str | None = None, errors: str = "strict") -> StreamRecoder: ... def iterencode(iterator: Iterable[str], encoding: str, errors: str = "strict") -> Generator[bytes, None, None]: ... def iterdecode(iterator: Iterable[bytes], encoding: str, errors: str = "strict") -> Generator[str, None, None]: ... diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index 955681c6ac0c..0df800a4a3be 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -1,8 +1,8 @@ import sys from _collections_abc import dict_items, dict_keys, dict_values from _typeshed import SupportsItems, SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT -from typing import Any, Generic, NoReturn, TypeVar, overload -from typing_extensions import Self, SupportsIndex, final +from typing import Any, Generic, NoReturn, SupportsIndex, TypeVar, final, overload +from typing_extensions import Self if sys.version_info >= (3, 9): from types import GenericAlias @@ -169,20 +169,12 @@ class UserString(Sequence[UserString]): def __mul__(self, n: int) -> Self: ... def __rmul__(self, n: int) -> Self: ... def __mod__(self, args: Any) -> Self: ... - if sys.version_info >= (3, 8): - def __rmod__(self, template: object) -> Self: ... - else: - def __rmod__(self, format: Any) -> Self: ... - + def __rmod__(self, template: object) -> Self: ... def capitalize(self) -> Self: ... def casefold(self) -> Self: ... def center(self, width: int, *args: Any) -> Self: ... def count(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... - if sys.version_info >= (3, 8): - def encode(self: UserString, encoding: str | None = "utf-8", errors: str | None = "strict") -> bytes: ... - else: - def encode(self, encoding: str | None = None, errors: str | None = None) -> Self: ... - + def encode(self: UserString, encoding: str | None = "utf-8", errors: str | None = "strict") -> bytes: ... def endswith(self, suffix: str | tuple[str, ...], start: int | None = 0, end: int | None = sys.maxsize) -> bool: ... def expandtabs(self, tabsize: int = 8) -> Self: ... def find(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/__init__.pyi b/mypy/typeshed/stdlib/concurrent/futures/__init__.pyi index ff2e72bbf4fb..07314ce9d402 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/__init__.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/__init__.pyi @@ -1,5 +1,3 @@ -import sys - from ._base import ( ALL_COMPLETED as ALL_COMPLETED, FIRST_COMPLETED as FIRST_COMPLETED, @@ -8,6 +6,7 @@ from ._base import ( CancelledError as CancelledError, Executor as Executor, Future as Future, + InvalidStateError as InvalidStateError, TimeoutError as TimeoutError, as_completed as as_completed, wait as wait, @@ -15,9 +14,6 @@ from ._base import ( from .process import ProcessPoolExecutor as ProcessPoolExecutor from .thread import ThreadPoolExecutor as ThreadPoolExecutor -if sys.version_info >= (3, 8): - from ._base import InvalidStateError as InvalidStateError - __all__ = ( "FIRST_COMPLETED", "FIRST_EXCEPTION", diff --git a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi index 8a11f47e5670..9ea4d5dff6fb 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi @@ -4,8 +4,8 @@ from _typeshed import Unused from collections.abc import Callable, Iterable, Iterator from logging import Logger from types import TracebackType -from typing import Any, Generic, NamedTuple, TypeVar -from typing_extensions import Literal, ParamSpec, Self +from typing import Any, Generic, Literal, NamedTuple, Protocol, TypeVar +from typing_extensions import ParamSpec, Self if sys.version_info >= (3, 9): from types import GenericAlias @@ -30,15 +30,19 @@ if sys.version_info >= (3, 11): else: class TimeoutError(Error): ... -if sys.version_info >= (3, 8): - class InvalidStateError(Error): ... - +class InvalidStateError(Error): ... class BrokenExecutor(RuntimeError): ... _T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) _P = ParamSpec("_P") class Future(Generic[_T]): + _condition: threading.Condition + _state: str + _result: _T | None + _exception: BaseException | None + _waiters: list[_Waiter] def cancel(self) -> bool: ... def cancelled(self) -> bool: ... def running(self) -> bool: ... @@ -71,7 +75,17 @@ class Executor: self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> bool | None: ... -def as_completed(fs: Iterable[Future[_T]], timeout: float | None = None) -> Iterator[Future[_T]]: ... +class _AsCompletedFuture(Protocol[_T_co]): + # as_completed only mutates non-generic aspects of passed Futures and does not do any nominal + # checks. Therefore, we can use a Protocol here to allow as_completed to act covariantly. + # See the tests for concurrent.futures + _condition: threading.Condition + _state: str + _waiters: list[_Waiter] + # Not used by as_completed, but needed to propagate the generic type + def result(self, timeout: float | None = None) -> _T_co: ... + +def as_completed(fs: Iterable[_AsCompletedFuture[_T]], timeout: float | None = None) -> Iterator[Future[_T]]: ... class DoneAndNotDoneFutures(NamedTuple, Generic[_T]): done: set[Future[_T]] diff --git a/mypy/typeshed/stdlib/configparser.pyi b/mypy/typeshed/stdlib/configparser.pyi index e6fedb0328c2..07b57b17d56d 100644 --- a/mypy/typeshed/stdlib/configparser.pyi +++ b/mypy/typeshed/stdlib/configparser.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import StrOrBytesPath, SupportsWrite from collections.abc import Callable, ItemsView, Iterable, Iterator, Mapping, MutableMapping, Sequence from re import Pattern -from typing import Any, ClassVar, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, ClassVar, Literal, TypeVar, overload +from typing_extensions import TypeAlias if sys.version_info >= (3, 12): __all__ = ( diff --git a/mypy/typeshed/stdlib/contextvars.pyi b/mypy/typeshed/stdlib/contextvars.pyi index 825c018d580f..3245cdd5dad2 100644 --- a/mypy/typeshed/stdlib/contextvars.pyi +++ b/mypy/typeshed/stdlib/contextvars.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable, Iterator, Mapping -from typing import Any, ClassVar, Generic, TypeVar, overload -from typing_extensions import ParamSpec, final +from typing import Any, ClassVar, Generic, TypeVar, final, overload +from typing_extensions import ParamSpec if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/csv.pyi b/mypy/typeshed/stdlib/csv.pyi index f48d9d2ff263..56f8bf029b12 100644 --- a/mypy/typeshed/stdlib/csv.pyi +++ b/mypy/typeshed/stdlib/csv.pyi @@ -24,15 +24,11 @@ from _csv import ( if sys.version_info >= (3, 12): from _csv import QUOTE_NOTNULL as QUOTE_NOTNULL, QUOTE_STRINGS as QUOTE_STRINGS + from _typeshed import SupportsWrite from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence -from typing import Any, Generic, TypeVar, overload -from typing_extensions import Literal, Self - -if sys.version_info >= (3, 8): - from builtins import dict as _DictReadMapping -else: - from collections import OrderedDict as _DictReadMapping +from typing import Any, Generic, Literal, TypeVar, overload +from typing_extensions import Self if sys.version_info >= (3, 12): from types import GenericAlias @@ -69,7 +65,7 @@ class excel(Dialect): ... class excel_tab(excel): ... class unix_dialect(Dialect): ... -class DictReader(Iterator[_DictReadMapping[_T | Any, str | Any]], Generic[_T]): +class DictReader(Iterator[dict[_T | Any, str | Any]], Generic[_T]): fieldnames: Sequence[_T] | None restkey: _T | None restval: str | Any | None @@ -113,7 +109,7 @@ class DictReader(Iterator[_DictReadMapping[_T | Any, str | Any]], Generic[_T]): strict: bool = False, ) -> None: ... def __iter__(self) -> Self: ... - def __next__(self) -> _DictReadMapping[_T | Any, str | Any]: ... + def __next__(self) -> dict[_T | Any, str | Any]: ... if sys.version_info >= (3, 12): def __class_getitem__(cls, item: Any) -> GenericAlias: ... @@ -139,11 +135,7 @@ class DictWriter(Generic[_T]): quoting: _QuotingType = 0, strict: bool = False, ) -> None: ... - if sys.version_info >= (3, 8): - def writeheader(self) -> Any: ... - else: - def writeheader(self) -> None: ... - + def writeheader(self) -> Any: ... def writerow(self, rowdict: Mapping[_T, Any]) -> Any: ... def writerows(self, rowdicts: Iterable[Mapping[_T, Any]]) -> None: ... if sys.version_info >= (3, 12): diff --git a/mypy/typeshed/stdlib/ctypes/__init__.pyi b/mypy/typeshed/stdlib/ctypes/__init__.pyi index b14fb93c8163..2fe551fa9dc2 100644 --- a/mypy/typeshed/stdlib/ctypes/__init__.pyi +++ b/mypy/typeshed/stdlib/ctypes/__init__.pyi @@ -3,7 +3,6 @@ from _ctypes import ( POINTER as POINTER, RTLD_GLOBAL as RTLD_GLOBAL, RTLD_LOCAL as RTLD_LOCAL, - ArgumentError as ArgumentError, Array as Array, CFuncPtr as _CFuncPtr, Structure as Structure, @@ -27,12 +26,16 @@ from _ctypes import ( set_errno as set_errno, sizeof as sizeof, ) +from ctypes._endian import BigEndianStructure as BigEndianStructure, LittleEndianStructure as LittleEndianStructure from typing import Any, ClassVar, Generic, TypeVar from typing_extensions import TypeAlias if sys.platform == "win32": from _ctypes import FormatError as FormatError, get_last_error as get_last_error, set_last_error as set_last_error +if sys.version_info >= (3, 11): + from ctypes._endian import BigEndianUnion as BigEndianUnion, LittleEndianUnion as LittleEndianUnion + if sys.version_info >= (3, 9): from types import GenericAlias @@ -41,32 +44,23 @@ _DLLT = TypeVar("_DLLT", bound=CDLL) DEFAULT_MODE: int +class ArgumentError(Exception): ... + class CDLL: _func_flags_: ClassVar[int] _func_restype_: ClassVar[_CData] _name: str _handle: int _FuncPtr: type[_FuncPointer] - if sys.version_info >= (3, 8): - def __init__( - self, - name: str | None, - mode: int = ..., - handle: int | None = None, - use_errno: bool = False, - use_last_error: bool = False, - winmode: int | None = None, - ) -> None: ... - else: - def __init__( - self, - name: str | None, - mode: int = ..., - handle: int | None = None, - use_errno: bool = False, - use_last_error: bool = False, - ) -> None: ... - + def __init__( + self, + name: str | None, + mode: int = ..., + handle: int | None = None, + use_errno: bool = False, + use_last_error: bool = False, + winmode: int | None = None, + ) -> None: ... def __getattr__(self, name: str) -> _NamedFuncPointer: ... def __getitem__(self, name_or_ordinal: str) -> _NamedFuncPointer: ... @@ -148,30 +142,36 @@ class c_char_p(_PointerLike, _SimpleCData[bytes | None]): def __init__(self, value: int | bytes | None = ...) -> None: ... class c_double(_SimpleCData[float]): ... -class c_longdouble(_SimpleCData[float]): ... +class c_longdouble(_SimpleCData[float]): ... # can be an alias for c_double class c_float(_SimpleCData[float]): ... -class c_int(_SimpleCData[int]): ... -class c_int8(_SimpleCData[int]): ... -class c_int16(_SimpleCData[int]): ... -class c_int32(_SimpleCData[int]): ... -class c_int64(_SimpleCData[int]): ... +class c_int(_SimpleCData[int]): ... # can be an alias for c_long class c_long(_SimpleCData[int]): ... -class c_longlong(_SimpleCData[int]): ... +class c_longlong(_SimpleCData[int]): ... # can be an alias for c_long class c_short(_SimpleCData[int]): ... -class c_size_t(_SimpleCData[int]): ... -class c_ssize_t(_SimpleCData[int]): ... +class c_size_t(_SimpleCData[int]): ... # alias for c_uint, c_ulong, or c_ulonglong +class c_ssize_t(_SimpleCData[int]): ... # alias for c_int, c_long, or c_longlong class c_ubyte(_SimpleCData[int]): ... -class c_uint(_SimpleCData[int]): ... -class c_uint8(_SimpleCData[int]): ... -class c_uint16(_SimpleCData[int]): ... -class c_uint32(_SimpleCData[int]): ... -class c_uint64(_SimpleCData[int]): ... +class c_uint(_SimpleCData[int]): ... # can be an alias for c_ulong class c_ulong(_SimpleCData[int]): ... -class c_ulonglong(_SimpleCData[int]): ... +class c_ulonglong(_SimpleCData[int]): ... # can be an alias for c_ulong class c_ushort(_SimpleCData[int]): ... class c_void_p(_PointerLike, _SimpleCData[int | None]): ... class c_wchar(_SimpleCData[str]): ... +c_int8 = c_byte + +# these are actually dynamic aliases for c_short, c_int, c_long, or c_longlong +class c_int16(_SimpleCData[int]): ... +class c_int32(_SimpleCData[int]): ... +class c_int64(_SimpleCData[int]): ... + +c_uint8 = c_ubyte + +# these are actually dynamic aliases for c_ushort, c_uint, c_ulong, or c_ulonglong +class c_uint16(_SimpleCData[int]): ... +class c_uint32(_SimpleCData[int]): ... +class c_uint64(_SimpleCData[int]): ... + class c_wchar_p(_PointerLike, _SimpleCData[str | None]): def __init__(self, value: int | str | None = ...) -> None: ... @@ -182,8 +182,6 @@ if sys.platform == "win32": class HRESULT(_SimpleCData[int]): ... # TODO undocumented if sys.version_info >= (3, 12): - c_time_t: type[c_int32 | c_int64] + c_time_t: type[c_int32 | c_int64] # alias for one or the other at runtime class py_object(_CanCastTo, _SimpleCData[_T]): ... -class BigEndianStructure(Structure): ... -class LittleEndianStructure(Structure): ... diff --git a/mypy/typeshed/stdlib/ctypes/_endian.pyi b/mypy/typeshed/stdlib/ctypes/_endian.pyi new file mode 100644 index 000000000000..add6365e615f --- /dev/null +++ b/mypy/typeshed/stdlib/ctypes/_endian.pyi @@ -0,0 +1,19 @@ +import sys +from _ctypes import RTLD_GLOBAL as RTLD_GLOBAL, RTLD_LOCAL as RTLD_LOCAL, Structure, Union +from ctypes import DEFAULT_MODE as DEFAULT_MODE, cdll as cdll, pydll as pydll, pythonapi as pythonapi + +if sys.version_info >= (3, 12): + from _ctypes import SIZEOF_TIME_T as SIZEOF_TIME_T + +if sys.platform == "win32": + from ctypes import oledll as oledll, windll as windll + +# At runtime, the native endianness is an alias for Structure, +# while the other is a subclass with a metaclass added in. +class BigEndianStructure(Structure): ... +class LittleEndianStructure(Structure): ... + +# Same thing for these: one is an alias of Union at runtime +if sys.version_info >= (3, 11): + class BigEndianUnion(Union): ... + class LittleEndianUnion(Union): ... diff --git a/mypy/typeshed/stdlib/ctypes/wintypes.pyi b/mypy/typeshed/stdlib/ctypes/wintypes.pyi index 84c9c9157a88..8847860f2002 100644 --- a/mypy/typeshed/stdlib/ctypes/wintypes.pyi +++ b/mypy/typeshed/stdlib/ctypes/wintypes.pyi @@ -186,53 +186,113 @@ class WIN32_FIND_DATAW(Structure): cFileName: _CField[Array[WCHAR], str, str] cAlternateFileName: _CField[Array[WCHAR], str, str] -class PBOOL(_Pointer[BOOL]): ... -class LPBOOL(_Pointer[BOOL]): ... -class PBOOLEAN(_Pointer[BOOLEAN]): ... +# These are all defined with the POINTER() function, which keeps a cache and will +# return a previously created class if it can. The self-reported __name__ +# of these classes is f"LP_{typ.__name__}", where typ is the original class +# passed in to the POINTER() function. + +# LP_c_short +class PSHORT(_Pointer[SHORT]): ... + +# LP_c_ushort +class PUSHORT(_Pointer[USHORT]): ... + +PWORD = PUSHORT +LPWORD = PUSHORT + +# LP_c_long +class PLONG(_Pointer[LONG]): ... + +LPLONG = PLONG +PBOOL = PLONG +LPBOOL = PLONG + +# LP_c_ulong +class PULONG(_Pointer[ULONG]): ... + +PDWORD = PULONG +LPDWORD = PDWORD +LPCOLORREF = PDWORD +PLCID = PDWORD + +# LP_c_int (or LP_c_long if int and long have the same size) +class PINT(_Pointer[INT]): ... + +LPINT = PINT + +# LP_c_uint (or LP_c_ulong if int and long have the same size) +class PUINT(_Pointer[UINT]): ... + +LPUINT = PUINT + +# LP_c_float +class PFLOAT(_Pointer[FLOAT]): ... + +# LP_c_longlong (or LP_c_long if long and long long have the same size) +class PLARGE_INTEGER(_Pointer[LARGE_INTEGER]): ... + +# LP_c_ulonglong (or LP_c_ulong if long and long long have the same size) +class PULARGE_INTEGER(_Pointer[ULARGE_INTEGER]): ... + +# LP_c_byte types class PBYTE(_Pointer[BYTE]): ... -class LPBYTE(_Pointer[BYTE]): ... + +LPBYTE = PBYTE +PBOOLEAN = PBYTE + +# LP_c_char class PCHAR(_Pointer[CHAR]): ... -class LPCOLORREF(_Pointer[COLORREF]): ... -class PDWORD(_Pointer[DWORD]): ... -class LPDWORD(_Pointer[DWORD]): ... -class PFILETIME(_Pointer[FILETIME]): ... -class LPFILETIME(_Pointer[FILETIME]): ... -class PFLOAT(_Pointer[FLOAT]): ... + +# LP_c_wchar +class PWCHAR(_Pointer[WCHAR]): ... + +# LP_c_void_p class PHANDLE(_Pointer[HANDLE]): ... -class LPHANDLE(_Pointer[HANDLE]): ... -class PHKEY(_Pointer[HKEY]): ... -class LPHKL(_Pointer[HKL]): ... -class PINT(_Pointer[INT]): ... -class LPINT(_Pointer[INT]): ... -class PLARGE_INTEGER(_Pointer[LARGE_INTEGER]): ... -class PLCID(_Pointer[LCID]): ... -class PLONG(_Pointer[LONG]): ... -class LPLONG(_Pointer[LONG]): ... + +LPHANDLE = PHANDLE +PHKEY = PHANDLE +LPHKL = PHANDLE +LPSC_HANDLE = PHANDLE + +# LP_FILETIME +class PFILETIME(_Pointer[FILETIME]): ... + +LPFILETIME = PFILETIME + +# LP_MSG class PMSG(_Pointer[MSG]): ... -class LPMSG(_Pointer[MSG]): ... + +LPMSG = PMSG + +# LP_POINT class PPOINT(_Pointer[POINT]): ... -class LPPOINT(_Pointer[POINT]): ... -class PPOINTL(_Pointer[POINTL]): ... + +LPPOINT = PPOINT +PPOINTL = PPOINT + +# LP_RECT class PRECT(_Pointer[RECT]): ... -class LPRECT(_Pointer[RECT]): ... -class PRECTL(_Pointer[RECTL]): ... -class LPRECTL(_Pointer[RECTL]): ... -class LPSC_HANDLE(_Pointer[SC_HANDLE]): ... -class PSHORT(_Pointer[SHORT]): ... + +LPRECT = PRECT +PRECTL = PRECT +LPRECTL = PRECT + +# LP_SIZE class PSIZE(_Pointer[SIZE]): ... -class LPSIZE(_Pointer[SIZE]): ... -class PSIZEL(_Pointer[SIZEL]): ... -class LPSIZEL(_Pointer[SIZEL]): ... + +LPSIZE = PSIZE +PSIZEL = PSIZE +LPSIZEL = PSIZE + +# LP__SMALL_RECT class PSMALL_RECT(_Pointer[SMALL_RECT]): ... -class PUINT(_Pointer[UINT]): ... -class LPUINT(_Pointer[UINT]): ... -class PULARGE_INTEGER(_Pointer[ULARGE_INTEGER]): ... -class PULONG(_Pointer[ULONG]): ... -class PUSHORT(_Pointer[USHORT]): ... -class PWCHAR(_Pointer[WCHAR]): ... + +# LP_WIN32_FIND_DATAA class PWIN32_FIND_DATAA(_Pointer[WIN32_FIND_DATAA]): ... -class LPWIN32_FIND_DATAA(_Pointer[WIN32_FIND_DATAA]): ... + +LPWIN32_FIND_DATAA = PWIN32_FIND_DATAA + +# LP_WIN32_FIND_DATAW class PWIN32_FIND_DATAW(_Pointer[WIN32_FIND_DATAW]): ... -class LPWIN32_FIND_DATAW(_Pointer[WIN32_FIND_DATAW]): ... -class PWORD(_Pointer[WORD]): ... -class LPWORD(_Pointer[WORD]): ... + +LPWIN32_FIND_DATAW = PWIN32_FIND_DATAW diff --git a/mypy/typeshed/stdlib/dataclasses.pyi b/mypy/typeshed/stdlib/dataclasses.pyi index 13cffcd70c0e..389a159a915f 100644 --- a/mypy/typeshed/stdlib/dataclasses.pyi +++ b/mypy/typeshed/stdlib/dataclasses.pyi @@ -4,8 +4,8 @@ import types from _typeshed import DataclassInstance from builtins import type as Type # alias to avoid name clashes with fields named "type" from collections.abc import Callable, Iterable, Mapping -from typing import Any, Generic, Protocol, TypeVar, overload -from typing_extensions import Literal, TypeAlias, TypeGuard +from typing import Any, Generic, Literal, Protocol, TypeVar, overload +from typing_extensions import TypeAlias, TypeGuard if sys.version_info >= (3, 9): from types import GenericAlias @@ -54,19 +54,10 @@ def asdict(obj: DataclassInstance, *, dict_factory: Callable[[list[tuple[str, An def astuple(obj: DataclassInstance) -> tuple[Any, ...]: ... @overload def astuple(obj: DataclassInstance, *, tuple_factory: Callable[[list[Any]], _T]) -> _T: ... - -if sys.version_info >= (3, 8): - # cls argument is now positional-only - @overload - def dataclass(__cls: None) -> Callable[[type[_T]], type[_T]]: ... - @overload - def dataclass(__cls: type[_T]) -> type[_T]: ... - -else: - @overload - def dataclass(_cls: None) -> Callable[[type[_T]], type[_T]]: ... - @overload - def dataclass(_cls: type[_T]) -> type[_T]: ... +@overload +def dataclass(__cls: None) -> Callable[[type[_T]], type[_T]]: ... +@overload +def dataclass(__cls: type[_T]) -> type[_T]: ... if sys.version_info >= (3, 11): @overload diff --git a/mypy/typeshed/stdlib/datetime.pyi b/mypy/typeshed/stdlib/datetime.pyi index 36577c5b7e1b..54ecddec3a9a 100644 --- a/mypy/typeshed/stdlib/datetime.pyi +++ b/mypy/typeshed/stdlib/datetime.pyi @@ -1,8 +1,8 @@ import sys from abc import abstractmethod from time import struct_time -from typing import ClassVar, NamedTuple, NoReturn, TypeVar, overload -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias, final +from typing import ClassVar, Literal, NamedTuple, NoReturn, SupportsIndex, TypeVar, final, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 11): __all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR", "UTC") @@ -60,10 +60,8 @@ class date: def fromordinal(cls, __n: int) -> Self: ... @classmethod def fromisoformat(cls, __date_string: str) -> Self: ... - if sys.version_info >= (3, 8): - @classmethod - def fromisocalendar(cls, year: int, week: int, day: int) -> Self: ... - + @classmethod + def fromisocalendar(cls, year: int, week: int, day: int) -> Self: ... @property def year(self) -> int: ... @property @@ -89,26 +87,14 @@ class date: def __ge__(self, __value: date) -> bool: ... def __gt__(self, __value: date) -> bool: ... def __eq__(self, __value: object) -> bool: ... - if sys.version_info >= (3, 8): - def __add__(self, __value: timedelta) -> Self: ... - def __radd__(self, __value: timedelta) -> Self: ... - @overload - def __sub__(self, __value: timedelta) -> Self: ... - @overload - def __sub__(self, __value: datetime) -> NoReturn: ... - @overload - def __sub__(self: _D, __value: _D) -> timedelta: ... - else: - # Prior to Python 3.8, arithmetic operations always returned `date`, even in subclasses - def __add__(self, __value: timedelta) -> date: ... - def __radd__(self, __value: timedelta) -> date: ... - @overload - def __sub__(self, __value: timedelta) -> date: ... - @overload - def __sub__(self, __value: datetime) -> NoReturn: ... - @overload - def __sub__(self, __value: date) -> timedelta: ... - + def __add__(self, __value: timedelta) -> Self: ... + def __radd__(self, __value: timedelta) -> Self: ... + @overload + def __sub__(self, __value: timedelta) -> Self: ... + @overload + def __sub__(self, __value: datetime) -> NoReturn: ... + @overload + def __sub__(self: _D, __value: _D) -> timedelta: ... def __hash__(self) -> int: ... def weekday(self) -> int: ... def isoweekday(self) -> int: ... @@ -266,17 +252,8 @@ class datetime(date): @classmethod def utcfromtimestamp(cls, __t: float) -> Self: ... - if sys.version_info >= (3, 8): - @classmethod - def now(cls, tz: _TzInfo | None = None) -> Self: ... - else: - @overload - @classmethod - def now(cls, tz: None = None) -> Self: ... - @overload - @classmethod - def now(cls, tz: _TzInfo) -> datetime: ... - + @classmethod + def now(cls, tz: _TzInfo | None = None) -> Self: ... @classmethod def utcnow(cls) -> Self: ... @classmethod @@ -299,11 +276,7 @@ class datetime(date): *, fold: int = ..., ) -> Self: ... - if sys.version_info >= (3, 8): - def astimezone(self, tz: _TzInfo | None = ...) -> Self: ... - else: - def astimezone(self, tz: _TzInfo | None = ...) -> datetime: ... - + def astimezone(self, tz: _TzInfo | None = ...) -> Self: ... def isoformat(self, sep: str = ..., timespec: str = ...) -> str: ... @classmethod def strptime(cls, __date_string: str, __format: str) -> Self: ... @@ -316,16 +289,7 @@ class datetime(date): def __gt__(self, __value: datetime) -> bool: ... # type: ignore[override] def __eq__(self, __value: object) -> bool: ... def __hash__(self) -> int: ... - if sys.version_info >= (3, 8): - @overload # type: ignore[override] - def __sub__(self, __value: timedelta) -> Self: ... - @overload - def __sub__(self: _D, __value: _D) -> timedelta: ... - else: - # Prior to Python 3.8, arithmetic operations always returned `datetime`, even in subclasses - def __add__(self, __value: timedelta) -> datetime: ... - def __radd__(self, __value: timedelta) -> datetime: ... - @overload # type: ignore[override] - def __sub__(self, __value: datetime) -> timedelta: ... - @overload - def __sub__(self, __value: timedelta) -> datetime: ... + @overload # type: ignore[override] + def __sub__(self, __value: timedelta) -> Self: ... + @overload + def __sub__(self: _D, __value: _D) -> timedelta: ... diff --git a/mypy/typeshed/stdlib/dbm/__init__.pyi b/mypy/typeshed/stdlib/dbm/__init__.pyi index d7115528868b..9c6989a1c151 100644 --- a/mypy/typeshed/stdlib/dbm/__init__.pyi +++ b/mypy/typeshed/stdlib/dbm/__init__.pyi @@ -1,6 +1,7 @@ from collections.abc import Iterator, MutableMapping from types import TracebackType -from typing_extensions import Literal, Self, TypeAlias +from typing import Literal +from typing_extensions import Self, TypeAlias __all__ = ["open", "whichdb", "error"] diff --git a/mypy/typeshed/stdlib/distutils/ccompiler.pyi b/mypy/typeshed/stdlib/distutils/ccompiler.pyi index e7277aa3f9c4..cc097728f77c 100644 --- a/mypy/typeshed/stdlib/distutils/ccompiler.pyi +++ b/mypy/typeshed/stdlib/distutils/ccompiler.pyi @@ -56,7 +56,7 @@ class CCompiler: self, sources: list[str], output_dir: str | None = None, - macros: _Macro | None = None, + macros: list[_Macro] | None = None, include_dirs: list[str] | None = None, debug: bool = ..., extra_preargs: list[str] | None = None, diff --git a/mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi b/mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi index a990c3e28f36..5f2e623eeff6 100644 --- a/mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi +++ b/mypy/typeshed/stdlib/distutils/cygwinccompiler.pyi @@ -1,7 +1,7 @@ from distutils.unixccompiler import UnixCCompiler from distutils.version import LooseVersion from re import Pattern -from typing_extensions import Literal +from typing import Literal def get_msvcr() -> list[str] | None: ... diff --git a/mypy/typeshed/stdlib/distutils/filelist.pyi b/mypy/typeshed/stdlib/distutils/filelist.pyi index bea48ac16ac5..25db2f3cb6cc 100644 --- a/mypy/typeshed/stdlib/distutils/filelist.pyi +++ b/mypy/typeshed/stdlib/distutils/filelist.pyi @@ -1,7 +1,6 @@ from collections.abc import Iterable from re import Pattern -from typing import overload -from typing_extensions import Literal +from typing import Literal, overload # class is entirely undocumented class FileList: diff --git a/mypy/typeshed/stdlib/distutils/util.pyi b/mypy/typeshed/stdlib/distutils/util.pyi index 83b03747fda6..835266edde59 100644 --- a/mypy/typeshed/stdlib/distutils/util.pyi +++ b/mypy/typeshed/stdlib/distutils/util.pyi @@ -1,12 +1,8 @@ -import sys from _typeshed import StrPath, Unused from collections.abc import Callable, Container, Iterable, Mapping -from typing import Any -from typing_extensions import Literal - -if sys.version_info >= (3, 8): - def get_host_platform() -> str: ... +from typing import Any, Literal +def get_host_platform() -> str: ... def get_platform() -> str: ... def convert_path(pathname: str) -> str: ... def change_root(new_root: str, pathname: str) -> str: ... diff --git a/mypy/typeshed/stdlib/email/_header_value_parser.pyi b/mypy/typeshed/stdlib/email/_header_value_parser.pyi index 97008140ec5d..806fc84cf784 100644 --- a/mypy/typeshed/stdlib/email/_header_value_parser.pyi +++ b/mypy/typeshed/stdlib/email/_header_value_parser.pyi @@ -1,10 +1,9 @@ -import sys from collections.abc import Iterable, Iterator from email.errors import HeaderParseError, MessageDefect from email.policy import Policy from re import Pattern -from typing import Any -from typing_extensions import Final, Self +from typing import Any, Final +from typing_extensions import Self WSP: Final[set[str]] CFWS_LEADER: Final[set[str]] @@ -195,10 +194,9 @@ class DotAtomText(TokenList): token_type: str as_ew_allowed: bool -if sys.version_info >= (3, 8): - class NoFoldLiteral(TokenList): - token_type: str - as_ew_allowed: bool +class NoFoldLiteral(TokenList): + token_type: str + as_ew_allowed: bool class AddrSpec(TokenList): token_type: str @@ -296,17 +294,16 @@ class HeaderLabel(TokenList): token_type: str as_ew_allowed: bool -if sys.version_info >= (3, 8): - class MsgID(TokenList): - token_type: str - as_ew_allowed: bool - def fold(self, policy: Policy) -> str: ... +class MsgID(TokenList): + token_type: str + as_ew_allowed: bool + def fold(self, policy: Policy) -> str: ... - class MessageID(MsgID): - token_type: str +class MessageID(MsgID): + token_type: str - class InvalidMessageID(MessageID): - token_type: str +class InvalidMessageID(MessageID): + token_type: str class Header(TokenList): token_type: str @@ -375,12 +372,9 @@ def get_group_list(value: str) -> tuple[GroupList, str]: ... def get_group(value: str) -> tuple[Group, str]: ... def get_address(value: str) -> tuple[Address, str]: ... def get_address_list(value: str) -> tuple[AddressList, str]: ... - -if sys.version_info >= (3, 8): - def get_no_fold_literal(value: str) -> tuple[NoFoldLiteral, str]: ... - def get_msg_id(value: str) -> tuple[MsgID, str]: ... - def parse_message_id(value: str) -> MessageID: ... - +def get_no_fold_literal(value: str) -> tuple[NoFoldLiteral, str]: ... +def get_msg_id(value: str) -> tuple[MsgID, str]: ... +def parse_message_id(value: str) -> MessageID: ... def parse_mime_version(value: str) -> MIMEVersion: ... def get_invalid_parameter(value: str) -> tuple[InvalidParameter, str]: ... def get_ttext(value: str) -> tuple[ValueTerminal, str]: ... diff --git a/mypy/typeshed/stdlib/email/headerregistry.pyi b/mypy/typeshed/stdlib/email/headerregistry.pyi index 94623e96f208..93a2b3ee72b5 100644 --- a/mypy/typeshed/stdlib/email/headerregistry.pyi +++ b/mypy/typeshed/stdlib/email/headerregistry.pyi @@ -1,4 +1,3 @@ -import sys import types from collections.abc import Iterable, Mapping from datetime import datetime as _datetime @@ -7,14 +6,15 @@ from email._header_value_parser import ( ContentDisposition, ContentTransferEncoding, ContentType, + MessageID, MIMEVersion, TokenList, UnstructuredTokenList, ) from email.errors import MessageDefect from email.policy import Policy -from typing import Any, ClassVar, Protocol -from typing_extensions import Literal, Self +from typing import Any, ClassVar, Literal, Protocol +from typing_extensions import Self class BaseHeader(str): # max_count is actually more of an abstract ClassVar (not defined on the base class, but expected to be defined in subclasses) @@ -130,15 +130,12 @@ class ContentTransferEncodingHeader: @staticmethod def value_parser(value: str) -> ContentTransferEncoding: ... -if sys.version_info >= (3, 8): - from email._header_value_parser import MessageID - - class MessageIDHeader: - max_count: ClassVar[Literal[1]] - @classmethod - def parse(cls, value: str, kwds: dict[str, Any]) -> None: ... - @staticmethod - def value_parser(value: str) -> MessageID: ... +class MessageIDHeader: + max_count: ClassVar[Literal[1]] + @classmethod + def parse(cls, value: str, kwds: dict[str, Any]) -> None: ... + @staticmethod + def value_parser(value: str) -> MessageID: ... class _HeaderParser(Protocol): max_count: ClassVar[Literal[1] | None] diff --git a/mypy/typeshed/stdlib/email/message.pyi b/mypy/typeshed/stdlib/email/message.pyi index 71c8da3a6a5a..7384f3146a8e 100644 --- a/mypy/typeshed/stdlib/email/message.pyi +++ b/mypy/typeshed/stdlib/email/message.pyi @@ -5,8 +5,8 @@ from email.contentmanager import ContentManager from email.errors import MessageDefect from email.header import Header from email.policy import Policy -from typing import Any, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Literal, Protocol, TypeVar, overload +from typing_extensions import Self, TypeAlias __all__ = ["Message", "EmailMessage"] diff --git a/mypy/typeshed/stdlib/enum.pyi b/mypy/typeshed/stdlib/enum.pyi index 10ea19257144..42d0c19d39e7 100644 --- a/mypy/typeshed/stdlib/enum.pyi +++ b/mypy/typeshed/stdlib/enum.pyi @@ -4,8 +4,8 @@ import types from _typeshed import SupportsKeysAndGetItem, Unused from builtins import property as _builtins_property from collections.abc import Callable, Iterable, Iterator, Mapping -from typing import Any, Generic, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Generic, Literal, TypeVar, overload +from typing_extensions import Self, TypeAlias __all__ = ["EnumMeta", "Enum", "IntEnum", "Flag", "IntFlag", "auto", "unique"] diff --git a/mypy/typeshed/stdlib/fcntl.pyi b/mypy/typeshed/stdlib/fcntl.pyi index 56fd5679a1c8..7e5af76c2aae 100644 --- a/mypy/typeshed/stdlib/fcntl.pyi +++ b/mypy/typeshed/stdlib/fcntl.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import FileDescriptorLike, ReadOnlyBuffer, WriteableBuffer -from typing import Any, overload -from typing_extensions import Buffer, Literal +from typing import Any, Literal, overload +from typing_extensions import Buffer if sys.platform != "win32": FASYNC: int @@ -37,13 +37,12 @@ if sys.platform != "win32": F_NOTIFY: int F_EXLCK: int F_GETLK64: int - if sys.version_info >= (3, 8): - F_ADD_SEALS: int - F_GET_SEALS: int - F_SEAL_GROW: int - F_SEAL_SEAL: int - F_SEAL_SHRINK: int - F_SEAL_WRITE: int + F_ADD_SEALS: int + F_GET_SEALS: int + F_SEAL_GROW: int + F_SEAL_SEAL: int + F_SEAL_SHRINK: int + F_SEAL_WRITE: int if sys.version_info >= (3, 9): F_OFD_GETLK: int F_OFD_SETLK: int diff --git a/mypy/typeshed/stdlib/filecmp.pyi b/mypy/typeshed/stdlib/filecmp.pyi index 008d7a44e6c4..4f54a9bff6ee 100644 --- a/mypy/typeshed/stdlib/filecmp.pyi +++ b/mypy/typeshed/stdlib/filecmp.pyi @@ -1,8 +1,7 @@ import sys from _typeshed import GenericPath, StrOrBytesPath from collections.abc import Callable, Iterable, Sequence -from typing import Any, AnyStr, Generic -from typing_extensions import Literal +from typing import Any, AnyStr, Generic, Literal if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/fileinput.pyi b/mypy/typeshed/stdlib/fileinput.pyi index c2fd31d1ea77..e8d5dd8d2d5b 100644 --- a/mypy/typeshed/stdlib/fileinput.pyi +++ b/mypy/typeshed/stdlib/fileinput.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import AnyStr_co, StrOrBytesPath from collections.abc import Callable, Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Protocol, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, AnyStr, Literal, Protocol, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -68,7 +68,7 @@ if sys.version_info >= (3, 10): errors: str | None = None, ) -> FileInput[Any]: ... -elif sys.version_info >= (3, 8): +else: # bufsize is dropped and mode and openhook become keyword-only @overload def input( @@ -98,57 +98,6 @@ elif sys.version_info >= (3, 8): openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, ) -> FileInput[Any]: ... -else: - @overload - def input( - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - mode: _TextMode = "r", - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = None, - ) -> FileInput[str]: ... - # Because mode isn't keyword-only here yet, we need two overloads each for - # the bytes case and the fallback case. - @overload - def input( - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - *, - mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = None, - ) -> FileInput[bytes]: ... - @overload - def input( - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, - inplace: bool, - backup: str, - bufsize: int, - mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = None, - ) -> FileInput[bytes]: ... - @overload - def input( - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - *, - mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, - ) -> FileInput[Any]: ... - @overload - def input( - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, - inplace: bool, - backup: str, - bufsize: int, - mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, - ) -> FileInput[Any]: ... - def close() -> None: ... def nextfile() -> None: ... def filename() -> str: ... @@ -198,7 +147,7 @@ class FileInput(Iterator[AnyStr]): errors: str | None = None, ) -> None: ... - elif sys.version_info >= (3, 8): + else: # bufsize is dropped and mode and openhook become keyword-only @overload def __init__( @@ -231,62 +180,6 @@ class FileInput(Iterator[AnyStr]): openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, ) -> None: ... - else: - @overload - def __init__( - self: FileInput[str], - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - mode: _TextMode = "r", - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[str]] | None = None, - ) -> None: ... - # Because mode isn't keyword-only here yet, we need two overloads each for - # the bytes case and the fallback case. - @overload - def __init__( - self: FileInput[bytes], - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - *, - mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = None, - ) -> None: ... - @overload - def __init__( - self: FileInput[bytes], - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, - inplace: bool, - backup: str, - bufsize: int, - mode: Literal["rb"], - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[bytes]] | None = None, - ) -> None: ... - @overload - def __init__( - self: FileInput[Any], - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None = None, - inplace: bool = False, - backup: str = "", - bufsize: int = 0, - *, - mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, - ) -> None: ... - @overload - def __init__( - self: FileInput[Any], - files: StrOrBytesPath | Iterable[StrOrBytesPath] | None, - inplace: bool, - backup: str, - bufsize: int, - mode: str, - openhook: Callable[[StrOrBytesPath, str], _HasReadlineAndFileno[Any]] | None = None, - ) -> None: ... - def __del__(self) -> None: ... def close(self) -> None: ... def __enter__(self) -> Self: ... diff --git a/mypy/typeshed/stdlib/fractions.pyi b/mypy/typeshed/stdlib/fractions.pyi index 7ec8addeb136..43eaa21bd039 100644 --- a/mypy/typeshed/stdlib/fractions.pyi +++ b/mypy/typeshed/stdlib/fractions.pyi @@ -2,8 +2,8 @@ import sys from collections.abc import Callable from decimal import Decimal from numbers import Integral, Rational, Real -from typing import Any, overload -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias +from typing import Any, Literal, SupportsIndex, overload +from typing_extensions import Self, TypeAlias _ComparableNum: TypeAlias = int | float | Decimal | Real @@ -30,8 +30,7 @@ class Fraction(Rational): @classmethod def from_decimal(cls, dec: Decimal) -> Self: ... def limit_denominator(self, max_denominator: int = 1000000) -> Fraction: ... - if sys.version_info >= (3, 8): - def as_integer_ratio(self) -> tuple[int, int]: ... + def as_integer_ratio(self) -> tuple[int, int]: ... if sys.version_info >= (3, 12): def is_integer(self) -> bool: ... @@ -103,25 +102,14 @@ class Fraction(Rational): def __rmod__(b, a: int | Fraction) -> Fraction: ... @overload def __rmod__(b, a: float) -> float: ... - if sys.version_info >= (3, 8): - @overload - def __divmod__(a, b: int | Fraction) -> tuple[int, Fraction]: ... - @overload - def __divmod__(a, b: float) -> tuple[float, Fraction]: ... - @overload - def __rdivmod__(a, b: int | Fraction) -> tuple[int, Fraction]: ... - @overload - def __rdivmod__(a, b: float) -> tuple[float, Fraction]: ... - else: - @overload - def __divmod__(self, other: int | Fraction) -> tuple[int, Fraction]: ... - @overload - def __divmod__(self, other: float) -> tuple[float, Fraction]: ... - @overload - def __rdivmod__(self, other: int | Fraction) -> tuple[int, Fraction]: ... - @overload - def __rdivmod__(self, other: float) -> tuple[float, Fraction]: ... - + @overload + def __divmod__(a, b: int | Fraction) -> tuple[int, Fraction]: ... + @overload + def __divmod__(a, b: float) -> tuple[float, Fraction]: ... + @overload + def __rdivmod__(a, b: int | Fraction) -> tuple[int, Fraction]: ... + @overload + def __rdivmod__(a, b: float) -> tuple[float, Fraction]: ... @overload def __pow__(a, b: int) -> Fraction: ... @overload diff --git a/mypy/typeshed/stdlib/ftplib.pyi b/mypy/typeshed/stdlib/ftplib.pyi index 2d2ffa9aff03..3bc03a0ff121 100644 --- a/mypy/typeshed/stdlib/ftplib.pyi +++ b/mypy/typeshed/stdlib/ftplib.pyi @@ -4,8 +4,8 @@ from collections.abc import Callable, Iterable, Iterator from socket import socket from ssl import SSLContext from types import TracebackType -from typing import Any, TextIO -from typing_extensions import Literal, Self +from typing import Any, Literal, TextIO +from typing_extensions import Self __all__ = ["FTP", "error_reply", "error_temp", "error_perm", "error_proto", "all_errors", "FTP_TLS"] diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 4d8c45e96103..0f1666024f84 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -2,8 +2,8 @@ import sys import types from _typeshed import IdentityFunction, SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized -from typing import Any, Generic, NamedTuple, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias, TypedDict, final +from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -20,11 +20,10 @@ __all__ = [ "partial", "partialmethod", "singledispatch", + "cached_property", + "singledispatchmethod", ] -if sys.version_info >= (3, 8): - __all__ += ["cached_property", "singledispatchmethod"] - if sys.version_info >= (3, 9): __all__ += ["cache"] @@ -61,14 +60,10 @@ class _lru_cache_wrapper(Generic[_T]): def __copy__(self) -> _lru_cache_wrapper[_T]: ... def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_T]: ... -if sys.version_info >= (3, 8): - @overload - def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ... - @overload - def lru_cache(maxsize: Callable[..., _T], typed: bool = False) -> _lru_cache_wrapper[_T]: ... - -else: - def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ... +@overload +def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ... +@overload +def lru_cache(maxsize: Callable[..., _T], typed: bool = False) -> _lru_cache_wrapper[_T]: ... if sys.version_info >= (3, 12): WRAPPER_ASSIGNMENTS: tuple[ @@ -137,11 +132,7 @@ class partialmethod(Generic[_T]): def __init__(self, __func: Callable[..., _T], *args: Any, **keywords: Any) -> None: ... @overload def __init__(self, __func: _Descriptor, *args: Any, **keywords: Any) -> None: ... - if sys.version_info >= (3, 8): - def __get__(self, obj: Any, cls: type[Any] | None = None) -> Callable[..., _T]: ... - else: - def __get__(self, obj: Any, cls: type[Any] | None) -> Callable[..., _T]: ... - + def __get__(self, obj: Any, cls: type[Any] | None = None) -> Callable[..., _T]: ... @property def __isabstractmethod__(self) -> bool: ... if sys.version_info >= (3, 9): @@ -166,34 +157,33 @@ class _SingleDispatchCallable(Generic[_T]): def singledispatch(func: Callable[..., _T]) -> _SingleDispatchCallable[_T]: ... -if sys.version_info >= (3, 8): - class singledispatchmethod(Generic[_T]): - dispatcher: _SingleDispatchCallable[_T] - func: Callable[..., _T] - def __init__(self, func: Callable[..., _T]) -> None: ... - @property - def __isabstractmethod__(self) -> bool: ... - @overload - def register(self, cls: type[Any], method: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ... - @overload - def register(self, cls: Callable[..., _T], method: None = None) -> Callable[..., _T]: ... - @overload - def register(self, cls: type[Any], method: Callable[..., _T]) -> Callable[..., _T]: ... - def __get__(self, obj: _S, cls: type[_S] | None = None) -> Callable[..., _T]: ... - - class cached_property(Generic[_T]): - func: Callable[[Any], _T] - attrname: str | None - def __init__(self, func: Callable[[Any], _T]) -> None: ... - @overload - def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... - @overload - def __get__(self, instance: object, owner: type[Any] | None = None) -> _T: ... - def __set_name__(self, owner: type[Any], name: str) -> None: ... - # __set__ is not defined at runtime, but @cached_property is designed to be settable - def __set__(self, instance: object, value: _T) -> None: ... - if sys.version_info >= (3, 9): - def __class_getitem__(cls, item: Any) -> GenericAlias: ... +class singledispatchmethod(Generic[_T]): + dispatcher: _SingleDispatchCallable[_T] + func: Callable[..., _T] + def __init__(self, func: Callable[..., _T]) -> None: ... + @property + def __isabstractmethod__(self) -> bool: ... + @overload + def register(self, cls: type[Any], method: None = None) -> Callable[[Callable[..., _T]], Callable[..., _T]]: ... + @overload + def register(self, cls: Callable[..., _T], method: None = None) -> Callable[..., _T]: ... + @overload + def register(self, cls: type[Any], method: Callable[..., _T]) -> Callable[..., _T]: ... + def __get__(self, obj: _S, cls: type[_S] | None = None) -> Callable[..., _T]: ... + +class cached_property(Generic[_T]): + func: Callable[[Any], _T] + attrname: str | None + def __init__(self, func: Callable[[Any], _T]) -> None: ... + @overload + def __get__(self, instance: None, owner: type[Any] | None = None) -> Self: ... + @overload + def __get__(self, instance: object, owner: type[Any] | None = None) -> _T: ... + def __set_name__(self, owner: type[Any], name: str) -> None: ... + # __set__ is not defined at runtime, but @cached_property is designed to be settable + def __set__(self, instance: object, value: _T) -> None: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... if sys.version_info >= (3, 9): def cache(__user_function: Callable[..., _T]) -> _lru_cache_wrapper[_T]: ... diff --git a/mypy/typeshed/stdlib/gc.pyi b/mypy/typeshed/stdlib/gc.pyi index 27cee726ba09..914c41434791 100644 --- a/mypy/typeshed/stdlib/gc.pyi +++ b/mypy/typeshed/stdlib/gc.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable -from typing import Any -from typing_extensions import Literal, TypeAlias +from typing import Any, Literal +from typing_extensions import TypeAlias DEBUG_COLLECTABLE: Literal[2] DEBUG_LEAK: Literal[38] @@ -19,13 +19,7 @@ def disable() -> None: ... def enable() -> None: ... def get_count() -> tuple[int, int, int]: ... def get_debug() -> int: ... - -if sys.version_info >= (3, 8): - def get_objects(generation: int | None = None) -> list[Any]: ... - -else: - def get_objects() -> list[Any]: ... - +def get_objects(generation: int | None = None) -> list[Any]: ... def freeze() -> None: ... def unfreeze() -> None: ... def get_freeze_count() -> int: ... diff --git a/mypy/typeshed/stdlib/genericpath.pyi b/mypy/typeshed/stdlib/genericpath.pyi index be08f7a3cb79..0dd5dec4b2ec 100644 --- a/mypy/typeshed/stdlib/genericpath.pyi +++ b/mypy/typeshed/stdlib/genericpath.pyi @@ -2,8 +2,8 @@ import os import sys from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRichComparisonT from collections.abc import Sequence -from typing import overload -from typing_extensions import Literal, LiteralString +from typing import Literal, overload +from typing_extensions import LiteralString __all__ = [ "commonprefix", diff --git a/mypy/typeshed/stdlib/gettext.pyi b/mypy/typeshed/stdlib/gettext.pyi index 57e81120b8ca..4c17c0dc5de4 100644 --- a/mypy/typeshed/stdlib/gettext.pyi +++ b/mypy/typeshed/stdlib/gettext.pyi @@ -2,8 +2,7 @@ import io import sys from _typeshed import StrPath from collections.abc import Callable, Container, Iterable, Sequence -from typing import Any, Protocol, TypeVar, overload -from typing_extensions import Final, Literal +from typing import Any, Final, Literal, Protocol, TypeVar, overload __all__ = [ "NullTranslations", @@ -18,14 +17,15 @@ __all__ = [ "dngettext", "gettext", "ngettext", + "dnpgettext", + "dpgettext", + "npgettext", + "pgettext", ] if sys.version_info < (3, 11): __all__ += ["bind_textdomain_codeset", "ldgettext", "ldngettext", "lgettext", "lngettext"] -if sys.version_info >= (3, 8): - __all__ += ["dnpgettext", "dpgettext", "npgettext", "pgettext"] - class _TranslationsReader(Protocol): def read(self) -> bytes: ... # optional: @@ -37,10 +37,8 @@ class NullTranslations: def add_fallback(self, fallback: NullTranslations) -> None: ... def gettext(self, message: str) -> str: ... def ngettext(self, msgid1: str, msgid2: str, n: int) -> str: ... - if sys.version_info >= (3, 8): - def pgettext(self, context: str, message: str) -> str: ... - def npgettext(self, context: str, msgid1: str, msgid2: str, n: int) -> str: ... - + def pgettext(self, context: str, message: str) -> str: ... + def npgettext(self, context: str, msgid1: str, msgid2: str, n: int) -> str: ... def info(self) -> dict[str, str]: ... def charset(self) -> str | None: ... if sys.version_info < (3, 11): @@ -156,12 +154,10 @@ def dgettext(domain: str, message: str) -> str: ... def dngettext(domain: str, msgid1: str, msgid2: str, n: int) -> str: ... def gettext(message: str) -> str: ... def ngettext(msgid1: str, msgid2: str, n: int) -> str: ... - -if sys.version_info >= (3, 8): - def pgettext(context: str, message: str) -> str: ... - def dpgettext(domain: str, context: str, message: str) -> str: ... - def npgettext(context: str, msgid1: str, msgid2: str, n: int) -> str: ... - def dnpgettext(domain: str, context: str, msgid1: str, msgid2: str, n: int) -> str: ... +def pgettext(context: str, message: str) -> str: ... +def dpgettext(domain: str, context: str, message: str) -> str: ... +def npgettext(context: str, msgid1: str, msgid2: str, n: int) -> str: ... +def dnpgettext(domain: str, context: str, msgid1: str, msgid2: str, n: int) -> str: ... if sys.version_info < (3, 11): def lgettext(message: str) -> str: ... diff --git a/mypy/typeshed/stdlib/grp.pyi b/mypy/typeshed/stdlib/grp.pyi index 4b66b84b6389..bb0d65180918 100644 --- a/mypy/typeshed/stdlib/grp.pyi +++ b/mypy/typeshed/stdlib/grp.pyi @@ -1,7 +1,6 @@ import sys from _typeshed import structseq -from typing import Any -from typing_extensions import Final, final +from typing import Any, Final, final if sys.platform != "win32": @final diff --git a/mypy/typeshed/stdlib/gzip.pyi b/mypy/typeshed/stdlib/gzip.pyi index d001849e609c..2c33d7cf5810 100644 --- a/mypy/typeshed/stdlib/gzip.pyi +++ b/mypy/typeshed/stdlib/gzip.pyi @@ -3,13 +3,10 @@ import sys import zlib from _typeshed import ReadableBuffer, SizedBuffer, StrOrBytesPath from io import FileIO -from typing import Protocol, TextIO, overload -from typing_extensions import Literal, TypeAlias +from typing import Literal, Protocol, TextIO, overload +from typing_extensions import TypeAlias -if sys.version_info >= (3, 8): - __all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"] -else: - __all__ = ["GzipFile", "open", "compress", "decompress"] +__all__ = ["BadGzipFile", "GzipFile", "open", "compress", "decompress"] _ReadBinaryMode: TypeAlias = Literal["r", "rb"] _WriteBinaryMode: TypeAlias = Literal["a", "ab", "w", "wb", "x", "xb"] @@ -85,8 +82,7 @@ class _PaddedFile: def seek(self, off: int) -> int: ... def seekable(self) -> bool: ... -if sys.version_info >= (3, 8): - class BadGzipFile(OSError): ... +class BadGzipFile(OSError): ... class GzipFile(_compression.BaseStream): myfileobj: FileIO | None @@ -160,10 +156,5 @@ class GzipFile(_compression.BaseStream): class _GzipReader(_compression.DecompressReader): def __init__(self, fp: _ReadableFileobj) -> None: ... -if sys.version_info >= (3, 8): - def compress(data: SizedBuffer, compresslevel: int = 9, *, mtime: float | None = None) -> bytes: ... - -else: - def compress(data: SizedBuffer, compresslevel: int = 9) -> bytes: ... - +def compress(data: SizedBuffer, compresslevel: int = 9, *, mtime: float | None = None) -> bytes: ... def decompress(data: ReadableBuffer) -> bytes: ... diff --git a/mypy/typeshed/stdlib/hashlib.pyi b/mypy/typeshed/stdlib/hashlib.pyi index ed1321f23b9e..38e846ab7eb3 100644 --- a/mypy/typeshed/stdlib/hashlib.pyi +++ b/mypy/typeshed/stdlib/hashlib.pyi @@ -1,8 +1,8 @@ import sys from _typeshed import ReadableBuffer from collections.abc import Callable, Set as AbstractSet -from typing import Protocol -from typing_extensions import Self, final +from typing import Protocol, final +from typing_extensions import Self if sys.version_info >= (3, 11): __all__ = ( @@ -70,7 +70,7 @@ if sys.version_info >= (3, 9): def sha384(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> _Hash: ... def sha512(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> _Hash: ... -elif sys.version_info >= (3, 8): +else: def new(name: str, data: ReadableBuffer = b"") -> _Hash: ... def md5(string: ReadableBuffer = b"") -> _Hash: ... def sha1(string: ReadableBuffer = b"") -> _Hash: ... @@ -79,15 +79,6 @@ elif sys.version_info >= (3, 8): def sha384(string: ReadableBuffer = b"") -> _Hash: ... def sha512(string: ReadableBuffer = b"") -> _Hash: ... -else: - def new(name: str, data: ReadableBuffer = b"") -> _Hash: ... - def md5(__string: ReadableBuffer = ...) -> _Hash: ... - def sha1(__string: ReadableBuffer = ...) -> _Hash: ... - def sha224(__string: ReadableBuffer = ...) -> _Hash: ... - def sha256(__string: ReadableBuffer = ...) -> _Hash: ... - def sha384(__string: ReadableBuffer = ...) -> _Hash: ... - def sha512(__string: ReadableBuffer = ...) -> _Hash: ... - algorithms_guaranteed: AbstractSet[str] algorithms_available: AbstractSet[str] diff --git a/mypy/typeshed/stdlib/heapq.pyi b/mypy/typeshed/stdlib/heapq.pyi index 3f4f274b9769..9198febd3cfa 100644 --- a/mypy/typeshed/stdlib/heapq.pyi +++ b/mypy/typeshed/stdlib/heapq.pyi @@ -1,8 +1,7 @@ from _heapq import * from _typeshed import SupportsRichComparison from collections.abc import Callable, Iterable -from typing import Any, TypeVar -from typing_extensions import Final +from typing import Any, Final, TypeVar __all__ = ["heappush", "heappop", "heapify", "heapreplace", "merge", "nlargest", "nsmallest", "heappushpop"] diff --git a/mypy/typeshed/stdlib/hmac.pyi b/mypy/typeshed/stdlib/hmac.pyi index 9ff99a5a05d5..614121529416 100644 --- a/mypy/typeshed/stdlib/hmac.pyi +++ b/mypy/typeshed/stdlib/hmac.pyi @@ -1,4 +1,3 @@ -import sys from _typeshed import ReadableBuffer, SizedBuffer from collections.abc import Callable from types import ModuleType @@ -14,29 +13,19 @@ trans_36: bytes digest_size: None -if sys.version_info >= (3, 8): - # In reality digestmod has a default value, but the function always throws an error - # if the argument is not given, so we pretend it is a required argument. - @overload - def new(key: bytes | bytearray, msg: ReadableBuffer | None, digestmod: _DigestMod) -> HMAC: ... - @overload - def new(key: bytes | bytearray, *, digestmod: _DigestMod) -> HMAC: ... - -else: - def new(key: bytes | bytearray, msg: ReadableBuffer | None = None, digestmod: _DigestMod | None = None) -> HMAC: ... +# In reality digestmod has a default value, but the function always throws an error +# if the argument is not given, so we pretend it is a required argument. +@overload +def new(key: bytes | bytearray, msg: ReadableBuffer | None, digestmod: _DigestMod) -> HMAC: ... +@overload +def new(key: bytes | bytearray, *, digestmod: _DigestMod) -> HMAC: ... class HMAC: digest_size: int block_size: int @property def name(self) -> str: ... - if sys.version_info >= (3, 8): - def __init__(self, key: bytes | bytearray, msg: ReadableBuffer | None = None, digestmod: _DigestMod = "") -> None: ... - else: - def __init__( - self, key: bytes | bytearray, msg: ReadableBuffer | None = None, digestmod: _DigestMod | None = None - ) -> None: ... - + def __init__(self, key: bytes | bytearray, msg: ReadableBuffer | None = None, digestmod: _DigestMod = "") -> None: ... def update(self, msg: ReadableBuffer) -> None: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... diff --git a/mypy/typeshed/stdlib/http/__init__.pyi b/mypy/typeshed/stdlib/http/__init__.pyi index 4310c79b9269..2eee06fdaaa9 100644 --- a/mypy/typeshed/stdlib/http/__init__.pyi +++ b/mypy/typeshed/stdlib/http/__init__.pyi @@ -1,6 +1,6 @@ import sys from enum import IntEnum -from typing_extensions import Literal +from typing import Literal if sys.version_info >= (3, 11): from enum import StrEnum @@ -73,8 +73,7 @@ class HTTPStatus(IntEnum): NOT_EXTENDED: int NETWORK_AUTHENTICATION_REQUIRED: int MISDIRECTED_REQUEST: int - if sys.version_info >= (3, 8): - UNAVAILABLE_FOR_LEGAL_REASONS: int + UNAVAILABLE_FOR_LEGAL_REASONS: int if sys.version_info >= (3, 9): EARLY_HINTS: Literal[103] IM_A_TEAPOT: Literal[418] diff --git a/mypy/typeshed/stdlib/http/cookiejar.pyi b/mypy/typeshed/stdlib/http/cookiejar.pyi index 482cbca1d88a..faac20d13125 100644 --- a/mypy/typeshed/stdlib/http/cookiejar.pyi +++ b/mypy/typeshed/stdlib/http/cookiejar.pyi @@ -44,13 +44,7 @@ class CookieJar(Iterable[Cookie]): class FileCookieJar(CookieJar): filename: str delayload: bool - if sys.version_info >= (3, 8): - def __init__( - self, filename: StrPath | None = None, delayload: bool = False, policy: CookiePolicy | None = None - ) -> None: ... - else: - def __init__(self, filename: str | None = None, delayload: bool = False, policy: CookiePolicy | None = None) -> None: ... - + def __init__(self, filename: StrPath | None = None, delayload: bool = False, policy: CookiePolicy | None = None) -> None: ... def save(self, filename: str | None = None, ignore_discard: bool = False, ignore_expires: bool = False) -> None: ... def load(self, filename: str | None = None, ignore_discard: bool = False, ignore_expires: bool = False) -> None: ... def revert(self, filename: str | None = None, ignore_discard: bool = False, ignore_expires: bool = False) -> None: ... @@ -84,40 +78,22 @@ class DefaultCookiePolicy(CookiePolicy): DomainRFC2965Match: ClassVar[int] DomainLiberal: ClassVar[int] DomainStrict: ClassVar[int] - if sys.version_info >= (3, 8): - def __init__( - self, - blocked_domains: Sequence[str] | None = None, - allowed_domains: Sequence[str] | None = None, - netscape: bool = True, - rfc2965: bool = False, - rfc2109_as_netscape: bool | None = None, - hide_cookie2: bool = False, - strict_domain: bool = False, - strict_rfc2965_unverifiable: bool = True, - strict_ns_unverifiable: bool = False, - strict_ns_domain: int = 0, - strict_ns_set_initial_dollar: bool = False, - strict_ns_set_path: bool = False, - secure_protocols: Sequence[str] = ("https", "wss"), - ) -> None: ... - else: - def __init__( - self, - blocked_domains: Sequence[str] | None = None, - allowed_domains: Sequence[str] | None = None, - netscape: bool = True, - rfc2965: bool = False, - rfc2109_as_netscape: bool | None = None, - hide_cookie2: bool = False, - strict_domain: bool = False, - strict_rfc2965_unverifiable: bool = True, - strict_ns_unverifiable: bool = False, - strict_ns_domain: int = 0, - strict_ns_set_initial_dollar: bool = False, - strict_ns_set_path: bool = False, - ) -> None: ... - + def __init__( + self, + blocked_domains: Sequence[str] | None = None, + allowed_domains: Sequence[str] | None = None, + netscape: bool = True, + rfc2965: bool = False, + rfc2109_as_netscape: bool | None = None, + hide_cookie2: bool = False, + strict_domain: bool = False, + strict_rfc2965_unverifiable: bool = True, + strict_ns_unverifiable: bool = False, + strict_ns_domain: int = 0, + strict_ns_set_initial_dollar: bool = False, + strict_ns_set_path: bool = False, + secure_protocols: Sequence[str] = ("https", "wss"), + ) -> None: ... def blocked_domains(self) -> tuple[str, ...]: ... def set_blocked_domains(self, blocked_domains: Sequence[str]) -> None: ... def is_blocked(self, domain: str) -> bool: ... diff --git a/mypy/typeshed/stdlib/http/server.pyi b/mypy/typeshed/stdlib/http/server.pyi index 22c33bc3787a..07cde553c1df 100644 --- a/mypy/typeshed/stdlib/http/server.pyi +++ b/mypy/typeshed/stdlib/http/server.pyi @@ -45,7 +45,7 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): def log_error(self, format: str, *args: Any) -> None: ... def log_message(self, format: str, *args: Any) -> None: ... def version_string(self) -> str: ... - def date_time_string(self, timestamp: int | None = None) -> str: ... + def date_time_string(self, timestamp: float | None = None) -> str: ... def log_date_time_string(self) -> str: ... def address_string(self) -> str: ... def parse_request(self) -> bool: ... # undocumented diff --git a/mypy/typeshed/stdlib/imaplib.pyi b/mypy/typeshed/stdlib/imaplib.pyi index a61848c9af13..6a4d8b2e720a 100644 --- a/mypy/typeshed/stdlib/imaplib.pyi +++ b/mypy/typeshed/stdlib/imaplib.pyi @@ -9,8 +9,8 @@ from re import Pattern from socket import socket as _socket from ssl import SSLContext, SSLSocket from types import TracebackType -from typing import IO, Any, SupportsAbs, SupportsInt -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Literal, SupportsAbs, SupportsInt +from typing_extensions import Self, TypeAlias __all__ = ["IMAP4", "IMAP4_stream", "Internaldate2tuple", "Int2AP", "ParseFlags", "Time2Internaldate", "IMAP4_SSL"] diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index eb13240f84ff..825eab7ffde2 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -6,8 +6,7 @@ from abc import ABCMeta, abstractmethod from collections.abc import Iterator, Mapping, Sequence from importlib.machinery import ModuleSpec from io import BufferedReader -from typing import IO, Any, Protocol, overload, runtime_checkable -from typing_extensions import Literal +from typing import IO, Any, Literal, Protocol, overload, runtime_checkable if sys.version_info >= (3, 11): __all__ = [ diff --git a/mypy/typeshed/stdlib/importlib/machinery.pyi b/mypy/typeshed/stdlib/importlib/machinery.pyi index a0431905a828..586c2b80ab7b 100644 --- a/mypy/typeshed/stdlib/importlib/machinery.pyi +++ b/mypy/typeshed/stdlib/importlib/machinery.pyi @@ -3,11 +3,9 @@ import sys import types from _typeshed import ReadableBuffer from collections.abc import Callable, Iterable, MutableSequence, Sequence -from typing import Any -from typing_extensions import Literal, deprecated - -if sys.version_info >= (3, 8): - from importlib.metadata import DistributionFinder, PathDistribution +from importlib.metadata import DistributionFinder, PathDistribution +from typing import Any, Literal +from typing_extensions import deprecated class ModuleSpec: def __init__( @@ -117,7 +115,7 @@ class PathFinder: if sys.version_info >= (3, 10): @staticmethod def find_distributions(context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... - elif sys.version_info >= (3, 8): + else: @classmethod def find_distributions(cls, context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... diff --git a/mypy/typeshed/stdlib/importlib/readers.pyi b/mypy/typeshed/stdlib/importlib/readers.pyi index f34794601b59..41d7af966d58 100644 --- a/mypy/typeshed/stdlib/importlib/readers.pyi +++ b/mypy/typeshed/stdlib/importlib/readers.pyi @@ -8,8 +8,8 @@ import zipfile from _typeshed import Incomplete, StrPath from collections.abc import Iterable, Iterator from io import BufferedReader -from typing import NoReturn, TypeVar -from typing_extensions import Literal, Never +from typing import Literal, NoReturn, TypeVar +from typing_extensions import Never if sys.version_info >= (3, 11): import importlib.resources.abc as abc diff --git a/mypy/typeshed/stdlib/importlib/resources/simple.pyi b/mypy/typeshed/stdlib/importlib/resources/simple.pyi index 9502375d00a2..9ff415156365 100644 --- a/mypy/typeshed/stdlib/importlib/resources/simple.pyi +++ b/mypy/typeshed/stdlib/importlib/resources/simple.pyi @@ -3,8 +3,8 @@ import sys from _typeshed import Incomplete, OpenBinaryMode, OpenTextMode, Unused from collections.abc import Iterator from io import TextIOWrapper -from typing import IO, Any, BinaryIO, NoReturn, overload -from typing_extensions import Literal, Never +from typing import IO, Any, BinaryIO, Literal, NoReturn, overload +from typing_extensions import Never if sys.version_info >= (3, 11): from .abc import Traversable, TraversableResources diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index 6498719df887..a26dc67f9945 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -25,8 +25,8 @@ from types import ( TracebackType, WrapperDescriptorType, ) -from typing import Any, ClassVar, NamedTuple, Protocol, TypeVar, overload -from typing_extensions import Literal, ParamSpec, Self, TypeAlias, TypeGuard +from typing import Any, ClassVar, Literal, NamedTuple, Protocol, TypeVar, overload +from typing_extensions import ParamSpec, Self, TypeAlias, TypeGuard if sys.version_info >= (3, 11): __all__ = [ @@ -200,57 +200,29 @@ def isfunction(object: object) -> TypeGuard[FunctionType]: ... if sys.version_info >= (3, 12): def markcoroutinefunction(func: _F) -> _F: ... -if sys.version_info >= (3, 8): - @overload - def isgeneratorfunction(obj: Callable[..., Generator[Any, Any, Any]]) -> bool: ... - @overload - def isgeneratorfunction(obj: Callable[_P, Any]) -> TypeGuard[Callable[_P, GeneratorType[Any, Any, Any]]]: ... - @overload - def isgeneratorfunction(obj: object) -> TypeGuard[Callable[..., GeneratorType[Any, Any, Any]]]: ... - @overload - def iscoroutinefunction(obj: Callable[..., Coroutine[Any, Any, Any]]) -> bool: ... - @overload - def iscoroutinefunction(obj: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, _T]]]: ... - @overload - def iscoroutinefunction(obj: Callable[_P, object]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, Any]]]: ... - @overload - def iscoroutinefunction(obj: object) -> TypeGuard[Callable[..., CoroutineType[Any, Any, Any]]]: ... - -else: - @overload - def isgeneratorfunction(object: Callable[..., Generator[Any, Any, Any]]) -> bool: ... - @overload - def isgeneratorfunction(object: Callable[_P, Any]) -> TypeGuard[Callable[_P, GeneratorType[Any, Any, Any]]]: ... - @overload - def isgeneratorfunction(object: object) -> TypeGuard[Callable[..., GeneratorType[Any, Any, Any]]]: ... - @overload - def iscoroutinefunction(object: Callable[..., Coroutine[Any, Any, Any]]) -> bool: ... - @overload - def iscoroutinefunction(object: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, _T]]]: ... - @overload - def iscoroutinefunction(object: Callable[_P, Any]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, Any]]]: ... - @overload - def iscoroutinefunction(object: object) -> TypeGuard[Callable[..., CoroutineType[Any, Any, Any]]]: ... - +@overload +def isgeneratorfunction(obj: Callable[..., Generator[Any, Any, Any]]) -> bool: ... +@overload +def isgeneratorfunction(obj: Callable[_P, Any]) -> TypeGuard[Callable[_P, GeneratorType[Any, Any, Any]]]: ... +@overload +def isgeneratorfunction(obj: object) -> TypeGuard[Callable[..., GeneratorType[Any, Any, Any]]]: ... +@overload +def iscoroutinefunction(obj: Callable[..., Coroutine[Any, Any, Any]]) -> bool: ... +@overload +def iscoroutinefunction(obj: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, _T]]]: ... +@overload +def iscoroutinefunction(obj: Callable[_P, object]) -> TypeGuard[Callable[_P, CoroutineType[Any, Any, Any]]]: ... +@overload +def iscoroutinefunction(obj: object) -> TypeGuard[Callable[..., CoroutineType[Any, Any, Any]]]: ... def isgenerator(object: object) -> TypeGuard[GeneratorType[Any, Any, Any]]: ... def iscoroutine(object: object) -> TypeGuard[CoroutineType[Any, Any, Any]]: ... def isawaitable(object: object) -> TypeGuard[Awaitable[Any]]: ... - -if sys.version_info >= (3, 8): - @overload - def isasyncgenfunction(obj: Callable[..., AsyncGenerator[Any, Any]]) -> bool: ... - @overload - def isasyncgenfunction(obj: Callable[_P, Any]) -> TypeGuard[Callable[_P, AsyncGeneratorType[Any, Any]]]: ... - @overload - def isasyncgenfunction(obj: object) -> TypeGuard[Callable[..., AsyncGeneratorType[Any, Any]]]: ... - -else: - @overload - def isasyncgenfunction(object: Callable[..., AsyncGenerator[Any, Any]]) -> bool: ... - @overload - def isasyncgenfunction(object: Callable[_P, Any]) -> TypeGuard[Callable[_P, AsyncGeneratorType[Any, Any]]]: ... - @overload - def isasyncgenfunction(object: object) -> TypeGuard[Callable[..., AsyncGeneratorType[Any, Any]]]: ... +@overload +def isasyncgenfunction(obj: Callable[..., AsyncGenerator[Any, Any]]) -> bool: ... +@overload +def isasyncgenfunction(obj: Callable[_P, Any]) -> TypeGuard[Callable[_P, AsyncGeneratorType[Any, Any]]]: ... +@overload +def isasyncgenfunction(obj: object) -> TypeGuard[Callable[..., AsyncGeneratorType[Any, Any]]]: ... class _SupportsSet(Protocol[_T_cont, _V_cont]): def __set__(self, __instance: _T_cont, __value: _V_cont) -> None: ... @@ -381,9 +353,8 @@ class _ParameterKind(enum.IntEnum): KEYWORD_ONLY: int VAR_KEYWORD: int - if sys.version_info >= (3, 8): - @property - def description(self) -> str: ... + @property + def description(self) -> str: ... if sys.version_info >= (3, 12): AGEN_CREATED: Literal["AGEN_CREATED"] diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index ee4eda1b4eb0..d949971048b0 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -6,12 +6,13 @@ from _typeshed import FileDescriptorOrPath, ReadableBuffer, WriteableBuffer from collections.abc import Callable, Iterable, Iterator from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, TextIO, TypeVar, overload -from typing_extensions import Literal, Self +from typing import IO, Any, BinaryIO, Literal, TextIO, TypeVar, overload +from typing_extensions import Self __all__ = [ "BlockingIOError", "open", + "open_code", "IOBase", "RawIOBase", "FileIO", @@ -30,9 +31,6 @@ __all__ = [ "SEEK_END", ] -if sys.version_info >= (3, 8): - __all__ += ["open_code"] - if sys.version_info >= (3, 11): __all__ += ["DEFAULT_BUFFER_SIZE", "IncrementalNewlineDecoder", "text_encoding"] @@ -46,8 +44,7 @@ SEEK_END: Literal[2] open = builtins.open -if sys.version_info >= (3, 8): - def open_code(path: str) -> IO[bytes]: ... +def open_code(path: str) -> IO[bytes]: ... BlockingIOError = builtins.BlockingIOError diff --git a/mypy/typeshed/stdlib/ipaddress.pyi b/mypy/typeshed/stdlib/ipaddress.pyi index 13a8c4330a50..98b1893d2a8a 100644 --- a/mypy/typeshed/stdlib/ipaddress.pyi +++ b/mypy/typeshed/stdlib/ipaddress.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Iterable, Iterator -from typing import Any, Generic, SupportsInt, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Generic, Literal, SupportsInt, TypeVar, overload +from typing_extensions import Self, TypeAlias # Undocumented length constants IPV4LENGTH: Literal[32] diff --git a/mypy/typeshed/stdlib/itertools.pyi b/mypy/typeshed/stdlib/itertools.pyi index 1bc0b2ec7390..1fa76399444a 100644 --- a/mypy/typeshed/stdlib/itertools.pyi +++ b/mypy/typeshed/stdlib/itertools.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable, Iterable, Iterator -from typing import Any, Generic, SupportsComplex, SupportsFloat, SupportsInt, TypeVar, overload -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias +from typing import Any, Generic, Literal, SupportsComplex, SupportsFloat, SupportsIndex, SupportsInt, TypeVar, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -49,14 +49,10 @@ class repeat(Iterator[_T]): def __length_hint__(self) -> int: ... class accumulate(Iterator[_T]): - if sys.version_info >= (3, 8): - @overload - def __init__(self, iterable: Iterable[_T], func: None = None, *, initial: _T | None = ...) -> None: ... - @overload - def __init__(self, iterable: Iterable[_S], func: Callable[[_T, _S], _T], *, initial: _T | None = ...) -> None: ... - else: - def __init__(self, iterable: Iterable[_T], func: Callable[[_T, _T], _T] | None = ...) -> None: ... - + @overload + def __init__(self, iterable: Iterable[_T], func: None = None, *, initial: _T | None = ...) -> None: ... + @overload + def __init__(self, iterable: Iterable[_S], func: Callable[[_T, _S], _T], *, initial: _T | None = ...) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... diff --git a/mypy/typeshed/stdlib/keyword.pyi b/mypy/typeshed/stdlib/keyword.pyi index 46c386048858..5eb7aab85317 100644 --- a/mypy/typeshed/stdlib/keyword.pyi +++ b/mypy/typeshed/stdlib/keyword.pyi @@ -1,6 +1,6 @@ import sys from collections.abc import Sequence -from typing_extensions import Final +from typing import Final if sys.version_info >= (3, 9): __all__ = ["iskeyword", "issoftkeyword", "kwlist", "softkwlist"] diff --git a/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi b/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi index eef386f709ac..5468ab1db5c3 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi @@ -1,8 +1,7 @@ from _typeshed import Incomplete, StrPath from abc import ABCMeta, abstractmethod from collections.abc import MutableMapping -from typing import ClassVar, TypeVar -from typing_extensions import Literal +from typing import ClassVar, Literal, TypeVar from .pytree import Base, Leaf, Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_apply.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_apply.pyi index 7c5451c15220..e53e3dd86457 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_apply.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_apply.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_asserts.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_asserts.pyi index bf73009e9dbf..fb0b472aa12a 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_asserts.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_asserts.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from ..fixer_base import BaseFix diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_basestring.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_basestring.pyi index 84a354d32777..8ed5ccaa7fd3 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_basestring.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_basestring.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_buffer.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_buffer.pyi index 857c1e2241b9..1efca6228ea2 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_buffer.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_buffer.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_dict.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_dict.pyi index 2e66911195bf..08c54c3bc376 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_dict.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_dict.pyi @@ -1,6 +1,5 @@ from _typeshed import Incomplete -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_except.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_except.pyi index b87aacd342e9..30930a2c381e 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_except.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_except.pyi @@ -1,6 +1,5 @@ from collections.abc import Generator, Iterable -from typing import ClassVar, TypeVar -from typing_extensions import Literal +from typing import ClassVar, Literal, TypeVar from .. import fixer_base from ..pytree import Base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_exec.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_exec.pyi index 306937eb9759..71e2a820a564 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_exec.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_exec.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_execfile.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_execfile.pyi index fb245e5a1c1c..8122a6389b12 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_execfile.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_execfile.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi index 10341d7985a8..7fc910c0a1bc 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_exitfunc.pyi @@ -1,7 +1,6 @@ from _typeshed import Incomplete, StrPath from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_filter.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_filter.pyi index 3998a1dd001e..638889be8b65 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_filter.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_filter.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_funcattrs.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_funcattrs.pyi index 59919446ffdd..60487bb1f2a6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_funcattrs.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_funcattrs.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_future.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_future.pyi index 8eb5ca35dcc3..12ed93f21223 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_future.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_future.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_getcwdu.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_getcwdu.pyi index d18a38f69be0..aa3ccf50be9e 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_getcwdu.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_getcwdu.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_has_key.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_has_key.pyi index 1e6b58dd3512..f6f5a072e21b 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_has_key.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_has_key.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_idioms.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_idioms.pyi index 8f02252f7bb9..4595c57c7eb9 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_idioms.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_idioms.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_import.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_import.pyi index 436e7f1915b2..bf4b2d00925e 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_import.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_import.pyi @@ -1,7 +1,6 @@ from _typeshed import StrPath from collections.abc import Generator -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_imports.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_imports.pyi index 277a172d3af9..dd6f72dd88ac 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_imports.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_imports.pyi @@ -1,7 +1,6 @@ from _typeshed import StrPath from collections.abc import Generator -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_input.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_input.pyi index df52f8d77427..fc1279535bed 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_input.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_input.pyi @@ -1,6 +1,5 @@ from _typeshed import Incomplete -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_intern.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_intern.pyi index f4e71b6da5f2..804b7b2517a5 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_intern.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_intern.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_isinstance.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_isinstance.pyi index e776ea043714..31eefd625317 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_isinstance.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_isinstance.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools.pyi index a19f7b5e8a00..229d86ee71bb 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi index 1ea0b506aaa2..39a4da506867 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_itertools_imports.pyi @@ -1,6 +1,5 @@ from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal class FixItertoolsImports(fixer_base.BaseFix): BM_compatible: ClassVar[Literal[True]] diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi index c47f4528de47..9ccf2711d7d1 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_long.pyi @@ -1,6 +1,5 @@ from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal class FixLong(fixer_base.BaseFix): BM_compatible: ClassVar[Literal[True]] diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_map.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_map.pyi index 66e311cba8a8..6e60282cf0be 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_map.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_map.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_metaclass.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_metaclass.pyi index 44626b47072d..1b1ec82032b4 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_metaclass.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_metaclass.pyi @@ -1,6 +1,5 @@ from collections.abc import Generator -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_methodattrs.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_methodattrs.pyi index 9bda7992dc8b..594b5e2c95c9 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_methodattrs.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_methodattrs.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi index 95dfacccf219..6ff1220b0472 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_ne.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_next.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_next.pyi index a5757d65064a..b13914ae8c01 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_next.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_next.pyi @@ -1,6 +1,5 @@ from _typeshed import StrPath -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_nonzero.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_nonzero.pyi index adf268fdb8e2..5c37fc12ef08 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_nonzero.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_nonzero.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_numliterals.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_numliterals.pyi index 6842e42e45f0..113145e395f6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_numliterals.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_numliterals.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi index 6da150a51c0c..b9863d38347b 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_operator.pyi @@ -1,6 +1,5 @@ from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal def invocation(s): ... diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_paren.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_paren.pyi index c730cdc5d0b2..237df6c5ff2c 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_paren.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_paren.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_print.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_print.pyi index 2261c9489299..e9564b04ac75 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_print.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_print.pyi @@ -1,6 +1,5 @@ from _typeshed import Incomplete -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_raise.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_raise.pyi index 756a05ea3ddd..e02c3080f409 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_raise.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_raise.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_raw_input.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_raw_input.pyi index 61d6ad7676ef..d1a0eb0e0a7e 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_raw_input.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_raw_input.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi index 4ea07fdde00b..f8ad876c21a6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_reduce.pyi @@ -1,6 +1,5 @@ from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal class FixReduce(fixer_base.BaseFix): BM_compatible: ClassVar[Literal[True]] diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_reload.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_reload.pyi index 8045ac507890..820075438eca 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_reload.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_reload.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_renames.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_renames.pyi index 2ceca053e903..6283f1ab7ce2 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_renames.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_renames.pyi @@ -1,6 +1,5 @@ from collections.abc import Generator -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_repr.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_repr.pyi index 6f3305846d18..3b192d396dd6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_repr.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_repr.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi index dd18413d6d5a..6962ff326f56 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_set_literal.pyi @@ -1,6 +1,5 @@ from lib2to3 import fixer_base -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal class FixSetLiteral(fixer_base.BaseFix): BM_compatible: ClassVar[Literal[True]] diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_standarderror.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_standarderror.pyi index fd23af5a711e..ba914bcab5d6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_standarderror.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_standarderror.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_sys_exc.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_sys_exc.pyi index 3dbcd38c4b26..0fa1a4787087 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_sys_exc.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_sys_exc.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_throw.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_throw.pyi index 50e37d44a58b..4c99855e5c37 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_throw.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_throw.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_tuple_params.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_tuple_params.pyi index 48eadf75341c..bfaa9970c996 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_tuple_params.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_tuple_params.pyi @@ -1,6 +1,5 @@ from _typeshed import Incomplete -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_types.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_types.pyi index 6ac1344b1e6c..e26dbec71a97 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_types.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_types.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_unicode.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_unicode.pyi index af63d1865f2d..80d9d8b6e656 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_unicode.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_unicode.pyi @@ -1,6 +1,5 @@ from _typeshed import StrPath -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_urllib.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_urllib.pyi index a37e63b31101..625472f609ab 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_urllib.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_urllib.pyi @@ -1,5 +1,5 @@ from collections.abc import Generator -from typing_extensions import Literal +from typing import Literal from .fix_imports import FixImports diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_ws_comma.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_ws_comma.pyi index 6231d90c65f1..4ce5cb2c4ac1 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_ws_comma.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_ws_comma.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Leaf diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_xrange.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_xrange.pyi index 89d300ef063a..71318b7660b6 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_xrange.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_xrange.pyi @@ -1,6 +1,5 @@ from _typeshed import Incomplete, StrPath -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base from ..pytree import Node diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_xreadlines.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_xreadlines.pyi index 39757155e5d9..b4794143a003 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_xreadlines.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_xreadlines.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/fixes/fix_zip.pyi b/mypy/typeshed/stdlib/lib2to3/fixes/fix_zip.pyi index 0c70717aa2ac..805886ee3180 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixes/fix_zip.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixes/fix_zip.pyi @@ -1,5 +1,4 @@ -from typing import ClassVar -from typing_extensions import Literal +from typing import ClassVar, Literal from .. import fixer_base diff --git a/mypy/typeshed/stdlib/lib2to3/main.pyi b/mypy/typeshed/stdlib/lib2to3/main.pyi index cfcaeeaf64ee..5b7fdfca5d65 100644 --- a/mypy/typeshed/stdlib/lib2to3/main.pyi +++ b/mypy/typeshed/stdlib/lib2to3/main.pyi @@ -1,8 +1,7 @@ from _typeshed import FileDescriptorOrPath from collections.abc import Container, Iterable, Iterator, Mapping, Sequence from logging import _ExcInfoType -from typing import AnyStr -from typing_extensions import Literal +from typing import AnyStr, Literal from . import refactor as refactor diff --git a/mypy/typeshed/stdlib/lib2to3/pygram.pyi b/mypy/typeshed/stdlib/lib2to3/pygram.pyi index 2d1e90e79927..86c74b54888a 100644 --- a/mypy/typeshed/stdlib/lib2to3/pygram.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pygram.pyi @@ -1,5 +1,3 @@ -import sys - from .pgen2.grammar import Grammar class Symbols: @@ -112,6 +110,5 @@ class pattern_symbols(Symbols): python_grammar: Grammar python_grammar_no_print_statement: Grammar -if sys.version_info >= (3, 8): - python_grammar_no_print_and_exec_statement: Grammar +python_grammar_no_print_and_exec_statement: Grammar pattern_grammar: Grammar diff --git a/mypy/typeshed/stdlib/lib2to3/pytree.pyi b/mypy/typeshed/stdlib/lib2to3/pytree.pyi index d14446f38565..138333bd58af 100644 --- a/mypy/typeshed/stdlib/lib2to3/pytree.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pytree.pyi @@ -1,7 +1,8 @@ from _typeshed import Incomplete, SupportsGetItem, SupportsLenAndGetItem, Unused from abc import abstractmethod from collections.abc import Iterable, Iterator, MutableSequence -from typing_extensions import Final, Self, TypeAlias +from typing import Final +from typing_extensions import Self, TypeAlias from .fixer_base import BaseFix from .pgen2.grammar import Grammar diff --git a/mypy/typeshed/stdlib/lib2to3/refactor.pyi b/mypy/typeshed/stdlib/lib2to3/refactor.pyi index d750d9c4a6cf..a7f382540648 100644 --- a/mypy/typeshed/stdlib/lib2to3/refactor.pyi +++ b/mypy/typeshed/stdlib/lib2to3/refactor.pyi @@ -3,8 +3,7 @@ from collections.abc import Container, Generator, Iterable, Mapping from logging import Logger, _ExcInfoType from multiprocessing import JoinableQueue from multiprocessing.synchronize import Lock -from typing import Any, ClassVar, NoReturn, overload -from typing_extensions import Final +from typing import Any, ClassVar, Final, NoReturn, overload from .btm_matcher import BottomMatcher from .fixer_base import BaseFix diff --git a/mypy/typeshed/stdlib/logging/__init__.pyi b/mypy/typeshed/stdlib/logging/__init__.pyi index 5a72b1fcd799..eae2bcd3e96c 100644 --- a/mypy/typeshed/stdlib/logging/__init__.pyi +++ b/mypy/typeshed/stdlib/logging/__init__.pyi @@ -7,8 +7,8 @@ from re import Pattern from string import Template from time import struct_time from types import FrameType, TracebackType -from typing import Any, ClassVar, Generic, Protocol, TextIO, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, ClassVar, Generic, Literal, Protocol, TextIO, TypeVar, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 11): from types import GenericAlias @@ -128,173 +128,94 @@ class Logger(Filterer): def getChild(self, suffix: str) -> Self: ... # see python/typing#980 if sys.version_info >= (3, 12): def getChildren(self) -> set[Logger]: ... - if sys.version_info >= (3, 8): - def debug( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def info( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warning( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warn( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def error( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def exception( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = True, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def critical( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def log( - self, - level: int, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def _log( - self, - level: int, - msg: object, - args: _ArgsType, - exc_info: _ExcInfoType | None = None, - extra: Mapping[str, object] | None = None, - stack_info: bool = False, - stacklevel: int = 1, - ) -> None: ... # undocumented - else: - def debug( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def info( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warning( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warn( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def error( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def critical( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def log( - self, - level: int, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def exception( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = True, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def _log( - self, - level: int, - msg: object, - args: _ArgsType, - exc_info: _ExcInfoType | None = None, - extra: Mapping[str, object] | None = None, - stack_info: bool = False, - ) -> None: ... # undocumented + + def debug( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def info( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def warning( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def warn( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def error( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def exception( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = True, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def critical( + self, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def log( + self, + level: int, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, + ) -> None: ... + def _log( + self, + level: int, + msg: object, + args: _ArgsType, + exc_info: _ExcInfoType | None = None, + extra: Mapping[str, object] | None = None, + stack_info: bool = False, + stacklevel: int = 1, + ) -> None: ... # undocumented fatal = critical def addHandler(self, hdlr: Handler) -> None: ... def removeHandler(self, hdlr: Handler) -> None: ... - if sys.version_info >= (3, 8): - def findCaller(self, stack_info: bool = False, stacklevel: int = 1) -> tuple[str, int, str, str | None]: ... - else: - def findCaller(self, stack_info: bool = False) -> tuple[str, int, str, str | None]: ... - + def findCaller(self, stack_info: bool = False, stacklevel: int = 1) -> tuple[str, int, str, str | None]: ... def handle(self, record: LogRecord) -> None: ... def makeRecord( self, @@ -366,12 +287,10 @@ class Formatter: *, defaults: Mapping[str, Any] | None = None, ) -> None: ... - elif sys.version_info >= (3, 8): + else: def __init__( self, fmt: str | None = None, datefmt: str | None = None, style: _FormatStyle = "%", validate: bool = True ) -> None: ... - else: - def __init__(self, fmt: str | None = None, datefmt: str | None = None, style: _FormatStyle = "%") -> None: ... def format(self, record: LogRecord) -> str: ... def formatTime(self, record: LogRecord, datefmt: str | None = None) -> str: ... @@ -451,310 +370,173 @@ class LoggerAdapter(Generic[_L]): def __init__(self, logger: _L, extra: Mapping[str, object]) -> None: ... def process(self, msg: Any, kwargs: MutableMapping[str, Any]) -> tuple[Any, MutableMapping[str, Any]]: ... - if sys.version_info >= (3, 8): - def debug( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def info( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def warning( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def warn( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def error( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def exception( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = True, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def critical( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def log( - self, - level: int, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - else: - def debug( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def info( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def warning( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def warn( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def error( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def exception( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = True, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def critical( - self, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - def log( - self, - level: int, - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - **kwargs: object, - ) -> None: ... - - def isEnabledFor(self, level: int) -> bool: ... - def getEffectiveLevel(self) -> int: ... - def setLevel(self, level: _Level) -> None: ... - def hasHandlers(self) -> bool: ... - def _log( - self, - level: int, - msg: object, - args: _ArgsType, - exc_info: _ExcInfoType | None = None, - extra: Mapping[str, object] | None = None, - stack_info: bool = False, - ) -> None: ... # undocumented - @property - def name(self) -> str: ... # undocumented - if sys.version_info >= (3, 11): - def __class_getitem__(cls, item: Any) -> GenericAlias: ... - -def getLogger(name: str | None = None) -> Logger: ... -def getLoggerClass() -> type[Logger]: ... -def getLogRecordFactory() -> Callable[..., LogRecord]: ... - -if sys.version_info >= (3, 8): def debug( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... def info( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... def warning( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... def warn( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... def error( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, - ) -> None: ... - def critical( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - stacklevel: int = 1, - extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... def exception( + self, msg: object, *args: object, exc_info: _ExcInfoType = True, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... - def log( - level: int, + def critical( + self, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... - -else: - def debug( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def info( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warning( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def warn( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def error( - msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def critical( + def log( + self, + level: int, msg: object, *args: object, exc_info: _ExcInfoType = None, stack_info: bool = False, + stacklevel: int = 1, extra: Mapping[str, object] | None = None, + **kwargs: object, ) -> None: ... - def exception( - msg: object, - *args: object, - exc_info: _ExcInfoType = True, - stack_info: bool = False, - extra: Mapping[str, object] | None = None, - ) -> None: ... - def log( + def isEnabledFor(self, level: int) -> bool: ... + def getEffectiveLevel(self) -> int: ... + def setLevel(self, level: _Level) -> None: ... + def hasHandlers(self) -> bool: ... + def _log( + self, level: int, msg: object, - *args: object, - exc_info: _ExcInfoType = None, - stack_info: bool = False, + args: _ArgsType, + exc_info: _ExcInfoType | None = None, extra: Mapping[str, object] | None = None, - ) -> None: ... + stack_info: bool = False, + ) -> None: ... # undocumented + @property + def name(self) -> str: ... # undocumented + if sys.version_info >= (3, 11): + def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +def getLogger(name: str | None = None) -> Logger: ... +def getLoggerClass() -> type[Logger]: ... +def getLogRecordFactory() -> Callable[..., LogRecord]: ... +def debug( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def info( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def warning( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def warn( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def error( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def critical( + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def exception( + msg: object, + *args: object, + exc_info: _ExcInfoType = True, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... +def log( + level: int, + msg: object, + *args: object, + exc_info: _ExcInfoType = None, + stack_info: bool = False, + stacklevel: int = 1, + extra: Mapping[str, object] | None = None, +) -> None: ... fatal = critical @@ -783,20 +565,6 @@ if sys.version_info >= (3, 9): errors: str | None = ..., ) -> None: ... -elif sys.version_info >= (3, 8): - def basicConfig( - *, - filename: StrPath | None = ..., - filemode: str = ..., - format: str = ..., - datefmt: str | None = ..., - style: _FormatStyle = ..., - level: _Level | None = ..., - stream: SupportsWrite[str] | None = ..., - handlers: Iterable[Handler] | None = ..., - force: bool = ..., - ) -> None: ... - else: def basicConfig( *, @@ -808,6 +576,7 @@ else: level: _Level | None = ..., stream: SupportsWrite[str] | None = ..., handlers: Iterable[Handler] | None = ..., + force: bool = ..., ) -> None: ... def shutdown(handlerList: Sequence[Any] = ...) -> None: ... # handlerList is undocumented @@ -863,8 +632,7 @@ class PercentStyle: # undocumented default_format: str asctime_format: str asctime_search: str - if sys.version_info >= (3, 8): - validation_pattern: Pattern[str] + validation_pattern: Pattern[str] _fmt: str if sys.version_info >= (3, 10): def __init__(self, fmt: str, *, defaults: Mapping[str, Any] | None = None) -> None: ... @@ -872,9 +640,7 @@ class PercentStyle: # undocumented def __init__(self, fmt: str) -> None: ... def usesTime(self) -> bool: ... - if sys.version_info >= (3, 8): - def validate(self) -> None: ... - + def validate(self) -> None: ... def format(self, record: Any) -> str: ... class StrFormatStyle(PercentStyle): # undocumented diff --git a/mypy/typeshed/stdlib/logging/config.pyi b/mypy/typeshed/stdlib/logging/config.pyi index 0a61e5b16870..7a26846addbb 100644 --- a/mypy/typeshed/stdlib/logging/config.pyi +++ b/mypy/typeshed/stdlib/logging/config.pyi @@ -4,8 +4,8 @@ from collections.abc import Callable, Hashable, Iterable, Sequence from configparser import RawConfigParser from re import Pattern from threading import Thread -from typing import IO, Any, overload -from typing_extensions import Literal, Required, SupportsIndex, TypeAlias, TypedDict +from typing import IO, Any, Literal, SupportsIndex, TypedDict, overload +from typing_extensions import Required, TypeAlias from . import Filter, Filterer, Formatter, Handler, Logger, _FilterType, _FormatStyle, _Level @@ -28,16 +28,9 @@ else: class _LoggerConfiguration(_RootLoggerConfiguration, TypedDict, total=False): propagate: bool -if sys.version_info >= (3, 8): - _FormatterConfigurationTypedDict = TypedDict( - "_FormatterConfigurationTypedDict", {"class": str, "format": str, "datefmt": str, "style": _FormatStyle}, total=False - ) -else: - _FormatterConfigurationTypedDict = TypedDict( - "_FormatterConfigurationTypedDict", - {"class": str, "format": str, "datefmt": str, "style": _FormatStyle, "validate": bool}, - total=False, - ) +_FormatterConfigurationTypedDict = TypedDict( + "_FormatterConfigurationTypedDict", {"class": str, "format": str, "datefmt": str, "style": _FormatStyle}, total=False +) class _FilterConfigurationTypedDict(TypedDict): name: str diff --git a/mypy/typeshed/stdlib/lzma.pyi b/mypy/typeshed/stdlib/lzma.pyi index be61cac08139..05248ee0e710 100644 --- a/mypy/typeshed/stdlib/lzma.pyi +++ b/mypy/typeshed/stdlib/lzma.pyi @@ -1,8 +1,8 @@ from _compression import BaseStream from _typeshed import ReadableBuffer, StrOrBytesPath from collections.abc import Mapping, Sequence -from typing import IO, Any, TextIO, overload -from typing_extensions import Literal, Self, TypeAlias, final +from typing import IO, Any, Literal, TextIO, final, overload +from typing_extensions import Self, TypeAlias __all__ = [ "CHECK_NONE", diff --git a/mypy/typeshed/stdlib/macpath.pyi b/mypy/typeshed/stdlib/macpath.pyi deleted file mode 100644 index 37821f44b200..000000000000 --- a/mypy/typeshed/stdlib/macpath.pyi +++ /dev/null @@ -1,104 +0,0 @@ -from _typeshed import BytesPath, StrOrBytesPath, StrPath -from genericpath import ( - commonprefix as commonprefix, - exists as exists, - getatime as getatime, - getctime as getctime, - getmtime as getmtime, - getsize as getsize, - isdir as isdir, - isfile as isfile, - samefile as samefile, - sameopenfile as sameopenfile, - samestat as samestat, -) -from os import PathLike - -# Re-export common definitions from posixpath to reduce duplication -from posixpath import ( - abspath as abspath, - curdir as curdir, - defpath as defpath, - devnull as devnull, - expanduser as expanduser, - expandvars as expandvars, - extsep as extsep, - isabs as isabs, - lexists as lexists, - pardir as pardir, - pathsep as pathsep, - sep as sep, - splitdrive as splitdrive, - splitext as splitext, - supports_unicode_filenames as supports_unicode_filenames, -) -from typing import AnyStr, overload - -__all__ = [ - "normcase", - "isabs", - "join", - "splitdrive", - "split", - "splitext", - "basename", - "dirname", - "commonprefix", - "getsize", - "getmtime", - "getatime", - "getctime", - "islink", - "exists", - "lexists", - "isdir", - "isfile", - "expanduser", - "expandvars", - "normpath", - "abspath", - "curdir", - "pardir", - "sep", - "pathsep", - "defpath", - "altsep", - "extsep", - "devnull", - "realpath", - "supports_unicode_filenames", -] - -altsep: str | None - -@overload -def basename(s: PathLike[AnyStr]) -> AnyStr: ... -@overload -def basename(s: AnyStr) -> AnyStr: ... -@overload -def dirname(s: PathLike[AnyStr]) -> AnyStr: ... -@overload -def dirname(s: AnyStr) -> AnyStr: ... -@overload -def normcase(path: PathLike[AnyStr]) -> AnyStr: ... -@overload -def normcase(path: AnyStr) -> AnyStr: ... -@overload -def normpath(s: PathLike[AnyStr]) -> AnyStr: ... -@overload -def normpath(s: AnyStr) -> AnyStr: ... -@overload -def realpath(path: PathLike[AnyStr]) -> AnyStr: ... -@overload -def realpath(path: AnyStr) -> AnyStr: ... -def islink(s: StrOrBytesPath) -> bool: ... - -# Mypy complains that the signatures overlap, but things seem to behave correctly anyway. -@overload -def join(s: StrPath, *paths: StrPath) -> str: ... -@overload -def join(s: BytesPath, *paths: BytesPath) -> bytes: ... -@overload -def split(s: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... -@overload -def split(s: AnyStr) -> tuple[AnyStr, AnyStr]: ... diff --git a/mypy/typeshed/stdlib/mailbox.pyi b/mypy/typeshed/stdlib/mailbox.pyi index 8053fad88ea5..1059bfe917e8 100644 --- a/mypy/typeshed/stdlib/mailbox.pyi +++ b/mypy/typeshed/stdlib/mailbox.pyi @@ -5,8 +5,8 @@ from _typeshed import StrPath, SupportsNoArgReadline, SupportsRead from abc import ABCMeta, abstractmethod from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence from types import TracebackType -from typing import IO, Any, AnyStr, Generic, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, AnyStr, Generic, Literal, Protocol, TypeVar, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/math.pyi b/mypy/typeshed/stdlib/math.pyi index 73b53a713301..ee0693912a8b 100644 --- a/mypy/typeshed/stdlib/math.pyi +++ b/mypy/typeshed/stdlib/math.pyi @@ -1,15 +1,12 @@ import sys from collections.abc import Iterable -from typing import Protocol, SupportsFloat, TypeVar, overload -from typing_extensions import SupportsIndex, TypeAlias +from typing import Protocol, SupportsFloat, SupportsIndex, TypeVar, overload +from typing_extensions import TypeAlias _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) -if sys.version_info >= (3, 8): - _SupportsFloatOrIndex: TypeAlias = SupportsFloat | SupportsIndex -else: - _SupportsFloatOrIndex: TypeAlias = SupportsFloat +_SupportsFloatOrIndex: TypeAlias = SupportsFloat | SupportsIndex e: float pi: float @@ -35,18 +32,12 @@ class _SupportsCeil(Protocol[_T_co]): def ceil(__x: _SupportsCeil[_T]) -> _T: ... @overload def ceil(__x: _SupportsFloatOrIndex) -> int: ... - -if sys.version_info >= (3, 8): - def comb(__n: SupportsIndex, __k: SupportsIndex) -> int: ... - +def comb(__n: SupportsIndex, __k: SupportsIndex) -> int: ... def copysign(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... def cos(__x: _SupportsFloatOrIndex) -> float: ... def cosh(__x: _SupportsFloatOrIndex) -> float: ... def degrees(__x: _SupportsFloatOrIndex) -> float: ... - -if sys.version_info >= (3, 8): - def dist(__p: Iterable[_SupportsFloatOrIndex], __q: Iterable[_SupportsFloatOrIndex]) -> float: ... - +def dist(__p: Iterable[_SupportsFloatOrIndex], __q: Iterable[_SupportsFloatOrIndex]) -> float: ... def erf(__x: _SupportsFloatOrIndex) -> float: ... def erfc(__x: _SupportsFloatOrIndex) -> float: ... def exp(__x: _SupportsFloatOrIndex) -> float: ... @@ -56,12 +47,7 @@ if sys.version_info >= (3, 11): def expm1(__x: _SupportsFloatOrIndex) -> float: ... def fabs(__x: _SupportsFloatOrIndex) -> float: ... - -if sys.version_info >= (3, 8): - def factorial(__x: SupportsIndex) -> int: ... - -else: - def factorial(__x: int) -> int: ... +def factorial(__x: SupportsIndex) -> int: ... class _SupportsFloor(Protocol[_T_co]): def __floor__(self) -> _T_co: ... @@ -81,12 +67,7 @@ if sys.version_info >= (3, 9): else: def gcd(__x: SupportsIndex, __y: SupportsIndex) -> int: ... -if sys.version_info >= (3, 8): - def hypot(*coordinates: _SupportsFloatOrIndex) -> float: ... - -else: - def hypot(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... - +def hypot(*coordinates: _SupportsFloatOrIndex) -> float: ... def isclose( a: _SupportsFloatOrIndex, b: _SupportsFloatOrIndex, @@ -97,9 +78,7 @@ def isclose( def isinf(__x: _SupportsFloatOrIndex) -> bool: ... def isfinite(__x: _SupportsFloatOrIndex) -> bool: ... def isnan(__x: _SupportsFloatOrIndex) -> bool: ... - -if sys.version_info >= (3, 8): - def isqrt(__n: SupportsIndex) -> int: ... +def isqrt(__n: SupportsIndex) -> int: ... if sys.version_info >= (3, 9): def lcm(*integers: SupportsIndex) -> int: ... @@ -118,17 +97,12 @@ if sys.version_info >= (3, 12): elif sys.version_info >= (3, 9): def nextafter(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... -if sys.version_info >= (3, 8): - def perm(__n: SupportsIndex, __k: SupportsIndex | None = None) -> int: ... - +def perm(__n: SupportsIndex, __k: SupportsIndex | None = None) -> int: ... def pow(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... - -if sys.version_info >= (3, 8): - @overload - def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = 1) -> int: ... # type: ignore[overload-overlap] - @overload - def prod(__iterable: Iterable[_SupportsFloatOrIndex], *, start: _SupportsFloatOrIndex = 1) -> float: ... - +@overload +def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = 1) -> int: ... # type: ignore[overload-overlap] +@overload +def prod(__iterable: Iterable[_SupportsFloatOrIndex], *, start: _SupportsFloatOrIndex = 1) -> float: ... def radians(__x: _SupportsFloatOrIndex) -> float: ... def remainder(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... def sin(__x: _SupportsFloatOrIndex) -> float: ... diff --git a/mypy/typeshed/stdlib/mimetypes.pyi b/mypy/typeshed/stdlib/mimetypes.pyi index 532cc5e3ce39..e74b214d3ff1 100644 --- a/mypy/typeshed/stdlib/mimetypes.pyi +++ b/mypy/typeshed/stdlib/mimetypes.pyi @@ -1,4 +1,3 @@ -import sys from _typeshed import StrPath from collections.abc import Sequence from typing import IO @@ -19,12 +18,7 @@ __all__ = [ "common_types", ] -if sys.version_info >= (3, 8): - def guess_type(url: StrPath, strict: bool = True) -> tuple[str | None, str | None]: ... - -else: - def guess_type(url: str, strict: bool = True) -> tuple[str | None, str | None]: ... - +def guess_type(url: StrPath, strict: bool = True) -> tuple[str | None, str | None]: ... def guess_all_extensions(type: str, strict: bool = True) -> list[str]: ... def guess_extension(type: str, strict: bool = True) -> str | None: ... def init(files: Sequence[str] | None = None) -> None: ... @@ -45,11 +39,7 @@ class MimeTypes: types_map_inv: tuple[dict[str, str], dict[str, str]] def __init__(self, filenames: tuple[str, ...] = (), strict: bool = True) -> None: ... def guess_extension(self, type: str, strict: bool = True) -> str | None: ... - if sys.version_info >= (3, 8): - def guess_type(self, url: StrPath, strict: bool = True) -> tuple[str | None, str | None]: ... - else: - def guess_type(self, url: str, strict: bool = True) -> tuple[str | None, str | None]: ... - + def guess_type(self, url: StrPath, strict: bool = True) -> tuple[str | None, str | None]: ... def guess_all_extensions(self, type: str, strict: bool = True) -> list[str]: ... def read(self, filename: str, strict: bool = True) -> None: ... def readfp(self, fp: IO[str], strict: bool = True) -> None: ... diff --git a/mypy/typeshed/stdlib/mmap.pyi b/mypy/typeshed/stdlib/mmap.pyi index 9a213a8b8cf0..6bbb797f054d 100644 --- a/mypy/typeshed/stdlib/mmap.pyi +++ b/mypy/typeshed/stdlib/mmap.pyi @@ -39,11 +39,7 @@ class mmap(Iterable[int], Sized): ) -> None: ... def close(self) -> None: ... - if sys.version_info >= (3, 8): - def flush(self, offset: int = ..., size: int = ...) -> None: ... - else: - def flush(self, offset: int = ..., size: int = ...) -> int: ... - + def flush(self, offset: int = ..., size: int = ...) -> None: ... def move(self, dest: int, src: int, count: int) -> None: ... def read_byte(self) -> int: ... def readline(self) -> bytes: ... @@ -54,7 +50,7 @@ class mmap(Iterable[int], Sized): def write_byte(self, byte: int) -> None: ... def __len__(self) -> int: ... closed: bool - if sys.version_info >= (3, 8) and sys.platform != "win32": + if sys.platform != "win32": def madvise(self, option: int, start: int = ..., length: int = ...) -> None: ... def find(self, sub: ReadableBuffer, start: int = ..., stop: int = ...) -> int: ... @@ -81,7 +77,7 @@ class mmap(Iterable[int], Sized): def __buffer__(self, __flags: int) -> memoryview: ... def __release_buffer__(self, __buffer: memoryview) -> None: ... -if sys.version_info >= (3, 8) and sys.platform != "win32": +if sys.platform != "win32": MADV_NORMAL: int MADV_RANDOM: int MADV_SEQUENTIAL: int @@ -89,28 +85,28 @@ if sys.version_info >= (3, 8) and sys.platform != "win32": MADV_DONTNEED: int MADV_FREE: int - if sys.platform == "linux": - MADV_REMOVE: int - MADV_DONTFORK: int - MADV_DOFORK: int - MADV_HWPOISON: int - MADV_MERGEABLE: int - MADV_UNMERGEABLE: int - # Seems like this constant is not defined in glibc. - # See https://github.com/python/typeshed/pull/5360 for details - # MADV_SOFT_OFFLINE: int - MADV_HUGEPAGE: int - MADV_NOHUGEPAGE: int - MADV_DONTDUMP: int - MADV_DODUMP: int +if sys.platform == "linux": + MADV_REMOVE: int + MADV_DONTFORK: int + MADV_DOFORK: int + MADV_HWPOISON: int + MADV_MERGEABLE: int + MADV_UNMERGEABLE: int + # Seems like this constant is not defined in glibc. + # See https://github.com/python/typeshed/pull/5360 for details + # MADV_SOFT_OFFLINE: int + MADV_HUGEPAGE: int + MADV_NOHUGEPAGE: int + MADV_DONTDUMP: int + MADV_DODUMP: int - # This Values are defined for FreeBSD but type checkers do not support conditions for these - if sys.platform != "linux" and sys.platform != "darwin": - MADV_NOSYNC: int - MADV_AUTOSYNC: int - MADV_NOCORE: int - MADV_CORE: int - MADV_PROTECT: int +# This Values are defined for FreeBSD but type checkers do not support conditions for these +if sys.platform != "linux" and sys.platform != "darwin" and sys.platform != "win32": + MADV_NOSYNC: int + MADV_AUTOSYNC: int + MADV_NOCORE: int + MADV_CORE: int + MADV_PROTECT: int if sys.version_info >= (3, 10) and sys.platform == "darwin": MADV_FREE_REUSABLE: int diff --git a/mypy/typeshed/stdlib/modulefinder.pyi b/mypy/typeshed/stdlib/modulefinder.pyi index 06bb50d26286..132cac5f1878 100644 --- a/mypy/typeshed/stdlib/modulefinder.pyi +++ b/mypy/typeshed/stdlib/modulefinder.pyi @@ -31,23 +31,13 @@ class ModuleFinder: excludes: Container[str] # undocumented replace_paths: Sequence[tuple[str, str]] # undocumented - if sys.version_info >= (3, 8): - def __init__( - self, - path: list[str] | None = None, - debug: int = 0, - excludes: Container[str] | None = None, - replace_paths: Sequence[tuple[str, str]] | None = None, - ) -> None: ... - else: - def __init__( - self, - path: list[str] | None = None, - debug: int = 0, - excludes: Container[str] = [], - replace_paths: Sequence[tuple[str, str]] = [], - ) -> None: ... - + def __init__( + self, + path: list[str] | None = None, + debug: int = 0, + excludes: Container[str] | None = None, + replace_paths: Sequence[tuple[str, str]] | None = None, + ) -> None: ... def msg(self, level: int, str: str, *args: Any) -> None: ... # undocumented def msgin(self, *args: Any) -> None: ... # undocumented def msgout(self, *args: Any) -> None: ... # undocumented diff --git a/mypy/typeshed/stdlib/msilib/__init__.pyi b/mypy/typeshed/stdlib/msilib/__init__.pyi index 9f7367d152ba..106805dab931 100644 --- a/mypy/typeshed/stdlib/msilib/__init__.pyi +++ b/mypy/typeshed/stdlib/msilib/__init__.pyi @@ -1,8 +1,7 @@ import sys from collections.abc import Container, Iterable, Sequence from types import ModuleType -from typing import Any -from typing_extensions import Literal +from typing import Any, Literal if sys.platform == "win32": from _msi import * diff --git a/mypy/typeshed/stdlib/msvcrt.pyi b/mypy/typeshed/stdlib/msvcrt.pyi index 768edbc18ab3..bfd7ec62a9be 100644 --- a/mypy/typeshed/stdlib/msvcrt.pyi +++ b/mypy/typeshed/stdlib/msvcrt.pyi @@ -1,5 +1,5 @@ import sys -from typing_extensions import Final, Literal +from typing import Final, Literal # This module is only available on Windows if sys.platform == "win32": diff --git a/mypy/typeshed/stdlib/multiprocessing/__init__.pyi b/mypy/typeshed/stdlib/multiprocessing/__init__.pyi index 186bd54a021d..2bd6e2883ddb 100644 --- a/mypy/typeshed/stdlib/multiprocessing/__init__.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/__init__.pyi @@ -1,4 +1,3 @@ -import sys from multiprocessing import context, reduction as reducer from multiprocessing.context import ( AuthenticationError as AuthenticationError, @@ -7,7 +6,11 @@ from multiprocessing.context import ( ProcessError as ProcessError, TimeoutError as TimeoutError, ) -from multiprocessing.process import active_children as active_children, current_process as current_process +from multiprocessing.process import ( + active_children as active_children, + current_process as current_process, + parent_process as parent_process, +) # These are technically functions that return instances of these Queue classes. # The stub here doesn't reflect reality exactly -- @@ -19,9 +22,6 @@ from multiprocessing.process import active_children as active_children, current_ from multiprocessing.queues import JoinableQueue as JoinableQueue, Queue as Queue, SimpleQueue as SimpleQueue from multiprocessing.spawn import freeze_support as freeze_support -if sys.version_info >= (3, 8): - from multiprocessing.process import parent_process as parent_process - __all__ = [ "Array", "AuthenticationError", @@ -55,15 +55,13 @@ __all__ = [ "get_logger", "get_start_method", "log_to_stderr", + "parent_process", "reducer", "set_executable", "set_forkserver_preload", "set_start_method", ] -if sys.version_info >= (3, 8): - __all__ += ["parent_process"] - # These functions (really bound methods) # are all autogenerated at runtime here: https://github.com/python/cpython/blob/600c65c094b0b48704d8ec2416930648052ba715/Lib/multiprocessing/__init__.py#L23 RawValue = context._default_context.RawValue diff --git a/mypy/typeshed/stdlib/multiprocessing/connection.pyi b/mypy/typeshed/stdlib/multiprocessing/connection.pyi index 333b8820d84d..7045a81b85be 100644 --- a/mypy/typeshed/stdlib/multiprocessing/connection.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/connection.pyi @@ -3,8 +3,8 @@ import sys import types from _typeshed import ReadableBuffer from collections.abc import Iterable -from typing import Any -from typing_extensions import Self, SupportsIndex, TypeAlias +from typing import Any, SupportsIndex +from typing_extensions import Self, TypeAlias __all__ = ["Client", "Listener", "Pipe", "wait"] diff --git a/mypy/typeshed/stdlib/multiprocessing/context.pyi b/mypy/typeshed/stdlib/multiprocessing/context.pyi index fe3b98024548..1cc8d03ea436 100644 --- a/mypy/typeshed/stdlib/multiprocessing/context.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/context.pyi @@ -8,18 +8,15 @@ from multiprocessing.managers import SyncManager from multiprocessing.pool import Pool as _Pool from multiprocessing.process import BaseProcess from multiprocessing.sharedctypes import SynchronizedArray, SynchronizedBase -from typing import Any, ClassVar, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, ClassVar, Literal, TypeVar, overload +from typing_extensions import TypeAlias if sys.platform != "win32": from multiprocessing.connection import Connection else: from multiprocessing.connection import PipeConnection -if sys.version_info >= (3, 8): - __all__ = () -else: - __all__: list[str] = [] +__all__ = () _LockLike: TypeAlias = synchronize.Lock | synchronize.RLock _CT = TypeVar("_CT", bound=_CData) @@ -39,10 +36,8 @@ class BaseContext: # multiprocessing.*, so the signatures should be identical (modulo self). @staticmethod def current_process() -> BaseProcess: ... - if sys.version_info >= (3, 8): - @staticmethod - def parent_process() -> BaseProcess | None: ... - + @staticmethod + def parent_process() -> BaseProcess | None: ... @staticmethod def active_children() -> list[BaseProcess]: ... def cpu_count(self) -> int: ... @@ -151,8 +146,6 @@ class DefaultContext(BaseContext): def __init__(self, context: BaseContext) -> None: ... def get_start_method(self, allow_none: bool = False) -> str: ... def get_all_start_methods(self) -> list[str]: ... - if sys.version_info < (3, 8): - __all__: ClassVar[list[str]] _default_context: DefaultContext diff --git a/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi b/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi index 967b57ded6c8..804a56e9cbcf 100644 --- a/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi @@ -12,8 +12,7 @@ from threading import ( RLock as RLock, Semaphore as Semaphore, ) -from typing import Any -from typing_extensions import Literal +from typing import Any, Literal from .connection import Pipe as Pipe diff --git a/mypy/typeshed/stdlib/multiprocessing/managers.pyi b/mypy/typeshed/stdlib/multiprocessing/managers.pyi index c0ef0a3609d0..eb3ac29b1449 100644 --- a/mypy/typeshed/stdlib/multiprocessing/managers.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/managers.pyi @@ -4,19 +4,14 @@ import threading from _typeshed import SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping, MutableSequence, Sequence from types import TracebackType -from typing import Any, AnyStr, ClassVar, Generic, TypeVar, overload -from typing_extensions import Self, SupportsIndex, TypeAlias +from typing import Any, AnyStr, ClassVar, Generic, SupportsIndex, TypeVar, overload +from typing_extensions import Self, TypeAlias from .connection import Connection from .context import BaseContext +from .shared_memory import _SLT, ShareableList as _ShareableList, SharedMemory as _SharedMemory -if sys.version_info >= (3, 8): - from .shared_memory import _SLT, ShareableList as _ShareableList, SharedMemory as _SharedMemory - - __all__ = ["BaseManager", "SyncManager", "BaseProxy", "Token", "SharedMemoryManager"] - -else: - __all__ = ["BaseManager", "SyncManager", "BaseProxy", "Token"] +__all__ = ["BaseManager", "SyncManager", "BaseProxy", "Token", "SharedMemoryManager"] if sys.version_info >= (3, 9): from types import GenericAlias @@ -208,12 +203,10 @@ class SyncManager(BaseManager): def list(self) -> ListProxy[Any]: ... class RemoteError(Exception): ... +class SharedMemoryServer(Server): ... -if sys.version_info >= (3, 8): - class SharedMemoryServer(Server): ... - - class SharedMemoryManager(BaseManager): - def get_server(self) -> SharedMemoryServer: ... - def SharedMemory(self, size: int) -> _SharedMemory: ... - def ShareableList(self, sequence: Iterable[_SLT] | None) -> _ShareableList[_SLT]: ... - def __del__(self) -> None: ... +class SharedMemoryManager(BaseManager): + def get_server(self) -> SharedMemoryServer: ... + def SharedMemory(self, size: int) -> _SharedMemory: ... + def ShareableList(self, sequence: Iterable[_SLT] | None) -> _ShareableList[_SLT]: ... + def __del__(self) -> None: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/pool.pyi b/mypy/typeshed/stdlib/multiprocessing/pool.pyi index 5ad4bfe93fe9..465c8e08c134 100644 --- a/mypy/typeshed/stdlib/multiprocessing/pool.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/pool.pyi @@ -1,8 +1,8 @@ import sys from collections.abc import Callable, Iterable, Iterator, Mapping from types import TracebackType -from typing import Any, Generic, TypeVar -from typing_extensions import Literal, Self +from typing import Any, Generic, Literal, TypeVar +from typing_extensions import Self if sys.version_info >= (3, 9): from types import GenericAlias @@ -13,18 +13,9 @@ _S = TypeVar("_S") _T = TypeVar("_T") class ApplyResult(Generic[_T]): - if sys.version_info >= (3, 8): - def __init__( - self, pool: Pool, callback: Callable[[_T], object] | None, error_callback: Callable[[BaseException], object] | None - ) -> None: ... - else: - def __init__( - self, - cache: dict[int, ApplyResult[Any]], - callback: Callable[[_T], object] | None, - error_callback: Callable[[BaseException], object] | None, - ) -> None: ... - + def __init__( + self, pool: Pool, callback: Callable[[_T], object] | None, error_callback: Callable[[BaseException], object] | None + ) -> None: ... def get(self, timeout: float | None = None) -> _T: ... def wait(self, timeout: float | None = None) -> None: ... def ready(self) -> bool: ... @@ -36,31 +27,17 @@ class ApplyResult(Generic[_T]): AsyncResult = ApplyResult class MapResult(ApplyResult[list[_T]]): - if sys.version_info >= (3, 8): - def __init__( - self, - pool: Pool, - chunksize: int, - length: int, - callback: Callable[[list[_T]], object] | None, - error_callback: Callable[[BaseException], object] | None, - ) -> None: ... - else: - def __init__( - self, - cache: dict[int, ApplyResult[Any]], - chunksize: int, - length: int, - callback: Callable[[list[_T]], object] | None, - error_callback: Callable[[BaseException], object] | None, - ) -> None: ... + def __init__( + self, + pool: Pool, + chunksize: int, + length: int, + callback: Callable[[list[_T]], object] | None, + error_callback: Callable[[BaseException], object] | None, + ) -> None: ... class IMapIterator(Iterator[_T]): - if sys.version_info >= (3, 8): - def __init__(self, pool: Pool) -> None: ... - else: - def __init__(self, cache: dict[int, IMapIterator[Any]]) -> None: ... - + def __init__(self, pool: Pool) -> None: ... def __iter__(self) -> Self: ... def next(self, timeout: float | None = None) -> _T: ... def __next__(self, timeout: float | None = None) -> _T: ... @@ -120,12 +97,7 @@ class ThreadPool(Pool): ) -> None: ... # undocumented -if sys.version_info >= (3, 8): - INIT: Literal["INIT"] - RUN: Literal["RUN"] - CLOSE: Literal["CLOSE"] - TERMINATE: Literal["TERMINATE"] -else: - RUN: Literal[0] - CLOSE: Literal[1] - TERMINATE: Literal[2] +INIT: Literal["INIT"] +RUN: Literal["RUN"] +CLOSE: Literal["CLOSE"] +TERMINATE: Literal["TERMINATE"] diff --git a/mypy/typeshed/stdlib/multiprocessing/process.pyi b/mypy/typeshed/stdlib/multiprocessing/process.pyi index 9863013fc05f..4d129b27b0e8 100644 --- a/mypy/typeshed/stdlib/multiprocessing/process.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/process.pyi @@ -1,11 +1,7 @@ -import sys from collections.abc import Callable, Iterable, Mapping from typing import Any -if sys.version_info >= (3, 8): - __all__ = ["BaseProcess", "current_process", "active_children", "parent_process"] -else: - __all__ = ["BaseProcess", "current_process", "active_children"] +__all__ = ["BaseProcess", "current_process", "active_children", "parent_process"] class BaseProcess: name: str @@ -40,6 +36,4 @@ class BaseProcess: def current_process() -> BaseProcess: ... def active_children() -> list[BaseProcess]: ... - -if sys.version_info >= (3, 8): - def parent_process() -> BaseProcess | None: ... +def parent_process() -> BaseProcess | None: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi index e5a8cde8f849..ad80169b463c 100644 --- a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi @@ -8,8 +8,7 @@ from copyreg import _DispatchTableType from multiprocessing import connection from pickle import _ReducedType from socket import socket -from typing import Any -from typing_extensions import Literal +from typing import Any, Literal if sys.platform == "win32": __all__ = ["send_handle", "recv_handle", "ForkingPickler", "register", "dump", "DupHandle", "duplicate", "steal_handle"] @@ -32,13 +31,9 @@ register = ForkingPickler.register def dump(obj: Any, file: SupportsWrite[bytes], protocol: int | None = None) -> None: ... if sys.platform == "win32": - if sys.version_info >= (3, 8): - def duplicate( - handle: int, target_process: int | None = None, inheritable: bool = False, *, source_process: int | None = None - ) -> int: ... - else: - def duplicate(handle: int, target_process: int | None = None, inheritable: bool = False) -> int: ... - + def duplicate( + handle: int, target_process: int | None = None, inheritable: bool = False, *, source_process: int | None = None + ) -> int: ... def steal_handle(source_pid: int, handle: int) -> int: ... def send_handle(conn: connection.PipeConnection, handle: int, destination_pid: int) -> None: ... def recv_handle(conn: connection.PipeConnection) -> int: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi b/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi index 636d58842158..3979f14cf636 100644 --- a/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi @@ -4,8 +4,7 @@ from ctypes import _CData, _SimpleCData, c_char from multiprocessing.context import BaseContext from multiprocessing.synchronize import _LockLike from types import TracebackType -from typing import Any, Generic, Protocol, TypeVar, overload -from typing_extensions import Literal +from typing import Any, Generic, Literal, Protocol, TypeVar, overload __all__ = ["RawValue", "RawArray", "Value", "Array", "copy", "synchronized"] diff --git a/mypy/typeshed/stdlib/nntplib.pyi b/mypy/typeshed/stdlib/nntplib.pyi index f948c1430c90..969c657e9aab 100644 --- a/mypy/typeshed/stdlib/nntplib.pyi +++ b/mypy/typeshed/stdlib/nntplib.pyi @@ -5,8 +5,8 @@ import sys from _typeshed import Unused from builtins import list as _list # conflicts with a method named "list" from collections.abc import Iterable -from typing import IO, Any, NamedTuple -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Literal, NamedTuple +from typing_extensions import Self, TypeAlias __all__ = [ "NNTP", diff --git a/mypy/typeshed/stdlib/ntpath.pyi b/mypy/typeshed/stdlib/ntpath.pyi index 1a58b52de050..bfa880ee03a8 100644 --- a/mypy/typeshed/stdlib/ntpath.pyi +++ b/mypy/typeshed/stdlib/ntpath.pyi @@ -42,11 +42,11 @@ from posixpath import ( splitext as splitext, supports_unicode_filenames as supports_unicode_filenames, ) +from typing import AnyStr, overload +from typing_extensions import LiteralString if sys.version_info >= (3, 12): from posixpath import isjunction as isjunction, splitroot as splitroot -from typing import AnyStr, overload -from typing_extensions import LiteralString __all__ = [ "normcase", diff --git a/mypy/typeshed/stdlib/numbers.pyi b/mypy/typeshed/stdlib/numbers.pyi index 55f21041ae44..c2a0301d5636 100644 --- a/mypy/typeshed/stdlib/numbers.pyi +++ b/mypy/typeshed/stdlib/numbers.pyi @@ -1,8 +1,9 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. +from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import Any, SupportsFloat, overload +from typing import SupportsFloat, overload __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -16,36 +17,36 @@ class Complex(Number): def __bool__(self) -> bool: ... @property @abstractmethod - def real(self) -> Any: ... + def real(self): ... @property @abstractmethod - def imag(self) -> Any: ... + def imag(self): ... @abstractmethod - def __add__(self, other: Any) -> Any: ... + def __add__(self, other): ... @abstractmethod - def __radd__(self, other: Any) -> Any: ... + def __radd__(self, other): ... @abstractmethod - def __neg__(self) -> Any: ... + def __neg__(self): ... @abstractmethod - def __pos__(self) -> Any: ... - def __sub__(self, other: Any) -> Any: ... - def __rsub__(self, other: Any) -> Any: ... + def __pos__(self): ... + def __sub__(self, other): ... + def __rsub__(self, other): ... @abstractmethod - def __mul__(self, other: Any) -> Any: ... + def __mul__(self, other): ... @abstractmethod - def __rmul__(self, other: Any) -> Any: ... + def __rmul__(self, other): ... @abstractmethod - def __truediv__(self, other: Any) -> Any: ... + def __truediv__(self, other): ... @abstractmethod - def __rtruediv__(self, other: Any) -> Any: ... + def __rtruediv__(self, other): ... @abstractmethod - def __pow__(self, exponent: Any) -> Any: ... + def __pow__(self, exponent): ... @abstractmethod - def __rpow__(self, base: Any) -> Any: ... + def __rpow__(self, base): ... @abstractmethod def __abs__(self) -> Real: ... @abstractmethod - def conjugate(self) -> Any: ... + def conjugate(self): ... @abstractmethod def __eq__(self, other: object) -> bool: ... @@ -63,27 +64,27 @@ class Real(Complex, SupportsFloat): def __round__(self, ndigits: None = None) -> int: ... @abstractmethod @overload - def __round__(self, ndigits: int) -> Any: ... - def __divmod__(self, other: Any) -> Any: ... - def __rdivmod__(self, other: Any) -> Any: ... + def __round__(self, ndigits: int): ... + def __divmod__(self, other): ... + def __rdivmod__(self, other): ... @abstractmethod - def __floordiv__(self, other: Any) -> int: ... + def __floordiv__(self, other) -> int: ... @abstractmethod - def __rfloordiv__(self, other: Any) -> int: ... + def __rfloordiv__(self, other) -> int: ... @abstractmethod - def __mod__(self, other: Any) -> Any: ... + def __mod__(self, other): ... @abstractmethod - def __rmod__(self, other: Any) -> Any: ... + def __rmod__(self, other): ... @abstractmethod - def __lt__(self, other: Any) -> bool: ... + def __lt__(self, other) -> bool: ... @abstractmethod - def __le__(self, other: Any) -> bool: ... + def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self) -> Any: ... + def real(self): ... @property - def imag(self) -> Any: ... - def conjugate(self) -> Any: ... + def imag(self): ... + def conjugate(self): ... class Rational(Real): @property @@ -99,29 +100,29 @@ class Integral(Rational): def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent: Any, modulus: Any | None = None) -> Any: ... + def __pow__(self, exponent, modulus: Incomplete | None = None): ... @abstractmethod - def __lshift__(self, other: Any) -> Any: ... + def __lshift__(self, other): ... @abstractmethod - def __rlshift__(self, other: Any) -> Any: ... + def __rlshift__(self, other): ... @abstractmethod - def __rshift__(self, other: Any) -> Any: ... + def __rshift__(self, other): ... @abstractmethod - def __rrshift__(self, other: Any) -> Any: ... + def __rrshift__(self, other): ... @abstractmethod - def __and__(self, other: Any) -> Any: ... + def __and__(self, other): ... @abstractmethod - def __rand__(self, other: Any) -> Any: ... + def __rand__(self, other): ... @abstractmethod - def __xor__(self, other: Any) -> Any: ... + def __xor__(self, other): ... @abstractmethod - def __rxor__(self, other: Any) -> Any: ... + def __rxor__(self, other): ... @abstractmethod - def __or__(self, other: Any) -> Any: ... + def __or__(self, other): ... @abstractmethod - def __ror__(self, other: Any) -> Any: ... + def __ror__(self, other): ... @abstractmethod - def __invert__(self) -> Any: ... + def __invert__(self): ... def __float__(self) -> float: ... @property def numerator(self) -> int: ... diff --git a/mypy/typeshed/stdlib/opcode.pyi b/mypy/typeshed/stdlib/opcode.pyi index f852489ffacf..02da0c9f954a 100644 --- a/mypy/typeshed/stdlib/opcode.pyi +++ b/mypy/typeshed/stdlib/opcode.pyi @@ -1,5 +1,5 @@ import sys -from typing_extensions import Literal +from typing import Literal __all__ = [ "cmp_op", @@ -56,8 +56,4 @@ opmap: dict[str, int] HAVE_ARGUMENT: Literal[90] EXTENDED_ARG: Literal[144] -if sys.version_info >= (3, 8): - def stack_effect(__opcode: int, __oparg: int | None = None, *, jump: bool | None = None) -> int: ... - -else: - def stack_effect(__opcode: int, __oparg: int | None = None) -> int: ... +def stack_effect(__opcode: int, __oparg: int | None = None, *, jump: bool | None = None) -> int: ... diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index e92dd7a095d6..3b277460d8f6 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -25,17 +25,28 @@ from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMappin from contextlib import AbstractContextManager from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper as _TextIOWrapper from subprocess import Popen -from typing import IO, Any, AnyStr, BinaryIO, Generic, NoReturn, Protocol, TypeVar, overload, runtime_checkable -from typing_extensions import Final, Literal, Self, TypeAlias, Unpack, final +from typing import ( + IO, + Any, + AnyStr, + BinaryIO, + Final, + Generic, + Literal, + NoReturn, + Protocol, + TypeVar, + final, + overload, + runtime_checkable, +) +from typing_extensions import Self, TypeAlias, Unpack from . import path as _path if sys.version_info >= (3, 9): from types import GenericAlias -if sys.platform != "win32": - from resource import struct_rusage - # This unnecessary alias is to work around various errors path = _path @@ -361,9 +372,8 @@ class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, flo if sys.platform == "win32": @property def st_file_attributes(self) -> int: ... - if sys.version_info >= (3, 8): - @property - def st_reparse_tag(self) -> int: ... + @property + def st_reparse_tag(self) -> int: ... if sys.version_info >= (3, 12): @property def st_birthtime(self) -> float: ... # time of file creation in seconds @@ -965,6 +975,8 @@ else: def waitid(__idtype: int, __ident: int, __options: int) -> waitid_result | None: ... + from resource import struct_rusage + def wait3(options: int) -> tuple[int, int, struct_rusage]: ... def wait4(pid: int, options: int) -> tuple[int, int, struct_rusage]: ... def WCOREDUMP(__status: int) -> bool: ... @@ -975,36 +987,35 @@ else: def WEXITSTATUS(status: int) -> int: ... def WSTOPSIG(status: int) -> int: ... def WTERMSIG(status: int) -> int: ... - if sys.version_info >= (3, 8): - def posix_spawn( - __path: StrOrBytesPath, - __argv: _ExecVArgs, - __env: _ExecEnv, - *, - file_actions: Sequence[tuple[Any, ...]] | None = ..., - setpgroup: int | None = ..., - resetids: bool = ..., - setsid: bool = ..., - setsigmask: Iterable[int] = ..., - setsigdef: Iterable[int] = ..., - scheduler: tuple[Any, sched_param] | None = ..., - ) -> int: ... - def posix_spawnp( - __path: StrOrBytesPath, - __argv: _ExecVArgs, - __env: _ExecEnv, - *, - file_actions: Sequence[tuple[Any, ...]] | None = ..., - setpgroup: int | None = ..., - resetids: bool = ..., - setsid: bool = ..., - setsigmask: Iterable[int] = ..., - setsigdef: Iterable[int] = ..., - scheduler: tuple[Any, sched_param] | None = ..., - ) -> int: ... - POSIX_SPAWN_OPEN: int - POSIX_SPAWN_CLOSE: int - POSIX_SPAWN_DUP2: int + def posix_spawn( + __path: StrOrBytesPath, + __argv: _ExecVArgs, + __env: _ExecEnv, + *, + file_actions: Sequence[tuple[Any, ...]] | None = ..., + setpgroup: int | None = ..., + resetids: bool = ..., + setsid: bool = ..., + setsigmask: Iterable[int] = ..., + setsigdef: Iterable[int] = ..., + scheduler: tuple[Any, sched_param] | None = ..., + ) -> int: ... + def posix_spawnp( + __path: StrOrBytesPath, + __argv: _ExecVArgs, + __env: _ExecEnv, + *, + file_actions: Sequence[tuple[Any, ...]] | None = ..., + setpgroup: int | None = ..., + resetids: bool = ..., + setsid: bool = ..., + setsigmask: Iterable[int] = ..., + setsigdef: Iterable[int] = ..., + scheduler: tuple[Any, sched_param] | None = ..., + ) -> int: ... + POSIX_SPAWN_OPEN: int + POSIX_SPAWN_CLOSE: int + POSIX_SPAWN_DUP2: int if sys.platform != "win32": @final @@ -1048,38 +1059,36 @@ if sys.platform != "win32": after_in_child: Callable[..., Any] | None = ..., ) -> None: ... -if sys.version_info >= (3, 8): - if sys.platform == "win32": - class _AddedDllDirectory: - path: str | None - def __init__(self, path: str | None, cookie: _T, remove_dll_directory: Callable[[_T], object]) -> None: ... - def close(self) -> None: ... - def __enter__(self) -> Self: ... - def __exit__(self, *args: Unused) -> None: ... - - def add_dll_directory(path: str) -> _AddedDllDirectory: ... - if sys.platform == "linux": - MFD_CLOEXEC: int - MFD_ALLOW_SEALING: int - MFD_HUGETLB: int - MFD_HUGE_SHIFT: int - MFD_HUGE_MASK: int - MFD_HUGE_64KB: int - MFD_HUGE_512KB: int - MFD_HUGE_1MB: int - MFD_HUGE_2MB: int - MFD_HUGE_8MB: int - MFD_HUGE_16MB: int - MFD_HUGE_32MB: int - MFD_HUGE_256MB: int - MFD_HUGE_512MB: int - MFD_HUGE_1GB: int - MFD_HUGE_2GB: int - MFD_HUGE_16GB: int - def memfd_create(name: str, flags: int = ...) -> int: ... - def copy_file_range( - src: int, dst: int, count: int, offset_src: int | None = ..., offset_dst: int | None = ... - ) -> int: ... +if sys.platform == "win32": + class _AddedDllDirectory: + path: str | None + def __init__(self, path: str | None, cookie: _T, remove_dll_directory: Callable[[_T], object]) -> None: ... + def close(self) -> None: ... + def __enter__(self) -> Self: ... + def __exit__(self, *args: Unused) -> None: ... + + def add_dll_directory(path: str) -> _AddedDllDirectory: ... + +if sys.platform == "linux": + MFD_CLOEXEC: int + MFD_ALLOW_SEALING: int + MFD_HUGETLB: int + MFD_HUGE_SHIFT: int + MFD_HUGE_MASK: int + MFD_HUGE_64KB: int + MFD_HUGE_512KB: int + MFD_HUGE_1MB: int + MFD_HUGE_2MB: int + MFD_HUGE_8MB: int + MFD_HUGE_16MB: int + MFD_HUGE_32MB: int + MFD_HUGE_256MB: int + MFD_HUGE_512MB: int + MFD_HUGE_1GB: int + MFD_HUGE_2GB: int + MFD_HUGE_16GB: int + def memfd_create(name: str, flags: int = ...) -> int: ... + def copy_file_range(src: int, dst: int, count: int, offset_src: int | None = ..., offset_dst: int | None = ...) -> int: ... if sys.version_info >= (3, 9): def waitstatus_to_exitcode(status: int) -> int: ... diff --git a/mypy/typeshed/stdlib/ossaudiodev.pyi b/mypy/typeshed/stdlib/ossaudiodev.pyi index d956a89729fd..b9ee3edab033 100644 --- a/mypy/typeshed/stdlib/ossaudiodev.pyi +++ b/mypy/typeshed/stdlib/ossaudiodev.pyi @@ -1,6 +1,5 @@ import sys -from typing import Any, overload -from typing_extensions import Literal +from typing import Any, Literal, overload if sys.platform != "win32" and sys.platform != "darwin": AFMT_AC3: int diff --git a/mypy/typeshed/stdlib/parser.pyi b/mypy/typeshed/stdlib/parser.pyi index cce8594eac58..bafc8015fed9 100644 --- a/mypy/typeshed/stdlib/parser.pyi +++ b/mypy/typeshed/stdlib/parser.pyi @@ -1,8 +1,7 @@ from _typeshed import StrOrBytesPath from collections.abc import Sequence from types import CodeType -from typing import Any -from typing_extensions import final +from typing import Any, final def expr(source: str) -> STType: ... def suite(source: str) -> STType: ... diff --git a/mypy/typeshed/stdlib/pathlib.pyi b/mypy/typeshed/stdlib/pathlib.pyi index 10ffa4a778e8..c3b0b7ad6337 100644 --- a/mypy/typeshed/stdlib/pathlib.pyi +++ b/mypy/typeshed/stdlib/pathlib.pyi @@ -14,8 +14,8 @@ from collections.abc import Callable, Generator, Iterator, Sequence from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from os import PathLike, stat_result from types import TracebackType -from typing import IO, Any, BinaryIO, overload -from typing_extensions import Literal, Self +from typing import IO, Any, BinaryIO, Literal, overload +from typing_extensions import Self if sys.version_info >= (3, 9): from types import GenericAlias @@ -196,13 +196,9 @@ class Path(PurePath): if sys.version_info >= (3, 9): def readlink(self) -> Self: ... - if sys.version_info >= (3, 8): - def rename(self, target: str | PurePath) -> Self: ... - def replace(self, target: str | PurePath) -> Self: ... - else: - def rename(self, target: str | PurePath) -> None: ... - def replace(self, target: str | PurePath) -> None: ... + def rename(self, target: str | PurePath) -> Self: ... + def replace(self, target: str | PurePath) -> Self: ... def resolve(self, strict: bool = False) -> Self: ... def rmdir(self) -> None: ... def symlink_to(self, target: StrOrBytesPath, target_is_directory: bool = False) -> None: ... @@ -210,11 +206,7 @@ class Path(PurePath): def hardlink_to(self, target: StrOrBytesPath) -> None: ... def touch(self, mode: int = 0o666, exist_ok: bool = True) -> None: ... - if sys.version_info >= (3, 8): - def unlink(self, missing_ok: bool = False) -> None: ... - else: - def unlink(self) -> None: ... - + def unlink(self, missing_ok: bool = False) -> None: ... @classmethod def home(cls) -> Self: ... def absolute(self) -> Self: ... @@ -229,7 +221,7 @@ class Path(PurePath): ) -> int: ... else: def write_text(self, data: str, encoding: str | None = None, errors: str | None = None) -> int: ... - if sys.version_info >= (3, 8) and sys.version_info < (3, 12): + if sys.version_info < (3, 12): def link_to(self, target: StrOrBytesPath) -> None: ... if sys.version_info >= (3, 12): def walk( diff --git a/mypy/typeshed/stdlib/pickle.pyi b/mypy/typeshed/stdlib/pickle.pyi index cf3995d74f5d..0a4d439976ff 100644 --- a/mypy/typeshed/stdlib/pickle.pyi +++ b/mypy/typeshed/stdlib/pickle.pyi @@ -1,10 +1,10 @@ -import sys from _typeshed import ReadableBuffer, SupportsWrite from collections.abc import Callable, Iterable, Iterator, Mapping -from typing import Any, ClassVar, Protocol, SupportsBytes -from typing_extensions import SupportsIndex, TypeAlias, final +from typing import Any, ClassVar, Protocol, SupportsBytes, SupportsIndex, final +from typing_extensions import TypeAlias __all__ = [ + "PickleBuffer", "PickleError", "PicklingError", "UnpicklingError", @@ -30,6 +30,7 @@ __all__ = [ "BINUNICODE", "BINUNICODE8", "BUILD", + "BYTEARRAY8", "DEFAULT_PROTOCOL", "DICT", "DUP", @@ -61,6 +62,7 @@ __all__ = [ "NEWOBJ", "NEWOBJ_EX", "NEWTRUE", + "NEXT_BUFFER", "NONE", "OBJ", "PERSID", @@ -68,6 +70,7 @@ __all__ = [ "POP_MARK", "PROTO", "PUT", + "READONLY_BUFFER", "REDUCE", "SETITEM", "SETITEMS", @@ -85,9 +88,6 @@ __all__ = [ "UNICODE", ] -if sys.version_info >= (3, 8): - __all__ += ["BYTEARRAY8", "NEXT_BUFFER", "PickleBuffer", "READONLY_BUFFER"] - HIGHEST_PROTOCOL: int DEFAULT_PROTOCOL: int @@ -97,48 +97,43 @@ class _ReadableFileobj(Protocol): def read(self, __n: int) -> bytes: ... def readline(self) -> bytes: ... -if sys.version_info >= (3, 8): - @final - class PickleBuffer: - def __init__(self, buffer: ReadableBuffer) -> None: ... - def raw(self) -> memoryview: ... - def release(self) -> None: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... - _BufferCallback: TypeAlias = Callable[[PickleBuffer], Any] | None - def dump( - obj: Any, - file: SupportsWrite[bytes], - protocol: int | None = None, - *, - fix_imports: bool = True, - buffer_callback: _BufferCallback = None, - ) -> None: ... - def dumps( - obj: Any, protocol: int | None = None, *, fix_imports: bool = True, buffer_callback: _BufferCallback = None - ) -> bytes: ... - def load( - file: _ReadableFileobj, - *, - fix_imports: bool = True, - encoding: str = "ASCII", - errors: str = "strict", - buffers: Iterable[Any] | None = (), - ) -> Any: ... - def loads( - __data: ReadableBuffer, - *, - fix_imports: bool = True, - encoding: str = "ASCII", - errors: str = "strict", - buffers: Iterable[Any] | None = (), - ) -> Any: ... +@final +class PickleBuffer: + def __init__(self, buffer: ReadableBuffer) -> None: ... + def raw(self) -> memoryview: ... + def release(self) -> None: ... + def __buffer__(self, __flags: int) -> memoryview: ... + def __release_buffer__(self, __buffer: memoryview) -> None: ... + +_BufferCallback: TypeAlias = Callable[[PickleBuffer], Any] | None -else: - def dump(obj: Any, file: SupportsWrite[bytes], protocol: int | None = None, *, fix_imports: bool = True) -> None: ... - def dumps(obj: Any, protocol: int | None = None, *, fix_imports: bool = True) -> bytes: ... - def load(file: _ReadableFileobj, *, fix_imports: bool = True, encoding: str = "ASCII", errors: str = "strict") -> Any: ... - def loads(data: ReadableBuffer, *, fix_imports: bool = True, encoding: str = "ASCII", errors: str = "strict") -> Any: ... +def dump( + obj: Any, + file: SupportsWrite[bytes], + protocol: int | None = None, + *, + fix_imports: bool = True, + buffer_callback: _BufferCallback = None, +) -> None: ... +def dumps( + obj: Any, protocol: int | None = None, *, fix_imports: bool = True, buffer_callback: _BufferCallback = None +) -> bytes: ... +def load( + file: _ReadableFileobj, + *, + fix_imports: bool = True, + encoding: str = "ASCII", + errors: str = "strict", + buffers: Iterable[Any] | None = (), +) -> Any: ... +def loads( + __data: ReadableBuffer, + *, + fix_imports: bool = True, + encoding: str = "ASCII", + errors: str = "strict", + buffers: Iterable[Any] | None = (), +) -> Any: ... class PickleError(Exception): ... class PicklingError(PickleError): ... @@ -158,19 +153,15 @@ class Pickler: bin: bool # undocumented dispatch: ClassVar[dict[type, Callable[[Unpickler, Any], None]]] # undocumented, _Pickler only - if sys.version_info >= (3, 8): - def __init__( - self, - file: SupportsWrite[bytes], - protocol: int | None = ..., - *, - fix_imports: bool = ..., - buffer_callback: _BufferCallback = ..., - ) -> None: ... - def reducer_override(self, obj: Any) -> Any: ... - else: - def __init__(self, file: SupportsWrite[bytes], protocol: int | None = ..., *, fix_imports: bool = ...) -> None: ... - + def __init__( + self, + file: SupportsWrite[bytes], + protocol: int | None = ..., + *, + fix_imports: bool = ..., + buffer_callback: _BufferCallback = ..., + ) -> None: ... + def reducer_override(self, obj: Any) -> Any: ... def dump(self, __obj: Any) -> None: ... def clear_memo(self) -> None: ... def persistent_id(self, obj: Any) -> Any: ... @@ -178,21 +169,15 @@ class Pickler: class Unpickler: dispatch: ClassVar[dict[int, Callable[[Unpickler], None]]] # undocumented, _Unpickler only - if sys.version_info >= (3, 8): - def __init__( - self, - file: _ReadableFileobj, - *, - fix_imports: bool = ..., - encoding: str = ..., - errors: str = ..., - buffers: Iterable[Any] | None = ..., - ) -> None: ... - else: - def __init__( - self, file: _ReadableFileobj, *, fix_imports: bool = ..., encoding: str = ..., errors: str = ... - ) -> None: ... - + def __init__( + self, + file: _ReadableFileobj, + *, + fix_imports: bool = ..., + encoding: str = ..., + errors: str = ..., + buffers: Iterable[Any] | None = ..., + ) -> None: ... def load(self) -> Any: ... def find_class(self, __module_name: str, __global_name: str) -> Any: ... def persistent_load(self, pid: Any) -> Any: ... @@ -272,11 +257,10 @@ STACK_GLOBAL: bytes MEMOIZE: bytes FRAME: bytes -if sys.version_info >= (3, 8): - # Protocol 5 - BYTEARRAY8: bytes - NEXT_BUFFER: bytes - READONLY_BUFFER: bytes +# protocol 5 +BYTEARRAY8: bytes +NEXT_BUFFER: bytes +READONLY_BUFFER: bytes def encode_long(x: int) -> bytes: ... # undocumented def decode_long(data: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer) -> int: ... # undocumented diff --git a/mypy/typeshed/stdlib/platform.pyi b/mypy/typeshed/stdlib/platform.pyi index 483d6c454c2e..f0e6d4123e1d 100644 --- a/mypy/typeshed/stdlib/platform.pyi +++ b/mypy/typeshed/stdlib/platform.pyi @@ -1,37 +1,10 @@ import sys - -if sys.version_info < (3, 8): - import os - - DEV_NULL = os.devnull from typing import NamedTuple -if sys.version_info >= (3, 8): - def libc_ver(executable: str | None = None, lib: str = "", version: str = "", chunksize: int = 16384) -> tuple[str, str]: ... - -else: - def libc_ver( - executable: str = sys.executable, lib: str = "", version: str = "", chunksize: int = 16384 - ) -> tuple[str, str]: ... - -if sys.version_info < (3, 8): - def linux_distribution( - distname: str = "", - version: str = "", - id: str = "", - supported_dists: tuple[str, ...] = ..., - full_distribution_name: bool = ..., - ) -> tuple[str, str, str]: ... - def dist( - distname: str = "", version: str = "", id: str = "", supported_dists: tuple[str, ...] = ... - ) -> tuple[str, str, str]: ... - +def libc_ver(executable: str | None = None, lib: str = "", version: str = "", chunksize: int = 16384) -> tuple[str, str]: ... def win32_ver(release: str = "", version: str = "", csd: str = "", ptype: str = "") -> tuple[str, str, str, str]: ... - -if sys.version_info >= (3, 8): - def win32_edition() -> str: ... - def win32_is_iot() -> bool: ... - +def win32_edition() -> str: ... +def win32_is_iot() -> bool: ... def mac_ver( release: str = "", versioninfo: tuple[str, str, str] = ("", "", ""), machine: str = "" ) -> tuple[str, tuple[str, str, str], str]: ... diff --git a/mypy/typeshed/stdlib/plistlib.pyi b/mypy/typeshed/stdlib/plistlib.pyi index bd5525484514..f7912a784987 100644 --- a/mypy/typeshed/stdlib/plistlib.pyi +++ b/mypy/typeshed/stdlib/plistlib.pyi @@ -6,39 +6,9 @@ from enum import Enum from typing import IO, Any from typing_extensions import Self -if sys.version_info >= (3, 9): - __all__ = ["InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID"] -elif sys.version_info >= (3, 8): - __all__ = [ - "readPlist", - "writePlist", - "readPlistFromBytes", - "writePlistToBytes", - "Data", - "InvalidFileException", - "FMT_XML", - "FMT_BINARY", - "load", - "dump", - "loads", - "dumps", - "UID", - ] -else: - __all__ = [ - "readPlist", - "writePlist", - "readPlistFromBytes", - "writePlistToBytes", - "Data", - "InvalidFileException", - "FMT_XML", - "FMT_BINARY", - "load", - "dump", - "loads", - "dumps", - ] +__all__ = ["InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID"] +if sys.version_info < (3, 9): + __all__ += ["readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes", "Data"] class PlistFormat(Enum): FMT_XML: int @@ -46,8 +16,23 @@ class PlistFormat(Enum): FMT_XML = PlistFormat.FMT_XML FMT_BINARY = PlistFormat.FMT_BINARY +if sys.version_info >= (3, 13): + def load( + fp: IO[bytes], + *, + fmt: PlistFormat | None = None, + dict_type: type[MutableMapping[str, Any]] = ..., + aware_datetime: bool = False, + ) -> Any: ... + def loads( + value: ReadableBuffer | str, + *, + fmt: PlistFormat | None = None, + dict_type: type[MutableMapping[str, Any]] = ..., + aware_datetime: bool = False, + ) -> Any: ... -if sys.version_info >= (3, 9): +elif sys.version_info >= (3, 9): def load(fp: IO[bytes], *, fmt: PlistFormat | None = None, dict_type: type[MutableMapping[str, Any]] = ...) -> Any: ... def loads( value: ReadableBuffer, *, fmt: PlistFormat | None = None, dict_type: type[MutableMapping[str, Any]] = ... @@ -69,21 +54,41 @@ else: dict_type: type[MutableMapping[str, Any]] = ..., ) -> Any: ... -def dump( - value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, - fp: IO[bytes], - *, - fmt: PlistFormat = ..., - sort_keys: bool = True, - skipkeys: bool = False, -) -> None: ... -def dumps( - value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, - *, - fmt: PlistFormat = ..., - skipkeys: bool = False, - sort_keys: bool = True, -) -> bytes: ... +if sys.version_info >= (3, 13): + def dump( + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, + fp: IO[bytes], + *, + fmt: PlistFormat = ..., + sort_keys: bool = True, + skipkeys: bool = False, + aware_datetime: bool = False, + ) -> None: ... + def dumps( + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, + *, + fmt: PlistFormat = ..., + skipkeys: bool = False, + sort_keys: bool = True, + aware_datetime: bool = False, + ) -> bytes: ... + +else: + def dump( + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, + fp: IO[bytes], + *, + fmt: PlistFormat = ..., + sort_keys: bool = True, + skipkeys: bool = False, + ) -> None: ... + def dumps( + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | bytearray | datetime, + *, + fmt: PlistFormat = ..., + skipkeys: bool = False, + sort_keys: bool = True, + ) -> bytes: ... if sys.version_info < (3, 9): def readPlist(pathOrFile: str | IO[bytes]) -> Any: ... @@ -96,14 +101,13 @@ if sys.version_info < (3, 9): data: bytes def __init__(self, data: bytes) -> None: ... -if sys.version_info >= (3, 8): - class UID: - data: int - def __init__(self, data: int) -> None: ... - def __index__(self) -> int: ... - def __reduce__(self) -> tuple[type[Self], tuple[int]]: ... - def __hash__(self) -> int: ... - def __eq__(self, other: object) -> bool: ... +class UID: + data: int + def __init__(self, data: int) -> None: ... + def __index__(self) -> int: ... + def __reduce__(self) -> tuple[type[Self], tuple[int]]: ... + def __hash__(self) -> int: ... + def __eq__(self, other: object) -> bool: ... class InvalidFileException(ValueError): def __init__(self, message: str = "Invalid file") -> None: ... diff --git a/mypy/typeshed/stdlib/poplib.pyi b/mypy/typeshed/stdlib/poplib.pyi index 808e7e5222af..12f1d16a0d6f 100644 --- a/mypy/typeshed/stdlib/poplib.pyi +++ b/mypy/typeshed/stdlib/poplib.pyi @@ -3,8 +3,8 @@ import ssl import sys from builtins import list as _list # conflicts with a method named "list" from re import Pattern -from typing import Any, BinaryIO, NoReturn, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, BinaryIO, Literal, NoReturn, overload +from typing_extensions import TypeAlias __all__ = ["POP3", "error_proto", "POP3_SSL"] diff --git a/mypy/typeshed/stdlib/posix.pyi b/mypy/typeshed/stdlib/posix.pyi index 81cc93c5aa66..6cba003bbd5f 100644 --- a/mypy/typeshed/stdlib/posix.pyi +++ b/mypy/typeshed/stdlib/posix.pyi @@ -51,6 +51,9 @@ if sys.platform != "win32": P_ALL as P_ALL, P_PGID as P_PGID, P_PID as P_PID, + POSIX_SPAWN_CLOSE as POSIX_SPAWN_CLOSE, + POSIX_SPAWN_DUP2 as POSIX_SPAWN_DUP2, + POSIX_SPAWN_OPEN as POSIX_SPAWN_OPEN, PRIO_PGRP as PRIO_PGRP, PRIO_PROCESS as PRIO_PROCESS, PRIO_USER as PRIO_USER, @@ -161,12 +164,17 @@ if sys.platform != "win32": pathconf as pathconf, pathconf_names as pathconf_names, pipe as pipe, + posix_spawn as posix_spawn, + posix_spawnp as posix_spawnp, pread as pread, + preadv as preadv, putenv as putenv, pwrite as pwrite, + pwritev as pwritev, read as read, readlink as readlink, readv as readv, + register_at_fork as register_at_fork, remove as remove, rename as rename, replace as replace, @@ -222,48 +230,28 @@ if sys.platform != "win32": writev as writev, ) - if sys.platform != "darwin": - from os import EX_NOTFOUND as EX_NOTFOUND + if sys.version_info >= (3, 9): + from os import CLD_KILLED as CLD_KILLED, CLD_STOPPED as CLD_STOPPED, waitstatus_to_exitcode as waitstatus_to_exitcode - if sys.platform == "linux": - from os import ( - GRND_NONBLOCK as GRND_NONBLOCK, - GRND_RANDOM as GRND_RANDOM, - RTLD_DEEPBIND as RTLD_DEEPBIND, - XATTR_CREATE as XATTR_CREATE, - XATTR_REPLACE as XATTR_REPLACE, - XATTR_SIZE_MAX as XATTR_SIZE_MAX, - getrandom as getrandom, - getxattr as getxattr, - listxattr as listxattr, - removexattr as removexattr, - setxattr as setxattr, - ) + if sys.version_info >= (3, 11): + from os import login_tty as login_tty - if sys.version_info >= (3, 10): - from os import ( - EFD_CLOEXEC as EFD_CLOEXEC, - EFD_NONBLOCK as EFD_NONBLOCK, - EFD_SEMAPHORE as EFD_SEMAPHORE, - SPLICE_F_MORE as SPLICE_F_MORE, - SPLICE_F_MOVE as SPLICE_F_MOVE, - SPLICE_F_NONBLOCK as SPLICE_F_NONBLOCK, - eventfd as eventfd, - eventfd_read as eventfd_read, - eventfd_write as eventfd_write, - splice as splice, - ) - else: + if sys.platform != "linux": from os import chflags as chflags, lchflags as lchflags, lchmod as lchmod if sys.platform != "darwin": from os import ( + EX_NOTFOUND as EX_NOTFOUND, POSIX_FADV_DONTNEED as POSIX_FADV_DONTNEED, POSIX_FADV_NOREUSE as POSIX_FADV_NOREUSE, POSIX_FADV_NORMAL as POSIX_FADV_NORMAL, POSIX_FADV_RANDOM as POSIX_FADV_RANDOM, POSIX_FADV_SEQUENTIAL as POSIX_FADV_SEQUENTIAL, POSIX_FADV_WILLNEED as POSIX_FADV_WILLNEED, + RWF_DSYNC as RWF_DSYNC, + RWF_HIPRI as RWF_HIPRI, + RWF_NOWAIT as RWF_NOWAIT, + RWF_SYNC as RWF_SYNC, fdatasync as fdatasync, getresgid as getresgid, getresuid as getresuid, @@ -286,78 +274,85 @@ if sys.platform != "win32": if sys.version_info >= (3, 10): from os import RWF_APPEND as RWF_APPEND - if sys.version_info >= (3, 11): - from os import login_tty as login_tty - - if sys.version_info >= (3, 9): - from os import CLD_KILLED as CLD_KILLED, CLD_STOPPED as CLD_STOPPED, waitstatus_to_exitcode as waitstatus_to_exitcode - - if sys.platform == "linux": - from os import P_PIDFD as P_PIDFD, pidfd_open as pidfd_open - - if sys.version_info >= (3, 8): + if sys.platform == "linux": from os import ( - POSIX_SPAWN_CLOSE as POSIX_SPAWN_CLOSE, - POSIX_SPAWN_DUP2 as POSIX_SPAWN_DUP2, - POSIX_SPAWN_OPEN as POSIX_SPAWN_OPEN, - posix_spawn as posix_spawn, - posix_spawnp as posix_spawnp, + GRND_NONBLOCK as GRND_NONBLOCK, + GRND_RANDOM as GRND_RANDOM, + MFD_ALLOW_SEALING as MFD_ALLOW_SEALING, + MFD_CLOEXEC as MFD_CLOEXEC, + MFD_HUGE_1GB as MFD_HUGE_1GB, + MFD_HUGE_1MB as MFD_HUGE_1MB, + MFD_HUGE_2GB as MFD_HUGE_2GB, + MFD_HUGE_2MB as MFD_HUGE_2MB, + MFD_HUGE_8MB as MFD_HUGE_8MB, + MFD_HUGE_16GB as MFD_HUGE_16GB, + MFD_HUGE_16MB as MFD_HUGE_16MB, + MFD_HUGE_32MB as MFD_HUGE_32MB, + MFD_HUGE_64KB as MFD_HUGE_64KB, + MFD_HUGE_256MB as MFD_HUGE_256MB, + MFD_HUGE_512KB as MFD_HUGE_512KB, + MFD_HUGE_512MB as MFD_HUGE_512MB, + MFD_HUGE_MASK as MFD_HUGE_MASK, + MFD_HUGE_SHIFT as MFD_HUGE_SHIFT, + MFD_HUGETLB as MFD_HUGETLB, + RTLD_DEEPBIND as RTLD_DEEPBIND, + XATTR_CREATE as XATTR_CREATE, + XATTR_REPLACE as XATTR_REPLACE, + XATTR_SIZE_MAX as XATTR_SIZE_MAX, + copy_file_range as copy_file_range, + getrandom as getrandom, + getxattr as getxattr, + listxattr as listxattr, + memfd_create as memfd_create, + removexattr as removexattr, + setxattr as setxattr, ) - if sys.platform == "linux": + if sys.version_info >= (3, 9): + from os import P_PIDFD as P_PIDFD, pidfd_open as pidfd_open + + if sys.version_info >= (3, 10): from os import ( - MFD_ALLOW_SEALING as MFD_ALLOW_SEALING, - MFD_CLOEXEC as MFD_CLOEXEC, - MFD_HUGE_1GB as MFD_HUGE_1GB, - MFD_HUGE_1MB as MFD_HUGE_1MB, - MFD_HUGE_2GB as MFD_HUGE_2GB, - MFD_HUGE_2MB as MFD_HUGE_2MB, - MFD_HUGE_8MB as MFD_HUGE_8MB, - MFD_HUGE_16GB as MFD_HUGE_16GB, - MFD_HUGE_16MB as MFD_HUGE_16MB, - MFD_HUGE_32MB as MFD_HUGE_32MB, - MFD_HUGE_64KB as MFD_HUGE_64KB, - MFD_HUGE_256MB as MFD_HUGE_256MB, - MFD_HUGE_512KB as MFD_HUGE_512KB, - MFD_HUGE_512MB as MFD_HUGE_512MB, - MFD_HUGE_MASK as MFD_HUGE_MASK, - MFD_HUGE_SHIFT as MFD_HUGE_SHIFT, - MFD_HUGETLB as MFD_HUGETLB, - copy_file_range as copy_file_range, - memfd_create as memfd_create, + EFD_CLOEXEC as EFD_CLOEXEC, + EFD_NONBLOCK as EFD_NONBLOCK, + EFD_SEMAPHORE as EFD_SEMAPHORE, + SPLICE_F_MORE as SPLICE_F_MORE, + SPLICE_F_MOVE as SPLICE_F_MOVE, + SPLICE_F_NONBLOCK as SPLICE_F_NONBLOCK, + eventfd as eventfd, + eventfd_read as eventfd_read, + eventfd_write as eventfd_write, + splice as splice, ) - from os import preadv as preadv, pwritev as pwritev, register_at_fork as register_at_fork - - if sys.platform != "darwin": - from os import RWF_DSYNC as RWF_DSYNC, RWF_HIPRI as RWF_HIPRI, RWF_NOWAIT as RWF_NOWAIT, RWF_SYNC as RWF_SYNC - if sys.version_info >= (3, 12) and sys.platform == "linux": - from os import ( - CLONE_FILES as CLONE_FILES, - CLONE_FS as CLONE_FS, - CLONE_NEWCGROUP as CLONE_NEWCGROUP, - CLONE_NEWIPC as CLONE_NEWIPC, - CLONE_NEWNET as CLONE_NEWNET, - CLONE_NEWNS as CLONE_NEWNS, - CLONE_NEWPID as CLONE_NEWPID, - CLONE_NEWTIME as CLONE_NEWTIME, - CLONE_NEWUSER as CLONE_NEWUSER, - CLONE_NEWUTS as CLONE_NEWUTS, - CLONE_SIGHAND as CLONE_SIGHAND, - CLONE_SYSVSEM as CLONE_SYSVSEM, - CLONE_THREAD as CLONE_THREAD, - CLONE_VM as CLONE_VM, - setns as setns, - unshare as unshare, - ) + if sys.version_info >= (3, 12): + from os import ( + CLONE_FILES as CLONE_FILES, + CLONE_FS as CLONE_FS, + CLONE_NEWCGROUP as CLONE_NEWCGROUP, + CLONE_NEWIPC as CLONE_NEWIPC, + CLONE_NEWNET as CLONE_NEWNET, + CLONE_NEWNS as CLONE_NEWNS, + CLONE_NEWPID as CLONE_NEWPID, + CLONE_NEWTIME as CLONE_NEWTIME, + CLONE_NEWUSER as CLONE_NEWUSER, + CLONE_NEWUTS as CLONE_NEWUTS, + CLONE_SIGHAND as CLONE_SIGHAND, + CLONE_SYSVSEM as CLONE_SYSVSEM, + CLONE_THREAD as CLONE_THREAD, + CLONE_VM as CLONE_VM, + setns as setns, + unshare as unshare, + ) - if sys.version_info >= (3, 12) and sys.platform == "darwin": - from os import ( - PRIO_DARWIN_BG as PRIO_DARWIN_BG, - PRIO_DARWIN_NONUI as PRIO_DARWIN_NONUI, - PRIO_DARWIN_PROCESS as PRIO_DARWIN_PROCESS, - PRIO_DARWIN_THREAD as PRIO_DARWIN_THREAD, - ) + if sys.platform == "darwin": + if sys.version_info >= (3, 12): + from os import ( + PRIO_DARWIN_BG as PRIO_DARWIN_BG, + PRIO_DARWIN_NONUI as PRIO_DARWIN_NONUI, + PRIO_DARWIN_PROCESS as PRIO_DARWIN_PROCESS, + PRIO_DARWIN_THREAD as PRIO_DARWIN_THREAD, + ) # Not same as os.environ or os.environb # Because of this variable, we can't do "from posix import *" in os/__init__.pyi diff --git a/mypy/typeshed/stdlib/posixpath.pyi b/mypy/typeshed/stdlib/posixpath.pyi index 45a8ad7ec6a4..29e7c0f01017 100644 --- a/mypy/typeshed/stdlib/posixpath.pyi +++ b/mypy/typeshed/stdlib/posixpath.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import AnyOrLiteralStr, BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath -from collections.abc import Sequence +from collections.abc import Iterable from genericpath import ( commonprefix as commonprefix, exists as exists, @@ -102,11 +102,11 @@ def normpath(path: PathLike[AnyStr]) -> AnyStr: ... @overload def normpath(path: AnyOrLiteralStr) -> AnyOrLiteralStr: ... @overload -def commonpath(paths: Sequence[LiteralString]) -> LiteralString: ... +def commonpath(paths: Iterable[LiteralString]) -> LiteralString: ... @overload -def commonpath(paths: Sequence[StrPath]) -> str: ... +def commonpath(paths: Iterable[StrPath]) -> str: ... @overload -def commonpath(paths: Sequence[BytesPath]) -> bytes: ... +def commonpath(paths: Iterable[BytesPath]) -> bytes: ... # First parameter is not actually pos-only, # but must be defined as pos-only in the stub or cross-platform code doesn't type-check, diff --git a/mypy/typeshed/stdlib/pprint.pyi b/mypy/typeshed/stdlib/pprint.pyi index 5a909c69b077..171878f4165d 100644 --- a/mypy/typeshed/stdlib/pprint.pyi +++ b/mypy/typeshed/stdlib/pprint.pyi @@ -1,10 +1,7 @@ import sys from typing import IO -if sys.version_info >= (3, 8): - __all__ = ["pprint", "pformat", "isreadable", "isrecursive", "saferepr", "PrettyPrinter", "pp"] -else: - __all__ = ["pprint", "pformat", "isreadable", "isrecursive", "saferepr", "PrettyPrinter"] +__all__ = ["pprint", "pformat", "isreadable", "isrecursive", "saferepr", "PrettyPrinter", "pp"] if sys.version_info >= (3, 10): def pformat( @@ -18,7 +15,7 @@ if sys.version_info >= (3, 10): underscore_numbers: bool = False, ) -> str: ... -elif sys.version_info >= (3, 8): +else: def pformat( object: object, indent: int = 1, @@ -29,9 +26,6 @@ elif sys.version_info >= (3, 8): sort_dicts: bool = True, ) -> str: ... -else: - def pformat(object: object, indent: int = 1, width: int = 80, depth: int | None = None, *, compact: bool = False) -> str: ... - if sys.version_info >= (3, 10): def pp( object: object, @@ -45,7 +39,7 @@ if sys.version_info >= (3, 10): underscore_numbers: bool = ..., ) -> None: ... -elif sys.version_info >= (3, 8): +else: def pp( object: object, stream: IO[str] | None = ..., @@ -70,18 +64,6 @@ if sys.version_info >= (3, 10): underscore_numbers: bool = False, ) -> None: ... -elif sys.version_info >= (3, 8): - def pprint( - object: object, - stream: IO[str] | None = None, - indent: int = 1, - width: int = 80, - depth: int | None = None, - *, - compact: bool = False, - sort_dicts: bool = True, - ) -> None: ... - else: def pprint( object: object, @@ -91,6 +73,7 @@ else: depth: int | None = None, *, compact: bool = False, + sort_dicts: bool = True, ) -> None: ... def isreadable(object: object) -> bool: ... @@ -110,17 +93,6 @@ class PrettyPrinter: sort_dicts: bool = True, underscore_numbers: bool = False, ) -> None: ... - elif sys.version_info >= (3, 8): - def __init__( - self, - indent: int = 1, - width: int = 80, - depth: int | None = None, - stream: IO[str] | None = None, - *, - compact: bool = False, - sort_dicts: bool = True, - ) -> None: ... else: def __init__( self, @@ -130,6 +102,7 @@ class PrettyPrinter: stream: IO[str] | None = None, *, compact: bool = False, + sort_dicts: bool = True, ) -> None: ... def pformat(self, object: object) -> str: ... diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index 44ce33469ff9..a6ffd54de005 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -3,8 +3,8 @@ from _typeshed import StrEnum, StrOrBytesPath from collections.abc import Iterable from cProfile import Profile as _cProfile from profile import Profile -from typing import IO, Any, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Literal, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): __all__ = ["Stats", "SortKey", "FunctionProfile", "StatsProfile"] diff --git a/mypy/typeshed/stdlib/pty.pyi b/mypy/typeshed/stdlib/pty.pyi index a6a2d8fabb69..022b08046c54 100644 --- a/mypy/typeshed/stdlib/pty.pyi +++ b/mypy/typeshed/stdlib/pty.pyi @@ -1,6 +1,7 @@ import sys from collections.abc import Callable, Iterable -from typing_extensions import Literal, TypeAlias +from typing import Literal +from typing_extensions import TypeAlias if sys.platform != "win32": __all__ = ["openpty", "fork", "spawn"] diff --git a/mypy/typeshed/stdlib/pwd.pyi b/mypy/typeshed/stdlib/pwd.pyi index 80813479d7af..64e831bcecce 100644 --- a/mypy/typeshed/stdlib/pwd.pyi +++ b/mypy/typeshed/stdlib/pwd.pyi @@ -1,7 +1,6 @@ import sys from _typeshed import structseq -from typing import Any -from typing_extensions import Final, final +from typing import Any, Final, final if sys.platform != "win32": @final diff --git a/mypy/typeshed/stdlib/py_compile.pyi b/mypy/typeshed/stdlib/py_compile.pyi index 48f1d7dc3e70..81561a202883 100644 --- a/mypy/typeshed/stdlib/py_compile.pyi +++ b/mypy/typeshed/stdlib/py_compile.pyi @@ -17,27 +17,15 @@ class PycInvalidationMode(enum.Enum): UNCHECKED_HASH: int def _get_default_invalidation_mode() -> PycInvalidationMode: ... - -if sys.version_info >= (3, 8): - def compile( - file: AnyStr, - cfile: AnyStr | None = None, - dfile: AnyStr | None = None, - doraise: bool = False, - optimize: int = -1, - invalidation_mode: PycInvalidationMode | None = None, - quiet: int = 0, - ) -> AnyStr | None: ... - -else: - def compile( - file: AnyStr, - cfile: AnyStr | None = None, - dfile: AnyStr | None = None, - doraise: bool = False, - optimize: int = -1, - invalidation_mode: PycInvalidationMode | None = None, - ) -> AnyStr | None: ... +def compile( + file: AnyStr, + cfile: AnyStr | None = None, + dfile: AnyStr | None = None, + doraise: bool = False, + optimize: int = -1, + invalidation_mode: PycInvalidationMode | None = None, + quiet: int = 0, +) -> AnyStr | None: ... if sys.version_info >= (3, 10): def main() -> None: ... diff --git a/mypy/typeshed/stdlib/pydoc.pyi b/mypy/typeshed/stdlib/pydoc.pyi index 1b09bcb059e4..3134de79352d 100644 --- a/mypy/typeshed/stdlib/pydoc.pyi +++ b/mypy/typeshed/stdlib/pydoc.pyi @@ -5,8 +5,8 @@ from builtins import list as _list # "list" conflicts with method name from collections.abc import Callable, Container, Mapping, MutableMapping from reprlib import Repr from types import MethodType, ModuleType, TracebackType -from typing import IO, Any, AnyStr, NoReturn, TypeVar -from typing_extensions import Final, TypeGuard +from typing import IO, Any, AnyStr, Final, NoReturn, TypeVar +from typing_extensions import TypeGuard __all__ = ["help"] diff --git a/mypy/typeshed/stdlib/pyexpat/__init__.pyi b/mypy/typeshed/stdlib/pyexpat/__init__.pyi index 9e1eea08be54..92d926ebd332 100644 --- a/mypy/typeshed/stdlib/pyexpat/__init__.pyi +++ b/mypy/typeshed/stdlib/pyexpat/__init__.pyi @@ -1,8 +1,8 @@ from _typeshed import ReadableBuffer, SupportsRead from collections.abc import Callable from pyexpat import errors as errors, model as model -from typing import Any -from typing_extensions import TypeAlias, final +from typing import Any, final +from typing_extensions import TypeAlias EXPAT_VERSION: str # undocumented version_info: tuple[int, int, int] # undocumented diff --git a/mypy/typeshed/stdlib/re.pyi b/mypy/typeshed/stdlib/re.pyi index ec532ca3cffe..84c6cfceb1de 100644 --- a/mypy/typeshed/stdlib/re.pyi +++ b/mypy/typeshed/stdlib/re.pyi @@ -4,8 +4,8 @@ import sys from _typeshed import ReadableBuffer from collections.abc import Callable, Iterator, Mapping from sre_constants import error as error -from typing import Any, AnyStr, Generic, TypeVar, overload -from typing_extensions import Literal, TypeAlias, final +from typing import Any, AnyStr, Generic, Literal, TypeVar, final, overload +from typing_extensions import TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/resource.pyi b/mypy/typeshed/stdlib/resource.pyi index 57cefb4681ac..31c55111360a 100644 --- a/mypy/typeshed/stdlib/resource.pyi +++ b/mypy/typeshed/stdlib/resource.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import structseq -from typing_extensions import Final, final +from typing import Final, final if sys.platform != "win32": RLIMIT_AS: int diff --git a/mypy/typeshed/stdlib/select.pyi b/mypy/typeshed/stdlib/select.pyi index 5e2828e42c30..f2cfc881c1da 100644 --- a/mypy/typeshed/stdlib/select.pyi +++ b/mypy/typeshed/stdlib/select.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import FileDescriptorLike from collections.abc import Iterable from types import TracebackType -from typing import Any -from typing_extensions import Self, final +from typing import Any, final +from typing_extensions import Self if sys.platform != "win32": PIPE_BUF: int diff --git a/mypy/typeshed/stdlib/shlex.pyi b/mypy/typeshed/stdlib/shlex.pyi index c4fd23d60666..3fda03b5694a 100644 --- a/mypy/typeshed/stdlib/shlex.pyi +++ b/mypy/typeshed/stdlib/shlex.pyi @@ -1,18 +1,11 @@ -import sys from collections.abc import Iterable from typing import TextIO from typing_extensions import Self -if sys.version_info >= (3, 8): - __all__ = ["shlex", "split", "quote", "join"] -else: - __all__ = ["shlex", "split", "quote"] +__all__ = ["shlex", "split", "quote", "join"] def split(s: str, comments: bool = False, posix: bool = True) -> list[str]: ... - -if sys.version_info >= (3, 8): - def join(split_command: Iterable[str]) -> str: ... - +def join(split_command: Iterable[str]) -> str: ... def quote(s: str) -> str: ... class shlex(Iterable[str]): diff --git a/mypy/typeshed/stdlib/shutil.pyi b/mypy/typeshed/stdlib/shutil.pyi index 78e930920073..f6440aa27513 100644 --- a/mypy/typeshed/stdlib/shutil.pyi +++ b/mypy/typeshed/stdlib/shutil.pyi @@ -48,12 +48,7 @@ class ExecError(OSError): ... class ReadError(OSError): ... class RegistryError(Exception): ... -if sys.version_info >= (3, 8): - def copyfileobj(fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = 0) -> None: ... - -else: - def copyfileobj(fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = 16384) -> None: ... - +def copyfileobj(fsrc: SupportsRead[AnyStr], fdst: SupportsWrite[AnyStr], length: int = 0) -> None: ... def copyfile(src: StrOrBytesPath, dst: _StrOrBytesPathT, *, follow_symlinks: bool = True) -> _StrOrBytesPathT: ... def copymode(src: StrOrBytesPath, dst: StrOrBytesPath, *, follow_symlinks: bool = True) -> None: ... def copystat(src: StrOrBytesPath, dst: StrOrBytesPath, *, follow_symlinks: bool = True) -> None: ... @@ -66,27 +61,15 @@ def copy2(src: StrPath, dst: StrPath, *, follow_symlinks: bool = True) -> _PathR @overload def copy2(src: BytesPath, dst: BytesPath, *, follow_symlinks: bool = True) -> _PathReturn: ... def ignore_patterns(*patterns: StrPath) -> Callable[[Any, list[str]], set[str]]: ... - -if sys.version_info >= (3, 8): - def copytree( - src: StrPath, - dst: StrPath, - symlinks: bool = False, - ignore: None | Callable[[str, list[str]], Iterable[str]] | Callable[[StrPath, list[str]], Iterable[str]] = None, - copy_function: Callable[[str, str], object] = ..., - ignore_dangling_symlinks: bool = False, - dirs_exist_ok: bool = False, - ) -> _PathReturn: ... - -else: - def copytree( - src: StrPath, - dst: StrPath, - symlinks: bool = False, - ignore: None | Callable[[str, list[str]], Iterable[str]] | Callable[[StrPath, list[str]], Iterable[str]] = None, - copy_function: Callable[[str, str], object] = ..., - ignore_dangling_symlinks: bool = False, - ) -> _PathReturn: ... +def copytree( + src: StrPath, + dst: StrPath, + symlinks: bool = False, + ignore: None | Callable[[str, list[str]], Iterable[str]] | Callable[[StrPath, list[str]], Iterable[str]] = None, + copy_function: Callable[[str, str], object] = ..., + ignore_dangling_symlinks: bool = False, + dirs_exist_ok: bool = False, +) -> _PathReturn: ... _OnErrorCallback: TypeAlias = Callable[[Callable[..., Any], str, Any], object] _OnExcCallback: TypeAlias = Callable[[Callable[..., Any], str, Exception], object] @@ -161,16 +144,10 @@ def chown(path: FileDescriptorOrPath, user: None = None, *, group: str | int) -> def chown(path: FileDescriptorOrPath, user: None, group: str | int) -> None: ... @overload def chown(path: FileDescriptorOrPath, user: str | int, group: str | int) -> None: ... - -if sys.version_info >= (3, 8): - @overload - def which(cmd: _StrPathT, mode: int = 1, path: StrPath | None = None) -> str | _StrPathT | None: ... - @overload - def which(cmd: bytes, mode: int = 1, path: StrPath | None = None) -> bytes | None: ... - -else: - def which(cmd: _StrPathT, mode: int = 1, path: StrPath | None = None) -> str | _StrPathT | None: ... - +@overload +def which(cmd: _StrPathT, mode: int = 1, path: StrPath | None = None) -> str | _StrPathT | None: ... +@overload +def which(cmd: bytes, mode: int = 1, path: StrPath | None = None) -> bytes | None: ... def make_archive( base_name: str, format: str, @@ -192,15 +169,9 @@ def register_archive_format( name: str, function: Callable[[str, str], object], extra_args: None = None, description: str = "" ) -> None: ... def unregister_archive_format(name: str) -> None: ... - -if sys.version_info >= (3, 8): - def unpack_archive( - filename: StrPath, extract_dir: StrPath | None = None, format: str | None = None, *, filter: _TarfileFilter | None = None - ) -> None: ... - -else: - def unpack_archive(filename: StrPath, extract_dir: StrPath | None = None, format: str | None = None) -> None: ... - +def unpack_archive( + filename: StrPath, extract_dir: StrPath | None = None, format: str | None = None, *, filter: _TarfileFilter | None = None +) -> None: ... @overload def register_unpack_format( name: str, diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index 906a6dabe192..910424c01c31 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -3,8 +3,8 @@ from _typeshed import structseq from collections.abc import Callable, Iterable from enum import IntEnum from types import FrameType -from typing import Any -from typing_extensions import Final, Never, TypeAlias, final +from typing import Any, Final, final +from typing_extensions import Never, TypeAlias NSIG: int @@ -179,11 +179,9 @@ else: def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... -if sys.version_info >= (3, 8): - def strsignal(__signalnum: _SIGNUM) -> str | None: ... - def valid_signals() -> set[Signals]: ... - def raise_signal(__signalnum: _SIGNUM) -> None: ... - +def strsignal(__signalnum: _SIGNUM) -> str | None: ... +def valid_signals() -> set[Signals]: ... +def raise_signal(__signalnum: _SIGNUM) -> None: ... def set_wakeup_fd(fd: int, *, warn_on_full_buffer: bool = ...) -> int: ... if sys.version_info >= (3, 9): diff --git a/mypy/typeshed/stdlib/socket.pyi b/mypy/typeshed/stdlib/socket.pyi index cc0cbe3709af..ce5e35228fe4 100644 --- a/mypy/typeshed/stdlib/socket.pyi +++ b/mypy/typeshed/stdlib/socket.pyi @@ -4,7 +4,7 @@ import _socket import sys from _socket import ( - _FD, + CAPI as CAPI, EAI_AGAIN as EAI_AGAIN, EAI_BADFLAGS as EAI_BADFLAGS, EAI_FAIL as EAI_FAIL, @@ -33,9 +33,28 @@ from _socket import ( IP_TTL as IP_TTL, IPPORT_RESERVED as IPPORT_RESERVED, IPPORT_USERRESERVED as IPPORT_USERRESERVED, + IPPROTO_AH as IPPROTO_AH, + IPPROTO_DSTOPTS as IPPROTO_DSTOPTS, + IPPROTO_EGP as IPPROTO_EGP, + IPPROTO_ESP as IPPROTO_ESP, + IPPROTO_FRAGMENT as IPPROTO_FRAGMENT, + IPPROTO_GGP as IPPROTO_GGP, + IPPROTO_HOPOPTS as IPPROTO_HOPOPTS, IPPROTO_ICMP as IPPROTO_ICMP, + IPPROTO_ICMPV6 as IPPROTO_ICMPV6, + IPPROTO_IDP as IPPROTO_IDP, + IPPROTO_IGMP as IPPROTO_IGMP, IPPROTO_IP as IPPROTO_IP, + IPPROTO_IPV4 as IPPROTO_IPV4, + IPPROTO_IPV6 as IPPROTO_IPV6, + IPPROTO_MAX as IPPROTO_MAX, + IPPROTO_ND as IPPROTO_ND, + IPPROTO_NONE as IPPROTO_NONE, + IPPROTO_PIM as IPPROTO_PIM, + IPPROTO_PUP as IPPROTO_PUP, IPPROTO_RAW as IPPROTO_RAW, + IPPROTO_ROUTING as IPPROTO_ROUTING, + IPPROTO_SCTP as IPPROTO_SCTP, IPPROTO_TCP as IPPROTO_TCP, IPPROTO_UDP as IPPROTO_UDP, IPV6_CHECKSUM as IPV6_CHECKSUM, @@ -82,11 +101,13 @@ from _socket import ( SOMAXCONN as SOMAXCONN, TCP_FASTOPEN as TCP_FASTOPEN, TCP_KEEPCNT as TCP_KEEPCNT, + TCP_KEEPINTVL as TCP_KEEPINTVL, TCP_MAXSEG as TCP_MAXSEG, TCP_NODELAY as TCP_NODELAY, SocketType as SocketType, _Address as _Address, _RetAddress as _RetAddress, + close as close, dup as dup, error as error, gaierror as gaierror, @@ -103,6 +124,9 @@ from _socket import ( herror as herror, htonl as htonl, htons as htons, + if_indextoname as if_indextoname, + if_nameindex as if_nameindex, + if_nametoindex as if_nametoindex, inet_aton as inet_aton, inet_ntoa as inet_ntoa, inet_ntop as inet_ntop, @@ -116,8 +140,20 @@ from _typeshed import ReadableBuffer, Unused, WriteableBuffer from collections.abc import Iterable from enum import IntEnum, IntFlag from io import BufferedReader, BufferedRWPair, BufferedWriter, IOBase, RawIOBase, TextIOWrapper -from typing import Any, Protocol, overload -from typing_extensions import Literal, Self +from typing import Any, Literal, Protocol, SupportsIndex, overload +from typing_extensions import Self + +if sys.platform == "win32": + from _socket import ( + RCVALL_MAX as RCVALL_MAX, + RCVALL_OFF as RCVALL_OFF, + RCVALL_ON as RCVALL_ON, + RCVALL_SOCKETLEVELONLY as RCVALL_SOCKETLEVELONLY, + SIO_KEEPALIVE_VALS as SIO_KEEPALIVE_VALS, + SIO_LOOPBACK_FAST_PATH as SIO_LOOPBACK_FAST_PATH, + SIO_RCVALL as SIO_RCVALL, + SO_EXCLUSIVEADDRUSE as SO_EXCLUSIVEADDRUSE, + ) if sys.platform != "darwin" or sys.version_info >= (3, 9): from _socket import ( @@ -131,54 +167,27 @@ if sys.platform != "darwin" or sys.version_info >= (3, 9): if sys.platform == "darwin": from _socket import PF_SYSTEM as PF_SYSTEM, SYSPROTO_CONTROL as SYSPROTO_CONTROL -else: - from _socket import SO_EXCLUSIVEADDRUSE as SO_EXCLUSIVEADDRUSE - -if sys.version_info >= (3, 10): - from _socket import IP_RECVTOS as IP_RECVTOS -elif sys.platform != "darwin" and sys.platform != "win32": - from _socket import IP_RECVTOS as IP_RECVTOS - -from _socket import TCP_KEEPINTVL as TCP_KEEPINTVL, close as close if sys.platform != "darwin": - from _socket import TCP_KEEPIDLE as TCP_KEEPIDLE - -if sys.platform != "win32" or sys.version_info >= (3, 8): from _socket import ( - IPPROTO_AH as IPPROTO_AH, - IPPROTO_DSTOPTS as IPPROTO_DSTOPTS, - IPPROTO_EGP as IPPROTO_EGP, - IPPROTO_ESP as IPPROTO_ESP, - IPPROTO_FRAGMENT as IPPROTO_FRAGMENT, - IPPROTO_GGP as IPPROTO_GGP, - IPPROTO_HOPOPTS as IPPROTO_HOPOPTS, - IPPROTO_ICMPV6 as IPPROTO_ICMPV6, - IPPROTO_IDP as IPPROTO_IDP, - IPPROTO_IGMP as IPPROTO_IGMP, - IPPROTO_IPV4 as IPPROTO_IPV4, - IPPROTO_IPV6 as IPPROTO_IPV6, - IPPROTO_MAX as IPPROTO_MAX, - IPPROTO_ND as IPPROTO_ND, - IPPROTO_NONE as IPPROTO_NONE, - IPPROTO_PIM as IPPROTO_PIM, - IPPROTO_PUP as IPPROTO_PUP, - IPPROTO_ROUTING as IPPROTO_ROUTING, - IPPROTO_SCTP as IPPROTO_SCTP, + IPPROTO_CBT as IPPROTO_CBT, + IPPROTO_ICLFXBM as IPPROTO_ICLFXBM, + IPPROTO_IGP as IPPROTO_IGP, + IPPROTO_L2TP as IPPROTO_L2TP, + IPPROTO_PGM as IPPROTO_PGM, + IPPROTO_RDP as IPPROTO_RDP, + IPPROTO_ST as IPPROTO_ST, + TCP_KEEPIDLE as TCP_KEEPIDLE, ) - if sys.platform != "darwin": - from _socket import ( - IPPROTO_CBT as IPPROTO_CBT, - IPPROTO_ICLFXBM as IPPROTO_ICLFXBM, - IPPROTO_IGP as IPPROTO_IGP, - IPPROTO_L2TP as IPPROTO_L2TP, - IPPROTO_PGM as IPPROTO_PGM, - IPPROTO_RDP as IPPROTO_RDP, - IPPROTO_ST as IPPROTO_ST, - ) +if sys.version_info >= (3, 10): + from _socket import IP_RECVTOS as IP_RECVTOS +elif sys.platform != "win32" and sys.platform != "darwin": + from _socket import IP_RECVTOS as IP_RECVTOS + if sys.platform != "win32" and sys.platform != "darwin": from _socket import ( + IP_BIND_ADDRESS_NO_PORT as IP_BIND_ADDRESS_NO_PORT, IP_TRANSPARENT as IP_TRANSPARENT, IPPROTO_BIP as IPPROTO_BIP, IPPROTO_MOBILE as IPPROTO_MOBILE, @@ -186,10 +195,14 @@ if sys.platform != "win32" and sys.platform != "darwin": IPX_TYPE as IPX_TYPE, SCM_CREDENTIALS as SCM_CREDENTIALS, SO_BINDTODEVICE as SO_BINDTODEVICE, + SO_DOMAIN as SO_DOMAIN, SO_MARK as SO_MARK, SO_PASSCRED as SO_PASSCRED, + SO_PASSSEC as SO_PASSSEC, SO_PEERCRED as SO_PEERCRED, + SO_PEERSEC as SO_PEERSEC, SO_PRIORITY as SO_PRIORITY, + SO_PROTOCOL as SO_PROTOCOL, SO_SETFIB as SO_SETFIB, SOL_ATALK as SOL_ATALK, SOL_AX25 as SOL_AX25, @@ -197,6 +210,7 @@ if sys.platform != "win32" and sys.platform != "darwin": SOL_IPX as SOL_IPX, SOL_NETROM as SOL_NETROM, SOL_ROSE as SOL_ROSE, + TCP_CONGESTION as TCP_CONGESTION, TCP_CORK as TCP_CORK, TCP_DEFER_ACCEPT as TCP_DEFER_ACCEPT, TCP_INFO as TCP_INFO, @@ -206,6 +220,7 @@ if sys.platform != "win32" and sys.platform != "darwin": TCP_USER_TIMEOUT as TCP_USER_TIMEOUT, TCP_WINDOW_CLAMP as TCP_WINDOW_CLAMP, ) + if sys.platform != "win32": from _socket import ( CMSG_LEN as CMSG_LEN, @@ -235,6 +250,7 @@ if sys.platform != "win32": SCM_CREDS as SCM_CREDS, SCM_RIGHTS as SCM_RIGHTS, SO_REUSEPORT as SO_REUSEPORT, + TCP_NOTSENT_LOWAT as TCP_NOTSENT_LOWAT, sethostname as sethostname, ) @@ -252,9 +268,6 @@ if sys.platform != "win32": IPV6_USE_MIN_MTU as IPV6_USE_MIN_MTU, ) -if sys.platform != "win32" or sys.version_info >= (3, 8): - from _socket import if_indextoname as if_indextoname, if_nameindex as if_nameindex, if_nametoindex as if_nametoindex - if sys.platform != "darwin": if sys.platform != "win32" or sys.version_info >= (3, 9): from _socket import BDADDR_ANY as BDADDR_ANY, BDADDR_LOCAL as BDADDR_LOCAL, BTPROTO_RFCOMM as BTPROTO_RFCOMM @@ -262,6 +275,9 @@ if sys.platform != "darwin": if sys.platform == "darwin" and sys.version_info >= (3, 10): from _socket import TCP_KEEPALIVE as TCP_KEEPALIVE +if sys.platform == "darwin" and sys.version_info >= (3, 11): + from _socket import TCP_CONNECTION_INFO as TCP_CONNECTION_INFO + if sys.platform == "linux": from _socket import ( ALG_OP_DECRYPT as ALG_OP_DECRYPT, @@ -275,15 +291,27 @@ if sys.platform == "linux": ALG_SET_OP as ALG_SET_OP, ALG_SET_PUBKEY as ALG_SET_PUBKEY, CAN_BCM as CAN_BCM, + CAN_BCM_CAN_FD_FRAME as CAN_BCM_CAN_FD_FRAME, + CAN_BCM_RX_ANNOUNCE_RESUME as CAN_BCM_RX_ANNOUNCE_RESUME, CAN_BCM_RX_CHANGED as CAN_BCM_RX_CHANGED, + CAN_BCM_RX_CHECK_DLC as CAN_BCM_RX_CHECK_DLC, CAN_BCM_RX_DELETE as CAN_BCM_RX_DELETE, + CAN_BCM_RX_FILTER_ID as CAN_BCM_RX_FILTER_ID, + CAN_BCM_RX_NO_AUTOTIMER as CAN_BCM_RX_NO_AUTOTIMER, CAN_BCM_RX_READ as CAN_BCM_RX_READ, + CAN_BCM_RX_RTR_FRAME as CAN_BCM_RX_RTR_FRAME, CAN_BCM_RX_SETUP as CAN_BCM_RX_SETUP, CAN_BCM_RX_STATUS as CAN_BCM_RX_STATUS, CAN_BCM_RX_TIMEOUT as CAN_BCM_RX_TIMEOUT, + CAN_BCM_SETTIMER as CAN_BCM_SETTIMER, + CAN_BCM_STARTTIMER as CAN_BCM_STARTTIMER, + CAN_BCM_TX_ANNOUNCE as CAN_BCM_TX_ANNOUNCE, + CAN_BCM_TX_COUNTEVT as CAN_BCM_TX_COUNTEVT, + CAN_BCM_TX_CP_CAN_ID as CAN_BCM_TX_CP_CAN_ID, CAN_BCM_TX_DELETE as CAN_BCM_TX_DELETE, CAN_BCM_TX_EXPIRED as CAN_BCM_TX_EXPIRED, CAN_BCM_TX_READ as CAN_BCM_TX_READ, + CAN_BCM_TX_RESET_MULTI_IDX as CAN_BCM_TX_RESET_MULTI_IDX, CAN_BCM_TX_SEND as CAN_BCM_TX_SEND, CAN_BCM_TX_SETUP as CAN_BCM_TX_SETUP, CAN_BCM_TX_STATUS as CAN_BCM_TX_STATUS, @@ -291,6 +319,7 @@ if sys.platform == "linux": CAN_EFF_MASK as CAN_EFF_MASK, CAN_ERR_FLAG as CAN_ERR_FLAG, CAN_ERR_MASK as CAN_ERR_MASK, + CAN_ISOTP as CAN_ISOTP, CAN_RAW as CAN_RAW, CAN_RAW_ERR_FILTER as CAN_RAW_ERR_FILTER, CAN_RAW_FD_FRAMES as CAN_RAW_FD_FRAMES, @@ -299,6 +328,7 @@ if sys.platform == "linux": CAN_RAW_RECV_OWN_MSGS as CAN_RAW_RECV_OWN_MSGS, CAN_RTR_FLAG as CAN_RTR_FLAG, CAN_SFF_MASK as CAN_SFF_MASK, + IOCTL_VM_SOCKETS_GET_LOCAL_CID as IOCTL_VM_SOCKETS_GET_LOCAL_CID, NETLINK_ARPD as NETLINK_ARPD, NETLINK_CRYPTO as NETLINK_CRYPTO, NETLINK_DNRTMSG as NETLINK_DNRTMSG, @@ -341,6 +371,9 @@ if sys.platform == "linux": RDS_RDMA_SILENT as RDS_RDMA_SILENT, RDS_RDMA_USE_ONCE as RDS_RDMA_USE_ONCE, RDS_RECVERR as RDS_RECVERR, + SO_VM_SOCKETS_BUFFER_MAX_SIZE as SO_VM_SOCKETS_BUFFER_MAX_SIZE, + SO_VM_SOCKETS_BUFFER_MIN_SIZE as SO_VM_SOCKETS_BUFFER_MIN_SIZE, + SO_VM_SOCKETS_BUFFER_SIZE as SO_VM_SOCKETS_BUFFER_SIZE, SOL_ALG as SOL_ALG, SOL_CAN_BASE as SOL_CAN_BASE, SOL_CAN_RAW as SOL_CAN_RAW, @@ -369,36 +402,12 @@ if sys.platform == "linux": TIPC_WAIT_FOREVER as TIPC_WAIT_FOREVER, TIPC_WITHDRAWN as TIPC_WITHDRAWN, TIPC_ZONE_SCOPE as TIPC_ZONE_SCOPE, - ) -if sys.platform == "linux": - from _socket import ( - CAN_ISOTP as CAN_ISOTP, - IOCTL_VM_SOCKETS_GET_LOCAL_CID as IOCTL_VM_SOCKETS_GET_LOCAL_CID, - SO_VM_SOCKETS_BUFFER_MAX_SIZE as SO_VM_SOCKETS_BUFFER_MAX_SIZE, - SO_VM_SOCKETS_BUFFER_MIN_SIZE as SO_VM_SOCKETS_BUFFER_MIN_SIZE, - SO_VM_SOCKETS_BUFFER_SIZE as SO_VM_SOCKETS_BUFFER_SIZE, VM_SOCKETS_INVALID_VERSION as VM_SOCKETS_INVALID_VERSION, VMADDR_CID_ANY as VMADDR_CID_ANY, VMADDR_CID_HOST as VMADDR_CID_HOST, VMADDR_PORT_ANY as VMADDR_PORT_ANY, ) -if sys.platform != "win32": - from _socket import TCP_NOTSENT_LOWAT as TCP_NOTSENT_LOWAT -if sys.platform == "linux" and sys.version_info >= (3, 8): - from _socket import ( - CAN_BCM_CAN_FD_FRAME as CAN_BCM_CAN_FD_FRAME, - CAN_BCM_RX_ANNOUNCE_RESUME as CAN_BCM_RX_ANNOUNCE_RESUME, - CAN_BCM_RX_CHECK_DLC as CAN_BCM_RX_CHECK_DLC, - CAN_BCM_RX_FILTER_ID as CAN_BCM_RX_FILTER_ID, - CAN_BCM_RX_NO_AUTOTIMER as CAN_BCM_RX_NO_AUTOTIMER, - CAN_BCM_RX_RTR_FRAME as CAN_BCM_RX_RTR_FRAME, - CAN_BCM_SETTIMER as CAN_BCM_SETTIMER, - CAN_BCM_STARTTIMER as CAN_BCM_STARTTIMER, - CAN_BCM_TX_ANNOUNCE as CAN_BCM_TX_ANNOUNCE, - CAN_BCM_TX_COUNTEVT as CAN_BCM_TX_COUNTEVT, - CAN_BCM_TX_CP_CAN_ID as CAN_BCM_TX_CP_CAN_ID, - CAN_BCM_TX_RESET_MULTI_IDX as CAN_BCM_TX_RESET_MULTI_IDX, - ) + if sys.platform == "linux" and sys.version_info >= (3, 9): from _socket import ( CAN_J1939 as CAN_J1939, @@ -426,21 +435,14 @@ if sys.platform == "linux" and sys.version_info >= (3, 9): SO_J1939_FILTER as SO_J1939_FILTER, SO_J1939_PROMISC as SO_J1939_PROMISC, SO_J1939_SEND_PRIO as SO_J1939_SEND_PRIO, + UDPLITE_RECV_CSCOV as UDPLITE_RECV_CSCOV, + UDPLITE_SEND_CSCOV as UDPLITE_SEND_CSCOV, ) if sys.platform == "linux" and sys.version_info >= (3, 10): from _socket import IPPROTO_MPTCP as IPPROTO_MPTCP if sys.platform == "linux" and sys.version_info >= (3, 11): from _socket import SO_INCOMING_CPU as SO_INCOMING_CPU -if sys.platform == "win32": - from _socket import ( - RCVALL_MAX as RCVALL_MAX, - RCVALL_OFF as RCVALL_OFF, - RCVALL_ON as RCVALL_ON, - RCVALL_SOCKETLEVELONLY as RCVALL_SOCKETLEVELONLY, - SIO_KEEPALIVE_VALS as SIO_KEEPALIVE_VALS, - SIO_LOOPBACK_FAST_PATH as SIO_LOOPBACK_FAST_PATH, - SIO_RCVALL as SIO_RCVALL, - ) + if sys.version_info >= (3, 12): from _socket import ( IP_ADD_SOURCE_MEMBERSHIP as IP_ADD_SOURCE_MEMBERSHIP, @@ -471,8 +473,6 @@ if sys.version_info >= (3, 12): ETHERTYPE_IPV6 as ETHERTYPE_IPV6, ETHERTYPE_VLAN as ETHERTYPE_VLAN, ) -if sys.version_info >= (3, 11) and sys.platform == "darwin": - from _socket import TCP_CONNECTION_INFO as TCP_CONNECTION_INFO # Re-exported from errno EBADF: int @@ -493,7 +493,7 @@ class AddressFamily(IntEnum): AF_ROUTE: int AF_SYSTEM: int AF_UNIX: int - if sys.platform != "darwin" and sys.platform != "win32": + if sys.platform != "win32" and sys.platform != "darwin": AF_AAL5: int AF_ASH: int AF_ATMPVC: int @@ -518,8 +518,7 @@ class AddressFamily(IntEnum): AF_ALG: int AF_NETLINK: int AF_VSOCK: int - if sys.version_info >= (3, 8): - AF_QIPCRTR: int + AF_QIPCRTR: int if sys.platform != "win32" or sys.version_info >= (3, 9): AF_LINK: int if sys.platform != "darwin": @@ -569,8 +568,7 @@ if sys.platform == "linux": AF_ALG = AddressFamily.AF_ALG AF_NETLINK = AddressFamily.AF_NETLINK AF_VSOCK = AddressFamily.AF_VSOCK - if sys.version_info >= (3, 8): - AF_QIPCRTR = AddressFamily.AF_QIPCRTR + AF_QIPCRTR = AddressFamily.AF_QIPCRTR if sys.platform != "win32" or sys.version_info >= (3, 9): AF_LINK = AddressFamily.AF_LINK @@ -771,7 +769,7 @@ class socket(_socket.socket): def get_inheritable(self) -> bool: ... def set_inheritable(self, inheritable: bool) -> None: ... -def fromfd(fd: _FD, family: AddressFamily | int, type: SocketKind | int, proto: int = 0) -> socket: ... +def fromfd(fd: SupportsIndex, family: AddressFamily | int, type: SocketKind | int, proto: int = 0) -> socket: ... if sys.platform != "win32": if sys.version_info >= (3, 9): @@ -816,16 +814,10 @@ else: address: tuple[str | None, int], timeout: float | None = ..., source_address: _Address | None = None # noqa: F811 ) -> socket: ... -if sys.version_info >= (3, 8): - def has_dualstack_ipv6() -> bool: ... - def create_server( - address: _Address, - *, - family: int = ..., - backlog: int | None = None, - reuse_port: bool = False, - dualstack_ipv6: bool = False, - ) -> socket: ... +def has_dualstack_ipv6() -> bool: ... +def create_server( + address: _Address, *, family: int = ..., backlog: int | None = None, reuse_port: bool = False, dualstack_ipv6: bool = False +) -> socket: ... # the 5th tuple item is an address def getaddrinfo( diff --git a/mypy/typeshed/stdlib/spwd.pyi b/mypy/typeshed/stdlib/spwd.pyi index 27b1061e1b0e..93dfad3b38cc 100644 --- a/mypy/typeshed/stdlib/spwd.pyi +++ b/mypy/typeshed/stdlib/spwd.pyi @@ -1,7 +1,6 @@ import sys from _typeshed import structseq -from typing import Any -from typing_extensions import Final, final +from typing import Any, Final, final if sys.platform != "win32": @final diff --git a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi index 236e093c9909..659545c50b41 100644 --- a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi +++ b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi @@ -1,11 +1,11 @@ import sqlite3 import sys -from _typeshed import Incomplete, ReadableBuffer, StrOrBytesPath, SupportsLenAndGetItem, Unused +from _typeshed import ReadableBuffer, StrOrBytesPath, SupportsLenAndGetItem, Unused from collections.abc import Callable, Generator, Iterable, Iterator, Mapping from datetime import date, datetime, time from types import TracebackType -from typing import Any, Protocol, TypeVar, overload -from typing_extensions import Literal, Self, SupportsIndex, TypeAlias, final +from typing import Any, Literal, Protocol, SupportsIndex, TypeVar, final, overload +from typing_extensions import Self, TypeAlias _T = TypeVar("_T") _CursorT = TypeVar("_CursorT", bound=Cursor) @@ -245,12 +245,6 @@ else: def register_adapter(__type: type[_T], __caster: _Adapter[_T]) -> None: ... def register_converter(__name: str, __converter: _Converter) -> None: ... -if sys.version_info < (3, 8): - class Cache: - def __init__(self, *args: Incomplete, **kwargs: Unused) -> None: ... - def display(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... - def get(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... - class _AggregateProtocol(Protocol): def step(self, __value: int) -> object: ... def finalize(self) -> int: ... @@ -341,13 +335,9 @@ class Connection: ) -> None: ... def create_collation(self, __name: str, __callback: Callable[[str, str], int | SupportsIndex] | None) -> None: ... - if sys.version_info >= (3, 8): - def create_function( - self, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False - ) -> None: ... - else: - def create_function(self, name: str, num_params: int, func: Callable[..., _SqliteData] | None) -> None: ... - + def create_function( + self, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False + ) -> None: ... @overload def cursor(self, factory: None = None) -> Cursor: ... @overload @@ -458,15 +448,8 @@ class Row: def __lt__(self, __value: object) -> bool: ... def __ne__(self, __value: object) -> bool: ... -if sys.version_info >= (3, 8): - @final - class _Statement: ... - -else: - @final - class Statement: - def __init__(self, *args: Incomplete, **kwargs: Incomplete) -> None: ... - _Statement: TypeAlias = Statement +@final +class _Statement: ... class Warning(Exception): ... diff --git a/mypy/typeshed/stdlib/sre_parse.pyi b/mypy/typeshed/stdlib/sre_parse.pyi index 2c10bf7e7c3b..c242bd2a065f 100644 --- a/mypy/typeshed/stdlib/sre_parse.pyi +++ b/mypy/typeshed/stdlib/sre_parse.pyi @@ -25,7 +25,14 @@ if sys.version_info >= (3, 11): if sys.version_info < (3, 11): class Verbose(Exception): ... -class _State: +_OpSubpatternType: TypeAlias = tuple[int | None, int, int, SubPattern] +_OpGroupRefExistsType: TypeAlias = tuple[int, SubPattern, SubPattern] +_OpInType: TypeAlias = list[tuple[_NIC, int]] +_OpBranchType: TypeAlias = tuple[None, list[SubPattern]] +_AvType: TypeAlias = _OpInType | _OpBranchType | Iterable[SubPattern] | _OpGroupRefExistsType | _OpSubpatternType +_CodeType: TypeAlias = tuple[_NIC, _AvType] + +class State: flags: int groupdict: dict[str, int] groupwidths: list[int | None] @@ -37,29 +44,12 @@ class _State: def checkgroup(self, gid: int) -> bool: ... def checklookbehindgroup(self, gid: int, source: Tokenizer) -> None: ... -if sys.version_info >= (3, 8): - State: TypeAlias = _State -else: - Pattern: TypeAlias = _State - -_OpSubpatternType: TypeAlias = tuple[int | None, int, int, SubPattern] -_OpGroupRefExistsType: TypeAlias = tuple[int, SubPattern, SubPattern] -_OpInType: TypeAlias = list[tuple[_NIC, int]] -_OpBranchType: TypeAlias = tuple[None, list[SubPattern]] -_AvType: TypeAlias = _OpInType | _OpBranchType | Iterable[SubPattern] | _OpGroupRefExistsType | _OpSubpatternType -_CodeType: TypeAlias = tuple[_NIC, _AvType] - class SubPattern: data: list[_CodeType] width: int | None + state: State - if sys.version_info >= (3, 8): - state: State - def __init__(self, state: State, data: list[_CodeType] | None = None) -> None: ... - else: - pattern: Pattern - def __init__(self, pattern: Pattern, data: list[_CodeType] | None = None) -> None: ... - + def __init__(self, state: State, data: list[_CodeType] | None = None) -> None: ... def dump(self, level: int = 0) -> None: ... def __len__(self) -> int: ... def __delitem__(self, index: int | slice) -> None: ... @@ -79,11 +69,7 @@ class Tokenizer: def match(self, char: str) -> bool: ... def get(self) -> str | None: ... def getwhile(self, n: int, charset: Iterable[str]) -> str: ... - if sys.version_info >= (3, 8): - def getuntil(self, terminator: str, name: str) -> str: ... - else: - def getuntil(self, terminator: str) -> str: ... - + def getuntil(self, terminator: str, name: str) -> str: ... @property def pos(self) -> int: ... def tell(self) -> int: ... @@ -106,23 +92,13 @@ if sys.version_info >= (3, 12): @overload def parse_template(source: bytes, pattern: _Pattern[Any]) -> _TemplateByteType: ... -elif sys.version_info >= (3, 8): +else: @overload def parse_template(source: str, state: _Pattern[Any]) -> _TemplateType: ... @overload def parse_template(source: bytes, state: _Pattern[Any]) -> _TemplateByteType: ... -else: - @overload - def parse_template(source: str, pattern: _Pattern[Any]) -> _TemplateType: ... - @overload - def parse_template(source: bytes, pattern: _Pattern[Any]) -> _TemplateByteType: ... - -if sys.version_info >= (3, 8): - def parse(str: str, flags: int = 0, state: State | None = None) -> SubPattern: ... - -else: - def parse(str: str, flags: int = 0, pattern: Pattern | None = None) -> SubPattern: ... +def parse(str: str, flags: int = 0, state: State | None = None) -> SubPattern: ... if sys.version_info < (3, 12): def expand_template(template: _TemplateType, match: Match[Any]) -> str: ... diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index d7f256d031ac..583ac82750ac 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -3,8 +3,8 @@ import socket import sys from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer from collections.abc import Callable, Iterable -from typing import Any, NamedTuple, overload -from typing_extensions import Literal, Never, Self, TypeAlias, TypedDict, final +from typing import Any, Literal, NamedTuple, TypedDict, final, overload +from typing_extensions import Never, Self, TypeAlias _PCTRTT: TypeAlias = tuple[tuple[str, str], ...] _PCTRTTT: TypeAlias = tuple[_PCTRTT, ...] @@ -199,14 +199,11 @@ class Options(enum.IntFlag): OP_NO_COMPRESSION: int OP_NO_TICKET: int OP_NO_RENEGOTIATION: int - if sys.version_info >= (3, 8): - OP_ENABLE_MIDDLEBOX_COMPAT: int + OP_ENABLE_MIDDLEBOX_COMPAT: int if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: int OP_ENABLE_KTLS: int - if sys.version_info >= (3, 11): - OP_IGNORE_UNEXPECTED_EOF: int - elif sys.version_info >= (3, 8) and sys.platform == "linux": + if sys.version_info >= (3, 11) or sys.platform == "linux": OP_IGNORE_UNEXPECTED_EOF: int OP_ALL: Options @@ -222,14 +219,11 @@ OP_SINGLE_ECDH_USE: Options OP_NO_COMPRESSION: Options OP_NO_TICKET: Options OP_NO_RENEGOTIATION: Options -if sys.version_info >= (3, 8): - OP_ENABLE_MIDDLEBOX_COMPAT: Options +OP_ENABLE_MIDDLEBOX_COMPAT: Options if sys.version_info >= (3, 12): OP_LEGACY_SERVER_CONNECT: Options OP_ENABLE_KTLS: Options -if sys.version_info >= (3, 11): - OP_IGNORE_UNEXPECTED_EOF: Options -elif sys.version_info >= (3, 8) and sys.platform == "linux": +if sys.version_info >= (3, 11) or sys.platform == "linux": OP_IGNORE_UNEXPECTED_EOF: Options HAS_NEVER_CHECK_COMMON_NAME: bool @@ -365,8 +359,7 @@ class SSLSocket(socket.socket): def unwrap(self) -> socket.socket: ... def version(self) -> str | None: ... def pending(self) -> int: ... - if sys.version_info >= (3, 8): - def verify_client_post_handshake(self) -> None: ... + def verify_client_post_handshake(self) -> None: ... # These methods always raise `NotImplementedError`: def recvmsg(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] def recvmsg_into(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] @@ -397,9 +390,8 @@ class SSLContext: # so making these ClassVars wouldn't be appropriate sslobject_class: type[SSLObject] sslsocket_class: type[SSLSocket] - if sys.version_info >= (3, 8): - keylog_filename: str - post_handshake_auth: bool + keylog_filename: str + post_handshake_auth: bool if sys.version_info >= (3, 10): security_level: int if sys.version_info >= (3, 10): @@ -481,8 +473,7 @@ class SSLObject: def unwrap(self) -> None: ... def version(self) -> str | None: ... def get_channel_binding(self, cb_type: str = "tls-unique") -> bytes | None: ... - if sys.version_info >= (3, 8): - def verify_client_post_handshake(self) -> None: ... + def verify_client_post_handshake(self) -> None: ... @final class MemoryBIO: diff --git a/mypy/typeshed/stdlib/statistics.pyi b/mypy/typeshed/stdlib/statistics.pyi index 07174f4531b9..f3f013fc93e7 100644 --- a/mypy/typeshed/stdlib/statistics.pyi +++ b/mypy/typeshed/stdlib/statistics.pyi @@ -3,11 +3,15 @@ from _typeshed import SupportsRichComparisonT from collections.abc import Hashable, Iterable, Sequence from decimal import Decimal from fractions import Fraction -from typing import Any, NamedTuple, SupportsFloat, TypeVar -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Literal, NamedTuple, SupportsFloat, TypeVar +from typing_extensions import Self, TypeAlias __all__ = [ "StatisticsError", + "fmean", + "geometric_mean", + "mean", + "harmonic_mean", "pstdev", "pvariance", "stdev", @@ -16,14 +20,12 @@ __all__ = [ "median_low", "median_high", "median_grouped", - "mean", "mode", - "harmonic_mean", + "multimode", + "NormalDist", + "quantiles", ] -if sys.version_info >= (3, 8): - __all__ += ["geometric_mean", "multimode", "NormalDist", "fmean", "quantiles"] - if sys.version_info >= (3, 10): __all__ += ["covariance", "correlation", "linear_regression"] @@ -39,12 +41,10 @@ class StatisticsError(ValueError): ... if sys.version_info >= (3, 11): def fmean(data: Iterable[SupportsFloat], weights: Iterable[SupportsFloat] | None = None) -> float: ... -elif sys.version_info >= (3, 8): +else: def fmean(data: Iterable[SupportsFloat]) -> float: ... -if sys.version_info >= (3, 8): - def geometric_mean(data: Iterable[SupportsFloat]) -> float: ... - +def geometric_mean(data: Iterable[SupportsFloat]) -> float: ... def mean(data: Iterable[_NumberT]) -> _NumberT: ... if sys.version_info >= (3, 10): @@ -64,56 +64,49 @@ else: def median_grouped(data: Iterable[_NumberT], interval: _NumberT | float = 1) -> _NumberT | float: ... def mode(data: Iterable[_HashableT]) -> _HashableT: ... - -if sys.version_info >= (3, 8): - def multimode(data: Iterable[_HashableT]) -> list[_HashableT]: ... - +def multimode(data: Iterable[_HashableT]) -> list[_HashableT]: ... def pstdev(data: Iterable[_NumberT], mu: _NumberT | None = None) -> _NumberT: ... def pvariance(data: Iterable[_NumberT], mu: _NumberT | None = None) -> _NumberT: ... - -if sys.version_info >= (3, 8): - def quantiles( - data: Iterable[_NumberT], *, n: int = 4, method: Literal["inclusive", "exclusive"] = "exclusive" - ) -> list[_NumberT]: ... - +def quantiles( + data: Iterable[_NumberT], *, n: int = 4, method: Literal["inclusive", "exclusive"] = "exclusive" +) -> list[_NumberT]: ... def stdev(data: Iterable[_NumberT], xbar: _NumberT | None = None) -> _NumberT: ... def variance(data: Iterable[_NumberT], xbar: _NumberT | None = None) -> _NumberT: ... -if sys.version_info >= (3, 8): - class NormalDist: - def __init__(self, mu: float = 0.0, sigma: float = 1.0) -> None: ... - @property - def mean(self) -> float: ... - @property - def median(self) -> float: ... - @property - def mode(self) -> float: ... - @property - def stdev(self) -> float: ... - @property - def variance(self) -> float: ... - @classmethod - def from_samples(cls, data: Iterable[SupportsFloat]) -> Self: ... - def samples(self, n: int, *, seed: Any | None = None) -> list[float]: ... - def pdf(self, x: float) -> float: ... - def cdf(self, x: float) -> float: ... - def inv_cdf(self, p: float) -> float: ... - def overlap(self, other: NormalDist) -> float: ... - def quantiles(self, n: int = 4) -> list[float]: ... - if sys.version_info >= (3, 9): - def zscore(self, x: float) -> float: ... - - def __eq__(self, x2: object) -> bool: ... - def __add__(self, x2: float | NormalDist) -> NormalDist: ... - def __sub__(self, x2: float | NormalDist) -> NormalDist: ... - def __mul__(self, x2: float) -> NormalDist: ... - def __truediv__(self, x2: float) -> NormalDist: ... - def __pos__(self) -> NormalDist: ... - def __neg__(self) -> NormalDist: ... - __radd__ = __add__ - def __rsub__(self, x2: float | NormalDist) -> NormalDist: ... - __rmul__ = __mul__ - def __hash__(self) -> int: ... +class NormalDist: + def __init__(self, mu: float = 0.0, sigma: float = 1.0) -> None: ... + @property + def mean(self) -> float: ... + @property + def median(self) -> float: ... + @property + def mode(self) -> float: ... + @property + def stdev(self) -> float: ... + @property + def variance(self) -> float: ... + @classmethod + def from_samples(cls, data: Iterable[SupportsFloat]) -> Self: ... + def samples(self, n: int, *, seed: Any | None = None) -> list[float]: ... + def pdf(self, x: float) -> float: ... + def cdf(self, x: float) -> float: ... + def inv_cdf(self, p: float) -> float: ... + def overlap(self, other: NormalDist) -> float: ... + def quantiles(self, n: int = 4) -> list[float]: ... + if sys.version_info >= (3, 9): + def zscore(self, x: float) -> float: ... + + def __eq__(self, x2: object) -> bool: ... + def __add__(self, x2: float | NormalDist) -> NormalDist: ... + def __sub__(self, x2: float | NormalDist) -> NormalDist: ... + def __mul__(self, x2: float) -> NormalDist: ... + def __truediv__(self, x2: float) -> NormalDist: ... + def __pos__(self) -> NormalDist: ... + def __neg__(self) -> NormalDist: ... + __radd__ = __add__ + def __rsub__(self, x2: float | NormalDist) -> NormalDist: ... + __rmul__ = __mul__ + def __hash__(self) -> int: ... if sys.version_info >= (3, 12): def correlation( diff --git a/mypy/typeshed/stdlib/subprocess.pyi b/mypy/typeshed/stdlib/subprocess.pyi index b89623f05c99..df1db5c82eea 100644 --- a/mypy/typeshed/stdlib/subprocess.pyi +++ b/mypy/typeshed/stdlib/subprocess.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import ReadableBuffer, StrOrBytesPath from collections.abc import Callable, Collection, Iterable, Mapping, Sequence from types import TracebackType -from typing import IO, Any, AnyStr, Generic, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, AnyStr, Generic, Literal, TypeVar, overload +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -64,12 +64,7 @@ if sys.platform == "win32": # reveal_type(e.cmd) # Any, but morally is _CMD _FILE: TypeAlias = None | int | IO[Any] _InputString: TypeAlias = ReadableBuffer | str -if sys.version_info >= (3, 8): - _CMD: TypeAlias = StrOrBytesPath | Sequence[StrOrBytesPath] -else: - # Python 3.7 doesn't support _CMD being a single PathLike. - # See: https://bugs.python.org/issue31961 - _CMD: TypeAlias = str | bytes | Sequence[StrOrBytesPath] +_CMD: TypeAlias = StrOrBytesPath | Sequence[StrOrBytesPath] if sys.platform == "win32": _ENV: TypeAlias = Mapping[str, str] else: @@ -80,8 +75,7 @@ _T = TypeVar("_T") # These two are private but documented if sys.version_info >= (3, 11): _USE_VFORK: bool -if sys.version_info >= (3, 8): - _USE_POSIX_SPAWN: bool +_USE_POSIX_SPAWN: bool class CompletedProcess(Generic[_T]): # morally: _CMD @@ -2577,11 +2571,7 @@ else: def getstatusoutput(cmd: str | bytes) -> tuple[int, str]: ... def getoutput(cmd: str | bytes) -> str: ... -if sys.version_info >= (3, 8): - def list2cmdline(seq: Iterable[StrOrBytesPath]) -> str: ... # undocumented - -else: - def list2cmdline(seq: Iterable[str]) -> str: ... # undocumented +def list2cmdline(seq: Iterable[StrOrBytesPath]) -> str: ... # undocumented if sys.platform == "win32": class STARTUPINFO: diff --git a/mypy/typeshed/stdlib/sunau.pyi b/mypy/typeshed/stdlib/sunau.pyi index b508a1ea8e20..9b051e82b64b 100644 --- a/mypy/typeshed/stdlib/sunau.pyi +++ b/mypy/typeshed/stdlib/sunau.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import Unused -from typing import IO, Any, NamedTuple, NoReturn, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Any, Literal, NamedTuple, NoReturn, overload +from typing_extensions import Self, TypeAlias _File: TypeAlias = str | IO[bytes] diff --git a/mypy/typeshed/stdlib/symbol.pyi b/mypy/typeshed/stdlib/symbol.pyi index bb6660374d16..48ae3567a1a5 100644 --- a/mypy/typeshed/stdlib/symbol.pyi +++ b/mypy/typeshed/stdlib/symbol.pyi @@ -1,5 +1,3 @@ -import sys - single_input: int file_input: int eval_input: int @@ -87,11 +85,9 @@ encoding_decl: int yield_expr: int yield_arg: int sync_comp_for: int -if sys.version_info >= (3, 8): - func_body_suite: int - func_type: int - func_type_input: int - namedexpr_test: int - typelist: int - +func_body_suite: int +func_type: int +func_type_input: int +namedexpr_test: int +typelist: int sym_name: dict[int, str] diff --git a/mypy/typeshed/stdlib/symtable.pyi b/mypy/typeshed/stdlib/symtable.pyi index 304ae8bf8126..0f080954ba2c 100644 --- a/mypy/typeshed/stdlib/symtable.pyi +++ b/mypy/typeshed/stdlib/symtable.pyi @@ -29,21 +29,16 @@ class Function(SymbolTable): def get_locals(self) -> tuple[str, ...]: ... def get_globals(self) -> tuple[str, ...]: ... def get_frees(self) -> tuple[str, ...]: ... - if sys.version_info >= (3, 8): - def get_nonlocals(self) -> tuple[str, ...]: ... + def get_nonlocals(self) -> tuple[str, ...]: ... class Class(SymbolTable): def get_methods(self) -> tuple[str, ...]: ... class Symbol: - if sys.version_info >= (3, 8): - def __init__( - self, name: str, flags: int, namespaces: Sequence[SymbolTable] | None = None, *, module_scope: bool = False - ) -> None: ... - def is_nonlocal(self) -> bool: ... - else: - def __init__(self, name: str, flags: int, namespaces: Sequence[SymbolTable] | None = None) -> None: ... - + def __init__( + self, name: str, flags: int, namespaces: Sequence[SymbolTable] | None = None, *, module_scope: bool = False + ) -> None: ... + def is_nonlocal(self) -> bool: ... def get_name(self) -> str: ... def is_referenced(self) -> bool: ... def is_parameter(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/sys/__init__.pyi b/mypy/typeshed/stdlib/sys/__init__.pyi index 1d4111af3a49..2f847498214b 100644 --- a/mypy/typeshed/stdlib/sys/__init__.pyi +++ b/mypy/typeshed/stdlib/sys/__init__.pyi @@ -1,13 +1,13 @@ import sys from _typeshed import OptExcInfo, ProfileFunction, TraceFunction, structseq from builtins import object as _object -from collections.abc import AsyncGenerator, Callable, Coroutine, Sequence +from collections.abc import AsyncGenerator, Callable, Sequence from importlib.abc import PathEntryFinder from importlib.machinery import ModuleSpec from io import TextIOWrapper from types import FrameType, ModuleType, TracebackType -from typing import Any, NoReturn, Protocol, TextIO, TypeVar -from typing_extensions import Final, Literal, TypeAlias, final +from typing import Any, Final, Literal, NoReturn, Protocol, TextIO, TypeVar, final +from typing_extensions import TypeAlias _T = TypeVar("_T") @@ -55,8 +55,7 @@ platform: str if sys.version_info >= (3, 9): platlibdir: str prefix: str -if sys.version_info >= (3, 8): - pycache_prefix: str | None +pycache_prefix: str | None ps1: object ps2: object @@ -322,18 +321,19 @@ if sys.version_info < (3, 9): # An 11-tuple or None def callstats() -> tuple[int, int, int, int, int, int, int, int, int, int, int] | None: ... -if sys.version_info >= (3, 8): - # Doesn't exist at runtime, but exported in the stubs so pytest etc. can annotate their code more easily. - class UnraisableHookArgs(Protocol): - exc_type: type[BaseException] - exc_value: BaseException | None - exc_traceback: TracebackType | None - err_msg: str | None - object: _object - unraisablehook: Callable[[UnraisableHookArgs], Any] - def __unraisablehook__(__unraisable: UnraisableHookArgs) -> Any: ... - def addaudithook(hook: Callable[[str, tuple[Any, ...]], Any]) -> None: ... - def audit(__event: str, *args: Any) -> None: ... +# Doesn't exist at runtime, but exported in the stubs so pytest etc. can annotate their code more easily. +class UnraisableHookArgs(Protocol): + exc_type: type[BaseException] + exc_value: BaseException | None + exc_traceback: TracebackType | None + err_msg: str | None + object: _object + +unraisablehook: Callable[[UnraisableHookArgs], Any] + +def __unraisablehook__(__unraisable: UnraisableHookArgs) -> Any: ... +def addaudithook(hook: Callable[[str, tuple[Any, ...]], Any]) -> None: ... +def audit(__event: str, *args: Any) -> None: ... _AsyncgenHook: TypeAlias = Callable[[AsyncGenerator[Any, Any]], None] | None @@ -353,12 +353,7 @@ if sys.platform == "win32": def get_coroutine_origin_tracking_depth() -> int: ... def set_coroutine_origin_tracking_depth(depth: int) -> None: ... -if sys.version_info < (3, 8): - _CoroWrapper: TypeAlias = Callable[[Coroutine[Any, Any, Any]], Any] - def set_coroutine_wrapper(__wrapper: _CoroWrapper) -> None: ... - def get_coroutine_wrapper() -> _CoroWrapper: ... - -# The following two functions were added in 3.11.0, 3.10.7, 3.9.14, 3.8.14, & 3.7.14, +# The following two functions were added in 3.11.0, 3.10.7, 3.9.14, and 3.8.14, # as part of the response to CVE-2020-10735 def set_int_max_str_digits(maxdigits: int) -> None: ... def get_int_max_str_digits() -> int: ... diff --git a/mypy/typeshed/stdlib/sysconfig.pyi b/mypy/typeshed/stdlib/sysconfig.pyi index 7e29cf1326d6..2edb71d78cdd 100644 --- a/mypy/typeshed/stdlib/sysconfig.pyi +++ b/mypy/typeshed/stdlib/sysconfig.pyi @@ -1,6 +1,5 @@ import sys -from typing import IO, Any, overload -from typing_extensions import Literal +from typing import IO, Any, Literal, overload __all__ = [ "get_config_h_filename", diff --git a/mypy/typeshed/stdlib/syslog.pyi b/mypy/typeshed/stdlib/syslog.pyi index 0b769301a482..164334f60a6f 100644 --- a/mypy/typeshed/stdlib/syslog.pyi +++ b/mypy/typeshed/stdlib/syslog.pyi @@ -1,6 +1,5 @@ import sys -from typing import overload -from typing_extensions import Literal +from typing import Literal, overload if sys.platform != "win32": LOG_ALERT: Literal[1] diff --git a/mypy/typeshed/stdlib/tarfile.pyi b/mypy/typeshed/stdlib/tarfile.pyi index d9d9641ac698..0bfd91ce2161 100644 --- a/mypy/typeshed/stdlib/tarfile.pyi +++ b/mypy/typeshed/stdlib/tarfile.pyi @@ -6,8 +6,8 @@ from builtins import list as _list # aliases to avoid name clashes with fields from collections.abc import Callable, Iterable, Iterator, Mapping from gzip import _ReadableFileobj as _GzipReadableFileobj, _WritableFileobj as _GzipWritableFileobj from types import TracebackType -from typing import IO, ClassVar, Protocol, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, ClassVar, Literal, Protocol, overload +from typing_extensions import Self, TypeAlias __all__ = [ "TarFile", @@ -119,6 +119,7 @@ def open( debug: int | None = ..., errorlevel: int | None = ..., compresslevel: int | None = ..., + preset: Literal[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None = ..., ) -> TarFile: ... class ExFileObject(io.BufferedReader): @@ -291,32 +292,23 @@ class TarFile: def getnames(self) -> _list[str]: ... def list(self, verbose: bool = True, *, members: _list[TarInfo] | None = None) -> None: ... def next(self) -> TarInfo | None: ... - if sys.version_info >= (3, 8): - def extractall( - self, - path: StrOrBytesPath = ".", - members: Iterable[TarInfo] | None = None, - *, - numeric_owner: bool = False, - filter: _TarfileFilter | None = ..., - ) -> None: ... - def extract( - self, - member: str | TarInfo, - path: StrOrBytesPath = "", - set_attrs: bool = True, - *, - numeric_owner: bool = False, - filter: _TarfileFilter | None = ..., - ) -> None: ... - else: - def extractall( - self, path: StrOrBytesPath = ".", members: Iterable[TarInfo] | None = None, *, numeric_owner: bool = False - ) -> None: ... - def extract( - self, member: str | TarInfo, path: StrOrBytesPath = "", set_attrs: bool = True, *, numeric_owner: bool = False - ) -> None: ... - + def extractall( + self, + path: StrOrBytesPath = ".", + members: Iterable[TarInfo] | None = None, + *, + numeric_owner: bool = False, + filter: _TarfileFilter | None = ..., + ) -> None: ... + def extract( + self, + member: str | TarInfo, + path: StrOrBytesPath = "", + set_attrs: bool = True, + *, + numeric_owner: bool = False, + filter: _TarfileFilter | None = ..., + ) -> None: ... def _extract_member( self, tarinfo: TarInfo, targetpath: str, set_attrs: bool = True, numeric_owner: bool = False ) -> None: ... # undocumented @@ -350,9 +342,6 @@ if sys.version_info >= (3, 9): else: def is_tarfile(name: StrOrBytesPath) -> bool: ... -if sys.version_info < (3, 8): - def filemode(mode: int) -> str: ... # undocumented - class TarError(Exception): ... class ReadError(TarError): ... class CompressionError(TarError): ... @@ -360,30 +349,29 @@ class StreamError(TarError): ... class ExtractError(TarError): ... class HeaderError(TarError): ... -if sys.version_info >= (3, 8): - class FilterError(TarError): - # This attribute is only set directly on the subclasses, but the documentation guarantees - # that it is always present on FilterError. - tarinfo: TarInfo +class FilterError(TarError): + # This attribute is only set directly on the subclasses, but the documentation guarantees + # that it is always present on FilterError. + tarinfo: TarInfo - class AbsolutePathError(FilterError): - def __init__(self, tarinfo: TarInfo) -> None: ... +class AbsolutePathError(FilterError): + def __init__(self, tarinfo: TarInfo) -> None: ... - class OutsideDestinationError(FilterError): - def __init__(self, tarinfo: TarInfo, path: str) -> None: ... +class OutsideDestinationError(FilterError): + def __init__(self, tarinfo: TarInfo, path: str) -> None: ... - class SpecialFileError(FilterError): - def __init__(self, tarinfo: TarInfo) -> None: ... +class SpecialFileError(FilterError): + def __init__(self, tarinfo: TarInfo) -> None: ... - class AbsoluteLinkError(FilterError): - def __init__(self, tarinfo: TarInfo) -> None: ... +class AbsoluteLinkError(FilterError): + def __init__(self, tarinfo: TarInfo) -> None: ... - class LinkOutsideDestinationError(FilterError): - def __init__(self, tarinfo: TarInfo, path: str) -> None: ... +class LinkOutsideDestinationError(FilterError): + def __init__(self, tarinfo: TarInfo, path: str) -> None: ... - def fully_trusted_filter(member: TarInfo, dest_path: str) -> TarInfo: ... - def tar_filter(member: TarInfo, dest_path: str) -> TarInfo: ... - def data_filter(member: TarInfo, dest_path: str) -> TarInfo: ... +def fully_trusted_filter(member: TarInfo, dest_path: str) -> TarInfo: ... +def tar_filter(member: TarInfo, dest_path: str) -> TarInfo: ... +def data_filter(member: TarInfo, dest_path: str) -> TarInfo: ... class TarInfo: name: str @@ -414,27 +402,21 @@ class TarInfo: def linkpath(self) -> str: ... @linkpath.setter def linkpath(self, linkname: str) -> None: ... - if sys.version_info >= (3, 8): - def replace( - self, - *, - name: str = ..., - mtime: int = ..., - mode: int = ..., - linkname: str = ..., - uid: int = ..., - gid: int = ..., - uname: str = ..., - gname: str = ..., - deep: bool = True, - ) -> Self: ... - + def replace( + self, + *, + name: str = ..., + mtime: int = ..., + mode: int = ..., + linkname: str = ..., + uid: int = ..., + gid: int = ..., + uname: str = ..., + gname: str = ..., + deep: bool = True, + ) -> Self: ... def get_info(self) -> Mapping[str, str | int | bytes | Mapping[str, str]]: ... - if sys.version_info >= (3, 8): - def tobuf(self, format: int | None = 2, encoding: str | None = "utf-8", errors: str = "surrogateescape") -> bytes: ... - else: - def tobuf(self, format: int | None = 1, encoding: str | None = "utf-8", errors: str = "surrogateescape") -> bytes: ... - + def tobuf(self, format: int | None = 2, encoding: str | None = "utf-8", errors: str = "surrogateescape") -> bytes: ... def create_ustar_header( self, info: Mapping[str, str | int | bytes | Mapping[str, str]], encoding: str, errors: str ) -> bytes: ... diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index 628f99410732..2c4b548458ea 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -14,8 +14,8 @@ from _typeshed import ( ) from collections.abc import Iterable, Iterator from types import TracebackType -from typing import IO, Any, AnyStr, Generic, overload -from typing_extensions import Literal, Self +from typing import IO, Any, AnyStr, Generic, Literal, overload +from typing_extensions import Self if sys.version_info >= (3, 9): from types import GenericAlias @@ -85,7 +85,7 @@ if sys.version_info >= (3, 12): delete_on_close: bool = True, ) -> _TemporaryFileWrapper[Any]: ... -elif sys.version_info >= (3, 8): +else: @overload def NamedTemporaryFile( mode: OpenTextMode, @@ -126,9 +126,12 @@ elif sys.version_info >= (3, 8): errors: str | None = None, ) -> _TemporaryFileWrapper[Any]: ... +if sys.platform == "win32": + TemporaryFile = NamedTemporaryFile else: + # See the comments for builtins.open() for an explanation of the overloads. @overload - def NamedTemporaryFile( + def TemporaryFile( mode: OpenTextMode, buffering: int = -1, encoding: str | None = None, @@ -136,21 +139,70 @@ else: suffix: AnyStr | None = None, prefix: AnyStr | None = None, dir: GenericPath[AnyStr] | None = None, - delete: bool = True, - ) -> _TemporaryFileWrapper[str]: ... + *, + errors: str | None = None, + ) -> io.TextIOWrapper: ... @overload - def NamedTemporaryFile( - mode: OpenBinaryMode = "w+b", - buffering: int = -1, + def TemporaryFile( + mode: OpenBinaryMode, + buffering: Literal[0], encoding: str | None = None, newline: str | None = None, suffix: AnyStr | None = None, prefix: AnyStr | None = None, dir: GenericPath[AnyStr] | None = None, - delete: bool = True, - ) -> _TemporaryFileWrapper[bytes]: ... + *, + errors: str | None = None, + ) -> io.FileIO: ... @overload - def NamedTemporaryFile( + def TemporaryFile( + *, + buffering: Literal[0], + encoding: str | None = None, + newline: str | None = None, + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: GenericPath[AnyStr] | None = None, + errors: str | None = None, + ) -> io.FileIO: ... + @overload + def TemporaryFile( + mode: OpenBinaryModeWriting, + buffering: Literal[-1, 1] = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: GenericPath[AnyStr] | None = None, + *, + errors: str | None = None, + ) -> io.BufferedWriter: ... + @overload + def TemporaryFile( + mode: OpenBinaryModeReading, + buffering: Literal[-1, 1] = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: GenericPath[AnyStr] | None = None, + *, + errors: str | None = None, + ) -> io.BufferedReader: ... + @overload + def TemporaryFile( + mode: OpenBinaryModeUpdating = "w+b", + buffering: Literal[-1, 1] = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: AnyStr | None = None, + prefix: AnyStr | None = None, + dir: GenericPath[AnyStr] | None = None, + *, + errors: str | None = None, + ) -> io.BufferedRandom: ... + @overload + def TemporaryFile( mode: str = "w+b", buffering: int = -1, encoding: str | None = None, @@ -158,168 +210,9 @@ else: suffix: AnyStr | None = None, prefix: AnyStr | None = None, dir: GenericPath[AnyStr] | None = None, - delete: bool = True, - ) -> _TemporaryFileWrapper[Any]: ... - -if sys.platform == "win32": - TemporaryFile = NamedTemporaryFile -else: - # See the comments for builtins.open() for an explanation of the overloads. - if sys.version_info >= (3, 8): - @overload - def TemporaryFile( - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> io.TextIOWrapper: ... - @overload - def TemporaryFile( - mode: OpenBinaryMode, - buffering: Literal[0], - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> io.FileIO: ... - @overload - def TemporaryFile( - *, - buffering: Literal[0], - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - errors: str | None = None, - ) -> io.FileIO: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeWriting, - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> io.BufferedWriter: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeReading, - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> io.BufferedReader: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeUpdating = "w+b", - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> io.BufferedRandom: ... - @overload - def TemporaryFile( - mode: str = "w+b", - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - *, - errors: str | None = None, - ) -> IO[Any]: ... - else: - @overload - def TemporaryFile( - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.TextIOWrapper: ... - @overload - def TemporaryFile( - mode: OpenBinaryMode, - buffering: Literal[0], - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.FileIO: ... - @overload - def TemporaryFile( - *, - buffering: Literal[0], - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.FileIO: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeUpdating = "w+b", - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.BufferedRandom: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeWriting, - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.BufferedWriter: ... - @overload - def TemporaryFile( - mode: OpenBinaryModeReading, - buffering: Literal[-1, 1] = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> io.BufferedReader: ... - @overload - def TemporaryFile( - mode: str = "w+b", - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: AnyStr | None = None, - prefix: AnyStr | None = None, - dir: GenericPath[AnyStr] | None = None, - ) -> IO[Any]: ... + *, + errors: str | None = None, + ) -> IO[Any]: ... class _TemporaryFileWrapper(IO[AnyStr]): file: IO[AnyStr] # io.TextIOWrapper, io.BufferedReader or io.BufferedWriter @@ -386,143 +279,78 @@ class SpooledTemporaryFile(IO[AnyStr], _SpooledTemporaryFileBase): @property def newlines(self) -> str | tuple[str, ...] | None: ... # undocumented # bytes needs to go first, as default mode is to open as bytes - if sys.version_info >= (3, 8): - @overload - def __init__( - self: SpooledTemporaryFile[bytes], - max_size: int = 0, - mode: OpenBinaryMode = "w+b", - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - *, - errors: str | None = None, - ) -> None: ... - @overload - def __init__( - self: SpooledTemporaryFile[str], - max_size: int, - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - *, - errors: str | None = None, - ) -> None: ... - @overload - def __init__( - self: SpooledTemporaryFile[str], - max_size: int = 0, - *, - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - errors: str | None = None, - ) -> None: ... - @overload - def __init__( - self, - max_size: int, - mode: str, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - *, - errors: str | None = None, - ) -> None: ... - @overload - def __init__( - self, - max_size: int = 0, - *, - mode: str, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - errors: str | None = None, - ) -> None: ... - @property - def errors(self) -> str | None: ... - else: - @overload - def __init__( - self: SpooledTemporaryFile[bytes], - max_size: int = 0, - mode: OpenBinaryMode = "w+b", - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - ) -> None: ... - @overload - def __init__( - self: SpooledTemporaryFile[str], - max_size: int, - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - ) -> None: ... - @overload - def __init__( - self: SpooledTemporaryFile[str], - max_size: int = 0, - *, - mode: OpenTextMode, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - ) -> None: ... - @overload - def __init__( - self, - max_size: int, - mode: str, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - ) -> None: ... - @overload - def __init__( - self, - max_size: int = 0, - *, - mode: str, - buffering: int = -1, - encoding: str | None = None, - newline: str | None = None, - suffix: str | None = None, - prefix: str | None = None, - dir: str | None = None, - ) -> None: ... - + @overload + def __init__( + self: SpooledTemporaryFile[bytes], + max_size: int = 0, + mode: OpenBinaryMode = "w+b", + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ) -> None: ... + @overload + def __init__( + self: SpooledTemporaryFile[str], + max_size: int, + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ) -> None: ... + @overload + def __init__( + self: SpooledTemporaryFile[str], + max_size: int = 0, + *, + mode: OpenTextMode, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + errors: str | None = None, + ) -> None: ... + @overload + def __init__( + self, + max_size: int, + mode: str, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + *, + errors: str | None = None, + ) -> None: ... + @overload + def __init__( + self, + max_size: int = 0, + *, + mode: str, + buffering: int = -1, + encoding: str | None = None, + newline: str | None = None, + suffix: str | None = None, + prefix: str | None = None, + dir: str | None = None, + errors: str | None = None, + ) -> None: ... + @property + def errors(self) -> str | None: ... def rollover(self) -> None: ... def __enter__(self) -> Self: ... def __exit__(self, exc: type[BaseException] | None, value: BaseException | None, tb: TracebackType | None) -> None: ... diff --git a/mypy/typeshed/stdlib/threading.pyi b/mypy/typeshed/stdlib/threading.pyi index bcd73823c63f..90b6cabb5237 100644 --- a/mypy/typeshed/stdlib/threading.pyi +++ b/mypy/typeshed/stdlib/threading.pyi @@ -1,10 +1,10 @@ import _thread import sys +from _thread import _excepthook, _ExceptHookArgs, get_native_id as get_native_id from _typeshed import ProfileFunction, TraceFunction from collections.abc import Callable, Iterable, Mapping from types import TracebackType -from typing import Any, TypeVar -from typing_extensions import final +from typing import Any, TypeVar, final _T = TypeVar("_T") @@ -26,15 +26,15 @@ __all__ = [ "BrokenBarrierError", "Timer", "ThreadError", + "ExceptHookArgs", "setprofile", "settrace", "local", "stack_size", + "excepthook", + "get_native_id", ] -if sys.version_info >= (3, 8): - __all__ += ["ExceptHookArgs", "excepthook", "get_native_id"] - if sys.version_info >= (3, 10): __all__ += ["getprofile", "gettrace"] @@ -50,10 +50,6 @@ def currentThread() -> Thread: ... # deprecated alias for current_thread() def get_ident() -> int: ... def enumerate() -> list[Thread]: ... def main_thread() -> Thread: ... - -if sys.version_info >= (3, 8): - from _thread import get_native_id as get_native_id - def settrace(func: TraceFunction) -> None: ... def setprofile(func: ProfileFunction | None) -> None: ... @@ -90,10 +86,8 @@ class Thread: def start(self) -> None: ... def run(self) -> None: ... def join(self, timeout: float | None = None) -> None: ... - if sys.version_info >= (3, 8): - @property - def native_id(self) -> int | None: ... # only available on some platforms - + @property + def native_id(self) -> int | None: ... # only available on some platforms def is_alive(self) -> bool: ... if sys.version_info < (3, 9): def isAlive(self) -> bool: ... @@ -159,11 +153,8 @@ class Event: def clear(self) -> None: ... def wait(self, timeout: float | None = None) -> bool: ... -if sys.version_info >= (3, 8): - from _thread import _excepthook, _ExceptHookArgs - - excepthook = _excepthook - ExceptHookArgs = _ExceptHookArgs +excepthook = _excepthook +ExceptHookArgs = _ExceptHookArgs class Timer(Thread): args: Iterable[Any] # undocumented diff --git a/mypy/typeshed/stdlib/time.pyi b/mypy/typeshed/stdlib/time.pyi index 035d78934f3a..28752bddc4dd 100644 --- a/mypy/typeshed/stdlib/time.pyi +++ b/mypy/typeshed/stdlib/time.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import structseq -from typing import Any, Protocol -from typing_extensions import Final, Literal, TypeAlias, final +from typing import Any, Final, Literal, Protocol, final +from typing_extensions import TypeAlias _TimeTuple: TypeAlias = tuple[int, int, int, int, int, int, int, int, int] @@ -25,7 +25,7 @@ if sys.platform != "win32": if sys.platform != "linux" and sys.platform != "darwin": CLOCK_HIGHRES: int # Solaris only -if sys.version_info >= (3, 8) and sys.platform == "darwin": +if sys.platform == "darwin": CLOCK_UPTIME_RAW: int if sys.version_info >= (3, 9) and sys.platform == "linux": @@ -63,18 +63,14 @@ class struct_time(structseq[Any | int], _TimeTuple): @property def tm_gmtoff(self) -> int: ... -def asctime(t: _TimeTuple | struct_time = ...) -> str: ... - -if sys.version_info < (3, 8): - def clock() -> float: ... - -def ctime(secs: float | None = ...) -> str: ... -def gmtime(secs: float | None = ...) -> struct_time: ... -def localtime(secs: float | None = ...) -> struct_time: ... -def mktime(t: _TimeTuple | struct_time) -> float: ... -def sleep(secs: float) -> None: ... -def strftime(format: str, t: _TimeTuple | struct_time = ...) -> str: ... -def strptime(string: str, format: str = ...) -> struct_time: ... +def asctime(time_tuple: _TimeTuple | struct_time = ..., /) -> str: ... +def ctime(seconds: float | None = None, /) -> str: ... +def gmtime(seconds: float | None = None, /) -> struct_time: ... +def localtime(seconds: float | None = None, /) -> struct_time: ... +def mktime(time_tuple: _TimeTuple | struct_time, /) -> float: ... +def sleep(seconds: float, /) -> None: ... +def strftime(format: str, time_tuple: _TimeTuple | struct_time = ..., /) -> str: ... +def strptime(data_string: str, format: str = "%a %b %d %H:%M:%S %Y", /) -> struct_time: ... def time() -> float: ... if sys.platform != "win32": @@ -86,22 +82,22 @@ class _ClockInfo(Protocol): monotonic: bool resolution: float -def get_clock_info(name: Literal["monotonic", "perf_counter", "process_time", "time", "thread_time"]) -> _ClockInfo: ... +def get_clock_info(name: Literal["monotonic", "perf_counter", "process_time", "time", "thread_time"], /) -> _ClockInfo: ... def monotonic() -> float: ... def perf_counter() -> float: ... def process_time() -> float: ... if sys.platform != "win32": - def clock_getres(clk_id: int) -> float: ... # Unix only - def clock_gettime(clk_id: int) -> float: ... # Unix only - def clock_settime(clk_id: int, time: float) -> None: ... # Unix only + def clock_getres(clk_id: int, /) -> float: ... # Unix only + def clock_gettime(clk_id: int, /) -> float: ... # Unix only + def clock_settime(clk_id: int, time: float, /) -> None: ... # Unix only if sys.platform != "win32": - def clock_gettime_ns(clock_id: int) -> int: ... - def clock_settime_ns(clock_id: int, time: int) -> int: ... + def clock_gettime_ns(clock_id: int, /) -> int: ... + def clock_settime_ns(clock_id: int, time: int, /) -> int: ... if sys.platform == "linux": - def pthread_getcpuclockid(thread_id: int) -> int: ... + def pthread_getcpuclockid(thread_id: int, /) -> int: ... def monotonic_ns() -> int: ... def perf_counter_ns() -> int: ... diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index 5f7c3cb4527d..ff876d0bb88c 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -5,8 +5,8 @@ from collections.abc import Callable, Mapping, Sequence from tkinter.constants import * from tkinter.font import _FontDescription from types import TracebackType -from typing import Any, Generic, NamedTuple, TypeVar, overload, type_check_only -from typing_extensions import Literal, TypeAlias, TypedDict, TypeVarTuple, Unpack, deprecated +from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, overload, type_check_only +from typing_extensions import TypeAlias, TypeVarTuple, Unpack, deprecated if sys.version_info >= (3, 9): __all__ = [ @@ -1254,7 +1254,7 @@ class Canvas(Widget, XView, YView): offset: _ScreenUnits = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1283,7 +1283,7 @@ class Canvas(Widget, XView, YView): offset: _ScreenUnits = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1318,7 +1318,7 @@ class Canvas(Widget, XView, YView): offset: _ScreenUnits = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1350,7 +1350,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1380,7 +1380,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1416,7 +1416,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1451,7 +1451,7 @@ class Canvas(Widget, XView, YView): outlinestipple: str = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1484,7 +1484,7 @@ class Canvas(Widget, XView, YView): outlinestipple: str = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1523,7 +1523,7 @@ class Canvas(Widget, XView, YView): outlinestipple: str = ..., smooth: bool = ..., splinesteps: float = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1555,7 +1555,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1585,7 +1585,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1621,7 +1621,7 @@ class Canvas(Widget, XView, YView): outline: str = ..., outlineoffset: _ScreenUnits = ..., outlinestipple: str = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., @@ -1642,7 +1642,7 @@ class Canvas(Widget, XView, YView): font: _FontDescription = ..., justify: Literal["left", "center", "right"] = ..., offset: _ScreenUnits = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., text: float | str = ..., @@ -1663,7 +1663,7 @@ class Canvas(Widget, XView, YView): font: _FontDescription = ..., justify: Literal["left", "center", "right"] = ..., offset: _ScreenUnits = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., stipple: str = ..., tags: str | list[str] | tuple[str, ...] = ..., text: float | str = ..., @@ -1677,7 +1677,7 @@ class Canvas(Widget, XView, YView): *, anchor: _Anchor = ..., height: _ScreenUnits = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., window: Widget = ..., @@ -1689,7 +1689,7 @@ class Canvas(Widget, XView, YView): *, anchor: _Anchor = ..., height: _ScreenUnits = ..., - state: Literal["normal", "active", "disabled"] = ..., + state: Literal["normal", "hidden", "disabled"] = ..., tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., window: Widget = ..., @@ -1712,9 +1712,7 @@ class Canvas(Widget, XView, YView): ) -> dict[str, tuple[str, str, str, str, str]] | None: ... itemconfig = itemconfigure def move(self, *args) -> None: ... - if sys.version_info >= (3, 8): - def moveto(self, tagOrId: str | int, x: Literal[""] | float = "", y: Literal[""] | float = "") -> None: ... - + def moveto(self, tagOrId: str | int, x: Literal[""] | float = "", y: Literal[""] | float = "") -> None: ... def postscript(self, cnf={}, **kw): ... # tkinter does: # lower = tag_lower @@ -3338,9 +3336,8 @@ class PhotoImage(Image, _PhotoImageLike): to: tuple[int, int] | None = None, ) -> None: ... def write(self, filename: StrOrBytesPath, format: str | None = None, from_coords: tuple[int, int] | None = None) -> None: ... - if sys.version_info >= (3, 8): - def transparency_get(self, x: int, y: int) -> bool: ... - def transparency_set(self, x: int, y: int, boolean: bool) -> None: ... + def transparency_get(self, x: int, y: int) -> bool: ... + def transparency_set(self, x: int, y: int, boolean: bool) -> None: ... class BitmapImage(Image, _BitmapImageLike): # This should be kept in sync with PIL.ImageTK.BitmapImage.__init__() @@ -3495,11 +3492,10 @@ class Spinbox(Widget, XView): def selection_adjust(self, index): ... def selection_clear(self): ... def selection_element(self, element: Incomplete | None = None): ... - if sys.version_info >= (3, 8): - def selection_from(self, index: int) -> None: ... - def selection_present(self) -> None: ... - def selection_range(self, start: int, end: int) -> None: ... - def selection_to(self, index: int) -> None: ... + def selection_from(self, index: int) -> None: ... + def selection_present(self) -> None: ... + def selection_range(self, start: int, end: int) -> None: ... + def selection_to(self, index: int) -> None: ... class LabelFrame(Widget): def __init__( diff --git a/mypy/typeshed/stdlib/tkinter/constants.pyi b/mypy/typeshed/stdlib/tkinter/constants.pyi index 1383b0f9bf4b..74fa72acb0bf 100644 --- a/mypy/typeshed/stdlib/tkinter/constants.pyi +++ b/mypy/typeshed/stdlib/tkinter/constants.pyi @@ -1,4 +1,4 @@ -from typing_extensions import Literal +from typing import Literal # These are not actually bools. See #4669 NO: bool diff --git a/mypy/typeshed/stdlib/tkinter/filedialog.pyi b/mypy/typeshed/stdlib/tkinter/filedialog.pyi index 10b36e4d3c06..3d62f079178e 100644 --- a/mypy/typeshed/stdlib/tkinter/filedialog.pyi +++ b/mypy/typeshed/stdlib/tkinter/filedialog.pyi @@ -2,8 +2,7 @@ import sys from _typeshed import Incomplete, StrOrBytesPath from collections.abc import Iterable from tkinter import Button, Entry, Frame, Listbox, Misc, Scrollbar, StringVar, Toplevel, commondialog -from typing import IO, ClassVar -from typing_extensions import Literal +from typing import IO, ClassVar, Literal if sys.version_info >= (3, 9): __all__ = [ diff --git a/mypy/typeshed/stdlib/tkinter/font.pyi b/mypy/typeshed/stdlib/tkinter/font.pyi index 9dffcd1ba0c6..448e2b0054a5 100644 --- a/mypy/typeshed/stdlib/tkinter/font.pyi +++ b/mypy/typeshed/stdlib/tkinter/font.pyi @@ -1,8 +1,8 @@ import _tkinter import sys import tkinter -from typing import Any, overload -from typing_extensions import Literal, TypeAlias, TypedDict +from typing import Any, Literal, TypedDict, overload +from typing_extensions import TypeAlias if sys.version_info >= (3, 9): __all__ = ["NORMAL", "ROMAN", "BOLD", "ITALIC", "nametofont", "Font", "families", "names"] @@ -15,8 +15,11 @@ ITALIC: Literal["italic"] _FontDescription: TypeAlias = ( str # "Helvetica 12" | Font # A font object constructed in Python - | list[Any] # ("Helvetica", 12, BOLD) - | tuple[Any, ...] + | list[Any] # ["Helvetica", 12, BOLD] + | tuple[str] # ("Liberation Sans",) needs wrapping in tuple/list to handle spaces + | tuple[str, int] # ("Liberation Sans", 12) + | tuple[str, int, str] # ("Liberation Sans", 12, "bold") + | tuple[str, int, list[str] | tuple[str, ...]] # e.g. bold and italic | _tkinter.Tcl_Obj # A font object constructed in Tcl ) diff --git a/mypy/typeshed/stdlib/tkinter/tix.pyi b/mypy/typeshed/stdlib/tkinter/tix.pyi index 672c5ab67403..73649de427e8 100644 --- a/mypy/typeshed/stdlib/tkinter/tix.pyi +++ b/mypy/typeshed/stdlib/tkinter/tix.pyi @@ -1,7 +1,6 @@ import tkinter from _typeshed import Incomplete -from typing import Any -from typing_extensions import Literal +from typing import Any, Literal WINDOW: Literal["window"] TEXT: Literal["text"] diff --git a/mypy/typeshed/stdlib/tkinter/ttk.pyi b/mypy/typeshed/stdlib/tkinter/ttk.pyi index 2bbbafbcb945..ac5accb73d9f 100644 --- a/mypy/typeshed/stdlib/tkinter/ttk.pyi +++ b/mypy/typeshed/stdlib/tkinter/ttk.pyi @@ -1,11 +1,10 @@ import _tkinter -import sys import tkinter from _typeshed import Incomplete from collections.abc import Callable from tkinter.font import _FontDescription -from typing import Any, overload -from typing_extensions import Literal, TypeAlias, TypedDict +from typing import Any, Literal, TypedDict, overload +from typing_extensions import TypeAlias __all__ = [ "Button", @@ -1102,11 +1101,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): def parent(self, item: str | int) -> str: ... def prev(self, item: str | int) -> str: ... # returning empty string means first item def see(self, item: str | int) -> None: ... - if sys.version_info >= (3, 8): - def selection(self) -> tuple[str, ...]: ... - else: - def selection(self, selop: Incomplete | None = ..., items: Incomplete | None = None) -> tuple[str, ...]: ... - + def selection(self) -> tuple[str, ...]: ... @overload def selection_set(self, __items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...]) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/token.pyi b/mypy/typeshed/stdlib/token.pyi index 85867a2b9744..f1fec7698043 100644 --- a/mypy/typeshed/stdlib/token.pyi +++ b/mypy/typeshed/stdlib/token.pyi @@ -3,11 +3,14 @@ import sys __all__ = [ "AMPER", "AMPEREQUAL", + "ASYNC", "AT", "ATEQUAL", + "AWAIT", "CIRCUMFLEX", "CIRCUMFLEXEQUAL", "COLON", + "COLONEQUAL", "COMMA", "DEDENT", "DOT", @@ -59,6 +62,8 @@ __all__ = [ "STAREQUAL", "STRING", "TILDE", + "TYPE_COMMENT", + "TYPE_IGNORE", "VBAR", "VBAREQUAL", "tok_name", @@ -67,9 +72,6 @@ __all__ = [ "COMMENT", ] -if sys.version_info >= (3, 8): - __all__ += ["ASYNC", "AWAIT", "COLONEQUAL", "TYPE_COMMENT", "TYPE_IGNORE"] - if sys.version_info >= (3, 10): __all__ += ["SOFT_KEYWORD"] @@ -129,9 +131,8 @@ AT: int RARROW: int ELLIPSIS: int ATEQUAL: int -if sys.version_info >= (3, 8): - AWAIT: int - ASYNC: int +AWAIT: int +ASYNC: int OP: int ERRORTOKEN: int N_TOKENS: int @@ -140,11 +141,10 @@ tok_name: dict[int, str] COMMENT: int NL: int ENCODING: int -if sys.version_info >= (3, 8): - TYPE_COMMENT: int - TYPE_IGNORE: int - COLONEQUAL: int - EXACT_TOKEN_TYPES: dict[str, int] +TYPE_COMMENT: int +TYPE_IGNORE: int +COLONEQUAL: int +EXACT_TOKEN_TYPES: dict[str, int] if sys.version_info >= (3, 10): SOFT_KEYWORD: int diff --git a/mypy/typeshed/stdlib/tokenize.pyi b/mypy/typeshed/stdlib/tokenize.pyi index 0028ed034ae6..3cd9ab8f87ce 100644 --- a/mypy/typeshed/stdlib/tokenize.pyi +++ b/mypy/typeshed/stdlib/tokenize.pyi @@ -3,17 +3,21 @@ from _typeshed import FileDescriptorOrPath from collections.abc import Callable, Generator, Iterable, Sequence from re import Pattern from token import * +from token import EXACT_TOKEN_TYPES as EXACT_TOKEN_TYPES from typing import Any, NamedTuple, TextIO from typing_extensions import TypeAlias __all__ = [ "AMPER", "AMPEREQUAL", + "ASYNC", "AT", "ATEQUAL", + "AWAIT", "CIRCUMFLEX", "CIRCUMFLEXEQUAL", "COLON", + "COLONEQUAL", "COMMA", "COMMENT", "DEDENT", @@ -68,29 +72,24 @@ __all__ = [ "STAREQUAL", "STRING", "TILDE", + "TYPE_COMMENT", + "TYPE_IGNORE", "TokenInfo", "VBAR", "VBAREQUAL", "detect_encoding", + "generate_tokens", "tok_name", "tokenize", "untokenize", ] -if sys.version_info >= (3, 8): - __all__ += ["ASYNC", "AWAIT", "COLONEQUAL", "generate_tokens", "TYPE_COMMENT", "TYPE_IGNORE"] - if sys.version_info >= (3, 10): __all__ += ["SOFT_KEYWORD"] if sys.version_info >= (3, 12): __all__ += ["EXCLAMATION", "FSTRING_END", "FSTRING_MIDDLE", "FSTRING_START"] -if sys.version_info >= (3, 8): - from token import EXACT_TOKEN_TYPES as EXACT_TOKEN_TYPES -else: - EXACT_TOKEN_TYPES: dict[str, int] - cookie_re: Pattern[str] blank_re: Pattern[bytes] diff --git a/mypy/typeshed/stdlib/traceback.pyi b/mypy/typeshed/stdlib/traceback.pyi index 47449dfe8143..f6720155936f 100644 --- a/mypy/typeshed/stdlib/traceback.pyi +++ b/mypy/typeshed/stdlib/traceback.pyi @@ -2,8 +2,8 @@ import sys from _typeshed import SupportsWrite, Unused from collections.abc import Generator, Iterable, Iterator, Mapping from types import FrameType, TracebackType -from typing import Any, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Literal, overload +from typing_extensions import Self, TypeAlias __all__ = [ "extract_stack", @@ -240,8 +240,7 @@ class FrameSummary(Iterable[Any]): def __getitem__(self, pos: int) -> Any: ... def __iter__(self) -> Iterator[Any]: ... def __eq__(self, other: object) -> bool: ... - if sys.version_info >= (3, 8): - def __len__(self) -> Literal[4]: ... + def __len__(self) -> Literal[4]: ... class StackSummary(list[FrameSummary]): @classmethod diff --git a/mypy/typeshed/stdlib/tracemalloc.pyi b/mypy/typeshed/stdlib/tracemalloc.pyi index 6448a16ce11a..e721e414138b 100644 --- a/mypy/typeshed/stdlib/tracemalloc.pyi +++ b/mypy/typeshed/stdlib/tracemalloc.pyi @@ -1,8 +1,8 @@ import sys from _tracemalloc import * from collections.abc import Sequence -from typing import Any, overload -from typing_extensions import SupportsIndex, TypeAlias +from typing import Any, SupportsIndex, overload +from typing_extensions import TypeAlias def get_object_traceback(obj: object) -> Traceback | None: ... def take_snapshot() -> Snapshot: ... diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index b26a668d273b..05ffc2143233 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -16,8 +16,8 @@ from collections.abc import ( from importlib.machinery import ModuleSpec # pytype crashes if types.MappingProxyType inherits from collections.abc.Mapping instead of typing.Mapping -from typing import Any, ClassVar, Mapping, Protocol, TypeVar, overload # noqa: Y022 -from typing_extensions import Literal, ParamSpec, Self, TypeVarTuple, final +from typing import Any, ClassVar, Literal, Mapping, Protocol, TypeVar, final, overload # noqa: Y022 +from typing_extensions import ParamSpec, Self, TypeVarTuple __all__ = [ "FunctionType", @@ -45,11 +45,9 @@ __all__ = [ "MethodWrapperType", "WrapperDescriptorType", "resolve_bases", + "CellType", ] -if sys.version_info >= (3, 8): - __all__ += ["CellType"] - if sys.version_info >= (3, 9): __all__ += ["GenericAlias"] @@ -68,9 +66,7 @@ _VT_co = TypeVar("_VT_co", covariant=True) @final class _Cell: - if sys.version_info >= (3, 8): - def __new__(cls, __contents: object = ...) -> Self: ... - + def __new__(cls, __contents: object = ...) -> Self: ... def __eq__(self, __value: object) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] cell_contents: Any @@ -118,10 +114,8 @@ class CodeType: def __hash__(self) -> int: ... @property def co_argcount(self) -> int: ... - if sys.version_info >= (3, 8): - @property - def co_posonlyargcount(self) -> int: ... - + @property + def co_posonlyargcount(self) -> int: ... @property def co_kwonlyargcount(self) -> int: ... @property @@ -203,30 +197,11 @@ class CodeType: __freevars: tuple[str, ...] = ..., __cellvars: tuple[str, ...] = ..., ) -> Self: ... - elif sys.version_info >= (3, 8): - def __new__( - cls, - __argcount: int, - __posonlyargcount: int, - __kwonlyargcount: int, - __nlocals: int, - __stacksize: int, - __flags: int, - __codestring: bytes, - __constants: tuple[object, ...], - __names: tuple[str, ...], - __varnames: tuple[str, ...], - __filename: str, - __name: str, - __firstlineno: int, - __lnotab: bytes, - __freevars: tuple[str, ...] = ..., - __cellvars: tuple[str, ...] = ..., - ) -> Self: ... else: def __new__( cls, __argcount: int, + __posonlyargcount: int, __kwonlyargcount: int, __nlocals: int, __stacksize: int, @@ -286,7 +261,7 @@ class CodeType: co_name: str = ..., co_linetable: bytes = ..., ) -> CodeType: ... - elif sys.version_info >= (3, 8): + else: def replace( self, *, @@ -418,18 +393,6 @@ class CoroutineType(Coroutine[_YieldT_co, _SendT_contra, _ReturnT_co]): @overload def throw(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = ...) -> _YieldT_co: ... -class _StaticFunctionType: - # Fictional type to correct the type of MethodType.__func__. - # FunctionType is a descriptor, so mypy follows the descriptor protocol and - # converts MethodType.__func__ back to MethodType (the return type of - # FunctionType.__get__). But this is actually a special case; MethodType is - # implemented in C and its attribute access doesn't go through - # __getattribute__. - # By wrapping FunctionType in _StaticFunctionType, we get the right result; - # similar to wrapping a function in staticmethod() at runtime to prevent it - # being bound as a method. - def __get__(self, obj: object, type: type | None) -> FunctionType: ... - @final class MethodType: @property @@ -437,7 +400,7 @@ class MethodType: @property def __defaults__(self) -> tuple[Any, ...] | None: ... # inherited from the added function @property - def __func__(self) -> _StaticFunctionType: ... + def __func__(self) -> Callable[..., Any]: ... @property def __self__(self) -> object: ... @property @@ -515,7 +478,7 @@ class ClassMethodDescriptorType: class TracebackType: def __new__(cls, tb_next: TracebackType | None, tb_frame: FrameType, tb_lasti: int, tb_lineno: int) -> Self: ... tb_next: TracebackType | None - # the rest are read-only even in 3.7 + # the rest are read-only @property def tb_frame(self) -> FrameType: ... @property @@ -598,8 +561,7 @@ def coroutine(func: Callable[_P, Generator[Any, Any, _R]]) -> Callable[_P, Await @overload def coroutine(func: _Fn) -> _Fn: ... -if sys.version_info >= (3, 8): - CellType = _Cell +CellType = _Cell if sys.version_info >= (3, 9): class GenericAlias: @@ -626,7 +588,10 @@ if sys.version_info >= (3, 10): @final class NoneType: def __bool__(self) -> Literal[False]: ... - EllipsisType = ellipsis # noqa: F821 from builtins + + @final + class EllipsisType: ... + from builtins import _NotImplementedType NotImplementedType = _NotImplementedType diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 555df0ea47c8..9fef9d3922f5 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -1,4 +1,6 @@ -import collections # Needed by aliases like DefaultDict, see mypy issue 2986 +# TODO: The collections import is required, otherwise mypy crashes. +# https://github.com/python/mypy/issues/16744 +import collections # noqa: F401 # pyright: ignore import sys import typing_extensions from _collections_abc import dict_items, dict_keys, dict_values @@ -18,7 +20,7 @@ from types import ( TracebackType, WrapperDescriptorType, ) -from typing_extensions import Never as _Never, ParamSpec as _ParamSpec, final as _final +from typing_extensions import Never as _Never, ParamSpec as _ParamSpec if sys.version_info >= (3, 10): from types import UnionType @@ -46,6 +48,7 @@ __all__ = [ "DefaultDict", "Deque", "Dict", + "Final", "FrozenSet", "Generator", "Generic", @@ -55,6 +58,7 @@ __all__ = [ "Iterator", "KeysView", "List", + "Literal", "Mapping", "MappingView", "MutableMapping", @@ -63,6 +67,7 @@ __all__ = [ "NamedTuple", "NewType", "Optional", + "Protocol", "Reversible", "Sequence", "Set", @@ -71,38 +76,31 @@ __all__ = [ "SupportsBytes", "SupportsComplex", "SupportsFloat", + "SupportsIndex", "SupportsInt", "SupportsRound", "Text", "Tuple", "Type", "TypeVar", + "TypedDict", "Union", "ValuesView", "TYPE_CHECKING", "cast", + "final", + "get_args", + "get_origin", "get_type_hints", "no_type_check", "no_type_check_decorator", "overload", + "runtime_checkable", "ForwardRef", "NoReturn", "OrderedDict", ] -if sys.version_info >= (3, 8): - __all__ += [ - "Final", - "Literal", - "Protocol", - "SupportsIndex", - "TypedDict", - "final", - "get_args", - "get_origin", - "runtime_checkable", - ] - if sys.version_info >= (3, 9): __all__ += ["Annotated", "BinaryIO", "IO", "Match", "Pattern", "TextIO"] @@ -137,7 +135,8 @@ def type_check_only(func_or_cls: _F) -> _F: ... Any = object() -@_final +def final(f: _T) -> _T: ... +@final class TypeVar: @property def __name__(self) -> str: ... @@ -175,7 +174,7 @@ class TypeVar: _promote = object() # N.B. Keep this definition in sync with typing_extensions._SpecialForm -@_final +@final class _SpecialForm: def __getitem__(self, parameters: Any) -> object: ... if sys.version_info >= (3, 10): @@ -199,12 +198,11 @@ ClassVar: _SpecialForm Optional: _SpecialForm Tuple: _SpecialForm -if sys.version_info >= (3, 8): - Final: _SpecialForm - def final(f: _T) -> _T: ... - Literal: _SpecialForm - # TypedDict is a (non-subscriptable) special form. - TypedDict: object +Final: _SpecialForm + +Literal: _SpecialForm +# TypedDict is a (non-subscriptable) special form. +TypedDict: object if sys.version_info >= (3, 11): Self: _SpecialForm @@ -214,7 +212,7 @@ if sys.version_info >= (3, 11): NotRequired: _SpecialForm LiteralString: _SpecialForm - @_final + @final class TypeVarTuple: @property def __name__(self) -> str: ... @@ -224,21 +222,21 @@ if sys.version_info >= (3, 11): def __typing_prepare_subst__(self, alias: Incomplete, args: Incomplete) -> Incomplete: ... if sys.version_info >= (3, 10): - @_final + @final class ParamSpecArgs: @property def __origin__(self) -> ParamSpec: ... def __init__(self, origin: ParamSpec) -> None: ... def __eq__(self, other: object) -> bool: ... - @_final + @final class ParamSpecKwargs: @property def __origin__(self) -> ParamSpec: ... def __init__(self, origin: ParamSpec) -> None: ... def __eq__(self, other: object) -> bool: ... - @_final + @final class ParamSpec: @property def __name__(self) -> str: ... @@ -301,7 +299,7 @@ _VT = TypeVar("_VT") # Value type. _T_co = TypeVar("_T_co", covariant=True) # Any type covariant containers. _KT_co = TypeVar("_KT_co", covariant=True) # Key type covariant containers. _VT_co = TypeVar("_VT_co", covariant=True) # Value type covariant containers. -_TC = TypeVar("_TC", bound=Type[object]) +_TC = TypeVar("_TC", bound=type[object]) def no_type_check(arg: _F) -> _F: ... def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... @@ -329,8 +327,6 @@ if sys.version_info >= (3, 9): # Predefined type variables. AnyStr = TypeVar("AnyStr", str, bytes) # noqa: Y001 -# Technically in 3.7 this inherited from GenericMeta. But let's not reflect that, since -# type checkers tend to assume that Protocols all have the ABCMeta metaclass. class _ProtocolMeta(ABCMeta): if sys.version_info >= (3, 12): def __init__(cls, *args: Any, **kwargs: Any) -> None: ... @@ -358,11 +354,10 @@ class SupportsBytes(Protocol, metaclass=ABCMeta): @abstractmethod def __bytes__(self) -> bytes: ... -if sys.version_info >= (3, 8): - @runtime_checkable - class SupportsIndex(Protocol, metaclass=ABCMeta): - @abstractmethod - def __index__(self) -> int: ... +@runtime_checkable +class SupportsIndex(Protocol, metaclass=ABCMeta): + @abstractmethod + def __index__(self) -> int: ... @runtime_checkable class SupportsAbs(Protocol[_T_co]): @@ -418,7 +413,7 @@ class Generator(Iterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra, _Return @overload @abstractmethod def throw( - self, __typ: Type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None + self, __typ: type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None ) -> _YieldT_co: ... @overload @abstractmethod @@ -455,7 +450,7 @@ class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _Retu @overload @abstractmethod def throw( - self, __typ: Type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None + self, __typ: type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None ) -> _YieldT_co: ... @overload @abstractmethod @@ -491,7 +486,7 @@ class AsyncGenerator(AsyncIterator[_YieldT_co], Generic[_YieldT_co, _SendT_contr @overload @abstractmethod def athrow( - self, __typ: Type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None + self, __typ: type[BaseException], __val: BaseException | object = None, __tb: TracebackType | None = None ) -> Awaitable[_YieldT_co]: ... @overload @abstractmethod @@ -602,9 +597,7 @@ class ItemsView(MappingView, AbstractSet[tuple[_KT_co, _VT_co]], Generic[_KT_co, def __rand__(self, other: Iterable[_T]) -> set[_T]: ... def __contains__(self, item: object) -> bool: ... def __iter__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... - if sys.version_info >= (3, 8): - def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... - + def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... def __or__(self, other: Iterable[_T]) -> set[tuple[_KT_co, _VT_co] | _T]: ... def __ror__(self, other: Iterable[_T]) -> set[tuple[_KT_co, _VT_co] | _T]: ... def __sub__(self, other: Iterable[Any]) -> set[tuple[_KT_co, _VT_co]]: ... @@ -618,9 +611,7 @@ class KeysView(MappingView, AbstractSet[_KT_co]): def __rand__(self, other: Iterable[_T]) -> set[_T]: ... def __contains__(self, key: object) -> bool: ... def __iter__(self) -> Iterator[_KT_co]: ... - if sys.version_info >= (3, 8): - def __reversed__(self) -> Iterator[_KT_co]: ... - + def __reversed__(self) -> Iterator[_KT_co]: ... def __or__(self, other: Iterable[_T]) -> set[_KT_co | _T]: ... def __ror__(self, other: Iterable[_T]) -> set[_KT_co | _T]: ... def __sub__(self, other: Iterable[Any]) -> set[_KT_co]: ... @@ -632,8 +623,7 @@ class ValuesView(MappingView, Collection[_VT_co]): def __init__(self, mapping: Mapping[Any, _VT_co]) -> None: ... # undocumented def __contains__(self, value: object) -> bool: ... def __iter__(self) -> Iterator[_VT_co]: ... - if sys.version_info >= (3, 8): - def __reversed__(self) -> Iterator[_VT_co]: ... + def __reversed__(self) -> Iterator[_VT_co]: ... class Mapping(Collection[_KT], Generic[_KT, _VT_co]): # TODO: We wish the key type could also be covariant, but that doesn't work, @@ -772,7 +762,7 @@ class IO(Iterator[AnyStr]): def __enter__(self) -> IO[AnyStr]: ... @abstractmethod def __exit__( - self, __type: Type[BaseException] | None, __value: BaseException | None, __traceback: TracebackType | None + self, __type: type[BaseException] | None, __value: BaseException | None, __traceback: TracebackType | None ) -> None: ... class BinaryIO(IO[bytes]): @@ -823,24 +813,25 @@ else: obj: _get_type_hints_obj_allowed_types, globalns: dict[str, Any] | None = None, localns: dict[str, Any] | None = None ) -> dict[str, Any]: ... -if sys.version_info >= (3, 8): - def get_args(tp: Any) -> tuple[Any, ...]: ... +def get_args(tp: Any) -> tuple[Any, ...]: ... - if sys.version_info >= (3, 10): - @overload - def get_origin(tp: ParamSpecArgs | ParamSpecKwargs) -> ParamSpec: ... - @overload - def get_origin(tp: UnionType) -> type[UnionType]: ... - if sys.version_info >= (3, 9): - @overload - def get_origin(tp: GenericAlias) -> type: ... - @overload - def get_origin(tp: Any) -> Any | None: ... - else: - def get_origin(tp: Any) -> Any | None: ... +if sys.version_info >= (3, 10): + @overload + def get_origin(tp: ParamSpecArgs | ParamSpecKwargs) -> ParamSpec: ... + @overload + def get_origin(tp: UnionType) -> type[UnionType]: ... + +if sys.version_info >= (3, 9): + @overload + def get_origin(tp: GenericAlias) -> type: ... + @overload + def get_origin(tp: Any) -> Any | None: ... + +else: + def get_origin(tp: Any) -> Any | None: ... @overload -def cast(typ: Type[_T], val: Any) -> _T: ... +def cast(typ: type[_T], val: Any) -> _T: ... @overload def cast(typ: str, val: Any) -> Any: ... @overload @@ -865,9 +856,7 @@ if sys.version_info >= (3, 11): # Type constructors class NamedTuple(tuple[Any, ...]): - if sys.version_info < (3, 8): - _field_types: ClassVar[collections.OrderedDict[str, type]] - elif sys.version_info < (3, 9): + if sys.version_info < (3, 9): _field_types: ClassVar[dict[str, type]] _field_defaults: ClassVar[dict[str, Any]] _fields: ClassVar[tuple[str, ...]] @@ -881,11 +870,7 @@ class NamedTuple(tuple[Any, ...]): def __init__(self, __typename: str, __fields: None = None, **kwargs: Any) -> None: ... @classmethod def _make(cls, iterable: Iterable[Any]) -> typing_extensions.Self: ... - if sys.version_info >= (3, 8): - def _asdict(self) -> dict[str, Any]: ... - else: - def _asdict(self) -> collections.OrderedDict[str, Any]: ... - + def _asdict(self) -> dict[str, Any]: ... def _replace(self, **kwargs: Any) -> typing_extensions.Self: ... # Internal mypy fallback type for all typed dicts (does not exist at runtime) @@ -923,7 +908,7 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): # supposedly incompatible definitions of __or__ and __ior__ def __ior__(self, __value: typing_extensions.Self) -> typing_extensions.Self: ... # type: ignore[misc] -@_final +@final class ForwardRef: __forward_arg__: str __forward_code__: CodeType @@ -958,7 +943,7 @@ def _type_repr(obj: object) -> str: ... if sys.version_info >= (3, 12): def override(__method: _F) -> _F: ... - @_final + @final class TypeAliasType: def __init__( self, name: str, value: Any, *, type_params: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] = () diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index 5c5b756f5256..ea5c7b21aa87 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -1,5 +1,4 @@ import abc -import collections import sys import typing from _collections_abc import dict_items, dict_keys, dict_values @@ -353,9 +352,7 @@ else: ) -> IdentityFunction: ... class NamedTuple(tuple[Any, ...]): - if sys.version_info < (3, 8): - _field_types: ClassVar[collections.OrderedDict[str, type]] - elif sys.version_info < (3, 9): + if sys.version_info < (3, 9): _field_types: ClassVar[dict[str, type]] _field_defaults: ClassVar[dict[str, Any]] _fields: ClassVar[tuple[str, ...]] @@ -366,11 +363,7 @@ else: def __init__(self, typename: str, fields: None = None, **kwargs: Any) -> None: ... @classmethod def _make(cls, iterable: Iterable[Any]) -> Self: ... - if sys.version_info >= (3, 8): - def _asdict(self) -> dict[str, Any]: ... - else: - def _asdict(self) -> collections.OrderedDict[str, Any]: ... - + def _asdict(self) -> dict[str, Any]: ... def _replace(self, **kwargs: Any) -> Self: ... class NewType: diff --git a/mypy/typeshed/stdlib/unicodedata.pyi b/mypy/typeshed/stdlib/unicodedata.pyi index 5a1f7fe6638d..35ab6d609a19 100644 --- a/mypy/typeshed/stdlib/unicodedata.pyi +++ b/mypy/typeshed/stdlib/unicodedata.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadOnlyBuffer -from typing import Any, TypeVar, overload -from typing_extensions import Literal, TypeAlias, final +from typing import Any, Literal, TypeVar, final, overload +from typing_extensions import TypeAlias ucd_3_2_0: UCD unidata_version: str @@ -27,10 +27,7 @@ def digit(__chr: str, __default: _T) -> int | _T: ... _EastAsianWidth: TypeAlias = Literal["F", "H", "W", "Na", "A", "N"] def east_asian_width(__chr: str) -> _EastAsianWidth: ... - -if sys.version_info >= (3, 8): - def is_normalized(__form: str, __unistr: str) -> bool: ... - +def is_normalized(__form: str, __unistr: str) -> bool: ... def lookup(__name: str | ReadOnlyBuffer) -> str: ... def mirrored(__chr: str) -> int: ... @overload @@ -60,9 +57,7 @@ class UCD: @overload def digit(self, __chr: str, __default: _T) -> int | _T: ... def east_asian_width(self, __chr: str) -> _EastAsianWidth: ... - if sys.version_info >= (3, 8): - def is_normalized(self, __form: str, __unistr: str) -> bool: ... - + def is_normalized(self, __form: str, __unistr: str) -> bool: ... def lookup(self, __name: str | ReadOnlyBuffer) -> str: ... def mirrored(self, __chr: str) -> int: ... @overload diff --git a/mypy/typeshed/stdlib/unittest/__init__.pyi b/mypy/typeshed/stdlib/unittest/__init__.pyi index f96d6fb185c5..f2532ccf7fd8 100644 --- a/mypy/typeshed/stdlib/unittest/__init__.pyi +++ b/mypy/typeshed/stdlib/unittest/__init__.pyi @@ -1,9 +1,11 @@ import sys +from unittest.async_case import * from .case import ( FunctionTestCase as FunctionTestCase, SkipTest as SkipTest, TestCase as TestCase, + addModuleCleanup as addModuleCleanup, expectedFailure as expectedFailure, skip as skip, skipIf as skipIf, @@ -27,15 +29,11 @@ from .signals import ( ) from .suite import BaseTestSuite as BaseTestSuite, TestSuite as TestSuite -if sys.version_info >= (3, 8): - from unittest.async_case import * - - from .case import addModuleCleanup as addModuleCleanup - if sys.version_info >= (3, 11): from .case import doModuleCleanups as doModuleCleanups, enterModuleContext as enterModuleContext __all__ = [ + "IsolatedAsyncioTestCase", "TestResult", "TestCase", "TestSuite", @@ -57,11 +55,9 @@ __all__ = [ "getTestCaseNames", "makeSuite", "findTestCases", + "addModuleCleanup", ] -if sys.version_info >= (3, 8): - __all__ += ["addModuleCleanup", "IsolatedAsyncioTestCase"] - if sys.version_info >= (3, 11): __all__ += ["enterModuleContext", "doModuleCleanups"] diff --git a/mypy/typeshed/stdlib/unittest/case.pyi b/mypy/typeshed/stdlib/unittest/case.pyi index d66f027324f1..120bb96d761b 100644 --- a/mypy/typeshed/stdlib/unittest/case.pyi +++ b/mypy/typeshed/stdlib/unittest/case.pyi @@ -68,9 +68,8 @@ else: self, exc_type: type[BaseException] | None, exc_value: BaseException | None, tb: TracebackType | None ) -> bool | None: ... -if sys.version_info >= (3, 8): - def addModuleCleanup(__function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... - def doModuleCleanups() -> None: ... +def addModuleCleanup(__function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... +def doModuleCleanups() -> None: ... if sys.version_info >= (3, 11): def enterModuleContext(cm: AbstractContextManager[_T]) -> _T: ... @@ -274,20 +273,16 @@ class TestCase: def defaultTestResult(self) -> unittest.result.TestResult: ... def id(self) -> str: ... def shortDescription(self) -> str | None: ... - if sys.version_info >= (3, 8): - def addCleanup(self, __function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... - else: - def addCleanup(self, function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... + def addCleanup(self, __function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... if sys.version_info >= (3, 11): def enterContext(self, cm: AbstractContextManager[_T]) -> _T: ... def doCleanups(self) -> None: ... - if sys.version_info >= (3, 8): - @classmethod - def addClassCleanup(cls, __function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... - @classmethod - def doClassCleanups(cls) -> None: ... + @classmethod + def addClassCleanup(cls, __function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... + @classmethod + def doClassCleanups(cls) -> None: ... if sys.version_info >= (3, 11): @classmethod diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index 8e96b23ce959..c6014d4bb886 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -2,8 +2,8 @@ import sys from collections.abc import Awaitable, Callable, Coroutine, Iterable, Mapping, Sequence from contextlib import _GeneratorContextManager from types import TracebackType -from typing import Any, Generic, TypeVar, overload -from typing_extensions import Final, Literal, ParamSpec, Self, TypeAlias +from typing import Any, Final, Generic, Literal, TypeVar, overload +from typing_extensions import ParamSpec, Self, TypeAlias _T = TypeVar("_T") _TT = TypeVar("_TT", bound=type[Any]) @@ -12,41 +12,23 @@ _F = TypeVar("_F", bound=Callable[..., Any]) _AF = TypeVar("_AF", bound=Callable[..., Coroutine[Any, Any, Any]]) _P = ParamSpec("_P") -if sys.version_info >= (3, 8): - __all__ = ( - "Mock", - "MagicMock", - "patch", - "sentinel", - "DEFAULT", - "ANY", - "call", - "create_autospec", - "AsyncMock", - "FILTER_DIR", - "NonCallableMock", - "NonCallableMagicMock", - "mock_open", - "PropertyMock", - "seal", - ) -else: - __all__ = ( - "Mock", - "MagicMock", - "patch", - "sentinel", - "DEFAULT", - "ANY", - "call", - "create_autospec", - "FILTER_DIR", - "NonCallableMock", - "NonCallableMagicMock", - "mock_open", - "PropertyMock", - "seal", - ) +__all__ = ( + "Mock", + "MagicMock", + "patch", + "sentinel", + "DEFAULT", + "ANY", + "call", + "create_autospec", + "AsyncMock", + "FILTER_DIR", + "NonCallableMock", + "NonCallableMagicMock", + "mock_open", + "PropertyMock", + "seal", +) if sys.version_info < (3, 9): __version__: Final[str] @@ -87,12 +69,10 @@ class _Call(tuple[Any, ...]): def __call__(self, *args: Any, **kwargs: Any) -> _Call: ... def __getattr__(self, attr: str) -> Any: ... def __getattribute__(self, attr: str) -> Any: ... - if sys.version_info >= (3, 8): - @property - def args(self) -> tuple[Any, ...]: ... - @property - def kwargs(self) -> Mapping[str, Any]: ... - + @property + def args(self) -> tuple[Any, ...]: ... + @property + def kwargs(self) -> Mapping[str, Any]: ... def call_list(self) -> Any: ... call: _Call @@ -144,24 +124,13 @@ class NonCallableMock(Base, Any): def __delattr__(self, name: str) -> None: ... def __setattr__(self, name: str, value: Any) -> None: ... def __dir__(self) -> list[str]: ... - if sys.version_info >= (3, 8): - def _calls_repr(self, prefix: str = "Calls") -> str: ... - def assert_called_with(self, *args: Any, **kwargs: Any) -> None: ... - def assert_not_called(self) -> None: ... - def assert_called_once_with(self, *args: Any, **kwargs: Any) -> None: ... - def _format_mock_failure_message(self, args: Any, kwargs: Any, action: str = "call") -> str: ... - else: - def assert_called_with(_mock_self, *args: Any, **kwargs: Any) -> None: ... - def assert_not_called(_mock_self) -> None: ... - def assert_called_once_with(_mock_self, *args: Any, **kwargs: Any) -> None: ... - def _format_mock_failure_message(self, args: Any, kwargs: Any) -> str: ... - if sys.version_info >= (3, 8): - def assert_called(self) -> None: ... - def assert_called_once(self) -> None: ... - else: - def assert_called(_mock_self) -> None: ... - def assert_called_once(_mock_self) -> None: ... - + def _calls_repr(self, prefix: str = "Calls") -> str: ... + def assert_called_with(self, *args: Any, **kwargs: Any) -> None: ... + def assert_not_called(self) -> None: ... + def assert_called_once_with(self, *args: Any, **kwargs: Any) -> None: ... + def _format_mock_failure_message(self, args: Any, kwargs: Any, action: str = "call") -> str: ... + def assert_called(self) -> None: ... + def assert_called_once(self) -> None: ... def reset_mock(self, visited: Any = None, *, return_value: bool = False, side_effect: bool = False) -> None: ... def _extract_mock_name(self) -> str: ... def _get_call_signature_from_name(self, name: str) -> Any: ... @@ -198,10 +167,7 @@ class CallableMixin(Base): _new_parent: Any | None = None, **kwargs: Any, ) -> None: ... - if sys.version_info >= (3, 8): - def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - else: - def __call__(_mock_self, *args: Any, **kwargs: Any) -> Any: ... + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... class Mock(CallableMixin, NonCallableMock): ... @@ -256,16 +222,12 @@ class _patch(Generic[_T]): # arguments. See the _patch_default_new class below for this functionality. @overload def __call__(self, func: Callable[_P, _R]) -> Callable[_P, _R]: ... - if sys.version_info >= (3, 8): - def decoration_helper( - self, patched: _patch[Any], args: Sequence[Any], keywargs: Any - ) -> _GeneratorContextManager[tuple[Sequence[Any], Any]]: ... - + def decoration_helper( + self, patched: _patch[Any], args: Sequence[Any], keywargs: Any + ) -> _GeneratorContextManager[tuple[Sequence[Any], Any]]: ... def decorate_class(self, klass: _TT) -> _TT: ... def decorate_callable(self, func: Callable[..., _R]) -> Callable[..., _R]: ... - if sys.version_info >= (3, 8): - def decorate_async_callable(self, func: Callable[..., Awaitable[_R]]) -> Callable[..., Awaitable[_R]]: ... - + def decorate_async_callable(self, func: Callable[..., Awaitable[_R]]) -> Callable[..., Awaitable[_R]]: ... def get_original(self) -> tuple[Any, bool]: ... target: Any temp_original: Any @@ -277,15 +239,10 @@ class _patch(Generic[_T]): def start(self) -> _T: ... def stop(self) -> None: ... -if sys.version_info >= (3, 8): - _Mock: TypeAlias = MagicMock | AsyncMock -else: - _Mock: TypeAlias = MagicMock - # This class does not exist at runtime, it's a hack to make this work: # @patch("foo") # def bar(..., mock: MagicMock) -> None: ... -class _patch_default_new(_patch[_Mock]): +class _patch_default_new(_patch[MagicMock | AsyncMock]): @overload def __call__(self, func: _TT) -> _TT: ... # Can't use the following as ParamSpec is only allowed as last parameter: @@ -366,7 +323,7 @@ class _patcher: autospec: Any | None = ..., new_callable: Any | None = ..., **kwargs: Any, - ) -> _patch[_Mock]: ... + ) -> _patch[MagicMock | AsyncMock]: ... @staticmethod def multiple( target: Any, @@ -388,38 +345,34 @@ class MagicMixin: class NonCallableMagicMock(MagicMixin, NonCallableMock): ... class MagicMock(MagicMixin, Mock): ... -if sys.version_info >= (3, 8): - class AsyncMockMixin(Base): - def __init__(self, *args: Any, **kwargs: Any) -> None: ... - async def _execute_mock_call(self, *args: Any, **kwargs: Any) -> Any: ... - def assert_awaited(self) -> None: ... - def assert_awaited_once(self) -> None: ... - def assert_awaited_with(self, *args: Any, **kwargs: Any) -> None: ... - def assert_awaited_once_with(self, *args: Any, **kwargs: Any) -> None: ... - def assert_any_await(self, *args: Any, **kwargs: Any) -> None: ... - def assert_has_awaits(self, calls: Iterable[_Call], any_order: bool = False) -> None: ... - def assert_not_awaited(self) -> None: ... - def reset_mock(self, *args: Any, **kwargs: Any) -> None: ... - await_count: int - await_args: _Call | None - await_args_list: _CallList - - class AsyncMagicMixin(MagicMixin): - def __init__(self, *args: Any, **kw: Any) -> None: ... - - class AsyncMock(AsyncMockMixin, AsyncMagicMixin, Mock): - # Improving the `reset_mock` signature. - # It is defined on `AsyncMockMixin` with `*args, **kwargs`, which is not ideal. - # But, `NonCallableMock` super-class has the better version. - def reset_mock(self, visited: Any = None, *, return_value: bool = False, side_effect: bool = False) -> None: ... +class AsyncMockMixin(Base): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + async def _execute_mock_call(self, *args: Any, **kwargs: Any) -> Any: ... + def assert_awaited(self) -> None: ... + def assert_awaited_once(self) -> None: ... + def assert_awaited_with(self, *args: Any, **kwargs: Any) -> None: ... + def assert_awaited_once_with(self, *args: Any, **kwargs: Any) -> None: ... + def assert_any_await(self, *args: Any, **kwargs: Any) -> None: ... + def assert_has_awaits(self, calls: Iterable[_Call], any_order: bool = False) -> None: ... + def assert_not_awaited(self) -> None: ... + def reset_mock(self, *args: Any, **kwargs: Any) -> None: ... + await_count: int + await_args: _Call | None + await_args_list: _CallList + +class AsyncMagicMixin(MagicMixin): + def __init__(self, *args: Any, **kw: Any) -> None: ... + +class AsyncMock(AsyncMockMixin, AsyncMagicMixin, Mock): + # Improving the `reset_mock` signature. + # It is defined on `AsyncMockMixin` with `*args, **kwargs`, which is not ideal. + # But, `NonCallableMock` super-class has the better version. + def reset_mock(self, visited: Any = None, *, return_value: bool = False, side_effect: bool = False) -> None: ... class MagicProxy: name: str parent: Any def __init__(self, name: str, parent: Any) -> None: ... - if sys.version_info < (3, 8): - def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def create_mock(self) -> Any: ... def __get__(self, obj: Any, _type: Any | None = None) -> Any: ... @@ -471,11 +424,7 @@ class _SpecState: def mock_open(mock: Any | None = None, read_data: Any = "") -> Any: ... class PropertyMock(Mock): - if sys.version_info >= (3, 8): - def __get__(self, obj: _T, obj_type: type[_T] | None = None) -> Self: ... - else: - def __get__(self, obj: _T, obj_type: type[_T] | None) -> Self: ... - + def __get__(self, obj: _T, obj_type: type[_T] | None = None) -> Self: ... def __set__(self, obj: Any, val: Any) -> None: ... def seal(mock: Any) -> None: ... diff --git a/mypy/typeshed/stdlib/urllib/parse.pyi b/mypy/typeshed/stdlib/urllib/parse.pyi index 116754091d1a..ed1929b26501 100644 --- a/mypy/typeshed/stdlib/urllib/parse.pyi +++ b/mypy/typeshed/stdlib/urllib/parse.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Callable, Iterable, Mapping, Sequence -from typing import Any, AnyStr, Generic, NamedTuple, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, AnyStr, Generic, Literal, NamedTuple, TypeVar, overload +from typing_extensions import TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias diff --git a/mypy/typeshed/stdlib/urllib/robotparser.pyi b/mypy/typeshed/stdlib/urllib/robotparser.pyi index d218c3dc6c0f..14ceef550dab 100644 --- a/mypy/typeshed/stdlib/urllib/robotparser.pyi +++ b/mypy/typeshed/stdlib/urllib/robotparser.pyi @@ -1,4 +1,3 @@ -import sys from collections.abc import Iterable from typing import NamedTuple @@ -18,5 +17,4 @@ class RobotFileParser: def modified(self) -> None: ... def crawl_delay(self, useragent: str) -> str | None: ... def request_rate(self, useragent: str) -> RequestRate | None: ... - if sys.version_info >= (3, 8): - def site_maps(self) -> list[str] | None: ... + def site_maps(self) -> list[str] | None: ... diff --git a/mypy/typeshed/stdlib/warnings.pyi b/mypy/typeshed/stdlib/warnings.pyi index 6222eb65918a..12afea9337e7 100644 --- a/mypy/typeshed/stdlib/warnings.pyi +++ b/mypy/typeshed/stdlib/warnings.pyi @@ -2,8 +2,8 @@ import sys from _warnings import warn as warn, warn_explicit as warn_explicit from collections.abc import Sequence from types import ModuleType, TracebackType -from typing import Any, Generic, TextIO, TypeVar, overload -from typing_extensions import Literal, TypeAlias +from typing import Any, Generic, Literal, TextIO, TypeVar, overload +from typing_extensions import TypeAlias __all__ = [ "warn", diff --git a/mypy/typeshed/stdlib/wave.pyi b/mypy/typeshed/stdlib/wave.pyi index 6b7af2f79da1..9137f1e47643 100644 --- a/mypy/typeshed/stdlib/wave.pyi +++ b/mypy/typeshed/stdlib/wave.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadableBuffer, Unused -from typing import IO, Any, BinaryIO, NamedTuple, NoReturn, overload -from typing_extensions import Literal, Self, TypeAlias, deprecated +from typing import IO, Any, BinaryIO, Literal, NamedTuple, NoReturn, overload +from typing_extensions import Self, TypeAlias, deprecated if sys.version_info >= (3, 9): __all__ = ["open", "Error", "Wave_read", "Wave_write"] diff --git a/mypy/typeshed/stdlib/webbrowser.pyi b/mypy/typeshed/stdlib/webbrowser.pyi index 99c7bb5846b6..2b3f978c814b 100644 --- a/mypy/typeshed/stdlib/webbrowser.pyi +++ b/mypy/typeshed/stdlib/webbrowser.pyi @@ -1,7 +1,7 @@ import sys from abc import abstractmethod from collections.abc import Callable, Sequence -from typing_extensions import Literal +from typing import Literal __all__ = ["Error", "open", "open_new", "open_new_tab", "get", "register"] diff --git a/mypy/typeshed/stdlib/winreg.pyi b/mypy/typeshed/stdlib/winreg.pyi index 613b239ff663..897177547c71 100644 --- a/mypy/typeshed/stdlib/winreg.pyi +++ b/mypy/typeshed/stdlib/winreg.pyi @@ -1,7 +1,7 @@ import sys from types import TracebackType -from typing import Any -from typing_extensions import Literal, Self, TypeAlias, final +from typing import Any, Literal, final +from typing_extensions import Self, TypeAlias if sys.platform == "win32": _KeyType: TypeAlias = HKEYType | int diff --git a/mypy/typeshed/stdlib/winsound.pyi b/mypy/typeshed/stdlib/winsound.pyi index aa04fdc27a01..bacc5302826f 100644 --- a/mypy/typeshed/stdlib/winsound.pyi +++ b/mypy/typeshed/stdlib/winsound.pyi @@ -1,7 +1,6 @@ import sys from _typeshed import ReadableBuffer -from typing import overload -from typing_extensions import Literal +from typing import Literal, overload if sys.platform == "win32": SND_APPLICATION: Literal[128] diff --git a/mypy/typeshed/stdlib/xml/dom/minicompat.pyi b/mypy/typeshed/stdlib/xml/dom/minicompat.pyi index 4d83bef025d9..162f60254a58 100644 --- a/mypy/typeshed/stdlib/xml/dom/minicompat.pyi +++ b/mypy/typeshed/stdlib/xml/dom/minicompat.pyi @@ -1,6 +1,5 @@ from collections.abc import Iterable -from typing import Any, TypeVar -from typing_extensions import Literal +from typing import Any, Literal, TypeVar __all__ = ["NodeList", "EmptyNodeList", "StringTypes", "defproperty"] diff --git a/mypy/typeshed/stdlib/xml/dom/minidom.pyi b/mypy/typeshed/stdlib/xml/dom/minidom.pyi index ec17f0a41497..28bfa1b36924 100644 --- a/mypy/typeshed/stdlib/xml/dom/minidom.pyi +++ b/mypy/typeshed/stdlib/xml/dom/minidom.pyi @@ -1,8 +1,8 @@ import sys import xml.dom from _typeshed import Incomplete, ReadableBuffer, SupportsRead, SupportsWrite -from typing import NoReturn, TypeVar, overload -from typing_extensions import Literal, Self +from typing import Literal, NoReturn, TypeVar, overload +from typing_extensions import Self from xml.dom.minicompat import NodeList from xml.dom.xmlbuilder import DocumentLS, DOMImplementationLS from xml.sax.xmlreader import XMLReader diff --git a/mypy/typeshed/stdlib/xml/dom/pulldom.pyi b/mypy/typeshed/stdlib/xml/dom/pulldom.pyi index 920905160e43..95436ab5dd38 100644 --- a/mypy/typeshed/stdlib/xml/dom/pulldom.pyi +++ b/mypy/typeshed/stdlib/xml/dom/pulldom.pyi @@ -1,7 +1,8 @@ import sys from _typeshed import Incomplete, SupportsRead from collections.abc import Sequence -from typing_extensions import Literal, TypeAlias +from typing import Literal +from typing_extensions import TypeAlias from xml.dom.minidom import Document, DOMImplementation, Element, Text from xml.sax.handler import ContentHandler from xml.sax.xmlreader import XMLReader diff --git a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi index c07e4ba2465e..480dd7ce732c 100644 --- a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi +++ b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi @@ -1,6 +1,6 @@ from _typeshed import Incomplete, Unused -from typing import Any, NoReturn -from typing_extensions import Literal, TypeAlias +from typing import Any, Literal, NoReturn +from typing_extensions import TypeAlias from urllib.request import OpenerDirector from xml.dom.expatbuilder import ExpatBuilder, ExpatBuilderNS from xml.dom.minidom import Node diff --git a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi index b08ca88e7e97..c508f72892c1 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi @@ -2,14 +2,16 @@ import sys from _collections_abc import dict_keys from _typeshed import FileDescriptorOrPath, ReadableBuffer, SupportsRead, SupportsWrite from collections.abc import Callable, Generator, ItemsView, Iterable, Iterator, Mapping, Sequence -from typing import Any, TypeVar, overload -from typing_extensions import Literal, SupportsIndex, TypeAlias, TypeGuard +from typing import Any, Literal, SupportsIndex, TypeVar, overload +from typing_extensions import TypeAlias, TypeGuard __all__ = [ + "C14NWriterTarget", "Comment", "dump", "Element", "ElementTree", + "canonicalize", "fromstring", "fromstringlist", "iselement", @@ -31,9 +33,6 @@ __all__ = [ "register_namespace", ] -if sys.version_info >= (3, 8): - __all__ += ["C14NWriterTarget", "canonicalize"] - if sys.version_info >= (3, 9): __all__ += ["indent"] @@ -50,36 +49,34 @@ class ParseError(SyntaxError): # In reality it works based on `.tag` attribute duck typing. def iselement(element: object) -> TypeGuard[Element]: ... - -if sys.version_info >= (3, 8): - @overload - def canonicalize( - xml_data: str | ReadableBuffer | None = None, - *, - out: None = None, - from_file: _FileRead | None = None, - with_comments: bool = False, - strip_text: bool = False, - rewrite_prefixes: bool = False, - qname_aware_tags: Iterable[str] | None = None, - qname_aware_attrs: Iterable[str] | None = None, - exclude_attrs: Iterable[str] | None = None, - exclude_tags: Iterable[str] | None = None, - ) -> str: ... - @overload - def canonicalize( - xml_data: str | ReadableBuffer | None = None, - *, - out: SupportsWrite[str], - from_file: _FileRead | None = None, - with_comments: bool = False, - strip_text: bool = False, - rewrite_prefixes: bool = False, - qname_aware_tags: Iterable[str] | None = None, - qname_aware_attrs: Iterable[str] | None = None, - exclude_attrs: Iterable[str] | None = None, - exclude_tags: Iterable[str] | None = None, - ) -> None: ... +@overload +def canonicalize( + xml_data: str | ReadableBuffer | None = None, + *, + out: None = None, + from_file: _FileRead | None = None, + with_comments: bool = False, + strip_text: bool = False, + rewrite_prefixes: bool = False, + qname_aware_tags: Iterable[str] | None = None, + qname_aware_attrs: Iterable[str] | None = None, + exclude_attrs: Iterable[str] | None = None, + exclude_tags: Iterable[str] | None = None, +) -> str: ... +@overload +def canonicalize( + xml_data: str | ReadableBuffer | None = None, + *, + out: SupportsWrite[str], + from_file: _FileRead | None = None, + with_comments: bool = False, + strip_text: bool = False, + rewrite_prefixes: bool = False, + qname_aware_tags: Iterable[str] | None = None, + qname_aware_attrs: Iterable[str] | None = None, + exclude_attrs: Iterable[str] | None = None, + exclude_tags: Iterable[str] | None = None, +) -> None: ... class Element: tag: str @@ -172,93 +169,66 @@ class ElementTree: def write_c14n(self, file: _FileWriteC14N) -> None: ... def register_namespace(prefix: str, uri: str) -> None: ... - -if sys.version_info >= (3, 8): - @overload - def tostring( - element: Element, - encoding: None = None, - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> bytes: ... - @overload - def tostring( - element: Element, - encoding: Literal["unicode"], - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> str: ... - @overload - def tostring( - element: Element, - encoding: str, - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> Any: ... - @overload - def tostringlist( - element: Element, - encoding: None = None, - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> list[bytes]: ... - @overload - def tostringlist( - element: Element, - encoding: Literal["unicode"], - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> list[str]: ... - @overload - def tostringlist( - element: Element, - encoding: str, - method: str | None = None, - *, - xml_declaration: bool | None = None, - default_namespace: str | None = None, - short_empty_elements: bool = True, - ) -> list[Any]: ... - -else: - @overload - def tostring( - element: Element, encoding: None = None, method: str | None = None, *, short_empty_elements: bool = True - ) -> bytes: ... - @overload - def tostring( - element: Element, encoding: Literal["unicode"], method: str | None = None, *, short_empty_elements: bool = True - ) -> str: ... - @overload - def tostring(element: Element, encoding: str, method: str | None = None, *, short_empty_elements: bool = True) -> Any: ... - @overload - def tostringlist( - element: Element, encoding: None = None, method: str | None = None, *, short_empty_elements: bool = True - ) -> list[bytes]: ... - @overload - def tostringlist( - element: Element, encoding: Literal["unicode"], method: str | None = None, *, short_empty_elements: bool = True - ) -> list[str]: ... - @overload - def tostringlist( - element: Element, encoding: str, method: str | None = None, *, short_empty_elements: bool = True - ) -> list[Any]: ... - +@overload +def tostring( + element: Element, + encoding: None = None, + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> bytes: ... +@overload +def tostring( + element: Element, + encoding: Literal["unicode"], + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> str: ... +@overload +def tostring( + element: Element, + encoding: str, + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> Any: ... +@overload +def tostringlist( + element: Element, + encoding: None = None, + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> list[bytes]: ... +@overload +def tostringlist( + element: Element, + encoding: Literal["unicode"], + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> list[str]: ... +@overload +def tostringlist( + element: Element, + encoding: str, + method: str | None = None, + *, + xml_declaration: bool | None = None, + default_namespace: str | None = None, + short_empty_elements: bool = True, +) -> list[Any]: ... def dump(elem: Element) -> None: ... if sys.version_info >= (3, 9): @@ -297,21 +267,18 @@ def fromstringlist(sequence: Sequence[str | ReadableBuffer], parser: XMLParser | _ElementFactory: TypeAlias = Callable[[Any, dict[Any, Any]], Element] class TreeBuilder: - if sys.version_info >= (3, 8): - # comment_factory can take None because passing None to Comment is not an error - def __init__( - self, - element_factory: _ElementFactory | None = ..., - *, - comment_factory: Callable[[str | None], Element] | None = ..., - pi_factory: Callable[[str, str | None], Element] | None = ..., - insert_comments: bool = ..., - insert_pis: bool = ..., - ) -> None: ... - insert_comments: bool - insert_pis: bool - else: - def __init__(self, element_factory: _ElementFactory | None = ...) -> None: ... + # comment_factory can take None because passing None to Comment is not an error + def __init__( + self, + element_factory: _ElementFactory | None = ..., + *, + comment_factory: Callable[[str | None], Element] | None = ..., + pi_factory: Callable[[str, str | None], Element] | None = ..., + insert_comments: bool = ..., + insert_pis: bool = ..., + ) -> None: ... + insert_comments: bool + insert_pis: bool def close(self) -> Element: ... def data(self, __data: str) -> None: ... @@ -319,31 +286,29 @@ class TreeBuilder: # depending on what the particular factory supports. def start(self, __tag: Any, __attrs: dict[Any, Any]) -> Element: ... def end(self, __tag: str) -> Element: ... - if sys.version_info >= (3, 8): - # These two methods have pos-only parameters in the C implementation - def comment(self, __text: str | None) -> Element: ... - def pi(self, __target: str, __text: str | None = None) -> Element: ... + # These two methods have pos-only parameters in the C implementation + def comment(self, __text: str | None) -> Element: ... + def pi(self, __target: str, __text: str | None = None) -> Element: ... -if sys.version_info >= (3, 8): - class C14NWriterTarget: - def __init__( - self, - write: Callable[[str], object], - *, - with_comments: bool = False, - strip_text: bool = False, - rewrite_prefixes: bool = False, - qname_aware_tags: Iterable[str] | None = None, - qname_aware_attrs: Iterable[str] | None = None, - exclude_attrs: Iterable[str] | None = None, - exclude_tags: Iterable[str] | None = None, - ) -> None: ... - def data(self, data: str) -> None: ... - def start_ns(self, prefix: str, uri: str) -> None: ... - def start(self, tag: str, attrs: Mapping[str, str]) -> None: ... - def end(self, tag: str) -> None: ... - def comment(self, text: str) -> None: ... - def pi(self, target: str, data: str) -> None: ... +class C14NWriterTarget: + def __init__( + self, + write: Callable[[str], object], + *, + with_comments: bool = False, + strip_text: bool = False, + rewrite_prefixes: bool = False, + qname_aware_tags: Iterable[str] | None = None, + qname_aware_attrs: Iterable[str] | None = None, + exclude_attrs: Iterable[str] | None = None, + exclude_tags: Iterable[str] | None = None, + ) -> None: ... + def data(self, data: str) -> None: ... + def start_ns(self, prefix: str, uri: str) -> None: ... + def start(self, tag: str, attrs: Mapping[str, str]) -> None: ... + def end(self, tag: str) -> None: ... + def comment(self, text: str) -> None: ... + def pi(self, target: str, data: str) -> None: ... class XMLParser: parser: Any @@ -351,11 +316,6 @@ class XMLParser: # TODO-what is entity used for??? entity: Any version: str - if sys.version_info >= (3, 8): - def __init__(self, *, target: Any = ..., encoding: str | None = ...) -> None: ... - else: - def __init__(self, html: int = ..., target: Any = ..., encoding: str | None = ...) -> None: ... - def doctype(self, __name: str, __pubid: str, __system: str) -> None: ... - + def __init__(self, *, target: Any = ..., encoding: str | None = ...) -> None: ... def close(self) -> Any: ... def feed(self, __data: str | ReadableBuffer) -> None: ... diff --git a/mypy/typeshed/stdlib/xml/sax/__init__.pyi b/mypy/typeshed/stdlib/xml/sax/__init__.pyi index d2d6f12d474a..a2eecc5a7864 100644 --- a/mypy/typeshed/stdlib/xml/sax/__init__.pyi +++ b/mypy/typeshed/stdlib/xml/sax/__init__.pyi @@ -1,4 +1,3 @@ -import sys from _typeshed import ReadableBuffer, StrPath, SupportsRead, _T_co from collections.abc import Iterable from typing import Protocol @@ -16,21 +15,11 @@ from xml.sax.xmlreader import XMLReader class _SupportsReadClose(SupportsRead[_T_co], Protocol[_T_co]): def close(self) -> None: ... -if sys.version_info >= (3, 8): - _Source: TypeAlias = StrPath | _SupportsReadClose[bytes] | _SupportsReadClose[str] -else: - _Source: TypeAlias = str | _SupportsReadClose[bytes] | _SupportsReadClose[str] +_Source: TypeAlias = StrPath | _SupportsReadClose[bytes] | _SupportsReadClose[str] default_parser_list: list[str] -if sys.version_info >= (3, 8): - - def make_parser(parser_list: Iterable[str] = ()) -> XMLReader: ... - -else: - - def make_parser(parser_list: list[str] = []) -> XMLReader: ... - +def make_parser(parser_list: Iterable[str] = ()) -> XMLReader: ... def parse(source: _Source, handler: ContentHandler, errorHandler: ErrorHandler = ...) -> None: ... def parseString(string: ReadableBuffer | str, handler: ContentHandler, errorHandler: ErrorHandler | None = ...) -> None: ... def _create_parser(parser_name: str) -> XMLReader: ... diff --git a/mypy/typeshed/stdlib/xmlrpc/client.pyi b/mypy/typeshed/stdlib/xmlrpc/client.pyi index 79969359f091..2be5f7df2d7d 100644 --- a/mypy/typeshed/stdlib/xmlrpc/client.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/client.pyi @@ -1,14 +1,13 @@ import gzip import http.client -import sys import time from _typeshed import ReadableBuffer, SizedBuffer, SupportsRead, SupportsWrite from collections.abc import Callable, Iterable, Mapping from datetime import datetime from io import BytesIO from types import TracebackType -from typing import Any, Protocol, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import Any, Literal, Protocol, overload +from typing_extensions import Self, TypeAlias class _SupportsTimeTuple(Protocol): def timetuple(self) -> time.struct_time: ... @@ -228,13 +227,9 @@ class Transport: _headers: list[tuple[str, str]] _extra_headers: list[tuple[str, str]] - if sys.version_info >= (3, 8): - def __init__( - self, use_datetime: bool = False, use_builtin_types: bool = False, *, headers: Iterable[tuple[str, str]] = () - ) -> None: ... - else: - def __init__(self, use_datetime: bool = False, use_builtin_types: bool = False) -> None: ... - + def __init__( + self, use_datetime: bool = False, use_builtin_types: bool = False, *, headers: Iterable[tuple[str, str]] = () + ) -> None: ... def request( self, host: _HostType, handler: str, request_body: SizedBuffer, verbose: bool = False ) -> tuple[_Marshallable, ...]: ... @@ -253,20 +248,14 @@ class Transport: def parse_response(self, response: http.client.HTTPResponse) -> tuple[_Marshallable, ...]: ... class SafeTransport(Transport): - if sys.version_info >= (3, 8): - def __init__( - self, - use_datetime: bool = False, - use_builtin_types: bool = False, - *, - headers: Iterable[tuple[str, str]] = (), - context: Any | None = None, - ) -> None: ... - else: - def __init__( - self, use_datetime: bool = False, use_builtin_types: bool = False, *, context: Any | None = None - ) -> None: ... - + def __init__( + self, + use_datetime: bool = False, + use_builtin_types: bool = False, + *, + headers: Iterable[tuple[str, str]] = (), + context: Any | None = None, + ) -> None: ... def make_connection(self, host: _HostType) -> http.client.HTTPSConnection: ... class ServerProxy: @@ -277,34 +266,19 @@ class ServerProxy: __verbose: bool __allow_none: bool - if sys.version_info >= (3, 8): - def __init__( - self, - uri: str, - transport: Transport | None = None, - encoding: str | None = None, - verbose: bool = False, - allow_none: bool = False, - use_datetime: bool = False, - use_builtin_types: bool = False, - *, - headers: Iterable[tuple[str, str]] = (), - context: Any | None = None, - ) -> None: ... - else: - def __init__( - self, - uri: str, - transport: Transport | None = None, - encoding: str | None = None, - verbose: bool = False, - allow_none: bool = False, - use_datetime: bool = False, - use_builtin_types: bool = False, - *, - context: Any | None = None, - ) -> None: ... - + def __init__( + self, + uri: str, + transport: Transport | None = None, + encoding: str | None = None, + verbose: bool = False, + allow_none: bool = False, + use_datetime: bool = False, + use_builtin_types: bool = False, + *, + headers: Iterable[tuple[str, str]] = (), + context: Any | None = None, + ) -> None: ... def __getattr__(self, name: str) -> _Method: ... @overload def __call__(self, attr: Literal["close"]) -> Callable[[], None]: ... diff --git a/mypy/typeshed/stdlib/xxlimited.pyi b/mypy/typeshed/stdlib/xxlimited.pyi index 7fc39138fec5..3e6e78de3f70 100644 --- a/mypy/typeshed/stdlib/xxlimited.pyi +++ b/mypy/typeshed/stdlib/xxlimited.pyi @@ -1,6 +1,5 @@ import sys -from typing import Any -from typing_extensions import final +from typing import Any, final class Str(str): ... diff --git a/mypy/typeshed/stdlib/zipfile/__init__.pyi b/mypy/typeshed/stdlib/zipfile/__init__.pyi index 83982be3be08..be0cdf12a4a9 100644 --- a/mypy/typeshed/stdlib/zipfile/__init__.pyi +++ b/mypy/typeshed/stdlib/zipfile/__init__.pyi @@ -5,12 +5,13 @@ from collections.abc import Callable, Iterable, Iterator from io import TextIOWrapper from os import PathLike from types import TracebackType -from typing import IO, Protocol, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Literal, Protocol, overload +from typing_extensions import Self, TypeAlias __all__ = [ "BadZipFile", "BadZipfile", + "Path", "error", "ZIP_STORED", "ZIP_DEFLATED", @@ -23,15 +24,13 @@ __all__ = [ "LargeZipFile", ] -if sys.version_info >= (3, 8): - __all__ += ["Path"] - -# TODO: use TypeAlias when mypy bugs are fixed +# TODO: use TypeAlias for these two when mypy bugs are fixed # https://github.com/python/mypy/issues/16581 _DateTuple = tuple[int, int, int, int, int, int] # noqa: Y026 +_ZipFileMode = Literal["r", "w", "x", "a"] # noqa: Y026 + _ReadWriteMode: TypeAlias = Literal["r", "w"] _ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] -_ZipFileMode: TypeAlias = Literal["r", "w", "x", "a"] class BadZipFile(Exception): ... @@ -132,7 +131,7 @@ class ZipFile: strict_timestamps: bool = True, metadata_encoding: None = None, ) -> None: ... - elif sys.version_info >= (3, 8): + else: def __init__( self, file: StrPath | IO[bytes], @@ -143,15 +142,6 @@ class ZipFile: *, strict_timestamps: bool = True, ) -> None: ... - else: - def __init__( - self, - file: StrPath | IO[bytes], - mode: _ZipFileMode = "r", - compression: int = 0, - allowZip64: bool = True, - compresslevel: int | None = None, - ) -> None: ... def __enter__(self) -> Self: ... def __exit__( @@ -217,20 +207,15 @@ class ZipInfo: file_size: int orig_filename: str # undocumented def __init__(self, filename: str = "NoName", date_time: _DateTuple = (1980, 1, 1, 0, 0, 0)) -> None: ... - if sys.version_info >= (3, 8): - @classmethod - def from_file(cls, filename: StrPath, arcname: StrPath | None = None, *, strict_timestamps: bool = True) -> Self: ... - else: - @classmethod - def from_file(cls, filename: StrPath, arcname: StrPath | None = None) -> Self: ... - + @classmethod + def from_file(cls, filename: StrPath, arcname: StrPath | None = None, *, strict_timestamps: bool = True) -> Self: ... def is_dir(self) -> bool: ... def FileHeader(self, zip64: bool | None = None) -> bytes: ... if sys.version_info >= (3, 12): from zipfile._path import CompleteDirs as CompleteDirs, Path as Path -elif sys.version_info >= (3, 8): +else: class CompleteDirs(ZipFile): def resolve_dir(self, name: str) -> str: ... @overload diff --git a/mypy/typeshed/stdlib/zipfile/_path.pyi b/mypy/typeshed/stdlib/zipfile/_path.pyi index 3cf034aec8f4..0398824e1fd2 100644 --- a/mypy/typeshed/stdlib/zipfile/_path.pyi +++ b/mypy/typeshed/stdlib/zipfile/_path.pyi @@ -3,8 +3,8 @@ from _typeshed import StrPath from collections.abc import Iterator, Sequence from io import TextIOWrapper from os import PathLike -from typing import IO, overload -from typing_extensions import Literal, Self, TypeAlias +from typing import IO, Literal, overload +from typing_extensions import Self, TypeAlias from zipfile import ZipFile _ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] diff --git a/mypy/typeshed/stdlib/zipimport.pyi b/mypy/typeshed/stdlib/zipimport.pyi index 0189bfe712b5..158d573cac74 100644 --- a/mypy/typeshed/stdlib/zipimport.pyi +++ b/mypy/typeshed/stdlib/zipimport.pyi @@ -4,8 +4,7 @@ from importlib.abc import ResourceReader from importlib.machinery import ModuleSpec from types import CodeType, ModuleType -if sys.version_info >= (3, 8): - __all__ = ["ZipImportError", "zipimporter"] +__all__ = ["ZipImportError", "zipimporter"] class ZipImportError(ImportError): ... diff --git a/mypy/typeshed/stdlib/zlib.pyi b/mypy/typeshed/stdlib/zlib.pyi index c3419af0de3f..efeb5a88a76f 100644 --- a/mypy/typeshed/stdlib/zlib.pyi +++ b/mypy/typeshed/stdlib/zlib.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import ReadableBuffer -from typing_extensions import Literal +from typing import Literal DEFLATED: Literal[8] DEF_MEM_LEVEL: int # can change diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 9f6f5d3838a4..b51a965c95da 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -866,30 +866,6 @@ _program.py:10: error: Incompatible types in assignment (expression has type "in _program.py:20: error: Argument 1 to "tst" has incompatible type "defaultdict[str, List[Never]]"; expected "defaultdict[int, List[Never]]" _program.py:24: error: Invalid index type "str" for "MyDDict[Dict[Never, Never]]"; expected type "int" -[case testNoSubcriptionOfStdlibCollections] -# flags: --python-version 3.7 -import collections -from collections import Counter -from typing import TypeVar - -collections.defaultdict[int, str]() -Counter[int]() - -T = TypeVar('T') -DDint = collections.defaultdict[T, int] - -d = DDint[str]() -d[0] = 1 - -def f(d: collections.defaultdict[int, str]) -> None: - ... -[out] -_program.py:6: error: "defaultdict" is not subscriptable -_program.py:7: error: "Counter" is not subscriptable -_program.py:10: error: "defaultdict" is not subscriptable -_program.py:13: error: Invalid index type "int" for "defaultdict[str, int]"; expected type "str" -_program.py:15: error: "defaultdict" is not subscriptable, use "typing.DefaultDict" instead - [case testCollectionsAliases] import typing as t import collections as c @@ -1590,12 +1566,11 @@ _testNoPython3StubAvailable.py:3: note: (or run "mypy --install-types" to instal [case testTypingOrderedDictAlias] -# flags: --python-version 3.7 from typing import OrderedDict x: OrderedDict[str, int] = OrderedDict({}) reveal_type(x) [out] -_testTypingOrderedDictAlias.py:4: note: Revealed type is "collections.OrderedDict[builtins.str, builtins.int]" +_testTypingOrderedDictAlias.py:3: note: Revealed type is "collections.OrderedDict[builtins.str, builtins.int]" [case testTypingExtensionsOrderedDictAlias] from typing_extensions import OrderedDict @@ -1711,7 +1686,6 @@ _testTypeAliasWithNewStyleUnion.py:25: note: Revealed type is "Union[Type[builti _testTypeAliasWithNewStyleUnion.py:28: note: Revealed type is "Union[Type[builtins.int], builtins.str]" [case testTypeAliasWithNewStyleUnionInStub] -# flags: --python-version 3.7 import m a: m.A reveal_type(a) @@ -1762,12 +1736,12 @@ CU4: TypeAlias = int | Callable[[str | bool], str] [out] m.pyi:5: note: Revealed type is "typing._SpecialForm" m.pyi:22: note: Revealed type is "typing._SpecialForm" -_testTypeAliasWithNewStyleUnionInStub.py:4: note: Revealed type is "Union[Type[builtins.int], builtins.str]" -_testTypeAliasWithNewStyleUnionInStub.py:6: note: Revealed type is "Union[Type[builtins.int], builtins.str]" -_testTypeAliasWithNewStyleUnionInStub.py:8: note: Revealed type is "Union[Type[builtins.int], builtins.str]" -_testTypeAliasWithNewStyleUnionInStub.py:10: note: Revealed type is "Union[Type[builtins.int], builtins.str]" -_testTypeAliasWithNewStyleUnionInStub.py:12: note: Revealed type is "Union[builtins.str, Type[builtins.int]]" -_testTypeAliasWithNewStyleUnionInStub.py:14: note: Revealed type is "Union[builtins.str, Type[builtins.int]]" +_testTypeAliasWithNewStyleUnionInStub.py:3: note: Revealed type is "Union[Type[builtins.int], builtins.str]" +_testTypeAliasWithNewStyleUnionInStub.py:5: note: Revealed type is "Union[Type[builtins.int], builtins.str]" +_testTypeAliasWithNewStyleUnionInStub.py:7: note: Revealed type is "Union[Type[builtins.int], builtins.str]" +_testTypeAliasWithNewStyleUnionInStub.py:9: note: Revealed type is "Union[Type[builtins.int], builtins.str]" +_testTypeAliasWithNewStyleUnionInStub.py:11: note: Revealed type is "Union[builtins.str, Type[builtins.int]]" +_testTypeAliasWithNewStyleUnionInStub.py:13: note: Revealed type is "Union[builtins.str, Type[builtins.int]]" [case testEnumNameWorkCorrectlyOn311] # flags: --python-version 3.11 From 3f58c2d940ac92afe8cf4c80cf6508b048dd272e Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 2 Feb 2024 16:56:02 +0100 Subject: [PATCH 56/69] Fix TypeVar defaults with None (PEP 696) (#16859) Ref: https://github.com/python/mypy/issues/14851 --- mypy/typeanal.py | 4 +++- test-data/unit/check-typevar-defaults.test | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 2b37d10e2aff..530793730f35 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -39,6 +39,7 @@ from mypy.options import Options from mypy.plugin import AnalyzeTypeContext, Plugin, TypeAnalyzerPluginInterface from mypy.semanal_shared import SemanticAnalyzerCoreInterface, paramspec_args, paramspec_kwargs +from mypy.state import state from mypy.tvar_scope import TypeVarLikeScope from mypy.types import ( ANNOTATED_TYPE_NAMES, @@ -1893,7 +1894,8 @@ def fix_instance( t.args = tuple(args) fix_type_var_tuple_argument(t) if not t.type.has_type_var_tuple_type: - fixed = expand_type(t, env) + with state.strict_optional_set(options.strict_optional): + fixed = expand_type(t, env) assert isinstance(fixed, Instance) t.args = fixed.args diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 6136746cbd0a..75453a3a4f80 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -124,6 +124,7 @@ from typing import Generic, TypeVar, Union, overload T1 = TypeVar("T1") T2 = TypeVar("T2", default=int) T3 = TypeVar("T3", default=str) +T4 = TypeVar("T4", default=Union[int, None]) class ClassA1(Generic[T2, T3]): ... @@ -200,6 +201,20 @@ def func_a3( n = ClassA3[float, float, float]() # E: Type application has too many types (expected between 1 and 2) reveal_type(n) # N: Revealed type is "Any" +class ClassA4(Generic[T4]): ... + +def func_a4( + a: ClassA4, + b: ClassA4[float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassA4[Union[builtins.int, None]]" + reveal_type(b) # N: Revealed type is "__main__.ClassA4[builtins.float]" + + k = ClassA4() + reveal_type(k) # N: Revealed type is "__main__.ClassA4[Union[builtins.int, None]]" + l = ClassA4[float]() + reveal_type(l) # N: Revealed type is "__main__.ClassA4[builtins.float]" + [case testTypeVarDefaultsClass2] # flags: --disallow-any-generics from typing import Generic, ParamSpec From 3804f7e320288e625bbedc916a6c26d635bf8e3f Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 3 Feb 2024 05:19:03 +0100 Subject: [PATCH 57/69] Expand TypeVarTuple default (PEP 696) (#16851) Small change to fix an error when expanding a TypeVarTuple default. ``` RuntimeError: Invalid type replacement to expand: Unpack[tuple[builtins.int, builtins.str]] ``` Ref: #14851 --- mypy/expandtype.py | 2 ++ mypy/test/testtypes.py | 2 +- test-data/unit/check-typevar-defaults.test | 12 ++++++------ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index b4bc1aa9b9a5..d2d294fb77f3 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -277,6 +277,8 @@ def visit_unpack_type(self, t: UnpackType) -> Type: def expand_unpack(self, t: UnpackType) -> list[Type]: assert isinstance(t.type, TypeVarTupleType) repl = get_proper_type(self.variables.get(t.type.id, t.type)) + if isinstance(repl, UnpackType): + repl = get_proper_type(repl.type) if isinstance(repl, TupleType): return repl.items elif ( diff --git a/mypy/test/testtypes.py b/mypy/test/testtypes.py index e8dd623bec53..b3f84905c47e 100644 --- a/mypy/test/testtypes.py +++ b/mypy/test/testtypes.py @@ -1541,7 +1541,7 @@ def make_call(*items: tuple[str, str | None]) -> CallExpr: class TestExpandTypeLimitGetProperType(TestCase): # WARNING: do not increase this number unless absolutely necessary, # and you understand what you are doing. - ALLOWED_GET_PROPER_TYPES = 8 + ALLOWED_GET_PROPER_TYPES = 9 @skipUnless(mypy.expandtype.__file__.endswith(".py"), "Skip for compiled mypy") def test_count_get_proper_type(self) -> None: diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 75453a3a4f80..544bc59494b3 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -289,8 +289,8 @@ def func_c1( # reveal_type(a) # Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" # TODO reveal_type(b) # N: Revealed type is "__main__.ClassC1[builtins.float]" - # k = ClassC1() # TODO - # reveal_type(k) # Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" # TODO + k = ClassC1() + reveal_type(k) # N: Revealed type is "__main__.ClassC1[builtins.int, builtins.str]" l = ClassC1[float]() reveal_type(l) # N: Revealed type is "__main__.ClassC1[builtins.float]" @@ -305,8 +305,8 @@ def func_c2( # reveal_type(b) # Revealed type is "__main__.ClassC2[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO reveal_type(c) # N: Revealed type is "__main__.ClassC2[builtins.int]" - # k = ClassC2() # TODO - # reveal_type(k) # Revealed type is "__main__.ClassC2[builtins.str, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO + k = ClassC2() + reveal_type(k) # N: Revealed type is "__main__.ClassC2[builtins.str, Unpack[builtins.tuple[builtins.float, ...]]]" l = ClassC2[int]() # reveal_type(l) # Revealed type is "__main__.ClassC2[builtins.int, Unpack[builtins.tuple[builtins.float, ...]]]" # TODO m = ClassC2[int, Unpack[Tuple[()]]]() @@ -323,8 +323,8 @@ def func_c3( reveal_type(b) # N: Revealed type is "__main__.ClassC3[builtins.int]" reveal_type(c) # N: Revealed type is "__main__.ClassC3[builtins.int, builtins.float]" - # k = ClassC3() # TODO - # reveal_type(k) # Revealed type is "__main__.ClassC3[builtins.str]" # TODO + k = ClassC3() + reveal_type(k) # N: Revealed type is "__main__.ClassC3[builtins.str]" l = ClassC3[int]() reveal_type(l) # N: Revealed type is "__main__.ClassC3[builtins.int]" m = ClassC3[int, Unpack[Tuple[float]]]() From 9bb102aafab24c59c42a8b0c071a467c123bd22e Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 3 Feb 2024 10:25:56 +0100 Subject: [PATCH 58/69] Sync typeshed Source commit: https://github.com/python/typeshed/commit/5ce34dc09606aa3fcd09254e6e51c9d68afefe49 --- mypy/typeshed/stdlib/_ctypes.pyi | 6 +- mypy/typeshed/stdlib/builtins.pyi | 91 +++++++++++++++++++++- mypy/typeshed/stdlib/functools.pyi | 40 ++++++---- mypy/typeshed/stdlib/numbers.pyi | 118 +++++++++++++++++------------ 4 files changed, 191 insertions(+), 64 deletions(-) diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index ec3d86e41687..36540172ab95 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -167,7 +167,11 @@ class Array(_CData, Generic[_CT]): def _type_(self) -> type[_CT]: ... @_type_.setter def _type_(self, value: type[_CT]) -> None: ... - raw: bytes # Note: only available if _CT == c_char + # Note: only available if _CT == c_char + @property + def raw(self) -> bytes: ... + @raw.setter + def raw(self, value: ReadableBuffer) -> None: ... value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise # TODO These methods cannot be annotated correctly at the moment. # All of these "Any"s stand for the array's element type, but it's not possible to use _CT diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 1ae1ba03e1ad..b8c807dd388d 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -61,6 +61,7 @@ from typing import ( # noqa: Y022 from typing_extensions import ( # noqa: Y023 Concatenate, Literal, + LiteralString, ParamSpec, Self, TypeAlias, @@ -434,8 +435,17 @@ class str(Sequence[str]): def __new__(cls, object: object = ...) -> Self: ... @overload def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ... + @overload + def capitalize(self: LiteralString) -> LiteralString: ... + @overload def capitalize(self) -> str: ... # type: ignore[misc] + @overload + def casefold(self: LiteralString) -> LiteralString: ... + @overload def casefold(self) -> str: ... # type: ignore[misc] + @overload + def center(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... + @overload def center(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] def count(self, x: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes: ... @@ -443,10 +453,13 @@ class str(Sequence[str]): self, __suffix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... @overload - def expandtabs(self: str, tabsize: SupportsIndex = 8) -> str: ... + def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] def find(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... + @overload + def format(self: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... + @overload def format(self, *args: object, **kwargs: object) -> str: ... def format_map(self, map: _FormatMapMapping) -> str: ... def index(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... @@ -462,32 +475,91 @@ class str(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... + @overload + def join(self: LiteralString, __iterable: Iterable[LiteralString]) -> LiteralString: ... + @overload def join(self, __iterable: Iterable[str]) -> str: ... # type: ignore[misc] + @overload + def ljust(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... + @overload def ljust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] + @overload + def lower(self: LiteralString) -> LiteralString: ... + @overload def lower(self) -> str: ... # type: ignore[misc] + @overload + def lstrip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... + @overload def lstrip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] + @overload + def partition(self: LiteralString, __sep: LiteralString) -> tuple[LiteralString, LiteralString, LiteralString]: ... + @overload def partition(self, __sep: str) -> tuple[str, str, str]: ... # type: ignore[misc] + @overload + def replace( + self: LiteralString, __old: LiteralString, __new: LiteralString, __count: SupportsIndex = -1 + ) -> LiteralString: ... + @overload def replace(self, __old: str, __new: str, __count: SupportsIndex = -1) -> str: ... # type: ignore[misc] if sys.version_info >= (3, 9): + @overload + def removeprefix(self: LiteralString, __prefix: LiteralString) -> LiteralString: ... + @overload def removeprefix(self, __prefix: str) -> str: ... # type: ignore[misc] + @overload + def removesuffix(self: LiteralString, __suffix: LiteralString) -> LiteralString: ... + @overload def removesuffix(self, __suffix: str) -> str: ... # type: ignore[misc] def rfind(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def rindex(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... + @overload + def rjust(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... + @overload def rjust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] + @overload + def rpartition(self: LiteralString, __sep: LiteralString) -> tuple[LiteralString, LiteralString, LiteralString]: ... + @overload def rpartition(self, __sep: str) -> tuple[str, str, str]: ... # type: ignore[misc] + @overload + def rsplit(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... + @overload def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] + @overload + def rstrip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... + @overload def rstrip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] + @overload + def split(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... + @overload def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] + @overload + def splitlines(self: LiteralString, keepends: bool = False) -> list[LiteralString]: ... + @overload def splitlines(self, keepends: bool = False) -> list[str]: ... # type: ignore[misc] def startswith( self, __prefix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... + @overload + def strip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... + @overload def strip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] + @overload + def swapcase(self: LiteralString) -> LiteralString: ... + @overload def swapcase(self) -> str: ... # type: ignore[misc] + @overload + def title(self: LiteralString) -> LiteralString: ... + @overload def title(self) -> str: ... # type: ignore[misc] def translate(self, __table: _TranslateTable) -> str: ... + @overload + def upper(self: LiteralString) -> LiteralString: ... + @overload def upper(self) -> str: ... # type: ignore[misc] + @overload + def zfill(self: LiteralString, __width: SupportsIndex) -> LiteralString: ... + @overload def zfill(self, __width: SupportsIndex) -> str: ... # type: ignore[misc] @staticmethod @overload @@ -498,6 +570,9 @@ class str(Sequence[str]): @staticmethod @overload def maketrans(__x: str, __y: str, __z: str) -> dict[int, int | None]: ... + @overload + def __add__(self: LiteralString, __value: LiteralString) -> LiteralString: ... + @overload def __add__(self, __value: str) -> str: ... # type: ignore[misc] # Incompatible with Sequence.__contains__ def __contains__(self, __key: str) -> bool: ... # type: ignore[override] @@ -506,13 +581,25 @@ class str(Sequence[str]): def __getitem__(self, __key: SupportsIndex | slice) -> str: ... def __gt__(self, __value: str) -> bool: ... def __hash__(self) -> int: ... + @overload + def __iter__(self: LiteralString) -> Iterator[LiteralString]: ... + @overload def __iter__(self) -> Iterator[str]: ... # type: ignore[misc] def __le__(self, __value: str) -> bool: ... def __len__(self) -> int: ... def __lt__(self, __value: str) -> bool: ... + @overload + def __mod__(self: LiteralString, __value: LiteralString | tuple[LiteralString, ...]) -> LiteralString: ... + @overload def __mod__(self, __value: Any) -> str: ... + @overload + def __mul__(self: LiteralString, __value: SupportsIndex) -> LiteralString: ... + @overload def __mul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] def __ne__(self, __value: object) -> bool: ... + @overload + def __rmul__(self: LiteralString, __value: SupportsIndex) -> LiteralString: ... + @overload def __rmul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] def __getnewargs__(self) -> tuple[str]: ... @@ -1593,7 +1680,7 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # without creating many false-positive errors (see #7578). # Instead, we special-case the most common examples of this: bool and literal integers. @overload -def sum(__iterable: Iterable[bool], start: int = 0) -> int: ... # type: ignore[overload-overlap] +def sum(__iterable: Iterable[bool | _LiteralInteger], start: int = 0) -> int: ... # type: ignore[overload-overlap] @overload def sum(__iterable: Iterable[_SupportsSumNoDefaultT]) -> _SupportsSumNoDefaultT | Literal[0]: ... @overload diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 0f1666024f84..8c48e77c16cf 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -1,9 +1,9 @@ import sys import types -from _typeshed import IdentityFunction, SupportsAllComparisons, SupportsItems +from _typeshed import SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload -from typing_extensions import Self, TypeAlias +from typing_extensions import ParamSpec, Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -27,10 +27,12 @@ __all__ = [ if sys.version_info >= (3, 9): __all__ += ["cache"] -_AnyCallable: TypeAlias = Callable[..., object] - _T = TypeVar("_T") _S = TypeVar("_S") +_PWrapped = ParamSpec("_PWrapped") +_RWrapped = TypeVar("_RWrapped") +_PWrapper = ParamSpec("_PWrapper") +_RWrapper = TypeVar("_RWrapper") @overload def reduce(__function: Callable[[_T, _S], _T], __sequence: Iterable[_S], __initial: _T) -> _T: ... @@ -80,31 +82,41 @@ else: ] WRAPPER_UPDATES: tuple[Literal["__dict__"]] +class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWrapper]): + __wrapped__: Callable[_PWrapped, _RWrapped] + def __call__(self, *args: _PWrapper.args, **kwargs: _PWrapper.kwargs) -> _RWrapper: ... + # as with ``Callable``, we'll assume that these attributes exist + __name__: str + __qualname__: str + +class _Wrapper(Generic[_PWrapped, _RWrapped]): + def __call__(self, f: Callable[_PWrapper, _RWrapper]) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... + if sys.version_info >= (3, 12): def update_wrapper( - wrapper: _T, - wrapped: _AnyCallable, + wrapper: Callable[_PWrapper, _RWrapper], + wrapped: Callable[_PWrapped, _RWrapped], assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__", "__type_params__"), updated: Sequence[str] = ("__dict__",), - ) -> _T: ... + ) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... def wraps( - wrapped: _AnyCallable, + wrapped: Callable[_PWrapped, _RWrapped], assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__", "__type_params__"), updated: Sequence[str] = ("__dict__",), - ) -> IdentityFunction: ... + ) -> _Wrapper[_PWrapped, _RWrapped]: ... else: def update_wrapper( - wrapper: _T, - wrapped: _AnyCallable, + wrapper: Callable[_PWrapper, _RWrapper], + wrapped: Callable[_PWrapped, _RWrapped], assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__"), updated: Sequence[str] = ("__dict__",), - ) -> _T: ... + ) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... def wraps( - wrapped: _AnyCallable, + wrapped: Callable[_PWrapped, _RWrapped], assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__"), updated: Sequence[str] = ("__dict__",), - ) -> IdentityFunction: ... + ) -> _Wrapper[_PWrapped, _RWrapped]: ... def total_ordering(cls: type[_T]) -> type[_T]: ... def cmp_to_key(mycmp: Callable[[_T, _T], int]) -> Callable[[_T], SupportsAllComparisons]: ... diff --git a/mypy/typeshed/stdlib/numbers.pyi b/mypy/typeshed/stdlib/numbers.pyi index c2a0301d5636..9f507d8335cf 100644 --- a/mypy/typeshed/stdlib/numbers.pyi +++ b/mypy/typeshed/stdlib/numbers.pyi @@ -1,9 +1,25 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. +# +# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module +# rather than `numbers.Complex`, `numbers.Real` and `numbers.Integral`, +# to avoid an excessive number of `type: ignore`s in subclasses of these ABCs +# (since type checkers don't see `complex` as a subtype of `numbers.Complex`, +# nor `float` as a subtype of `numbers.Real`, etc.) +import sys from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import SupportsFloat, overload +from typing import Literal, SupportsFloat, SupportsIndex, overload +from typing_extensions import TypeAlias + +if sys.version_info >= (3, 11): + from typing import SupportsComplex as _SupportsComplex +else: + # builtins.complex didn't have a __complex__ method on older Pythons + import typing + + _SupportsComplex: TypeAlias = typing.SupportsComplex | complex __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -11,120 +27,128 @@ class Number(metaclass=ABCMeta): @abstractmethod def __hash__(self) -> int: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Complex(Number): @abstractmethod def __complex__(self) -> complex: ... def __bool__(self) -> bool: ... @property @abstractmethod - def real(self): ... + def real(self) -> SupportsFloat: ... @property @abstractmethod - def imag(self): ... + def imag(self) -> SupportsFloat: ... @abstractmethod - def __add__(self, other): ... + def __add__(self, other) -> _SupportsComplex: ... @abstractmethod - def __radd__(self, other): ... + def __radd__(self, other) -> _SupportsComplex: ... @abstractmethod - def __neg__(self): ... + def __neg__(self) -> _SupportsComplex: ... @abstractmethod - def __pos__(self): ... - def __sub__(self, other): ... - def __rsub__(self, other): ... + def __pos__(self) -> _SupportsComplex: ... + def __sub__(self, other) -> _SupportsComplex: ... + def __rsub__(self, other) -> _SupportsComplex: ... @abstractmethod - def __mul__(self, other): ... + def __mul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rmul__(self, other): ... + def __rmul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __truediv__(self, other): ... + def __truediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rtruediv__(self, other): ... + def __rtruediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __pow__(self, exponent): ... + def __pow__(self, exponent) -> _SupportsComplex: ... @abstractmethod - def __rpow__(self, base): ... + def __rpow__(self, base) -> _SupportsComplex: ... @abstractmethod - def __abs__(self) -> Real: ... + def __abs__(self) -> SupportsFloat: ... @abstractmethod - def conjugate(self): ... + def conjugate(self) -> _SupportsComplex: ... @abstractmethod def __eq__(self, other: object) -> bool: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Real(Complex, SupportsFloat): @abstractmethod def __float__(self) -> float: ... @abstractmethod - def __trunc__(self) -> int: ... + def __trunc__(self) -> SupportsIndex: ... @abstractmethod - def __floor__(self) -> int: ... + def __floor__(self) -> SupportsIndex: ... @abstractmethod - def __ceil__(self) -> int: ... + def __ceil__(self) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: None = None) -> int: ... + def __round__(self, ndigits: None = None) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: int): ... - def __divmod__(self, other): ... - def __rdivmod__(self, other): ... + def __round__(self, ndigits: int) -> SupportsFloat: ... + def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... + def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... @abstractmethod - def __floordiv__(self, other) -> int: ... + def __floordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __rfloordiv__(self, other) -> int: ... + def __rfloordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __mod__(self, other): ... + def __mod__(self, other) -> SupportsFloat: ... @abstractmethod - def __rmod__(self, other): ... + def __rmod__(self, other) -> SupportsFloat: ... @abstractmethod def __lt__(self, other) -> bool: ... @abstractmethod def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self): ... + def real(self) -> SupportsFloat: ... @property - def imag(self): ... - def conjugate(self): ... + def imag(self) -> Literal[0]: ... + def conjugate(self) -> SupportsFloat: ... # type: ignore[override] +# See comment at the top of the file +# for why some of these return types are purposefully vague class Rational(Real): @property @abstractmethod - def numerator(self) -> int: ... + def numerator(self) -> SupportsIndex: ... @property @abstractmethod - def denominator(self) -> int: ... + def denominator(self) -> SupportsIndex: ... def __float__(self) -> float: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Integral(Rational): @abstractmethod def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent, modulus: Incomplete | None = None): ... + def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] @abstractmethod - def __lshift__(self, other): ... + def __lshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rlshift__(self, other): ... + def __rlshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rshift__(self, other): ... + def __rshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rrshift__(self, other): ... + def __rrshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __and__(self, other): ... + def __and__(self, other) -> SupportsIndex: ... @abstractmethod - def __rand__(self, other): ... + def __rand__(self, other) -> SupportsIndex: ... @abstractmethod - def __xor__(self, other): ... + def __xor__(self, other) -> SupportsIndex: ... @abstractmethod - def __rxor__(self, other): ... + def __rxor__(self, other) -> SupportsIndex: ... @abstractmethod - def __or__(self, other): ... + def __or__(self, other) -> SupportsIndex: ... @abstractmethod - def __ror__(self, other): ... + def __ror__(self, other) -> SupportsIndex: ... @abstractmethod - def __invert__(self): ... + def __invert__(self) -> SupportsIndex: ... def __float__(self) -> float: ... @property - def numerator(self) -> int: ... + def numerator(self) -> SupportsIndex: ... @property - def denominator(self) -> int: ... + def denominator(self) -> Literal[1]: ... From d25e4a9ebb83d8fb2c49135be1e0c090196ee3b3 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:55:07 -0700 Subject: [PATCH 59/69] Remove use of LiteralString in builtins (#13743) --- mypy/typeshed/stdlib/builtins.pyi | 90 ------------------------------- 1 file changed, 90 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index b8c807dd388d..df78cec18226 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -61,7 +61,6 @@ from typing import ( # noqa: Y022 from typing_extensions import ( # noqa: Y023 Concatenate, Literal, - LiteralString, ParamSpec, Self, TypeAlias, @@ -435,31 +434,16 @@ class str(Sequence[str]): def __new__(cls, object: object = ...) -> Self: ... @overload def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ... - @overload - def capitalize(self: LiteralString) -> LiteralString: ... - @overload def capitalize(self) -> str: ... # type: ignore[misc] - @overload - def casefold(self: LiteralString) -> LiteralString: ... - @overload def casefold(self) -> str: ... # type: ignore[misc] - @overload - def center(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... - @overload def center(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] def count(self, x: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes: ... def endswith( self, __suffix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... - @overload - def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... - @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] def find(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... - @overload - def format(self: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... - @overload def format(self, *args: object, **kwargs: object) -> str: ... def format_map(self, map: _FormatMapMapping) -> str: ... def index(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... @@ -475,91 +459,32 @@ class str(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - @overload - def join(self: LiteralString, __iterable: Iterable[LiteralString]) -> LiteralString: ... - @overload def join(self, __iterable: Iterable[str]) -> str: ... # type: ignore[misc] - @overload - def ljust(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... - @overload def ljust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] - @overload - def lower(self: LiteralString) -> LiteralString: ... - @overload def lower(self) -> str: ... # type: ignore[misc] - @overload - def lstrip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... - @overload def lstrip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] - @overload - def partition(self: LiteralString, __sep: LiteralString) -> tuple[LiteralString, LiteralString, LiteralString]: ... - @overload def partition(self, __sep: str) -> tuple[str, str, str]: ... # type: ignore[misc] - @overload - def replace( - self: LiteralString, __old: LiteralString, __new: LiteralString, __count: SupportsIndex = -1 - ) -> LiteralString: ... - @overload def replace(self, __old: str, __new: str, __count: SupportsIndex = -1) -> str: ... # type: ignore[misc] if sys.version_info >= (3, 9): - @overload - def removeprefix(self: LiteralString, __prefix: LiteralString) -> LiteralString: ... - @overload def removeprefix(self, __prefix: str) -> str: ... # type: ignore[misc] - @overload - def removesuffix(self: LiteralString, __suffix: LiteralString) -> LiteralString: ... - @overload def removesuffix(self, __suffix: str) -> str: ... # type: ignore[misc] def rfind(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def rindex(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... - @overload - def rjust(self: LiteralString, __width: SupportsIndex, __fillchar: LiteralString = " ") -> LiteralString: ... - @overload def rjust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] - @overload - def rpartition(self: LiteralString, __sep: LiteralString) -> tuple[LiteralString, LiteralString, LiteralString]: ... - @overload def rpartition(self, __sep: str) -> tuple[str, str, str]: ... # type: ignore[misc] - @overload - def rsplit(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... - @overload def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] - @overload - def rstrip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... - @overload def rstrip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] - @overload - def split(self: LiteralString, sep: LiteralString | None = None, maxsplit: SupportsIndex = -1) -> list[LiteralString]: ... - @overload def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]: ... # type: ignore[misc] - @overload - def splitlines(self: LiteralString, keepends: bool = False) -> list[LiteralString]: ... - @overload def splitlines(self, keepends: bool = False) -> list[str]: ... # type: ignore[misc] def startswith( self, __prefix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... - @overload - def strip(self: LiteralString, __chars: LiteralString | None = None) -> LiteralString: ... - @overload def strip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] - @overload - def swapcase(self: LiteralString) -> LiteralString: ... - @overload def swapcase(self) -> str: ... # type: ignore[misc] - @overload - def title(self: LiteralString) -> LiteralString: ... - @overload def title(self) -> str: ... # type: ignore[misc] def translate(self, __table: _TranslateTable) -> str: ... - @overload - def upper(self: LiteralString) -> LiteralString: ... - @overload def upper(self) -> str: ... # type: ignore[misc] - @overload - def zfill(self: LiteralString, __width: SupportsIndex) -> LiteralString: ... - @overload def zfill(self, __width: SupportsIndex) -> str: ... # type: ignore[misc] @staticmethod @overload @@ -570,9 +495,6 @@ class str(Sequence[str]): @staticmethod @overload def maketrans(__x: str, __y: str, __z: str) -> dict[int, int | None]: ... - @overload - def __add__(self: LiteralString, __value: LiteralString) -> LiteralString: ... - @overload def __add__(self, __value: str) -> str: ... # type: ignore[misc] # Incompatible with Sequence.__contains__ def __contains__(self, __key: str) -> bool: ... # type: ignore[override] @@ -581,25 +503,13 @@ class str(Sequence[str]): def __getitem__(self, __key: SupportsIndex | slice) -> str: ... def __gt__(self, __value: str) -> bool: ... def __hash__(self) -> int: ... - @overload - def __iter__(self: LiteralString) -> Iterator[LiteralString]: ... - @overload def __iter__(self) -> Iterator[str]: ... # type: ignore[misc] def __le__(self, __value: str) -> bool: ... def __len__(self) -> int: ... def __lt__(self, __value: str) -> bool: ... - @overload - def __mod__(self: LiteralString, __value: LiteralString | tuple[LiteralString, ...]) -> LiteralString: ... - @overload def __mod__(self, __value: Any) -> str: ... - @overload - def __mul__(self: LiteralString, __value: SupportsIndex) -> LiteralString: ... - @overload def __mul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] def __ne__(self, __value: object) -> bool: ... - @overload - def __rmul__(self: LiteralString, __value: SupportsIndex) -> LiteralString: ... - @overload def __rmul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] def __getnewargs__(self) -> tuple[str]: ... From d132999ba631b332d0684173897e5947591f4acc Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sat, 29 Oct 2022 12:47:21 -0700 Subject: [PATCH 60/69] Revert sum literal integer change (#13961) This is allegedly causing large performance problems, see 13821 typeshed/8231 had zero hits on mypy_primer, so it's not the worst thing to undo. Patching this in typeshed also feels weird, since there's a more general soundness issue. If a typevar has a bound or constraint, we might not want to solve it to a Literal. If we can confirm the performance regression or fix the unsoundness within mypy, I might pursue upstreaming this in typeshed. (Reminder: add this to the sync_typeshed script once merged) --- mypy/typeshed/stdlib/builtins.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index df78cec18226..09f082f2fe48 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1590,7 +1590,7 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # without creating many false-positive errors (see #7578). # Instead, we special-case the most common examples of this: bool and literal integers. @overload -def sum(__iterable: Iterable[bool | _LiteralInteger], start: int = 0) -> int: ... # type: ignore[overload-overlap] +def sum(__iterable: Iterable[bool], start: int = 0) -> int: ... # type: ignore[overload-overlap] @overload def sum(__iterable: Iterable[_SupportsSumNoDefaultT]) -> _SupportsSumNoDefaultT | Literal[0]: ... @overload From dd12a2d810f2bbe7a8686674397043b18575480f Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 1 May 2023 20:34:55 +0100 Subject: [PATCH 61/69] Revert typeshed ctypes change Since the plugin provides superior type checking: https://github.com/python/mypy/pull/13987#issuecomment-1310863427 A manual cherry-pick of e437cdf. --- mypy/typeshed/stdlib/_ctypes.pyi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 36540172ab95..ec3d86e41687 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -167,11 +167,7 @@ class Array(_CData, Generic[_CT]): def _type_(self) -> type[_CT]: ... @_type_.setter def _type_(self, value: type[_CT]) -> None: ... - # Note: only available if _CT == c_char - @property - def raw(self) -> bytes: ... - @raw.setter - def raw(self, value: ReadableBuffer) -> None: ... + raw: bytes # Note: only available if _CT == c_char value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise # TODO These methods cannot be annotated correctly at the moment. # All of these "Any"s stand for the array's element type, but it's not possible to use _CT From 0dd4b6f7576be3d3857fecefb298decdf0711ac7 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sat, 4 Mar 2023 13:14:11 +0000 Subject: [PATCH 62/69] Revert use of `ParamSpec` for `functools.wraps` --- mypy/typeshed/stdlib/functools.pyi | 40 +++++++++++------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 8c48e77c16cf..0f1666024f84 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -1,9 +1,9 @@ import sys import types -from _typeshed import SupportsAllComparisons, SupportsItems +from _typeshed import IdentityFunction, SupportsAllComparisons, SupportsItems from collections.abc import Callable, Hashable, Iterable, Sequence, Sized from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload -from typing_extensions import ParamSpec, Self, TypeAlias +from typing_extensions import Self, TypeAlias if sys.version_info >= (3, 9): from types import GenericAlias @@ -27,12 +27,10 @@ __all__ = [ if sys.version_info >= (3, 9): __all__ += ["cache"] +_AnyCallable: TypeAlias = Callable[..., object] + _T = TypeVar("_T") _S = TypeVar("_S") -_PWrapped = ParamSpec("_PWrapped") -_RWrapped = TypeVar("_RWrapped") -_PWrapper = ParamSpec("_PWrapper") -_RWrapper = TypeVar("_RWrapper") @overload def reduce(__function: Callable[[_T, _S], _T], __sequence: Iterable[_S], __initial: _T) -> _T: ... @@ -82,41 +80,31 @@ else: ] WRAPPER_UPDATES: tuple[Literal["__dict__"]] -class _Wrapped(Generic[_PWrapped, _RWrapped, _PWrapper, _RWrapper]): - __wrapped__: Callable[_PWrapped, _RWrapped] - def __call__(self, *args: _PWrapper.args, **kwargs: _PWrapper.kwargs) -> _RWrapper: ... - # as with ``Callable``, we'll assume that these attributes exist - __name__: str - __qualname__: str - -class _Wrapper(Generic[_PWrapped, _RWrapped]): - def __call__(self, f: Callable[_PWrapper, _RWrapper]) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... - if sys.version_info >= (3, 12): def update_wrapper( - wrapper: Callable[_PWrapper, _RWrapper], - wrapped: Callable[_PWrapped, _RWrapped], + wrapper: _T, + wrapped: _AnyCallable, assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__", "__type_params__"), updated: Sequence[str] = ("__dict__",), - ) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... + ) -> _T: ... def wraps( - wrapped: Callable[_PWrapped, _RWrapped], + wrapped: _AnyCallable, assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__", "__type_params__"), updated: Sequence[str] = ("__dict__",), - ) -> _Wrapper[_PWrapped, _RWrapped]: ... + ) -> IdentityFunction: ... else: def update_wrapper( - wrapper: Callable[_PWrapper, _RWrapper], - wrapped: Callable[_PWrapped, _RWrapped], + wrapper: _T, + wrapped: _AnyCallable, assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__"), updated: Sequence[str] = ("__dict__",), - ) -> _Wrapped[_PWrapped, _RWrapped, _PWrapper, _RWrapper]: ... + ) -> _T: ... def wraps( - wrapped: Callable[_PWrapped, _RWrapped], + wrapped: _AnyCallable, assigned: Sequence[str] = ("__module__", "__name__", "__qualname__", "__doc__", "__annotations__"), updated: Sequence[str] = ("__dict__",), - ) -> _Wrapper[_PWrapped, _RWrapped]: ... + ) -> IdentityFunction: ... def total_ordering(cls: type[_T]) -> type[_T]: ... def cmp_to_key(mycmp: Callable[[_T, _T], int]) -> Callable[[_T], SupportsAllComparisons]: ... From 8c2ef9dde8aa803e04038427ad84f09664d9d93f Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 3 Feb 2024 17:05:10 +0100 Subject: [PATCH 63/69] Update hashes in sync-typeshed.py following recent typeshed sync --- misc/sync-typeshed.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/misc/sync-typeshed.py b/misc/sync-typeshed.py index 9d6fd92270a5..ee6414ab7b19 100644 --- a/misc/sync-typeshed.py +++ b/misc/sync-typeshed.py @@ -179,10 +179,10 @@ def main() -> None: print("Created typeshed sync commit.") commits_to_cherry_pick = [ - "588623ff2", # LiteralString reverts - "bdcc90e85", # sum reverts - "3e5d81337", # ctypes reverts - "344298e3a", # ParamSpec for functools.wraps + "d25e4a9eb", # LiteralString reverts + "d132999ba", # sum reverts + "dd12a2d81", # ctypes reverts + "0dd4b6f75", # ParamSpec for functools.wraps ] for commit in commits_to_cherry_pick: try: From 7bdd61f2d89ecd2cee4ebe6eb2375a72b29f0b10 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Mon, 5 Feb 2024 01:41:24 +0100 Subject: [PATCH 64/69] stubgen: Fix crash on star unpack of TypeVarTuple (#16869) Fixes #16864 --- mypy/stubgen.py | 4 +++ mypy/test/teststubgen.py | 4 +++ test-data/unit/stubgen.test | 50 +++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 1f7a01e6ae3c..c314fabc882d 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -100,6 +100,7 @@ OpExpr, OverloadedFuncDef, SetExpr, + StarExpr, Statement, StrExpr, TempNode, @@ -339,6 +340,9 @@ def visit_ellipsis(self, node: EllipsisExpr) -> str: def visit_op_expr(self, o: OpExpr) -> str: return f"{o.left.accept(self)} {o.op} {o.right.accept(self)}" + def visit_star_expr(self, o: StarExpr) -> str: + return f"*{o.expr.accept(self)}" + def find_defined_names(file: MypyFile) -> set[str]: finder = DefinitionFinder() diff --git a/mypy/test/teststubgen.py b/mypy/test/teststubgen.py index c138f9953918..3669772854cb 100644 --- a/mypy/test/teststubgen.py +++ b/mypy/test/teststubgen.py @@ -10,6 +10,8 @@ from types import ModuleType from typing import Any +import pytest + from mypy.errors import CompileError from mypy.moduleinspect import InspectError, ModuleInspect from mypy.stubdoc import ( @@ -698,6 +700,8 @@ def run_case_inner(self, testcase: DataDrivenTestCase) -> None: f.write(content) options = self.parse_flags(source, extra) + if sys.version_info < options.pyversion: + pytest.skip() modules = self.parse_modules(source) out_dir = "out" try: diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 751a1a7fbbcf..3b3bc658a14a 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -1211,6 +1211,56 @@ T = TypeVar('T') class D(Generic[T]): ... +[case testGenericClassTypeVarTuple] +from typing import Generic +from typing_extensions import TypeVarTuple, Unpack +Ts = TypeVarTuple('Ts') +class D(Generic[Unpack[Ts]]): ... +[out] +from typing import Generic +from typing_extensions import TypeVarTuple, Unpack + +Ts = TypeVarTuple('Ts') + +class D(Generic[Unpack[Ts]]): ... + +[case testGenericClassTypeVarTuple_semanal] +from typing import Generic +from typing_extensions import TypeVarTuple, Unpack +Ts = TypeVarTuple('Ts') +class D(Generic[Unpack[Ts]]): ... +[out] +from typing import Generic +from typing_extensions import TypeVarTuple, Unpack + +Ts = TypeVarTuple('Ts') + +class D(Generic[Unpack[Ts]]): ... + +[case testGenericClassTypeVarTuplePy311] +# flags: --python-version=3.11 +from typing import Generic, TypeVarTuple +Ts = TypeVarTuple('Ts') +class D(Generic[*Ts]): ... +[out] +from typing import Generic, TypeVarTuple + +Ts = TypeVarTuple('Ts') + +class D(Generic[*Ts]): ... + +[case testGenericClassTypeVarTuplePy311_semanal] +# flags: --python-version=3.11 +from typing import Generic, TypeVarTuple +Ts = TypeVarTuple('Ts') +class D(Generic[*Ts]): ... +[out] +from typing import Generic, TypeVarTuple + +Ts = TypeVarTuple('Ts') + +class D(Generic[*Ts]): ... + [case testObjectBaseClass] class A(object): ... [out] From ede0b200a10186a095378516d840389f8da4edd4 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 5 Feb 2024 00:42:13 +0000 Subject: [PATCH 65/69] Bump ruff to 0.2.0 (#16870) Fix this deprecation warning when running ruff on the repository directly: ``` warning: The top-level linter settings are deprecated in favour of their counterparts in the `lint` section. Please update the following options in `pyproject.toml`: - 'ignore' -> 'lint.ignore' - 'select' -> 'lint.select' - 'unfixable' -> 'lint.unfixable' - 'isort' -> 'lint.isort' ``` Note that you don't see the deprecation warnings if you run ruff via pre-commit (only if you run ruff directly, e.g. via ruff .), since pre-commit [swallows all output from a tool if the tool exits with code 0](https://stackoverflow.com/questions/72895720/pre-commit-hook-does-not-echo-on-terminal/72898524#72898524). --- .pre-commit-config.yaml | 2 +- pyproject.toml | 29 +++++++++++++++-------------- test-requirements.in | 2 +- test-requirements.txt | 2 +- 4 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eec410457641..4cfb8297a66a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - id: black exclude: '^(test-data/)' - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.15 # must match test-requirements.txt + rev: v0.2.0 # must match test-requirements.txt hooks: - id: ruff args: [--exit-non-zero-on-fix] diff --git a/pyproject.toml b/pyproject.toml index 5fc0cee3f65c..fa6cf876b647 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,20 @@ line-length = 99 target-version = "py38" fix = true +extend-exclude = [ + "@*", + # Sphinx configuration is irrelevant + "docs/source/conf.py", + "mypyc/doc/conf.py", + # tests have more relaxed styling requirements + # fixtures have their own .pyi-specific configuration + "test-data/*", + "mypyc/test-data/*", + # typeshed has its own .pyi-specific configuration + "mypy/typeshed/*", +] + +[tool.ruff.lint] select = [ "E", # pycodestyle (error) "F", # pyflakes @@ -66,20 +80,7 @@ unfixable = [ "UP036", # sometimes it's better to just noqa this ] -extend-exclude = [ - "@*", - # Sphinx configuration is irrelevant - "docs/source/conf.py", - "mypyc/doc/conf.py", - # tests have more relaxed styling requirements - # fixtures have their own .pyi-specific configuration - "test-data/*", - "mypyc/test-data/*", - # typeshed has its own .pyi-specific configuration - "mypy/typeshed/*", -] - -[tool.ruff.isort] +[tool.ruff.lint.isort] combine-as-imports = true extra-standard-library = ["typing_extensions"] diff --git a/test-requirements.in b/test-requirements.in index a158f5c05ee1..8eeef206018e 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -14,6 +14,6 @@ psutil>=4.0 pytest>=7.4.0 pytest-xdist>=1.34.0 pytest-cov>=2.10.0 -ruff==0.1.15 # must match version in .pre-commit-config.yaml +ruff==0.2.0 # must match version in .pre-commit-config.yaml setuptools>=65.5.1 tomli>=1.1.0 # needed even on py311+ so the self check passes with --python-version 3.8 diff --git a/test-requirements.txt b/test-requirements.txt index dcd250970a15..525edbc252d8 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -67,7 +67,7 @@ ruamel-yaml==0.17.40 # via pre-commit-hooks ruamel-yaml-clib==0.2.8 # via ruamel-yaml -ruff==0.1.15 +ruff==0.2.0 # via -r test-requirements.in tomli==2.0.1 # via -r test-requirements.in From b956e6a57c4dd36d670097a3eccf7dc092348fec Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Mon, 5 Feb 2024 14:17:43 +0100 Subject: [PATCH 66/69] stubtest: Private parameters can be omitted (#16507) Fixes #16443 --- CHANGELOG.md | 3 ++ mypy/stubtest.py | 14 ++++++-- mypy/test/teststubtest.py | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d79b415f5d..bae881656865 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Next release +Stubtest will ignore private function/method parameters when they are missing from the stub. Private parameters +names start with a single underscore and have a default (PR [16507](https://github.com/python/mypy/pull/16507)). + ## Mypy 1.8 We’ve just uploaded mypy 1.8 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)). Mypy is a static type checker for Python. This release includes new features, performance improvements and bug fixes. You can install it as follows: diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 225c1c35c1be..0e8a1c3ceac2 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -940,7 +940,8 @@ def _verify_signature( elif len(stub.pos) < len(runtime.pos): for runtime_arg in runtime.pos[len(stub.pos) :]: if runtime_arg.name not in stub.kwonly: - yield f'stub does not have argument "{runtime_arg.name}"' + if not _is_private_parameter(runtime_arg): + yield f'stub does not have argument "{runtime_arg.name}"' else: yield f'runtime argument "{runtime_arg.name}" is not keyword-only' @@ -980,7 +981,8 @@ def _verify_signature( ): yield f'stub argument "{arg}" is not keyword-only' else: - yield f'stub does not have argument "{arg}"' + if not _is_private_parameter(runtime.kwonly[arg]): + yield f'stub does not have argument "{arg}"' # Checks involving **kwargs if stub.varkw is None and runtime.varkw is not None: @@ -995,6 +997,14 @@ def _verify_signature( yield f'runtime does not have **kwargs argument "{stub.varkw.variable.name}"' +def _is_private_parameter(arg: inspect.Parameter) -> bool: + return ( + arg.name.startswith("_") + and not arg.name.startswith("__") + and arg.default is not inspect.Parameter.empty + ) + + @verify.register(nodes.FuncItem) def verify_funcitem( stub: nodes.FuncItem, runtime: MaybeMissing[Any], object_path: list[str] diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 55f35200a7f5..418308e2e65e 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -346,6 +346,78 @@ def test_arg_kind(self) -> Iterator[Case]: error="stub_posonly_570", ) + @collect_cases + def test_private_parameters(self) -> Iterator[Case]: + # Private parameters can optionally be omitted. + yield Case( + stub="def priv_pos_arg_missing() -> None: ...", + runtime="def priv_pos_arg_missing(_p1=None): pass", + error=None, + ) + yield Case( + stub="def multi_priv_args() -> None: ...", + runtime="def multi_priv_args(_p='', _q=''): pass", + error=None, + ) + yield Case( + stub="def priv_kwarg_missing() -> None: ...", + runtime="def priv_kwarg_missing(*, _p2=''): pass", + error=None, + ) + # But if they are included, they must be correct. + yield Case( + stub="def priv_pos_arg_wrong(_p: int = ...) -> None: ...", + runtime="def priv_pos_arg_wrong(_p=None): pass", + error="priv_pos_arg_wrong", + ) + yield Case( + stub="def priv_kwarg_wrong(*, _p: int = ...) -> None: ...", + runtime="def priv_kwarg_wrong(*, _p=None): pass", + error="priv_kwarg_wrong", + ) + # Private parameters must have a default and start with exactly one + # underscore. + yield Case( + stub="def pos_arg_no_default() -> None: ...", + runtime="def pos_arg_no_default(_np): pass", + error="pos_arg_no_default", + ) + yield Case( + stub="def kwarg_no_default() -> None: ...", + runtime="def kwarg_no_default(*, _np): pass", + error="kwarg_no_default", + ) + yield Case( + stub="def double_underscore_pos_arg() -> None: ...", + runtime="def double_underscore_pos_arg(__np = None): pass", + error="double_underscore_pos_arg", + ) + yield Case( + stub="def double_underscore_kwarg() -> None: ...", + runtime="def double_underscore_kwarg(*, __np = None): pass", + error="double_underscore_kwarg", + ) + # But spot parameters that are accidentally not marked kw-only and + # vice-versa. + yield Case( + stub="def priv_arg_is_kwonly(_p=...) -> None: ...", + runtime="def priv_arg_is_kwonly(*, _p=''): pass", + error="priv_arg_is_kwonly", + ) + yield Case( + stub="def priv_arg_is_positional(*, _p=...) -> None: ...", + runtime="def priv_arg_is_positional(_p=''): pass", + error="priv_arg_is_positional", + ) + # Private parameters not at the end of the parameter list must be + # included so that users can pass the following arguments using + # positional syntax. + yield Case( + stub="def priv_args_not_at_end(*, q='') -> None: ...", + runtime="def priv_args_not_at_end(_p='', q=''): pass", + error="priv_args_not_at_end", + ) + @collect_cases def test_default_presence(self) -> Iterator[Case]: yield Case( From 6615cabe57c661114d0ed44784f67301619faadf Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 10 Feb 2024 17:26:49 +0100 Subject: [PATCH 67/69] [Release 1.9] Stubtest: ignore a new protocol dunder (#16895) (#16899) This is added to all protocol classes on Python 3.12.2+ (it was added in a patch release of 3.12 as part of a bugfix). There's no reason why you'd want to explicitly include it in a stub (and doing so would lead the type checker to incorrectly conclude that you wanted a member literally called `__non_callable_proto_members__`) Cf. https://github.com/python/typeshed/pull/11384 and https://github.com/python/typeshed/issues/11383 (cherry picked from commit 517f5aee23ba218f615bcd4427bca62f120bc222) Co-authored-by: Alex Waygood --- mypy/stubtest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index 0e8a1c3ceac2..c2f82c98d089 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1486,6 +1486,7 @@ def verify_typealias( # Added to all protocol classes on 3.12+ (or if using typing_extensions.Protocol) "__protocol_attrs__", "__callable_proto_members_only__", + "__non_callable_proto_members__", # typing implementation details, consider removing some of these: "__parameters__", "__origin__", From 155909ad1bde747d89fcd091621d7cd9b1e15818 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 10 Feb 2024 17:28:56 +0100 Subject: [PATCH 68/69] [Release 1.9] Unsupport targetting 3.7. (#16883) (#16900) This syncs up this constant to the actual minimum version that typeshed is now targetting. Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> (cherry picked from commit d8e3d591048cfe16dbc9cfa2ff88db38c587e3d0) Co-authored-by: jhance --- mypy/defaults.py | 2 +- test-data/unit/cmdline.test | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mypy/defaults.py b/mypy/defaults.py index 6a09a61a461e..2bbae23d7e2d 100644 --- a/mypy/defaults.py +++ b/mypy/defaults.py @@ -10,7 +10,7 @@ # Earliest Python 3.x version supported via --python-version 3.x. To run # mypy, at least version PYTHON3_VERSION is needed. -PYTHON3_VERSION_MIN: Final = (3, 7) # Keep in sync with typeshed's python support +PYTHON3_VERSION_MIN: Final = (3, 8) # Keep in sync with typeshed's python support CACHE_DIR: Final = ".mypy_cache" CONFIG_FILE: Final = ["mypy.ini", ".mypy.ini"] diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index f286f4781ed5..2262b7e7280c 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -592,7 +592,7 @@ main.py:1: error: Cannot find implementation or library stub for module named "a \[tool.mypy] python_version = 3.10 [out] -pyproject.toml: [mypy]: python_version: Python 3.1 is not supported (must be 3.7 or higher). You may need to put quotes around your Python version +pyproject.toml: [mypy]: python_version: Python 3.1 is not supported (must be 3.8 or higher). You may need to put quotes around your Python version == Return code: 0 [case testPythonVersionTooOld10] @@ -604,13 +604,13 @@ python_version = 1.0 mypy.ini: [mypy]: python_version: Python major version '1' out of range (must be 3) == Return code: 0 -[case testPythonVersionTooOld36] +[case testPythonVersionTooOld37] # cmd: mypy -c pass [file mypy.ini] \[mypy] -python_version = 3.6 +python_version = 3.7 [out] -mypy.ini: [mypy]: python_version: Python 3.6 is not supported (must be 3.7 or higher) +mypy.ini: [mypy]: python_version: Python 3.7 is not supported (must be 3.8 or higher) == Return code: 0 [case testPythonVersionTooNew40] @@ -633,11 +633,11 @@ usage: mypy [-h] [-v] [-V] [more options; see below] mypy: error: Mypy no longer supports checking Python 2 code. Consider pinning to mypy<0.980 if you need to check Python 2 code. == Return code: 2 -[case testPythonVersionAccepted37] +[case testPythonVersionAccepted38] # cmd: mypy -c pass [file mypy.ini] \[mypy] -python_version = 3.7 +python_version = 3.8 [out] [case testPythonVersionAccepted311] From 5ff46f8b3706d005fabab2227ec84476d605bfd4 Mon Sep 17 00:00:00 2001 From: Jared Hance Date: Fri, 1 Mar 2024 11:49:33 -0800 Subject: [PATCH 69/69] Remove +dev. --- mypy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/version.py b/mypy/version.py index 74e80839308c..e21d7956391a 100644 --- a/mypy/version.py +++ b/mypy/version.py @@ -8,7 +8,7 @@ # - Release versions have the form "1.2.3". # - Dev versions have the form "1.2.3+dev" (PLUS sign to conform to PEP 440). # - Before 1.0 we had the form "0.NNN". -__version__ = "1.9.0+dev" +__version__ = "1.9.0" base_version = __version__ mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))