From e69c5cde8643e04a54a644cc27814ab98181541d Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Mon, 27 Nov 2023 03:27:08 +0200 Subject: [PATCH 001/172] stubgen: Preserve simple defaults in function signatures (#15355) Fixes #13238 See also https://github.com/python/typeshed/issues/8988 --- mypy/stubdoc.py | 15 +++++-- mypy/stubgen.py | 73 +++++++++++++++++++++++++++++- test-data/unit/stubgen.test | 89 ++++++++++++++++++++++++++++--------- 3 files changed, 153 insertions(+), 24 deletions(-) diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index c277573f0b59..126ac44e142e 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -36,11 +36,19 @@ def is_valid_type(s: str) -> bool: class ArgSig: """Signature info for a single argument.""" - def __init__(self, name: str, type: str | None = None, default: bool = False): + def __init__( + self, + name: str, + type: str | None = None, + *, + default: bool = False, + default_value: str = "...", + ) -> None: self.name = name self.type = type # Does this argument have a default value? self.default = default + self.default_value = default_value def is_star_arg(self) -> bool: return self.name.startswith("*") and not self.name.startswith("**") @@ -59,6 +67,7 @@ def __eq__(self, other: Any) -> bool: self.name == other.name and self.type == other.type and self.default == other.default + and self.default_value == other.default_value ) return False @@ -119,10 +128,10 @@ def format_sig( if arg_type: arg_def += ": " + arg_type if arg.default: - arg_def += " = ..." + arg_def += f" = {arg.default_value}" elif arg.default: - arg_def += "=..." + arg_def += f"={arg.default_value}" args.append(arg_def) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 837cd723c410..fff6ab058459 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -99,6 +99,7 @@ NameExpr, OpExpr, OverloadedFuncDef, + SetExpr, Statement, StrExpr, TempNode, @@ -491,15 +492,21 @@ def _get_func_args(self, o: FuncDef, ctx: FunctionContext) -> list[ArgSig]: if kind.is_named() and not any(arg.name.startswith("*") for arg in args): args.append(ArgSig("*")) + default = "..." if arg_.initializer: if not typename: typename = self.get_str_type_of_node(arg_.initializer, True, False) + potential_default, valid = self.get_str_default_of_node(arg_.initializer) + if valid and len(potential_default) <= 200: + default = potential_default elif kind == ARG_STAR: name = f"*{name}" elif kind == ARG_STAR2: name = f"**{name}" - args.append(ArgSig(name, typename, default=bool(arg_.initializer))) + args.append( + ArgSig(name, typename, default=bool(arg_.initializer), default_value=default) + ) if ctx.class_info is not None and all( arg.type is None and arg.default is False for arg in args @@ -1234,6 +1241,70 @@ def maybe_unwrap_unary_expr(self, expr: Expression) -> Expression: # This is some other unary expr, we cannot do anything with it (yet?). return expr + def get_str_default_of_node(self, rvalue: Expression) -> tuple[str, bool]: + """Get a string representation of the default value of a node. + + Returns a 2-tuple of the default and whether or not it is valid. + """ + if isinstance(rvalue, NameExpr): + if rvalue.name in ("None", "True", "False"): + return rvalue.name, True + elif isinstance(rvalue, (IntExpr, FloatExpr)): + return f"{rvalue.value}", True + elif isinstance(rvalue, UnaryExpr): + if isinstance(rvalue.expr, (IntExpr, FloatExpr)): + return f"{rvalue.op}{rvalue.expr.value}", True + elif isinstance(rvalue, StrExpr): + return repr(rvalue.value), True + elif isinstance(rvalue, BytesExpr): + return "b" + repr(rvalue.value).replace("\\\\", "\\"), True + elif isinstance(rvalue, TupleExpr): + items_defaults = [] + for e in rvalue.items: + e_default, valid = self.get_str_default_of_node(e) + if not valid: + break + items_defaults.append(e_default) + else: + closing = ",)" if len(items_defaults) == 1 else ")" + default = "(" + ", ".join(items_defaults) + closing + return default, True + elif isinstance(rvalue, ListExpr): + items_defaults = [] + for e in rvalue.items: + e_default, valid = self.get_str_default_of_node(e) + if not valid: + break + items_defaults.append(e_default) + else: + default = "[" + ", ".join(items_defaults) + "]" + return default, True + elif isinstance(rvalue, SetExpr): + items_defaults = [] + for e in rvalue.items: + e_default, valid = self.get_str_default_of_node(e) + if not valid: + break + items_defaults.append(e_default) + else: + if items_defaults: + default = "{" + ", ".join(items_defaults) + "}" + return default, True + elif isinstance(rvalue, DictExpr): + items_defaults = [] + for k, v in rvalue.items: + if k is None: + break + k_default, k_valid = self.get_str_default_of_node(k) + v_default, v_valid = self.get_str_default_of_node(v) + if not (k_valid and v_valid): + break + items_defaults.append(f"{k_default}: {v_default}") + else: + default = "{" + ", ".join(items_defaults) + "}" + return default, True + return "...", False + def should_reexport(self, name: str, full_module: str, name_is_alias: bool) -> bool: is_private = self.is_private_name(name, full_module + "." + name) if ( diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 2a43ce16383d..cd38242ce031 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -27,20 +27,20 @@ def g(arg) -> None: ... def f(a, b=2): ... def g(b=-1, c=0): ... [out] -def f(a, b: int = ...) -> None: ... -def g(b: int = ..., c: int = ...) -> None: ... +def f(a, b: int = 2) -> None: ... +def g(b: int = -1, c: int = 0) -> None: ... [case testDefaultArgNone] def f(x=None): ... [out] from _typeshed import Incomplete -def f(x: Incomplete | None = ...) -> None: ... +def f(x: Incomplete | None = None) -> None: ... [case testDefaultArgBool] def f(x=True, y=False): ... [out] -def f(x: bool = ..., y: bool = ...) -> None: ... +def f(x: bool = True, y: bool = False) -> None: ... [case testDefaultArgBool_inspect] def f(x=True, y=False): ... @@ -48,9 +48,9 @@ def f(x=True, y=False): ... def f(x: bool = ..., y: bool = ...): ... [case testDefaultArgStr] -def f(x='foo'): ... +def f(x='foo',y="how's quotes"): ... [out] -def f(x: str = ...) -> None: ... +def f(x: str = 'foo', y: str = "how's quotes") -> None: ... [case testDefaultArgStr_inspect] def f(x='foo'): ... @@ -58,14 +58,16 @@ def f(x='foo'): ... def f(x: str = ...): ... [case testDefaultArgBytes] -def f(x=b'foo'): ... +def f(x=b'foo',y=b"what's up",z=b'\xc3\xa0 la une'): ... [out] -def f(x: bytes = ...) -> None: ... +def f(x: bytes = b'foo', y: bytes = b"what's up", z: bytes = b'\xc3\xa0 la une') -> None: ... [case testDefaultArgFloat] -def f(x=1.2): ... +def f(x=1.2,y=1e-6,z=0.0,w=-0.0,v=+1.0): ... +def g(x=float("nan"), y=float("inf"), z=float("-inf")): ... [out] -def f(x: float = ...) -> None: ... +def f(x: float = 1.2, y: float = 1e-06, z: float = 0.0, w: float = -0.0, v: float = +1.0) -> None: ... +def g(x=..., y=..., z=...) -> None: ... [case testDefaultArgOther] def f(x=ord): ... @@ -126,10 +128,10 @@ def i(a, *, b=1): ... def j(a, *, b=1, **c): ... [out] def f(a, *b, **c) -> None: ... -def g(a, *b, c: int = ...) -> None: ... -def h(a, *b, c: int = ..., **d) -> None: ... -def i(a, *, b: int = ...) -> None: ... -def j(a, *, b: int = ..., **c) -> None: ... +def g(a, *b, c: int = 1) -> None: ... +def h(a, *b, c: int = 1, **d) -> None: ... +def i(a, *, b: int = 1) -> None: ... +def j(a, *, b: int = 1, **c) -> None: ... [case testClass] class A: @@ -356,8 +358,8 @@ y: Incomplete def f(x, *, y=1): ... def g(x, *, y=1, z=2): ... [out] -def f(x, *, y: int = ...) -> None: ... -def g(x, *, y: int = ..., z: int = ...) -> None: ... +def f(x, *, y: int = 1) -> None: ... +def g(x, *, y: int = 1, z: int = 2) -> None: ... [case testProperty] class A: @@ -1285,8 +1287,8 @@ from _typeshed import Incomplete class A: x: Incomplete - def __init__(self, a: Incomplete | None = ...) -> None: ... - def method(self, a: Incomplete | None = ...) -> None: ... + def __init__(self, a: Incomplete | None = None) -> None: ... + def method(self, a: Incomplete | None = None) -> None: ... [case testAnnotationImportsFrom] import foo @@ -2514,7 +2516,7 @@ from _typeshed import Incomplete as _Incomplete Y: _Incomplete -def g(x: _Incomplete | None = ...) -> None: ... +def g(x: _Incomplete | None = None) -> None: ... x: _Incomplete @@ -3503,7 +3505,7 @@ class P(Protocol): [case testNonDefaultKeywordOnlyArgAfterAsterisk] def func(*, non_default_kwarg: bool, default_kwarg: bool = True): ... [out] -def func(*, non_default_kwarg: bool, default_kwarg: bool = ...): ... +def func(*, non_default_kwarg: bool, default_kwarg: bool = True): ... [case testNestedGenerator] def f1(): @@ -3909,6 +3911,53 @@ def gen2() -> _Generator[_Incomplete, _Incomplete, _Incomplete]: ... class X(_Incomplete): ... class Y(_Incomplete): ... +[case testIgnoreLongDefaults] +def f(x='abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'): ... + +def g(x=b'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ +abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'): ... + +def h(x=123456789012345678901234567890123456789012345678901234567890\ +123456789012345678901234567890123456789012345678901234567890\ +123456789012345678901234567890123456789012345678901234567890\ +123456789012345678901234567890123456789012345678901234567890): ... + +[out] +def f(x: str = ...) -> None: ... +def g(x: bytes = ...) -> None: ... +def h(x: int = ...) -> None: ... + +[case testDefaultsOfBuiltinContainers] +def f(x=(), y=(1,), z=(1, 2)): ... +def g(x=[], y=[1, 2]): ... +def h(x={}, y={1: 2, 3: 4}): ... +def i(x={1, 2, 3}): ... +def j(x=[(1,"a"), (2,"b")]): ... + +[out] +def f(x=(), y=(1,), z=(1, 2)) -> None: ... +def g(x=[], y=[1, 2]) -> None: ... +def h(x={}, y={1: 2, 3: 4}) -> None: ... +def i(x={1, 2, 3}) -> None: ... +def j(x=[(1, 'a'), (2, 'b')]) -> None: ... + +[case testDefaultsOfBuiltinContainersWithNonTrivialContent] +def f(x=(1, u.v), y=(k(),), z=(w,)): ... +def g(x=[1, u.v], y=[k()], z=[w]): ... +def h(x={1: u.v}, y={k(): 2}, z={m: m}, w={**n}): ... +def i(x={u.v, 2}, y={3, k()}, z={w}): ... + +[out] +def f(x=..., y=..., z=...) -> None: ... +def g(x=..., y=..., z=...) -> None: ... +def h(x=..., y=..., z=..., w=...) -> None: ... +def i(x=..., y=..., z=...) -> None: ... + [case testDataclass] import dataclasses import dataclasses as dcs From 379d59e1a7e121d5b7f75aed26944620d4ccff37 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Mon, 27 Nov 2023 16:41:36 +0000 Subject: [PATCH 002/172] Fix multiprocessing warnings when runnign tests on Python 3.12 (#16564) I saw a bunch of warnings when running tests in parallel using pytest. When running tests sequentially using `-n0` I didn't see warnings. This only seems to happen on Linux. The warnings were like these, which can be fixed by avoiding the use of fork, and using forkserver instead: ``` mypy/test/teststubgen.py::StubgenPythonSuite::stubgen.test::testNestedClass_inspect /usr/local/lib/python3.12/multiprocessing/popen_fork.py:66: DeprecationWarning: This process (pid=84587) is multi-threaded, use of fork() may lead to deadlocks in the child. self.pid = os.fork() ``` Relevant discussion: https://discuss.python.org/t/concerns-regarding-deprecation-of-fork-with-alive-threads/33555 --- mypy/moduleinspect.py | 12 ++++++++---- mypy/test/testipc.py | 21 ++++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/mypy/moduleinspect.py b/mypy/moduleinspect.py index 580b31fb4107..35db2132f66c 100644 --- a/mypy/moduleinspect.py +++ b/mypy/moduleinspect.py @@ -8,7 +8,7 @@ import pkgutil import queue import sys -from multiprocessing import Process, Queue +from multiprocessing import Queue, get_context from types import ModuleType @@ -123,9 +123,13 @@ def __init__(self) -> None: self._start() def _start(self) -> None: - self.tasks: Queue[str] = Queue() - self.results: Queue[ModuleProperties | str] = Queue() - self.proc = Process(target=worker, args=(self.tasks, self.results, sys.path)) + if sys.platform == "linux": + ctx = get_context("forkserver") + else: + ctx = get_context("spawn") + self.tasks: Queue[str] = ctx.Queue() + self.results: Queue[ModuleProperties | str] = ctx.Queue() + self.proc = ctx.Process(target=worker, args=(self.tasks, self.results, sys.path)) self.proc.start() self.counter = 0 # Number of successful roundtrips diff --git a/mypy/test/testipc.py b/mypy/test/testipc.py index 8ef656dc4579..0224035a7b61 100644 --- a/mypy/test/testipc.py +++ b/mypy/test/testipc.py @@ -2,7 +2,7 @@ import sys import time -from multiprocessing import Process, Queue +from multiprocessing import Queue, get_context from unittest import TestCase, main import pytest @@ -35,10 +35,17 @@ def server_multi_message_echo(q: Queue[str]) -> None: class IPCTests(TestCase): + def setUp(self) -> None: + if sys.platform == "linux": + # The default "fork" start method is potentially unsafe + self.ctx = get_context("forkserver") + else: + self.ctx = get_context("spawn") + def test_transaction_large(self) -> None: - queue: Queue[str] = Queue() + queue: Queue[str] = self.ctx.Queue() msg = "t" * 200000 # longer than the max read size of 100_000 - p = Process(target=server, args=(msg, queue), daemon=True) + p = self.ctx.Process(target=server, args=(msg, queue), daemon=True) p.start() connection_name = queue.get() with IPCClient(connection_name, timeout=1) as client: @@ -49,9 +56,9 @@ def test_transaction_large(self) -> None: p.join() def test_connect_twice(self) -> None: - queue: Queue[str] = Queue() + queue: Queue[str] = self.ctx.Queue() msg = "this is a test message" - p = Process(target=server, args=(msg, queue), daemon=True) + p = self.ctx.Process(target=server, args=(msg, queue), daemon=True) p.start() connection_name = queue.get() with IPCClient(connection_name, timeout=1) as client: @@ -67,8 +74,8 @@ def test_connect_twice(self) -> None: assert p.exitcode == 0 def test_multiple_messages(self) -> None: - queue: Queue[str] = Queue() - p = Process(target=server_multi_message_echo, args=(queue,), daemon=True) + queue: Queue[str] = self.ctx.Queue() + p = self.ctx.Process(target=server_multi_message_echo, args=(queue,), daemon=True) p.start() connection_name = queue.get() with IPCClient(connection_name, timeout=1) as client: From 69b31445280d7c495fa0268b24fc558bcbe74505 Mon Sep 17 00:00:00 2001 From: Chad Dombrova Date: Wed, 29 Nov 2023 00:14:38 -0500 Subject: [PATCH 003/172] Fix stubgen regressions with pybind11 and mypy 1.7 (#16504) This addresses several regressions identified in https://github.com/python/mypy/issues/16486 The primary regression from https://github.com/python/mypy/pull/15770 is that pybind11 properties with docstrings were erroneously assigned `typeshed. Incomplete`. The reason for the regression is that as of the introduction of the `--include-docstring` feature (https://github.com/python/mypy/pull/13284, not my PR, ftr), `./misc/test-stubgenc.sh` began always reporting success. That has been fixed. It was also pointed out that `--include-docstring` does not work for C-extensions. This was not actually a regression as it turns out this feature was never implemented for C-extensions (though the tests suggested it had been), but luckily my efforts to unify the pure-python and C-extension code-paths made fixing this super easy (barely an inconvenience)! So that is working now. I added back the extended list of `typing` objects that generate implicit imports for the inspection-based stub generator. I originally removed these because I encountered an issue generating stubs for `PySide2` (and another internal library) where there was an object with the same name as one of the `typing` objects and the auto-import created broken stubs. I felt somewhat justified in this decision as there was a straightforward solution -- e.g. use `list` or `typing.List` instead of `List`. That said, I recognize that the problem that I encountered is more niche than the general desire to add import statements for typing objects, so I've changed the behavior back for now, with the intention to eventually add a flag to control this behavior. --- misc/test-stubgenc.sh | 2 +- mypy/stubdoc.py | 3 +- mypy/stubgen.py | 1 + mypy/stubgenc.py | 52 +++++++++++++++++-- mypy/stubutil.py | 18 +++---- test-data/pybind11_mypy_demo/src/main.cpp | 11 +++- .../pybind11_mypy_demo/__init__.pyi | 1 + .../pybind11_mypy_demo/basics.pyi | 32 ++++++------ .../stubgen/pybind11_mypy_demo/basics.pyi | 3 +- 9 files changed, 88 insertions(+), 35 deletions(-) diff --git a/misc/test-stubgenc.sh b/misc/test-stubgenc.sh index 7713e1b04e43..5cb5140eba76 100755 --- a/misc/test-stubgenc.sh +++ b/misc/test-stubgenc.sh @@ -24,7 +24,7 @@ function stubgenc_test() { # Compare generated stubs to expected ones if ! git diff --exit-code "$STUBGEN_OUTPUT_FOLDER"; then - EXIT=$? + EXIT=1 fi } diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index 126ac44e142e..86ff6e2bb540 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -383,7 +383,8 @@ def infer_ret_type_sig_from_docstring(docstr: str, name: str) -> str | None: def infer_ret_type_sig_from_anon_docstring(docstr: str) -> str | None: """Convert signature in form of "(self: TestClass, arg0) -> int" to their return type.""" - return infer_ret_type_sig_from_docstring("stub" + docstr.strip(), "stub") + lines = ["stub" + line.strip() for line in docstr.splitlines() if line.strip().startswith("(")] + return infer_ret_type_sig_from_docstring("".join(lines), "stub") def parse_signature(sig: str) -> tuple[str, list[str], list[str]] | None: diff --git a/mypy/stubgen.py b/mypy/stubgen.py index fff6ab058459..23b5fde9dff2 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -1700,6 +1700,7 @@ def generate_stubs(options: Options) -> None: doc_dir=options.doc_dir, include_private=options.include_private, export_less=options.export_less, + include_docstrings=options.include_docstrings, ) num_modules = len(all_modules) if not options.quiet and num_modules > 0: diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 0ad79a4265b3..39288197f477 100755 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -126,10 +126,12 @@ def get_property_type(self, default_type: str | None, ctx: FunctionContext) -> s """Infer property type from docstring or docstring signature.""" if ctx.docstring is not None: inferred = infer_ret_type_sig_from_anon_docstring(ctx.docstring) - if not inferred: - inferred = infer_ret_type_sig_from_docstring(ctx.docstring, ctx.name) - if not inferred: - inferred = infer_prop_type_from_docstring(ctx.docstring) + if inferred: + return inferred + inferred = infer_ret_type_sig_from_docstring(ctx.docstring, ctx.name) + if inferred: + return inferred + inferred = infer_prop_type_from_docstring(ctx.docstring) return inferred else: return None @@ -237,6 +239,26 @@ def __init__( self.resort_members = self.is_c_module super().__init__(_all_, include_private, export_less, include_docstrings) self.module_name = module_name + if self.is_c_module: + # Add additional implicit imports. + # C-extensions are given more lattitude since they do not import the typing module. + self.known_imports.update( + { + "typing": [ + "Any", + "Callable", + "ClassVar", + "Dict", + "Iterable", + "Iterator", + "List", + "NamedTuple", + "Optional", + "Tuple", + "Union", + ] + } + ) def get_default_function_sig(self, func: object, ctx: FunctionContext) -> FunctionSig: argspec = None @@ -590,9 +612,29 @@ def generate_function_stub( if inferred[0].args and inferred[0].args[0].name == "cls": decorators.append("@classmethod") + if docstring: + docstring = self._indent_docstring(docstring) output.extend(self.format_func_def(inferred, decorators=decorators, docstring=docstring)) self._fix_iter(ctx, inferred, output) + def _indent_docstring(self, docstring: str) -> str: + """Fix indentation of docstring extracted from pybind11 or other binding generators.""" + lines = docstring.splitlines(keepends=True) + indent = self._indent + " " + if len(lines) > 1: + if not all(line.startswith(indent) or not line.strip() for line in lines): + # if the docstring is not indented, then indent all but the first line + for i, line in enumerate(lines[1:]): + if line.strip(): + lines[i + 1] = indent + line + # if there's a trailing newline, add a final line to visually indent the quoted docstring + if lines[-1].endswith("\n"): + if len(lines) > 1: + lines.append(indent) + else: + lines[-1] = lines[-1][:-1] + return "".join(lines) + def _fix_iter( self, ctx: FunctionContext, inferred: list[FunctionSig], output: list[str] ) -> None: @@ -640,7 +682,7 @@ def generate_property_stub( if fget: alt_docstr = getattr(fget, "__doc__", None) if alt_docstr and docstring: - docstring += alt_docstr + docstring += "\n" + alt_docstr elif alt_docstr: docstring = alt_docstr diff --git a/mypy/stubutil.py b/mypy/stubutil.py index 5ec240087145..b8d601ed3c6b 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -576,6 +576,14 @@ def __init__( self.sig_generators = self.get_sig_generators() # populated by visit_mypy_file self.module_name: str = "" + # These are "soft" imports for objects which might appear in annotations but not have + # a corresponding import statement. + self.known_imports = { + "_typeshed": ["Incomplete"], + "typing": ["Any", "TypeVar", "NamedTuple"], + "collections.abc": ["Generator"], + "typing_extensions": ["TypedDict", "ParamSpec", "TypeVarTuple"], + } def get_sig_generators(self) -> list[SignatureGenerator]: return [] @@ -667,15 +675,7 @@ def set_defined_names(self, defined_names: set[str]) -> None: for name in self._all_ or (): self.import_tracker.reexport(name) - # These are "soft" imports for objects which might appear in annotations but not have - # a corresponding import statement. - known_imports = { - "_typeshed": ["Incomplete"], - "typing": ["Any", "TypeVar", "NamedTuple"], - "collections.abc": ["Generator"], - "typing_extensions": ["TypedDict", "ParamSpec", "TypeVarTuple"], - } - for pkg, imports in known_imports.items(): + for pkg, imports in self.known_imports.items(): for t in imports: # require=False means that the import won't be added unless require_name() is called # for the object during generation. diff --git a/test-data/pybind11_mypy_demo/src/main.cpp b/test-data/pybind11_mypy_demo/src/main.cpp index 00e5b2f4e871..192a90cf8e30 100644 --- a/test-data/pybind11_mypy_demo/src/main.cpp +++ b/test-data/pybind11_mypy_demo/src/main.cpp @@ -44,6 +44,7 @@ #include #include +#include namespace py = pybind11; @@ -102,6 +103,11 @@ struct Point { return distance_to(other.x, other.y); } + std::vector as_vector() + { + return std::vector{x, y}; + } + double x, y; }; @@ -134,14 +140,15 @@ void bind_basics(py::module& basics) { .def(py::init(), py::arg("x"), py::arg("y")) .def("distance_to", py::overload_cast(&Point::distance_to, py::const_), py::arg("x"), py::arg("y")) .def("distance_to", py::overload_cast(&Point::distance_to, py::const_), py::arg("other")) - .def_readwrite("x", &Point::x) + .def("as_list", &Point::as_vector) + .def_readwrite("x", &Point::x, "some docstring") .def_property("y", [](Point& self){ return self.y; }, [](Point& self, double value){ self.y = value; } ) .def_property_readonly("length", &Point::length) .def_property_readonly_static("x_axis", [](py::object cls){return Point::x_axis;}) - .def_property_readonly_static("y_axis", [](py::object cls){return Point::y_axis;}) + .def_property_readonly_static("y_axis", [](py::object cls){return Point::y_axis;}, "another docstring") .def_readwrite_static("length_unit", &Point::length_unit) .def_property_static("angle_unit", [](py::object& /*cls*/){ return Point::angle_unit; }, 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 index e69de29bb2d1..0cb252f00259 100644 --- 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 @@ -0,0 +1 @@ +from . import basics as basics 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 676d7f6d3f15..b761291e11f3 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 @@ -1,7 +1,7 @@ -from typing import ClassVar +from typing import ClassVar, List, overload -from typing import overload PI: float +__version__: str class Point: class AngleUnit: @@ -13,8 +13,6 @@ class Point: """__init__(self: pybind11_mypy_demo.basics.Point.AngleUnit, value: int) -> None""" def __eq__(self, other: object) -> bool: """__eq__(self: object, other: object) -> bool""" - def __getstate__(self) -> int: - """__getstate__(self: object) -> int""" def __hash__(self) -> int: """__hash__(self: object) -> int""" def __index__(self) -> int: @@ -23,8 +21,6 @@ class Point: """__int__(self: pybind11_mypy_demo.basics.Point.AngleUnit) -> int""" def __ne__(self, other: object) -> bool: """__ne__(self: object, other: object) -> bool""" - def __setstate__(self, state: int) -> None: - """__setstate__(self: pybind11_mypy_demo.basics.Point.AngleUnit, state: int) -> None""" @property def name(self) -> str: ... @property @@ -40,8 +36,6 @@ class Point: """__init__(self: pybind11_mypy_demo.basics.Point.LengthUnit, value: int) -> None""" def __eq__(self, other: object) -> bool: """__eq__(self: object, other: object) -> bool""" - def __getstate__(self) -> int: - """__getstate__(self: object) -> int""" def __hash__(self) -> int: """__hash__(self: object) -> int""" def __index__(self) -> int: @@ -50,8 +44,6 @@ class Point: """__int__(self: pybind11_mypy_demo.basics.Point.LengthUnit) -> int""" def __ne__(self, other: object) -> bool: """__ne__(self: object, other: object) -> bool""" - def __setstate__(self, state: int) -> None: - """__setstate__(self: pybind11_mypy_demo.basics.Point.LengthUnit, state: int) -> None""" @property def name(self) -> str: ... @property @@ -70,7 +62,8 @@ class Point: 1. __init__(self: pybind11_mypy_demo.basics.Point) -> None - 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None""" + 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None + """ @overload def __init__(self, x: float, y: float) -> None: """__init__(*args, **kwargs) @@ -78,7 +71,10 @@ class Point: 1. __init__(self: pybind11_mypy_demo.basics.Point) -> None - 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None""" + 2. __init__(self: pybind11_mypy_demo.basics.Point, x: float, y: float) -> None + """ + def as_list(self) -> List[float]: + """as_list(self: pybind11_mypy_demo.basics.Point) -> List[float]""" @overload def distance_to(self, x: float, y: float) -> float: """distance_to(*args, **kwargs) @@ -86,7 +82,8 @@ class Point: 1. distance_to(self: pybind11_mypy_demo.basics.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_mypy_demo.basics.Point, other: pybind11_mypy_demo.basics.Point) -> float + """ @overload def distance_to(self, other: Point) -> float: """distance_to(*args, **kwargs) @@ -94,19 +91,22 @@ class Point: 1. distance_to(self: pybind11_mypy_demo.basics.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_mypy_demo.basics.Point, other: pybind11_mypy_demo.basics.Point) -> float + """ @property def length(self) -> float: ... def answer() -> int: '''answer() -> int - answer docstring, with end quote"''' + answer docstring, with end quote" + ''' def midpoint(left: float, right: float) -> float: """midpoint(left: float, right: float) -> float""" def sum(arg0: int, arg1: int) -> int: '''sum(arg0: int, arg1: int) -> int - multiline docstring test, edge case quotes """\'\'\'''' + multiline docstring test, edge case quotes """\'\'\' + ''' def weighted_midpoint(left: float, right: float, alpha: float = ...) -> float: """weighted_midpoint(left: float, right: float, alpha: float = 0.5) -> float""" 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 6527f5733eaf..6f164a03edcc 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 @@ -1,4 +1,4 @@ -from typing import ClassVar, overload +from typing import ClassVar, List, overload PI: float __version__: str @@ -47,6 +47,7 @@ class Point: def __init__(self) -> None: ... @overload def __init__(self, x: float, y: float) -> None: ... + def as_list(self) -> List[float]: ... @overload def distance_to(self, x: float, y: float) -> float: ... @overload From 95e7fcbe9a4c1d366e90c23f44459032cf0740de Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 30 Nov 2023 17:46:42 +0000 Subject: [PATCH 004/172] Fix stubtest's tests to work with the latest typing_extensions release (#16588) Stubtest's tests will start failing when `typing_extensions==4.9.0` comes out, due to some new `ClassVar`s on `typing_extensions.TypedDict`. This PR fixes that. Fixes https://github.com/python/typing_extensions/issues/309 --- test-data/unit/lib-stub/typing_extensions.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index c88aa5c815c5..7aca6fad1b42 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -59,6 +59,8 @@ class _TypedDict(Mapping[str, object]): # Stubtest's tests need the following items: __required_keys__: frozenset[str] __optional_keys__: frozenset[str] + __readonly_keys__: frozenset[str] + __mutable_keys__: frozenset[str] __total__: bool def TypedDict(typename: str, fields: Dict[str, Type[_T]], *, total: Any = ...) -> Type[dict]: ... From c0fce06da362e9660f4aec3b58fb72a9a2dfb7a6 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Fri, 1 Dec 2023 15:47:57 +0000 Subject: [PATCH 005/172] Sync typeshed Source commit: https://github.com/python/typeshed/commit/5f12eebda4bfddb247c05fb06c6762bd262a9420 --- mypy/typeshed/stdlib/_codecs.pyi | 4 +- mypy/typeshed/stdlib/_ctypes.pyi | 6 +- mypy/typeshed/stdlib/argparse.pyi | 10 +- mypy/typeshed/stdlib/asyncio/base_events.pyi | 2 + .../stdlib/asyncio/base_subprocess.pyi | 1 + mypy/typeshed/stdlib/asyncio/events.pyi | 15 ++- mypy/typeshed/stdlib/asyncio/sslproto.pyi | 2 + mypy/typeshed/stdlib/asyncio/streams.pyi | 3 + mypy/typeshed/stdlib/asyncio/subprocess.pyi | 18 +-- mypy/typeshed/stdlib/asyncio/tasks.pyi | 67 +++++----- mypy/typeshed/stdlib/asyncio/unix_events.pyi | 116 +++++++++++++----- mypy/typeshed/stdlib/builtins.pyi | 105 +++++++++++++++- mypy/typeshed/stdlib/cgi.pyi | 3 +- mypy/typeshed/stdlib/collections/__init__.pyi | 4 +- mypy/typeshed/stdlib/contextvars.pyi | 2 +- mypy/typeshed/stdlib/functools.pyi | 44 ++++--- mypy/typeshed/stdlib/http/client.pyi | 2 +- mypy/typeshed/stdlib/importlib/abc.pyi | 2 +- mypy/typeshed/stdlib/importlib/machinery.pyi | 23 +++- .../stdlib/importlib/metadata/__init__.pyi | 2 +- mypy/typeshed/stdlib/io.pyi | 2 +- mypy/typeshed/stdlib/itertools.pyi | 26 ++-- mypy/typeshed/stdlib/logging/config.pyi | 10 +- mypy/typeshed/stdlib/math.pyi | 2 +- .../stdlib/multiprocessing/connection.pyi | 1 + .../stdlib/multiprocessing/managers.pyi | 1 + mypy/typeshed/stdlib/multiprocessing/pool.pyi | 1 + .../stdlib/multiprocessing/shared_memory.pyi | 1 + mypy/typeshed/stdlib/os/__init__.pyi | 2 +- mypy/typeshed/stdlib/pkgutil.pyi | 3 + mypy/typeshed/stdlib/re.pyi | 14 +-- mypy/typeshed/stdlib/shelve.pyi | 3 +- mypy/typeshed/stdlib/shutil.pyi | 8 +- mypy/typeshed/stdlib/subprocess.pyi | 1 + mypy/typeshed/stdlib/sunau.pyi | 2 + mypy/typeshed/stdlib/telnetlib.pyi | 1 + mypy/typeshed/stdlib/tempfile.pyi | 4 +- mypy/typeshed/stdlib/tkinter/__init__.pyi | 1 + mypy/typeshed/stdlib/tkinter/dnd.pyi | 1 + mypy/typeshed/stdlib/tkinter/font.pyi | 1 + mypy/typeshed/stdlib/tkinter/ttk.pyi | 4 +- mypy/typeshed/stdlib/turtle.pyi | 12 +- mypy/typeshed/stdlib/types.pyi | 3 +- mypy/typeshed/stdlib/typing.pyi | 12 +- mypy/typeshed/stdlib/typing_extensions.pyi | 30 +++-- mypy/typeshed/stdlib/unittest/async_case.pyi | 2 + mypy/typeshed/stdlib/unittest/mock.pyi | 4 +- mypy/typeshed/stdlib/urllib/request.pyi | 1 + mypy/typeshed/stdlib/wave.pyi | 9 +- mypy/typeshed/stdlib/weakref.pyi | 2 +- mypy/typeshed/stdlib/xml/sax/xmlreader.pyi | 2 +- mypy/typeshed/stdlib/zipfile.pyi | 8 +- 52 files changed, 436 insertions(+), 169 deletions(-) diff --git a/mypy/typeshed/stdlib/_codecs.pyi b/mypy/typeshed/stdlib/_codecs.pyi index 51f17f01ca71..f8141d8bad4b 100644 --- a/mypy/typeshed/stdlib/_codecs.pyi +++ b/mypy/typeshed/stdlib/_codecs.pyi @@ -47,11 +47,11 @@ _StrToStrEncoding: TypeAlias = Literal["rot13", "rot_13"] @overload def encode(obj: ReadableBuffer, encoding: _BytesToBytesEncoding, errors: str = "strict") -> bytes: ... @overload -def encode(obj: str, encoding: _StrToStrEncoding, errors: str = "strict") -> str: ... # type: ignore[misc] +def encode(obj: str, encoding: _StrToStrEncoding, errors: str = "strict") -> str: ... # type: ignore[overload-overlap] @overload def encode(obj: str, encoding: str = "utf-8", errors: str = "strict") -> bytes: ... @overload -def decode(obj: ReadableBuffer, encoding: _BytesToBytesEncoding, errors: str = "strict") -> bytes: ... # type: ignore[misc] +def decode(obj: ReadableBuffer, encoding: _BytesToBytesEncoding, errors: str = "strict") -> bytes: ... # type: ignore[overload-overlap] @overload def decode(obj: str, encoding: _StrToStrEncoding, errors: str = "strict") -> str: ... diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index 8a891971e9f1..495e29dfd8ce 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/argparse.pyi b/mypy/typeshed/stdlib/argparse.pyi index e947f67edd55..0cbbcd242195 100644 --- a/mypy/typeshed/stdlib/argparse.pyi +++ b/mypy/typeshed/stdlib/argparse.pyi @@ -172,7 +172,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ) -> None: ... @overload - def parse_args(self, args: Sequence[str] | None = None, namespace: None = None) -> Namespace: ... # type: ignore[misc] + def parse_args(self, args: Sequence[str] | None = None, namespace: None = None) -> Namespace: ... @overload def parse_args(self, args: Sequence[str] | None, namespace: _N) -> _N: ... @overload @@ -211,7 +211,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def format_usage(self) -> str: ... def format_help(self) -> str: ... @overload - def parse_known_args(self, args: Sequence[str] | None = None, namespace: None = None) -> tuple[Namespace, list[str]]: ... # type: ignore[misc] + def parse_known_args(self, args: Sequence[str] | None = None, namespace: None = None) -> tuple[Namespace, list[str]]: ... @overload def parse_known_args(self, args: Sequence[str] | None, namespace: _N) -> tuple[_N, list[str]]: ... @overload @@ -220,13 +220,15 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def exit(self, status: int = 0, message: str | None = None) -> NoReturn: ... def error(self, message: str) -> NoReturn: ... @overload - def parse_intermixed_args(self, args: Sequence[str] | None = None, namespace: None = None) -> Namespace: ... # type: ignore[misc] + def parse_intermixed_args(self, args: Sequence[str] | None = None, namespace: None = None) -> Namespace: ... @overload def parse_intermixed_args(self, args: Sequence[str] | None, namespace: _N) -> _N: ... @overload def parse_intermixed_args(self, *, namespace: _N) -> _N: ... @overload - def parse_known_intermixed_args(self, args: Sequence[str] | None = None, namespace: None = None) -> tuple[Namespace, list[str]]: ... # type: ignore[misc] + def parse_known_intermixed_args( + self, args: Sequence[str] | None = None, namespace: None = None + ) -> tuple[Namespace, list[str]]: ... @overload def parse_known_intermixed_args(self, args: Sequence[str] | None, namespace: _N) -> tuple[_N, list[str]]: ... @overload diff --git a/mypy/typeshed/stdlib/asyncio/base_events.pyi b/mypy/typeshed/stdlib/asyncio/base_events.pyi index cdf295d510d4..afddcd918584 100644 --- a/mypy/typeshed/stdlib/asyncio/base_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_events.pyi @@ -471,3 +471,5 @@ class BaseEventLoop(AbstractEventLoop): async def shutdown_default_executor(self, timeout: float | None = None) -> None: ... elif sys.version_info >= (3, 9): async def shutdown_default_executor(self) -> None: ... + + def __del__(self) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi b/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi index 8f262cd5c760..a5fe24e8768b 100644 --- a/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi @@ -55,6 +55,7 @@ class BaseSubprocessTransport(transports.SubprocessTransport): async def _wait(self) -> int: ... # undocumented def _try_finish(self) -> None: ... # undocumented def _call_connection_lost(self, exc: BaseException | None) -> None: ... # undocumented + def __del__(self) -> None: ... class WriteSubprocessPipeProto(protocols.BaseProtocol): # undocumented def __init__(self, proc: BaseSubprocessTransport, fd: int) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 4c62043875ba..87e7edb461ac 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 +from typing_extensions import Literal, Self, TypeAlias, deprecated from . import _AwaitableLike, _CoroutineLike from .base_events import Server @@ -613,8 +613,17 @@ def set_event_loop_policy(policy: AbstractEventLoopPolicy | None) -> None: ... def get_event_loop() -> AbstractEventLoop: ... def set_event_loop(loop: AbstractEventLoop | None) -> None: ... def new_event_loop() -> AbstractEventLoop: ... -def get_child_watcher() -> AbstractChildWatcher: ... -def set_child_watcher(watcher: AbstractChildWatcher) -> None: ... + +if sys.version_info >= (3, 12): + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def get_child_watcher() -> AbstractChildWatcher: ... + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def set_child_watcher(watcher: AbstractChildWatcher) -> None: ... + +else: + def get_child_watcher() -> AbstractChildWatcher: ... + def set_child_watcher(watcher: AbstractChildWatcher) -> None: ... + def _set_running_loop(__loop: AbstractEventLoop | None) -> None: ... def _get_running_loop() -> AbstractEventLoop: ... def get_running_loop() -> AbstractEventLoop: ... diff --git a/mypy/typeshed/stdlib/asyncio/sslproto.pyi b/mypy/typeshed/stdlib/asyncio/sslproto.pyi index 09733e5f9a01..393a1fbdc468 100644 --- a/mypy/typeshed/stdlib/asyncio/sslproto.pyi +++ b/mypy/typeshed/stdlib/asyncio/sslproto.pyi @@ -83,6 +83,8 @@ class _SSLProtocolTransport(transports._FlowControlMixin, transports.Transport): def set_read_buffer_limits(self, high: int | None = None, low: int | None = None) -> None: ... def get_read_buffer_size(self) -> int: ... + def __del__(self) -> None: ... + if sys.version_info >= (3, 11): _SSLProtocolBase: TypeAlias = protocols.BufferedProtocol else: diff --git a/mypy/typeshed/stdlib/asyncio/streams.pyi b/mypy/typeshed/stdlib/asyncio/streams.pyi index 804be1ca5065..81a94425f8de 100644 --- a/mypy/typeshed/stdlib/asyncio/streams.pyi +++ b/mypy/typeshed/stdlib/asyncio/streams.pyi @@ -128,6 +128,7 @@ class StreamReaderProtocol(FlowControlMixin, protocols.Protocol): client_connected_cb: _ClientConnectedCallback | None = None, loop: events.AbstractEventLoop | None = None, ) -> None: ... + def __del__(self) -> None: ... class StreamWriter: def __init__( @@ -161,6 +162,8 @@ class StreamWriter: async def start_tls( self, sslcontext: ssl.SSLContext, *, server_hostname: str | None = None, ssl_handshake_timeout: float | None = None ) -> None: ... + if sys.version_info >= (3, 11): + def __del__(self) -> None: ... class StreamReader(AsyncIterator[bytes]): def __init__(self, limit: int = 65536, loop: events.AbstractEventLoop | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/subprocess.pyi b/mypy/typeshed/stdlib/asyncio/subprocess.pyi index 9b7c82e689bf..03aea65f6d54 100644 --- a/mypy/typeshed/stdlib/asyncio/subprocess.pyi +++ b/mypy/typeshed/stdlib/asyncio/subprocess.pyi @@ -80,14 +80,14 @@ if sys.version_info >= (3, 11): stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, limit: int = 65536, - # These parameters are forced to these values by BaseEventLoop.subprocess_shell + # These parameters are forced to these values by BaseEventLoop.subprocess_exec universal_newlines: Literal[False] = False, - shell: Literal[True] = True, + shell: Literal[False] = False, bufsize: Literal[0] = 0, encoding: None = None, errors: None = None, + text: Literal[False] | None = None, # These parameters are taken by subprocess.Popen, which this ultimately delegates to - text: bool | None = None, executable: StrOrBytesPath | None = None, preexec_fn: Callable[[], Any] | None = None, close_fds: bool = True, @@ -145,14 +145,14 @@ elif sys.version_info >= (3, 10): stdout: int | IO[Any] | None = None, stderr: int | IO[Any] | None = None, limit: int = 65536, - # These parameters are forced to these values by BaseEventLoop.subprocess_shell + # These parameters are forced to these values by BaseEventLoop.subprocess_exec universal_newlines: Literal[False] = False, - shell: Literal[True] = True, + shell: Literal[False] = False, bufsize: Literal[0] = 0, encoding: None = None, errors: None = None, + text: Literal[False] | None = None, # These parameters are taken by subprocess.Popen, which this ultimately delegates to - text: bool | None = None, executable: StrOrBytesPath | None = None, preexec_fn: Callable[[], Any] | None = None, close_fds: bool = True, @@ -210,14 +210,14 @@ else: # >= 3.9 stderr: int | IO[Any] | None = None, loop: events.AbstractEventLoop | None = None, limit: int = 65536, - # These parameters are forced to these values by BaseEventLoop.subprocess_shell + # These parameters are forced to these values by BaseEventLoop.subprocess_exec universal_newlines: Literal[False] = False, - shell: Literal[True] = True, + shell: Literal[False] = False, bufsize: Literal[0] = 0, encoding: None = None, errors: None = None, + text: Literal[False] | None = None, # These parameters are taken by subprocess.Popen, which this ultimately delegates to - text: bool | None = None, executable: StrOrBytesPath | None = None, preexec_fn: Callable[[], Any] | None = None, close_fds: bool = True, diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index cdac7d359781..7c76abaf1dca 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -86,7 +86,7 @@ else: ) -> Iterator[Future[_T]]: ... @overload -def ensure_future(coro_or_future: _FT, *, loop: AbstractEventLoop | None = None) -> _FT: ... # type: ignore[misc] +def ensure_future(coro_or_future: _FT, *, loop: AbstractEventLoop | None = None) -> _FT: ... # type: ignore[overload-overlap] @overload def ensure_future(coro_or_future: Awaitable[_T], *, loop: AbstractEventLoop | None = None) -> Task[_T]: ... @@ -95,17 +95,16 @@ def ensure_future(coro_or_future: Awaitable[_T], *, loop: AbstractEventLoop | No # zip() because typing does not support variadic type variables. See # typing PR #1550 for discussion. # -# The many type: ignores here are because the overloads overlap, -# but having overlapping overloads is the only way to get acceptable type inference in all edge cases. +# N.B. Having overlapping overloads is the only way to get acceptable type inference in all edge cases. if sys.version_info >= (3, 10): @overload - def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: Literal[False] = False) -> Future[tuple[_T1]]: ... # type: ignore[misc] + def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: Literal[False] = False) -> Future[tuple[_T1]]: ... # type: ignore[overload-overlap] @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, return_exceptions: Literal[False] = False ) -> Future[tuple[_T1, _T2]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -113,7 +112,7 @@ if sys.version_info >= (3, 10): return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -122,7 +121,7 @@ if sys.version_info >= (3, 10): return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -132,7 +131,7 @@ if sys.version_info >= (3, 10): return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -143,15 +142,15 @@ if sys.version_info >= (3, 10): return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... @overload - def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: Literal[False] = False) -> Future[list[_T]]: ... # type: ignore[misc] + def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: Literal[False] = False) -> Future[list[_T]]: ... # type: ignore[overload-overlap] @overload - def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ... # type: ignore[misc] + def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ... # type: ignore[overload-overlap] @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, return_exceptions: bool ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -159,7 +158,7 @@ if sys.version_info >= (3, 10): return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -168,7 +167,7 @@ if sys.version_info >= (3, 10): return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -180,7 +179,7 @@ if sys.version_info >= (3, 10): tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException, _T5 | BaseException] ]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -204,11 +203,11 @@ if sys.version_info >= (3, 10): else: @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False ) -> Future[tuple[_T1]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, @@ -216,7 +215,7 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -225,7 +224,7 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -235,7 +234,7 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -246,7 +245,7 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -258,15 +257,15 @@ else: return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] *coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False ) -> Future[list[_T]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], *, loop: AbstractEventLoop | None = None, return_exceptions: bool ) -> Future[tuple[_T1 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, @@ -274,7 +273,7 @@ else: return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -283,7 +282,7 @@ else: return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -293,7 +292,7 @@ else: return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ... @overload - def gather( # type: ignore[misc] + def gather( # type: ignore[overload-overlap] __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], __coro_or_future3: _FutureLike[_T3], @@ -314,7 +313,7 @@ else: ] ]: ... @overload - def gather( # type: ignore[misc] + def gather( *coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: bool ) -> Future[list[_T | BaseException]]: ... @@ -338,7 +337,9 @@ else: if sys.version_info >= (3, 11): @overload - async def wait(fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED") -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] + async def wait( + fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> tuple[set[_FT], set[_FT]]: ... @overload async def wait( fs: Iterable[Task[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" @@ -346,7 +347,9 @@ if sys.version_info >= (3, 11): elif sys.version_info >= (3, 10): @overload - async def wait(fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED") -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] + async def wait( # type: ignore[overload-overlap] + fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> tuple[set[_FT], set[_FT]]: ... @overload async def wait( fs: Iterable[Awaitable[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED" @@ -354,7 +357,7 @@ elif sys.version_info >= (3, 10): else: @overload - async def wait( # type: ignore[misc] + async def wait( # type: ignore[overload-overlap] fs: Iterable[_FT], *, loop: AbstractEventLoop | None = None, diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index dc3d3496ae55..d440206aa0b9 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -3,7 +3,7 @@ import types from abc import ABCMeta, abstractmethod from collections.abc import Callable from typing import Any -from typing_extensions import Literal, Self +from typing_extensions import Literal, Self, deprecated from .events import AbstractEventLoop, BaseDefaultEventLoopPolicy from .selector_events import BaseSelectorEventLoop @@ -11,22 +11,46 @@ from .selector_events import BaseSelectorEventLoop # This is also technically not available on Win, # but other parts of typeshed need this definition. # So, it is special cased. -class AbstractChildWatcher: - @abstractmethod - def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... - @abstractmethod - def remove_child_handler(self, pid: int) -> bool: ... - @abstractmethod - def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... - @abstractmethod - def close(self) -> None: ... - @abstractmethod - def __enter__(self) -> Self: ... - @abstractmethod - def __exit__(self, typ: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None) -> None: ... - if sys.version_info >= (3, 8): +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: ... + @abstractmethod + def remove_child_handler(self, pid: int) -> bool: ... + @abstractmethod + def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... + @abstractmethod + def close(self) -> None: ... + @abstractmethod + def __enter__(self) -> Self: ... + @abstractmethod + 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: ... + +else: + class AbstractChildWatcher: @abstractmethod - def is_active(self) -> bool: ... + def add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + @abstractmethod + def remove_child_handler(self, pid: int) -> bool: ... + @abstractmethod + def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... + @abstractmethod + def close(self) -> None: ... + @abstractmethod + def __enter__(self) -> Self: ... + @abstractmethod + 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: ... if sys.platform != "win32": if sys.version_info >= (3, 9): @@ -62,28 +86,61 @@ if sys.platform != "win32": def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... - 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 remove_child_handler(self, pid: int) -> bool: ... + if sys.version_info >= (3, 12): + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + 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 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 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 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 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 remove_child_handler(self, pid: int) -> bool: ... class _UnixSelectorEventLoop(BaseSelectorEventLoop): ... class _UnixDefaultEventLoopPolicy(BaseDefaultEventLoopPolicy): - def get_child_watcher(self) -> AbstractChildWatcher: ... - def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ... + if sys.version_info >= (3, 12): + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def get_child_watcher(self) -> AbstractChildWatcher: ... + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ... + else: + def get_child_watcher(self) -> AbstractChildWatcher: ... + def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ... SelectorEventLoop = _UnixSelectorEventLoop DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy - if sys.version_info >= (3, 8): + if sys.version_info >= (3, 12): + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + class MultiLoopChildWatcher(AbstractChildWatcher): + def is_active(self) -> bool: ... + 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 add_child_handler(self, pid: int, callback: Callable[..., object], *args: Any) -> None: ... + def remove_child_handler(self, pid: int) -> bool: ... + def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... + elif sys.version_info >= (3, 8): class MultiLoopChildWatcher(AbstractChildWatcher): def is_active(self) -> bool: ... def close(self) -> None: ... @@ -95,6 +152,7 @@ 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: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 4f04b6286258..92b5279bcfcd 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -57,12 +57,14 @@ from typing import ( # noqa: Y022 from typing_extensions import ( Concatenate, Literal, + LiteralString, ParamSpec, Self, SupportsIndex, TypeAlias, TypeGuard, TypeVarTuple, + deprecated, final, ) @@ -160,8 +162,9 @@ class classmethod(Generic[_T, _P, _R_co]): def __wrapped__(self) -> Callable[Concatenate[type[_T], _P], _R_co]: ... class type: + # object.__base__ is None. Otherwise, it would be a type. @property - def __base__(self) -> type: ... + def __base__(self) -> type | None: ... __bases__: tuple[type, ...] @property def __basicsize__(self) -> int: ... @@ -442,8 +445,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: ... @@ -451,11 +463,20 @@ class str(Sequence[str]): self, __suffix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... if sys.version_info >= (3, 8): + @overload + def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... + @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] else: + @overload + def expandtabs(self: LiteralString, tabsize: int = 8) -> LiteralString: ... + @overload def expandtabs(self, tabsize: int = 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: ... @@ -471,32 +492,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 @@ -507,6 +587,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] @@ -515,13 +598,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]: ... @@ -844,6 +939,8 @@ class bool(int): @overload def __rxor__(self, __value: int) -> int: ... def __getnewargs__(self) -> tuple[int]: ... + @deprecated("Will throw an error in Python 3.14. Use `not` for logical negation of bools instead.") + def __invert__(self) -> int: ... @final class slice: @@ -1698,11 +1795,11 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # 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[misc] + def sum(__iterable: Iterable[bool | _LiteralInteger], start: int = 0) -> int: ... # type: ignore[overload-overlap] else: @overload - def sum(__iterable: Iterable[bool], __start: int = 0) -> int: ... # type: ignore[misc] + def sum(__iterable: Iterable[bool | _LiteralInteger], __start: int = 0) -> int: ... # type: ignore[overload-overlap] @overload def sum(__iterable: Iterable[_SupportsSumNoDefaultT]) -> _SupportsSumNoDefaultT | Literal[0]: ... @@ -1719,7 +1816,7 @@ else: # (A "SupportsDunderDict" protocol doesn't work) # Use a type: ignore to make complaints about overlapping overloads go away @overload -def vars(__object: type) -> types.MappingProxyType[str, Any]: ... # type: ignore[misc] +def vars(__object: type) -> types.MappingProxyType[str, Any]: ... # type: ignore[overload-overlap] @overload def vars(__object: Any = ...) -> dict[str, Any]: ... diff --git a/mypy/typeshed/stdlib/cgi.pyi b/mypy/typeshed/stdlib/cgi.pyi index a2acfa92d463..21bf8ca25394 100644 --- a/mypy/typeshed/stdlib/cgi.pyi +++ b/mypy/typeshed/stdlib/cgi.pyi @@ -117,7 +117,8 @@ class FieldStorage: def __contains__(self, key: str) -> bool: ... def __len__(self) -> int: ... def __bool__(self) -> bool: ... - # In Python 3 it returns bytes or str IO depending on an internal flag + def __del__(self) -> None: ... + # Returns bytes or str IO depending on an internal flag def make_file(self) -> IO[Any]: ... def print_exception( diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index bb51dec50cab..955681c6ac0c 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -87,9 +87,9 @@ class UserDict(MutableMapping[_KT, _VT]): def __or__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ... @overload def __or__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ... - @overload # type: ignore[misc] + @overload def __ror__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ... - @overload # type: ignore[misc] + @overload def __ror__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ... # UserDict.__ior__ should be kept roughly in line with MutableMapping.update() @overload # type: ignore[misc] diff --git a/mypy/typeshed/stdlib/contextvars.pyi b/mypy/typeshed/stdlib/contextvars.pyi index a67d0349b46a..825c018d580f 100644 --- a/mypy/typeshed/stdlib/contextvars.pyi +++ b/mypy/typeshed/stdlib/contextvars.pyi @@ -50,7 +50,7 @@ def copy_context() -> Context: ... class Context(Mapping[ContextVar[Any], Any]): def __init__(self) -> None: ... @overload - def get(self, __key: ContextVar[_T], __default: None = None) -> _T | None: ... # type: ignore[misc] # overlapping overloads + def get(self, __key: ContextVar[_T], __default: None = None) -> _T | None: ... @overload def get(self, __key: ContextVar[_T], __default: _T) -> _T: ... @overload diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 1b4e59b7c120..451896bed72a 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, NamedTuple, TypeVar, overload -from typing_extensions import Literal, Self, TypeAlias, TypedDict, final +from typing_extensions import Literal, ParamSpec, Self, TypeAlias, TypedDict, final if sys.version_info >= (3, 9): from types import GenericAlias @@ -28,15 +28,17 @@ if sys.version_info >= (3, 8): 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: ... +def reduce(__function: Callable[[_T, _S], _T], __sequence: Iterable[_S], __initial: _T) -> _T: ... @overload -def reduce(function: Callable[[_T, _T], _T], sequence: Iterable[_T]) -> _T: ... +def reduce(__function: Callable[[_T, _T], _T], __sequence: Iterable[_T]) -> _T: ... class _CacheInfo(NamedTuple): hits: int @@ -85,31 +87,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/http/client.pyi b/mypy/typeshed/stdlib/http/client.pyi index 305568fce6cf..20223695a1a8 100644 --- a/mypy/typeshed/stdlib/http/client.pyi +++ b/mypy/typeshed/stdlib/http/client.pyi @@ -187,7 +187,7 @@ class HTTPSConnection(HTTPConnection): def __init__( self, host: str, - port: str | None = None, + port: int | None = None, *, timeout: float | None = ..., source_address: tuple[str, int] | None = None, diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index 8c395f8a18af..148e12ec7e3f 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -134,7 +134,7 @@ if sys.version_info >= (3, 9): def joinpath(self, __child: str) -> Traversable: ... # The documentation and runtime protocol allows *args, **kwargs arguments, - # but this would mean that all implementors would have to support them, + # but this would mean that all implementers would have to support them, # which is not the case. @overload @abstractmethod diff --git a/mypy/typeshed/stdlib/importlib/machinery.pyi b/mypy/typeshed/stdlib/importlib/machinery.pyi index 1a9680ab3c46..a0431905a828 100644 --- a/mypy/typeshed/stdlib/importlib/machinery.pyi +++ b/mypy/typeshed/stdlib/importlib/machinery.pyi @@ -2,8 +2,9 @@ import importlib.abc import sys import types from _typeshed import ReadableBuffer -from collections.abc import Callable, Iterable, Sequence +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 @@ -158,3 +159,23 @@ class ExtensionFileLoader(importlib.abc.ExecutionLoader): def get_code(self, fullname: str) -> None: ... def __eq__(self, other: object) -> bool: ... def __hash__(self) -> int: ... + +if sys.version_info >= (3, 11): + import importlib.readers + + class NamespaceLoader(importlib.abc.InspectLoader): + def __init__( + self, name: str, path: MutableSequence[str], path_finder: Callable[[str, tuple[str, ...]], ModuleSpec] + ) -> None: ... + def is_package(self, fullname: str) -> Literal[True]: ... + def get_source(self, fullname: str) -> Literal[""]: ... + def get_code(self, fullname: str) -> types.CodeType: ... + def create_module(self, spec: ModuleSpec) -> None: ... + def exec_module(self, module: types.ModuleType) -> None: ... + @deprecated("load_module() is deprecated; use exec_module() instead") + def load_module(self, fullname: str) -> types.ModuleType: ... + def get_resource_reader(self, module: types.ModuleType) -> importlib.readers.NamespaceReader: ... + if sys.version_info < (3, 12): + @staticmethod + @deprecated("module_repr() is deprecated, and has been removed in Python 3.12") + def module_repr(module: types.ModuleType) -> str: ... diff --git a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi index e52756544e9a..fd470b8f061d 100644 --- a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi @@ -207,7 +207,7 @@ if sys.version_info >= (3, 12): elif sys.version_info >= (3, 10): @overload - def entry_points() -> SelectableGroups: ... # type: ignore[misc] + def entry_points() -> SelectableGroups: ... # type: ignore[overload-overlap] @overload def entry_points( *, name: str = ..., value: str = ..., group: str = ..., module: str = ..., attr: str = ..., extras: list[str] = ... diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index b54e0a9fd05b..16270b948f35 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -94,7 +94,7 @@ class BufferedIOBase(IOBase): class FileIO(RawIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of writelines in the base classes mode: str - name: FileDescriptorOrPath # type: ignore[assignment] + name: FileDescriptorOrPath def __init__( self, file: FileDescriptorOrPath, mode: str = ..., closefd: bool = ..., opener: _Opener | None = ... ) -> None: ... diff --git a/mypy/typeshed/stdlib/itertools.pyi b/mypy/typeshed/stdlib/itertools.pyi index 55f9c92d8cac..1bc0b2ec7390 100644 --- a/mypy/typeshed/stdlib/itertools.pyi +++ b/mypy/typeshed/stdlib/itertools.pyi @@ -10,6 +10,7 @@ _T = TypeVar("_T") _S = TypeVar("_S") _N = TypeVar("_N", int, float, SupportsFloat, SupportsInt, SupportsIndex, SupportsComplex) _T_co = TypeVar("_T_co", covariant=True) +_S_co = TypeVar("_S_co", covariant=True) _T1 = TypeVar("_T1") _T2 = TypeVar("_T2") _T3 = TypeVar("_T3") @@ -84,13 +85,13 @@ class filterfalse(Iterator[_T]): def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class groupby(Iterator[tuple[_T, Iterator[_S]]], Generic[_T, _S]): +class groupby(Iterator[tuple[_T_co, Iterator[_S_co]]], Generic[_T_co, _S_co]): @overload def __new__(cls, iterable: Iterable[_T1], key: None = None) -> groupby[_T1, _T1]: ... @overload def __new__(cls, iterable: Iterable[_T1], key: Callable[[_T1], _T2]) -> groupby[_T2, _T1]: ... def __iter__(self) -> Self: ... - def __next__(self) -> tuple[_T, Iterator[_S]]: ... + def __next__(self) -> tuple[_T_co, Iterator[_S_co]]: ... class islice(Iterator[_T]): @overload @@ -100,10 +101,10 @@ class islice(Iterator[_T]): def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -class starmap(Iterator[_T]): - def __init__(self, __function: Callable[..., _T], __iterable: Iterable[Iterable[Any]]) -> None: ... +class starmap(Iterator[_T_co]): + def __new__(cls, __function: Callable[..., _T], __iterable: Iterable[Iterable[Any]]) -> starmap[_T]: ... def __iter__(self) -> Self: ... - def __next__(self) -> _T: ... + def __next__(self) -> _T_co: ... class takewhile(Iterator[_T]): def __init__(self, __predicate: _Predicate[_T], __iterable: Iterable[_T]) -> None: ... @@ -269,10 +270,19 @@ class combinations(Iterator[_T_co]): def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... -class combinations_with_replacement(Iterator[tuple[_T, ...]], Generic[_T]): - def __init__(self, iterable: Iterable[_T], r: int) -> None: ... +class combinations_with_replacement(Iterator[_T_co]): + @overload + def __new__(cls, iterable: Iterable[_T], r: Literal[2]) -> combinations_with_replacement[tuple[_T, _T]]: ... + @overload + def __new__(cls, iterable: Iterable[_T], r: Literal[3]) -> combinations_with_replacement[tuple[_T, _T, _T]]: ... + @overload + def __new__(cls, iterable: Iterable[_T], r: Literal[4]) -> combinations_with_replacement[tuple[_T, _T, _T, _T]]: ... + @overload + def __new__(cls, iterable: Iterable[_T], r: Literal[5]) -> combinations_with_replacement[tuple[_T, _T, _T, _T, _T]]: ... + @overload + def __new__(cls, iterable: Iterable[_T], r: int) -> combinations_with_replacement[tuple[_T, ...]]: ... def __iter__(self) -> Self: ... - def __next__(self) -> tuple[_T, ...]: ... + def __next__(self) -> _T_co: ... if sys.version_info >= (3, 10): class pairwise(Iterator[_T_co]): diff --git a/mypy/typeshed/stdlib/logging/config.pyi b/mypy/typeshed/stdlib/logging/config.pyi index e92658f7f1b3..0a61e5b16870 100644 --- a/mypy/typeshed/stdlib/logging/config.pyi +++ b/mypy/typeshed/stdlib/logging/config.pyi @@ -5,7 +5,7 @@ from configparser import RawConfigParser from re import Pattern from threading import Thread from typing import IO, Any, overload -from typing_extensions import Literal, SupportsIndex, TypeAlias, TypedDict +from typing_extensions import Literal, Required, SupportsIndex, TypeAlias, TypedDict from . import Filter, Filterer, Formatter, Handler, Logger, _FilterType, _FormatStyle, _Level @@ -50,18 +50,16 @@ _FilterConfiguration: TypeAlias = _FilterConfigurationTypedDict | dict[str, Any] # Handler config can have additional keys even when not providing a custom factory so we just use `dict`. _HandlerConfiguration: TypeAlias = dict[str, Any] -class _OptionalDictConfigArgs(TypedDict, total=False): +class _DictConfigArgs(TypedDict, total=False): + version: Required[Literal[1]] formatters: dict[str, _FormatterConfiguration] filters: dict[str, _FilterConfiguration] handlers: dict[str, _HandlerConfiguration] loggers: dict[str, _LoggerConfiguration] - root: _RootLoggerConfiguration | None + root: _RootLoggerConfiguration incremental: bool disable_existing_loggers: bool -class _DictConfigArgs(_OptionalDictConfigArgs, TypedDict): - version: Literal[1] - # Accept dict[str, Any] to avoid false positives if called with a dict # type, since dict types are not compatible with TypedDicts. # diff --git a/mypy/typeshed/stdlib/math.pyi b/mypy/typeshed/stdlib/math.pyi index 4a4d592b860d..73b53a713301 100644 --- a/mypy/typeshed/stdlib/math.pyi +++ b/mypy/typeshed/stdlib/math.pyi @@ -125,7 +125,7 @@ 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[misc] + def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = 1) -> int: ... # type: ignore[overload-overlap] @overload def prod(__iterable: Iterable[_SupportsFloatOrIndex], *, start: _SupportsFloatOrIndex = 1) -> float: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/connection.pyi b/mypy/typeshed/stdlib/multiprocessing/connection.pyi index 28696fe6a3a3..333b8820d84d 100644 --- a/mypy/typeshed/stdlib/multiprocessing/connection.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/connection.pyi @@ -31,6 +31,7 @@ class _ConnectionBase: def __exit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, exc_tb: types.TracebackType | None ) -> None: ... + def __del__(self) -> None: ... class Connection(_ConnectionBase): ... diff --git a/mypy/typeshed/stdlib/multiprocessing/managers.pyi b/mypy/typeshed/stdlib/multiprocessing/managers.pyi index 9cfc1ebbdd5e..c0ef0a3609d0 100644 --- a/mypy/typeshed/stdlib/multiprocessing/managers.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/managers.pyi @@ -216,3 +216,4 @@ if sys.version_info >= (3, 8): 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 c52f1c1f5453..5ad4bfe93fe9 100644 --- a/mypy/typeshed/stdlib/multiprocessing/pool.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/pool.pyi @@ -112,6 +112,7 @@ class Pool: def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> None: ... + def __del__(self) -> None: ... class ThreadPool(Pool): def __init__( diff --git a/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi b/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi index ae6e2a0ed19f..adbe8b943de6 100644 --- a/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi @@ -20,6 +20,7 @@ class SharedMemory: def size(self) -> int: ... def close(self) -> None: ... def unlink(self) -> None: ... + def __del__(self) -> None: ... class ShareableList(Generic[_SLT]): shm: SharedMemory diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 2810d086ae49..45eaf2a66e80 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -248,7 +248,7 @@ class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]): unsetenv: Callable[[AnyStr, AnyStr], object], ) -> None: ... - def setdefault(self, key: AnyStr, value: AnyStr) -> AnyStr: ... # type: ignore[override] + def setdefault(self, key: AnyStr, value: AnyStr) -> AnyStr: ... def copy(self) -> dict[AnyStr, AnyStr]: ... def __delitem__(self, key: AnyStr) -> None: ... def __getitem__(self, key: AnyStr) -> AnyStr: ... diff --git a/mypy/typeshed/stdlib/pkgutil.pyi b/mypy/typeshed/stdlib/pkgutil.pyi index 59f1f734cf90..4a0c8d101b7a 100644 --- a/mypy/typeshed/stdlib/pkgutil.pyi +++ b/mypy/typeshed/stdlib/pkgutil.pyi @@ -3,6 +3,7 @@ from _typeshed import SupportsRead from collections.abc import Callable, Iterable, Iterator from importlib.abc import Loader, MetaPathFinder, PathEntryFinder from typing import IO, Any, NamedTuple, TypeVar +from typing_extensions import deprecated __all__ = [ "get_importer", @@ -35,8 +36,10 @@ if sys.version_info < (3, 12): class ImpLoader: def __init__(self, fullname: str, file: IO[str], filename: str, etc: tuple[str, str, int]) -> None: ... +@deprecated("Use importlib.util.find_spec() instead. Will be removed in Python 3.14.") def find_loader(fullname: str) -> Loader | None: ... def get_importer(path_item: str) -> PathEntryFinder | None: ... +@deprecated("Use importlib.util.find_spec() instead. Will be removed in Python 3.14.") def get_loader(module_or_name: str) -> Loader | None: ... def iter_importers(fullname: str = "") -> Iterator[MetaPathFinder | PathEntryFinder]: ... def iter_modules(path: Iterable[str] | None = None, prefix: str = "") -> Iterator[ModuleInfo]: ... diff --git a/mypy/typeshed/stdlib/re.pyi b/mypy/typeshed/stdlib/re.pyi index 29ee8b66815e..ec532ca3cffe 100644 --- a/mypy/typeshed/stdlib/re.pyi +++ b/mypy/typeshed/stdlib/re.pyi @@ -67,7 +67,7 @@ class Match(Generic[AnyStr]): @overload def expand(self: Match[str], template: str) -> str: ... @overload - def expand(self: Match[bytes], template: ReadableBuffer) -> bytes: ... # type: ignore[misc] + def expand(self: Match[bytes], template: ReadableBuffer) -> bytes: ... # type: ignore[overload-overlap] @overload def expand(self, template: AnyStr) -> AnyStr: ... # group() returns "AnyStr" or "AnyStr | None", depending on the pattern. @@ -117,19 +117,19 @@ class Pattern(Generic[AnyStr]): @overload def search(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Match[str] | None: ... @overload - def search(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[misc] + def search(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[overload-overlap] @overload def search(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Match[AnyStr] | None: ... @overload def match(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Match[str] | None: ... @overload - def match(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[misc] + def match(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[overload-overlap] @overload def match(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Match[AnyStr] | None: ... @overload def fullmatch(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Match[str] | None: ... @overload - def fullmatch(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[misc] + def fullmatch(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... # type: ignore[overload-overlap] @overload def fullmatch(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Match[AnyStr] | None: ... @overload @@ -148,13 +148,13 @@ class Pattern(Generic[AnyStr]): @overload def finditer(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[str]]: ... @overload - def finditer(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[bytes]]: ... # type: ignore[misc] + def finditer(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[bytes]]: ... # type: ignore[overload-overlap] @overload def finditer(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Iterator[Match[AnyStr]]: ... @overload def sub(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = 0) -> str: ... @overload - def sub( # type: ignore[misc] + def sub( # type: ignore[overload-overlap] self: Pattern[bytes], repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer], string: ReadableBuffer, @@ -165,7 +165,7 @@ class Pattern(Generic[AnyStr]): @overload def subn(self: Pattern[str], repl: str | Callable[[Match[str]], str], string: str, count: int = 0) -> tuple[str, int]: ... @overload - def subn( # type: ignore[misc] + def subn( # type: ignore[overload-overlap] self: Pattern[bytes], repl: ReadableBuffer | Callable[[Match[bytes]], ReadableBuffer], string: ReadableBuffer, diff --git a/mypy/typeshed/stdlib/shelve.pyi b/mypy/typeshed/stdlib/shelve.pyi index b162b3a85766..59abeafe6fca 100644 --- a/mypy/typeshed/stdlib/shelve.pyi +++ b/mypy/typeshed/stdlib/shelve.pyi @@ -16,7 +16,7 @@ class Shelf(MutableMapping[str, _VT]): def __iter__(self) -> Iterator[str]: ... def __len__(self) -> int: ... @overload # type: ignore[override] - def get(self, key: str, default: None = None) -> _VT | None: ... # type: ignore[misc] # overlapping overloads + def get(self, key: str, default: None = None) -> _VT | None: ... @overload def get(self, key: str, default: _VT) -> _VT: ... @overload @@ -29,6 +29,7 @@ class Shelf(MutableMapping[str, _VT]): def __exit__( self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... + def __del__(self) -> None: ... def close(self) -> None: ... def sync(self) -> None: ... diff --git a/mypy/typeshed/stdlib/shutil.pyi b/mypy/typeshed/stdlib/shutil.pyi index 38c50d51b129..78e930920073 100644 --- a/mypy/typeshed/stdlib/shutil.pyi +++ b/mypy/typeshed/stdlib/shutil.pyi @@ -154,13 +154,13 @@ def disk_usage(path: FileDescriptorOrPath) -> _ntuple_diskusage: ... # see https://bugs.python.org/issue33140. We keep it here because it's # in __all__. @overload -def chown(path: StrOrBytesPath, user: str | int, group: None = None) -> None: ... +def chown(path: FileDescriptorOrPath, user: str | int, group: None = None) -> None: ... @overload -def chown(path: StrOrBytesPath, user: None = None, *, group: str | int) -> None: ... +def chown(path: FileDescriptorOrPath, user: None = None, *, group: str | int) -> None: ... @overload -def chown(path: StrOrBytesPath, user: None, group: str | int) -> None: ... +def chown(path: FileDescriptorOrPath, user: None, group: str | int) -> None: ... @overload -def chown(path: StrOrBytesPath, user: str | int, group: str | int) -> None: ... +def chown(path: FileDescriptorOrPath, user: str | int, group: str | int) -> None: ... if sys.version_info >= (3, 8): @overload diff --git a/mypy/typeshed/stdlib/subprocess.pyi b/mypy/typeshed/stdlib/subprocess.pyi index b6cc23651ade..b89623f05c99 100644 --- a/mypy/typeshed/stdlib/subprocess.pyi +++ b/mypy/typeshed/stdlib/subprocess.pyi @@ -2564,6 +2564,7 @@ class Popen(Generic[AnyStr]): def __exit__( self, exc_type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... + def __del__(self) -> None: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/mypy/typeshed/stdlib/sunau.pyi b/mypy/typeshed/stdlib/sunau.pyi index 6109b368c01a..b508a1ea8e20 100644 --- a/mypy/typeshed/stdlib/sunau.pyi +++ b/mypy/typeshed/stdlib/sunau.pyi @@ -34,6 +34,7 @@ class Au_read: def __init__(self, f: _File) -> None: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... + def __del__(self) -> None: ... def getfp(self) -> IO[bytes] | None: ... def rewind(self) -> None: ... def close(self) -> None: ... @@ -54,6 +55,7 @@ class Au_write: def __init__(self, f: _File) -> None: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... + def __del__(self) -> None: ... def setnchannels(self, nchannels: int) -> None: ... def getnchannels(self) -> int: ... def setsampwidth(self, sampwidth: int) -> None: ... diff --git a/mypy/typeshed/stdlib/telnetlib.pyi b/mypy/typeshed/stdlib/telnetlib.pyi index 10f6e4930f75..d244d54f2fbf 100644 --- a/mypy/typeshed/stdlib/telnetlib.pyi +++ b/mypy/typeshed/stdlib/telnetlib.pyi @@ -119,3 +119,4 @@ class Telnet: def __exit__( self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... + def __del__(self) -> None: ... diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index f8dcb24c1daf..628f99410732 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -629,7 +629,7 @@ class TemporaryDirectory(Generic[AnyStr]): # The overloads overlap, but they should still work fine. @overload -def mkstemp( # type: ignore[misc] +def mkstemp( # type: ignore[overload-overlap] suffix: str | None = None, prefix: str | None = None, dir: StrPath | None = None, text: bool = False ) -> tuple[int, str]: ... @overload @@ -639,7 +639,7 @@ def mkstemp( # The overloads overlap, but they should still work fine. @overload -def mkdtemp(suffix: str | None = None, prefix: str | None = None, dir: StrPath | None = None) -> str: ... # type: ignore[misc] +def mkdtemp(suffix: str | None = None, prefix: str | None = None, dir: StrPath | None = None) -> str: ... # type: ignore[overload-overlap] @overload def mkdtemp(suffix: bytes | None = None, prefix: bytes | None = None, dir: BytesPath | None = None) -> bytes: ... def mktemp(suffix: str = "", prefix: str = "tmp", dir: StrPath | None = None) -> str: ... diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index d0eb97aa5ebd..a73b1e275f11 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -282,6 +282,7 @@ class Variable: @deprecated("use trace_info() instead of trace_vinfo()") def trace_vinfo(self): ... def __eq__(self, other: object) -> bool: ... + def __del__(self) -> None: ... class StringVar(Variable): def __init__(self, master: Misc | None = None, value: str | None = None, name: str | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/tkinter/dnd.pyi b/mypy/typeshed/stdlib/tkinter/dnd.pyi index 8f438537369c..5a83bb56679f 100644 --- a/mypy/typeshed/stdlib/tkinter/dnd.pyi +++ b/mypy/typeshed/stdlib/tkinter/dnd.pyi @@ -15,5 +15,6 @@ class DndHandler: def finish(self, event: Event[Misc] | None, commit: int = 0) -> None: ... def on_motion(self, event: Event[Misc]) -> None: ... def on_release(self, event: Event[Misc]) -> None: ... + def __del__(self) -> None: ... def dnd_start(source: _DndSource, event: Event[Misc]) -> DndHandler | None: ... diff --git a/mypy/typeshed/stdlib/tkinter/font.pyi b/mypy/typeshed/stdlib/tkinter/font.pyi index 0a557e921914..9dffcd1ba0c6 100644 --- a/mypy/typeshed/stdlib/tkinter/font.pyi +++ b/mypy/typeshed/stdlib/tkinter/font.pyi @@ -101,6 +101,7 @@ class Font: def metrics(self, *, displayof: tkinter.Misc | None = ...) -> _MetricsDict: ... def measure(self, text: str, displayof: tkinter.Misc | None = None) -> int: ... def __eq__(self, other: object) -> bool: ... + def __del__(self) -> None: ... def families(root: tkinter.Misc | None = None, displayof: tkinter.Misc | None = None) -> tuple[str, ...]: ... def names(root: tkinter.Misc | None = None) -> tuple[str, ...]: ... diff --git a/mypy/typeshed/stdlib/tkinter/ttk.pyi b/mypy/typeshed/stdlib/tkinter/ttk.pyi index bb416717a378..2bbbafbcb945 100644 --- a/mypy/typeshed/stdlib/tkinter/ttk.pyi +++ b/mypy/typeshed/stdlib/tkinter/ttk.pyi @@ -1039,7 +1039,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): @overload def heading(self, column: str | int, option: str) -> Any: ... @overload - def heading(self, column: str | int, option: None = None) -> _TreeviewHeaderDict: ... # type: ignore[misc] + def heading(self, column: str | int, option: None = None) -> _TreeviewHeaderDict: ... # type: ignore[overload-overlap] @overload def heading( self, @@ -1083,7 +1083,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): @overload def item(self, item: str | int, option: str) -> Any: ... @overload - def item(self, item: str | int, option: None = None) -> _TreeviewItemDict: ... # type: ignore[misc] + def item(self, item: str | int, option: None = None) -> _TreeviewItemDict: ... # type: ignore[overload-overlap] @overload def item( self, diff --git a/mypy/typeshed/stdlib/turtle.pyi b/mypy/typeshed/stdlib/turtle.pyi index 36cd5f1f6e9d..fd0723fd73ed 100644 --- a/mypy/typeshed/stdlib/turtle.pyi +++ b/mypy/typeshed/stdlib/turtle.pyi @@ -336,7 +336,7 @@ class TPen: def isvisible(self) -> bool: ... # Note: signatures 1 and 2 overlap unsafely when no arguments are provided @overload - def pen(self) -> _PenState: ... # type: ignore[misc] + def pen(self) -> _PenState: ... # type: ignore[overload-overlap] @overload def pen( self, @@ -382,7 +382,7 @@ class RawTurtle(TPen, TNavigator): def shape(self, name: str) -> None: ... # Unsafely overlaps when no arguments are provided @overload - def shapesize(self) -> tuple[float, float, float]: ... # type: ignore[misc] + def shapesize(self) -> tuple[float, float, float]: ... # type: ignore[overload-overlap] @overload def shapesize( self, stretch_wid: float | None = None, stretch_len: float | None = None, outline: float | None = None @@ -393,7 +393,7 @@ class RawTurtle(TPen, TNavigator): def shearfactor(self, shear: float) -> None: ... # Unsafely overlaps when no arguments are provided @overload - def shapetransform(self) -> tuple[float, float, float, float]: ... # type: ignore[misc] + def shapetransform(self) -> tuple[float, float, float, float]: ... # type: ignore[overload-overlap] @overload def shapetransform( self, t11: float | None = None, t12: float | None = None, t21: float | None = None, t22: float | None = None @@ -617,7 +617,7 @@ def isvisible() -> bool: ... # Note: signatures 1 and 2 overlap unsafely when no arguments are provided @overload -def pen() -> _PenState: ... # type: ignore[misc] +def pen() -> _PenState: ... # type: ignore[overload-overlap] @overload def pen( pen: _PenState | None = None, @@ -656,7 +656,7 @@ if sys.version_info >= (3, 12): # Unsafely overlaps when no arguments are provided @overload -def shapesize() -> tuple[float, float, float]: ... # type: ignore[misc] +def shapesize() -> tuple[float, float, float]: ... # type: ignore[overload-overlap] @overload def shapesize(stretch_wid: float | None = None, stretch_len: float | None = None, outline: float | None = None) -> None: ... @overload @@ -666,7 +666,7 @@ def shearfactor(shear: float) -> None: ... # Unsafely overlaps when no arguments are provided @overload -def shapetransform() -> tuple[float, float, float, float]: ... # type: ignore[misc] +def shapetransform() -> tuple[float, float, float, float]: ... # type: ignore[overload-overlap] @overload def shapetransform( t11: float | None = None, t12: float | None = None, t21: float | None = None, t22: float | None = None diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index fcaf5264c5e3..b26a668d273b 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -593,9 +593,8 @@ _R = TypeVar("_R") _P = ParamSpec("_P") # it's not really an Awaitable, but can be used in an await expression. Real type: Generator & Awaitable -# The type: ignore is due to overlapping overloads, not the use of ParamSpec @overload -def coroutine(func: Callable[_P, Generator[Any, Any, _R]]) -> Callable[_P, Awaitable[_R]]: ... # type: ignore[misc] +def coroutine(func: Callable[_P, Generator[Any, Any, _R]]) -> Callable[_P, Awaitable[_R]]: ... # type: ignore[overload-overlap] @overload def coroutine(func: _Fn) -> _Fn: ... diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 7694157d70fe..555df0ea47c8 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -281,7 +281,12 @@ if sys.version_info >= (3, 10): class NewType: def __init__(self, name: str, tp: Any) -> None: ... - def __call__(self, __x: _T) -> _T: ... + if sys.version_info >= (3, 11): + @staticmethod + def __call__(__x: _T) -> _T: ... + else: + def __call__(self, x: _T) -> _T: ... + def __or__(self, other: Any) -> _SpecialForm: ... def __ror__(self, other: Any) -> _SpecialForm: ... __supertype__: type @@ -970,9 +975,8 @@ if sys.version_info >= (3, 12): @property def __module__(self) -> str | None: ... # type: ignore[override] def __getitem__(self, parameters: Any) -> Any: ... - if sys.version_info >= (3, 10): - def __or__(self, right: Any) -> _SpecialForm: ... - def __ror__(self, left: Any) -> _SpecialForm: ... + def __or__(self, right: Any) -> _SpecialForm: ... + def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 13): def is_protocol(__tp: type) -> bool: ... diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index b5e2341cd020..5c5b756f5256 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -182,6 +182,7 @@ __all__ = [ "is_protocol", "no_type_check", "no_type_check_decorator", + "ReadOnly", ] _T = typing.TypeVar("_T") @@ -220,6 +221,8 @@ def IntVar(name: str) -> Any: ... # returns a new TypeVar class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): __required_keys__: ClassVar[frozenset[str]] __optional_keys__: ClassVar[frozenset[str]] + __readonly_keys__: ClassVar[frozenset[str]] + __mutable_keys__: ClassVar[frozenset[str]] __total__: ClassVar[bool] __orig_bases__: ClassVar[tuple[Any, ...]] def copy(self) -> Self: ... @@ -283,7 +286,6 @@ class SupportsIndex(Protocol, metaclass=abc.ABCMeta): if sys.version_info >= (3, 10): from typing import ( Concatenate as Concatenate, - NewType as NewType, ParamSpecArgs as ParamSpecArgs, ParamSpecKwargs as ParamSpecKwargs, TypeAlias as TypeAlias, @@ -308,18 +310,13 @@ else: TypeGuard: _SpecialForm def is_typeddict(tp: object) -> bool: ... - class NewType: - def __init__(self, name: str, tp: Any) -> None: ... - def __call__(self, __x: _T) -> _T: ... - __supertype__: type - -# New things in 3.11 -# NamedTuples are not new, but the ability to create generic NamedTuples is new in 3.11 +# New and changed things in 3.11 if sys.version_info >= (3, 11): from typing import ( LiteralString as LiteralString, NamedTuple as NamedTuple, Never as Never, + NewType as NewType, NotRequired as NotRequired, Required as Required, Self as Self, @@ -376,6 +373,14 @@ else: def _replace(self, **kwargs: Any) -> Self: ... + class NewType: + def __init__(self, name: str, tp: Any) -> None: ... + def __call__(self, __obj: _T) -> _T: ... + __supertype__: type + if sys.version_info >= (3, 10): + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... + # New things in 3.xx # The `default` parameter was added to TypeVar, ParamSpec, and TypeVarTuple (PEP 696) # The `infer_variance` parameter was added to TypeVar in 3.12 (PEP 695) @@ -449,7 +454,12 @@ class TypeVarTuple: def __init__(self, name: str, *, default: Any | None = None) -> None: ... def __iter__(self) -> Any: ... # Unpack[Self] -def deprecated(__msg: str, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> Callable[[_T], _T]: ... +class deprecated: + message: str + category: type[Warning] | None + stacklevel: int + def __init__(self, __message: str, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> None: ... + def __call__(self, __arg: _T) -> _T: ... if sys.version_info >= (3, 12): from collections.abc import Buffer as Buffer @@ -496,3 +506,5 @@ class Doc: def __init__(self, __documentation: str) -> None: ... def __hash__(self) -> int: ... def __eq__(self, other: object) -> bool: ... + +ReadOnly: _SpecialForm diff --git a/mypy/typeshed/stdlib/unittest/async_case.pyi b/mypy/typeshed/stdlib/unittest/async_case.pyi index c1de205fbd55..b71eec2e0644 100644 --- a/mypy/typeshed/stdlib/unittest/async_case.pyi +++ b/mypy/typeshed/stdlib/unittest/async_case.pyi @@ -17,3 +17,5 @@ class IsolatedAsyncioTestCase(TestCase): def addAsyncCleanup(self, __func: Callable[_P, Awaitable[object]], *args: _P.args, **kwargs: _P.kwargs) -> None: ... if sys.version_info >= (3, 11): async def enterAsyncContext(self, cm: AbstractAsyncContextManager[_T]) -> _T: ... + if sys.version_info >= (3, 9): + def __del__(self) -> None: ... diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index baf025bdeb5a..8e96b23ce959 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -318,7 +318,7 @@ class _patcher: # Ideally we'd be able to add an overload for it so that the return type is _patch[MagicMock], # but that's impossible with the current type system. @overload - def __call__( # type: ignore[misc] + def __call__( # type: ignore[overload-overlap] self, target: str, new: _T, @@ -343,7 +343,7 @@ class _patcher: ) -> _patch_default_new: ... @overload @staticmethod - def object( # type: ignore[misc] + def object( target: Any, attribute: str, new: _T, diff --git a/mypy/typeshed/stdlib/urllib/request.pyi b/mypy/typeshed/stdlib/urllib/request.pyi index 237a4d264b51..ca3feaea262a 100644 --- a/mypy/typeshed/stdlib/urllib/request.pyi +++ b/mypy/typeshed/stdlib/urllib/request.pyi @@ -337,6 +337,7 @@ class URLopener: def open_https(self, url: str, data: ReadableBuffer | None = None) -> _UrlopenRet: ... # undocumented def open_local_file(self, url: str) -> addinfourl: ... # undocumented def open_unknown_proxy(self, proxy: str, fullurl: str, data: ReadableBuffer | None = None) -> None: ... # undocumented + def __del__(self) -> None: ... class FancyURLopener(URLopener): def prompt_user_passwd(self, host: str, realm: str) -> tuple[str, str]: ... diff --git a/mypy/typeshed/stdlib/wave.pyi b/mypy/typeshed/stdlib/wave.pyi index 0d004d6b2d8a..6b7af2f79da1 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 +from typing_extensions import Literal, Self, TypeAlias, deprecated if sys.version_info >= (3, 9): __all__ = ["open", "Error", "Wave_read", "Wave_write"] @@ -26,6 +26,7 @@ class Wave_read: def __init__(self, f: _File) -> None: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... + def __del__(self) -> None: ... def getfp(self) -> BinaryIO | None: ... def rewind(self) -> None: ... def close(self) -> None: ... @@ -37,7 +38,9 @@ class Wave_read: def getcomptype(self) -> str: ... def getcompname(self) -> str: ... def getparams(self) -> _wave_params: ... + @deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15") def getmarkers(self) -> None: ... + @deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15") def getmark(self, id: Any) -> NoReturn: ... def setpos(self, pos: int) -> None: ... def readframes(self, nframes: int) -> bytes: ... @@ -46,6 +49,7 @@ class Wave_write: def __init__(self, f: _File) -> None: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... + def __del__(self) -> None: ... def setnchannels(self, nchannels: int) -> None: ... def getnchannels(self) -> int: ... def setsampwidth(self, sampwidth: int) -> None: ... @@ -59,8 +63,11 @@ class Wave_write: def getcompname(self) -> str: ... def setparams(self, params: _wave_params | tuple[int, int, int, int, str, str]) -> None: ... def getparams(self) -> _wave_params: ... + @deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15") def setmark(self, id: Any, pos: Any, name: Any) -> NoReturn: ... + @deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15") def getmark(self, id: Any) -> NoReturn: ... + @deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15") def getmarkers(self) -> None: ... def tell(self) -> int: ... def writeframesraw(self, data: ReadableBuffer) -> None: ... diff --git a/mypy/typeshed/stdlib/weakref.pyi b/mypy/typeshed/stdlib/weakref.pyi index ae88f3a317c1..1bb2eacfb46a 100644 --- a/mypy/typeshed/stdlib/weakref.pyi +++ b/mypy/typeshed/stdlib/weakref.pyi @@ -75,7 +75,7 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): def items(self) -> Iterator[tuple[_KT, _VT]]: ... # type: ignore[override] def itervaluerefs(self) -> Iterator[KeyedRef[_KT, _VT]]: ... def valuerefs(self) -> list[KeyedRef[_KT, _VT]]: ... - def setdefault(self, key: _KT, default: _VT) -> _VT: ... # type: ignore[override] + def setdefault(self, key: _KT, default: _VT) -> _VT: ... @overload def pop(self, key: _KT) -> _VT: ... @overload diff --git a/mypy/typeshed/stdlib/xml/sax/xmlreader.pyi b/mypy/typeshed/stdlib/xml/sax/xmlreader.pyi index 74d2efb010cd..2ccbc95bbef0 100644 --- a/mypy/typeshed/stdlib/xml/sax/xmlreader.pyi +++ b/mypy/typeshed/stdlib/xml/sax/xmlreader.pyi @@ -82,6 +82,6 @@ class AttributesNSImpl(AttributesImpl): def __contains__(self, name: _NSName) -> bool: ... # type: ignore[override] @overload # type: ignore[override] def get(self, name: _NSName, alternative: None = None) -> str | None: ... - @overload # type: ignore[override] + @overload def get(self, name: _NSName, alternative: str) -> str: ... def items(self) -> list[tuple[_NSName, str]]: ... # type: ignore[override] diff --git a/mypy/typeshed/stdlib/zipfile.pyi b/mypy/typeshed/stdlib/zipfile.pyi index b7144f3ab528..5483b84fe6f6 100644 --- a/mypy/typeshed/stdlib/zipfile.pyi +++ b/mypy/typeshed/stdlib/zipfile.pyi @@ -26,7 +26,9 @@ __all__ = [ if sys.version_info >= (3, 8): __all__ += ["Path"] -_DateTuple: TypeAlias = tuple[int, int, int, int, int, int] +# TODO: use TypeAlias when mypy bugs are fixed +# https://github.com/python/mypy/issues/16581 +_DateTuple = tuple[int, int, int, int, int, int] # noqa: Y026 _ReadWriteMode: TypeAlias = Literal["r", "w"] _ReadWriteBinaryMode: TypeAlias = Literal["r", "w", "rb", "wb"] _ZipFileMode: TypeAlias = Literal["r", "w", "x", "a"] @@ -187,6 +189,8 @@ class ZipFile: if sys.version_info >= (3, 11): def mkdir(self, zinfo_or_directory_name: str | ZipInfo, mode: int = 0o777) -> None: ... + def __del__(self) -> None: ... + class PyZipFile(ZipFile): def __init__( self, file: str | IO[bytes], mode: _ZipFileMode = "r", compression: int = 0, allowZip64: bool = True, optimize: int = -1 @@ -231,7 +235,7 @@ if sys.version_info >= (3, 8): def make(cls, source: ZipFile) -> CompleteDirs: ... @overload @classmethod - def make(cls: type[Self], source: StrPath | IO[bytes]) -> Self: ... + def make(cls, source: StrPath | IO[bytes]) -> Self: ... class Path: root: CompleteDirs From 588623ff2fd1d842ce3b70d330d8c37a166db8c4 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 006/172] Remove use of LiteralString in builtins (#13743) --- mypy/typeshed/stdlib/builtins.pyi | 93 ------------------------------- 1 file changed, 93 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 92b5279bcfcd..04f2f8a89539 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -57,7 +57,6 @@ from typing import ( # noqa: Y022 from typing_extensions import ( Concatenate, Literal, - LiteralString, ParamSpec, Self, SupportsIndex, @@ -445,17 +444,8 @@ 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: ... @@ -463,20 +453,11 @@ class str(Sequence[str]): self, __suffix: str | tuple[str, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... if sys.version_info >= (3, 8): - @overload - def expandtabs(self: LiteralString, tabsize: SupportsIndex = 8) -> LiteralString: ... - @overload def expandtabs(self, tabsize: SupportsIndex = 8) -> str: ... # type: ignore[misc] else: - @overload - def expandtabs(self: LiteralString, tabsize: int = 8) -> LiteralString: ... - @overload def expandtabs(self, tabsize: int = 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: ... @@ -492,91 +473,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 @@ -587,9 +509,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] @@ -598,25 +517,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 bdcc90e85be8b18c3a37b4ef83645e1c09f96495 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 007/172] 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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 04f2f8a89539..e3d7ee7e5cc1 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1702,11 +1702,11 @@ _SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWit # 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 | _LiteralInteger], start: int = 0) -> int: ... # type: ignore[overload-overlap] + def sum(__iterable: Iterable[bool], start: int = 0) -> int: ... # type: ignore[overload-overlap] else: @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]: ... From 3e5d813372e4fc1899319f31425bfc11c27fddb3 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 1 May 2023 20:34:55 +0100 Subject: [PATCH 008/172] 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 495e29dfd8ce..8a891971e9f1 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 344298e3a7b1a299092c684c11c28e9f4dc44dd9 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Sat, 4 Mar 2023 13:14:11 +0000 Subject: [PATCH 009/172] 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 451896bed72a..4d8c45e96103 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, NamedTuple, TypeVar, overload -from typing_extensions import Literal, ParamSpec, Self, TypeAlias, TypedDict, final +from typing_extensions import Literal, Self, TypeAlias, TypedDict, final if sys.version_info >= (3, 9): from types import GenericAlias @@ -28,12 +28,10 @@ if sys.version_info >= (3, 8): 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: ... @@ -87,41 +85,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 eb1ee973778e3cf719948e1653db9760ea49405d Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 3 Dec 2023 00:23:54 +0000 Subject: [PATCH 010/172] Update hashes in `sync-typeshed.py` following recent typeshed sync (#16600) Followup to #16598 --- 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 77f921a89b1b..9d6fd92270a5 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 = [ - "9859fe7ba", # LiteralString reverts - "378a866e9", # sum reverts - "2816b97d5", # ctypes reverts - "7d987a105", # ParamSpec for functools.wraps + "588623ff2", # LiteralString reverts + "bdcc90e85", # sum reverts + "3e5d81337", # ctypes reverts + "344298e3a", # ParamSpec for functools.wraps ] for commit in commits_to_cherry_pick: try: From d54cc35a93b1f1bda8f837e0f3ae6f964a1c7feb Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Mon, 4 Dec 2023 08:11:45 +0100 Subject: [PATCH 011/172] Change example in test cases with no stubs available (#16513) Fixes https://github.com/python/mypy/issues/16466 --- test-data/unit/pythoneval.test | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 7dd2b2f76f8c..c6ca71f5d56a 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -1568,24 +1568,24 @@ note: A user-defined top-level module with name "typing" is not supported # flags: --ignore-missing-imports import scribe # No Python 3 stubs available for scribe from scribe import x -import docutils # Python 3 stubs available for docutils +import python2 # Python 3 stubs available for python2 import foobar_asdf import jack # This has a stubs package but was never bundled with mypy, so ignoring works [out] -_testIgnoreImportIfNoPython3StubAvailable.py:4: error: Library stubs not installed for "docutils" -_testIgnoreImportIfNoPython3StubAvailable.py:4: note: Hint: "python3 -m pip install types-docutils" +_testIgnoreImportIfNoPython3StubAvailable.py:4: error: Library stubs not installed for "python2" +_testIgnoreImportIfNoPython3StubAvailable.py:4: note: Hint: "python3 -m pip install types-six" _testIgnoreImportIfNoPython3StubAvailable.py:4: note: (or run "mypy --install-types" to install all missing stub packages) _testIgnoreImportIfNoPython3StubAvailable.py:4: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports [case testNoPython3StubAvailable] import scribe from scribe import x -import docutils +import python2 [out] _testNoPython3StubAvailable.py:1: error: Cannot find implementation or library stub for module named "scribe" _testNoPython3StubAvailable.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports -_testNoPython3StubAvailable.py:3: error: Library stubs not installed for "docutils" -_testNoPython3StubAvailable.py:3: note: Hint: "python3 -m pip install types-docutils" +_testNoPython3StubAvailable.py:3: error: Library stubs not installed for "python2" +_testNoPython3StubAvailable.py:3: note: Hint: "python3 -m pip install types-six" _testNoPython3StubAvailable.py:3: note: (or run "mypy --install-types" to install all missing stub packages) From c224da5c7c414f92ded4b7816d16d5dd4ed32193 Mon Sep 17 00:00:00 2001 From: Christoph Tyralla Date: Mon, 4 Dec 2023 08:13:58 +0100 Subject: [PATCH 012/172] Do not intersect types in isinstance checks if at least one is final (#16330) Fixes #15148 I think it also fixes the [initial bug](https://github.com/python/mypy/issues/12163#issue-1131262225) reported in #12163 (this is why I added a TypeVar test case) but not [this bug](https://github.com/python/mypy/issues/12163#issuecomment-1035865305) reported later in the same issue. --- mypy/checker.py | 13 +++- mypy/messages.py | 2 +- test-data/unit/check-narrowing.test | 99 +++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 7c6f59fafdc8..979a55b223c9 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -5254,6 +5254,15 @@ def _make_fake_typeinfo_and_full_name( pretty_names_list = pretty_seq( format_type_distinctly(*base_classes, options=self.options, bare=True), "and" ) + + new_errors = [] + for base in base_classes: + if base.type.is_final: + new_errors.append((pretty_names_list, f'"{base.type.name}" is final')) + if new_errors: + errors.extend(new_errors) + return None + try: info, full_name = _make_fake_typeinfo_and_full_name(base_classes, curr_module) with self.msg.filter_errors() as local_errors: @@ -5266,10 +5275,10 @@ def _make_fake_typeinfo_and_full_name( self.check_multiple_inheritance(info) info.is_intersection = True except MroError: - errors.append((pretty_names_list, "inconsistent method resolution order")) + errors.append((pretty_names_list, "would have inconsistent method resolution order")) return None if local_errors.has_new_errors(): - errors.append((pretty_names_list, "incompatible method signatures")) + errors.append((pretty_names_list, "would have incompatible method signatures")) return None curr_module.names[full_name] = SymbolTableNode(GDEF, info) diff --git a/mypy/messages.py b/mypy/messages.py index ddb048444695..069c4d51e281 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2051,7 +2051,7 @@ def redundant_expr(self, description: str, truthiness: bool, context: Context) - def impossible_intersection( self, formatted_base_class_list: str, reason: str, context: Context ) -> None: - template = "Subclass of {} cannot exist: would have {}" + template = "Subclass of {} cannot exist: {}" self.fail( template.format(formatted_base_class_list, reason), context, code=codes.UNREACHABLE ) diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index d0ad1367aca0..a2859dfffa3a 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -1020,6 +1020,105 @@ else: reveal_type(true_or_false) # N: Revealed type is "Literal[False]" [builtins fixtures/primitives.pyi] + +[case testNarrowingIsInstanceFinalSubclass] +# flags: --warn-unreachable + +from typing import final + +class N: ... +@final +class F1: ... +@final +class F2: ... + +n: N +f1: F1 + +if isinstance(f1, F1): + reveal_type(f1) # N: Revealed type is "__main__.F1" +else: + reveal_type(f1) # E: Statement is unreachable + +if isinstance(n, F1): # E: Subclass of "N" and "F1" cannot exist: "F1" is final + reveal_type(n) # E: Statement is unreachable +else: + reveal_type(n) # N: Revealed type is "__main__.N" + +if isinstance(f1, N): # E: Subclass of "F1" and "N" cannot exist: "F1" is final + reveal_type(f1) # E: Statement is unreachable +else: + reveal_type(f1) # N: Revealed type is "__main__.F1" + +if isinstance(f1, F2): # E: Subclass of "F1" and "F2" cannot exist: "F1" is final \ + # E: Subclass of "F1" and "F2" cannot exist: "F2" is final + reveal_type(f1) # E: Statement is unreachable +else: + reveal_type(f1) # N: Revealed type is "__main__.F1" +[builtins fixtures/isinstance.pyi] + + +[case testNarrowingIsInstanceFinalSubclassWithUnions] +# flags: --warn-unreachable + +from typing import final, Union + +class N: ... +@final +class F1: ... +@final +class F2: ... + +n_f1: Union[N, F1] +n_f2: Union[N, F2] +f1_f2: Union[F1, F2] + +if isinstance(n_f1, F1): + reveal_type(n_f1) # N: Revealed type is "__main__.F1" +else: + reveal_type(n_f1) # N: Revealed type is "__main__.N" + +if isinstance(n_f2, F1): # E: Subclass of "N" and "F1" cannot exist: "F1" is final \ + # E: Subclass of "F2" and "F1" cannot exist: "F2" is final \ + # E: Subclass of "F2" and "F1" cannot exist: "F1" is final + reveal_type(n_f2) # E: Statement is unreachable +else: + reveal_type(n_f2) # N: Revealed type is "Union[__main__.N, __main__.F2]" + +if isinstance(f1_f2, F1): + reveal_type(f1_f2) # N: Revealed type is "__main__.F1" +else: + reveal_type(f1_f2) # N: Revealed type is "__main__.F2" +[builtins fixtures/isinstance.pyi] + + +[case testNarrowingIsSubclassFinalSubclassWithTypeVar] +# flags: --warn-unreachable + +from typing import final, Type, TypeVar + +@final +class A: ... +@final +class B: ... + +T = TypeVar("T", A, B) + +def f(cls: Type[T]) -> T: + if issubclass(cls, A): + reveal_type(cls) # N: Revealed type is "Type[__main__.A]" + x: bool + if x: + return A() + else: + return B() # E: Incompatible return value type (got "B", expected "A") + assert False + +reveal_type(f(A)) # N: Revealed type is "__main__.A" +reveal_type(f(B)) # N: Revealed type is "__main__.B" +[builtins fixtures/isinstance.pyi] + + [case testNarrowingLiteralIdentityCheck] from typing import Union from typing_extensions import Literal From 7c33e7c03444ae748b82163e7b4e1666dfaf94c7 Mon Sep 17 00:00:00 2001 From: Ilya Priven Date: Mon, 4 Dec 2023 04:33:25 -0500 Subject: [PATCH 013/172] @final class without __bool__ cannot have falsey instances (#16566) Once class C is final, we know that a derived class won't add a `__bool__` or a `__len__` so if they're missing, we can assume every instance of C to be truthy. Relates to #16565 --- mypy/typeops.py | 25 ++++++++++++------- test-data/unit/check-final.test | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/mypy/typeops.py b/mypy/typeops.py index e92fad0e872c..2bf8ffbf47ab 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -569,15 +569,15 @@ def _remove_redundant_union_items(items: list[Type], keep_erased: bool) -> list[ return items -def _get_type_special_method_bool_ret_type(t: Type) -> Type | None: +def _get_type_method_ret_type(t: Type, *, name: str) -> Type | None: t = get_proper_type(t) if isinstance(t, Instance): - bool_method = t.type.get("__bool__") - if bool_method: - callee = get_proper_type(bool_method.type) - if isinstance(callee, CallableType): - return callee.ret_type + sym = t.type.get(name) + if sym: + sym_type = get_proper_type(sym.type) + if isinstance(sym_type, CallableType): + return sym_type.ret_type return None @@ -600,7 +600,9 @@ def true_only(t: Type) -> ProperType: can_be_true_items = [item for item in new_items if item.can_be_true] return make_simplified_union(can_be_true_items, line=t.line, column=t.column) else: - ret_type = _get_type_special_method_bool_ret_type(t) + ret_type = _get_type_method_ret_type(t, name="__bool__") or _get_type_method_ret_type( + t, name="__len__" + ) if ret_type and not ret_type.can_be_true: return UninhabitedType(line=t.line, column=t.column) @@ -633,9 +635,14 @@ def false_only(t: Type) -> ProperType: can_be_false_items = [item for item in new_items if item.can_be_false] return make_simplified_union(can_be_false_items, line=t.line, column=t.column) else: - ret_type = _get_type_special_method_bool_ret_type(t) + ret_type = _get_type_method_ret_type(t, name="__bool__") or _get_type_method_ret_type( + t, name="__len__" + ) - if ret_type and not ret_type.can_be_false: + if ret_type: + if not ret_type.can_be_false: + return UninhabitedType(line=t.line) + elif isinstance(t, Instance) and t.type.is_final: return UninhabitedType(line=t.line) new_t = copy_type(t) diff --git a/test-data/unit/check-final.test b/test-data/unit/check-final.test index a2fd64386707..b1378a47b1b1 100644 --- a/test-data/unit/check-final.test +++ b/test-data/unit/check-final.test @@ -1130,3 +1130,47 @@ class Child(Parent): __foo: Final[int] = 1 @final def __bar(self) -> None: ... + +[case testFinalWithoutBool] +from typing_extensions import final, Literal + +class A: + pass + +@final +class B: + pass + +@final +class C: + def __len__(self) -> Literal[1]: return 1 + +reveal_type(A() and 42) # N: Revealed type is "Union[__main__.A, Literal[42]?]" +reveal_type(B() and 42) # N: Revealed type is "Literal[42]?" +reveal_type(C() and 42) # N: Revealed type is "Literal[42]?" + +[builtins fixtures/bool.pyi] + +[case testFinalWithoutBoolButWithLen] +from typing_extensions import final, Literal + +# Per Python data model, __len__ is called if __bool__ does not exist. +# In a @final class, __bool__ would not exist. + +@final +class A: + def __len__(self) -> int: ... + +@final +class B: + def __len__(self) -> Literal[1]: return 1 + +@final +class C: + def __len__(self) -> Literal[0]: return 0 + +reveal_type(A() and 42) # N: Revealed type is "Union[__main__.A, Literal[42]?]" +reveal_type(B() and 42) # N: Revealed type is "Literal[42]?" +reveal_type(C() and 42) # N: Revealed type is "__main__.C" + +[builtins fixtures/bool.pyi] From 1cdeecdcc11115a3d15610801fdf91b0ed6bbe0a Mon Sep 17 00:00:00 2001 From: Wesley Collin Wright Date: Mon, 4 Dec 2023 12:56:59 -0600 Subject: [PATCH 014/172] 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 015/172] 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 016/172] 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 017/172] 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 018/172] 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 019/172] 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 020/172] 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 021/172] 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 022/172] 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 023/172] 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 024/172] 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 025/172] 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 026/172] 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 027/172] 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 028/172] 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 029/172] 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 030/172] 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 031/172] 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 032/172] 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 033/172] 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 034/172] 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 035/172] 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 036/172] 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 037/172] 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 038/172] [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 039/172] 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 040/172] 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 041/172] 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 042/172] 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 043/172] 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 044/172] 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 045/172] 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 046/172] 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 047/172] 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 048/172] 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 049/172] 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 050/172] 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 051/172] 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 052/172] 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 053/172] 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 054/172] 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 055/172] 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 056/172] 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 057/172] 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 058/172] 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 059/172] 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 060/172] 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 061/172] 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 062/172] 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 063/172] 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 064/172] 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 065/172] 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 066/172] 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 067/172] 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 068/172] 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 069/172] 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 070/172] 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 071/172] 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 072/172] 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 073/172] 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 074/172] 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 075/172] 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 076/172] 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 077/172] 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 078/172] 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 079/172] 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 5c5f3ad412bcd0ea510f5918578ed24325829033 Mon Sep 17 00:00:00 2001 From: James Braza Date: Tue, 6 Feb 2024 16:49:52 -0800 Subject: [PATCH 080/172] Docs: adding missing `mutable-override` to section title (#16886) Closes https://github.com/python/mypy/issues/16880 Supercedes https://github.com/python/mypy/pull/16881 --- docs/source/error_code_list2.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index 60f870c57db9..c966fe1f7ea6 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -484,11 +484,11 @@ Example: .. _code-mutable-override: -Check that overrides of mutable attributes are safe ---------------------------------------------------- +Check that overrides of mutable attributes are safe [mutable-override] +---------------------------------------------------------------------- -This will enable the check for unsafe overrides of mutable attributes. For -historical reasons, and because this is a relatively common pattern in Python, +`mutable-override` will enable the check for unsafe overrides of mutable attributes. +For historical reasons, and because this is a relatively common pattern in Python, this check is not enabled by default. The example below is unsafe, and will be flagged when this error code is enabled: From 780a29d0b1b93848d7ce3faf8e819a6cc140b2e5 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:28:03 +0100 Subject: [PATCH 081/172] Bump version to 1.10.0+dev (#16888) The release branch has been cut: https://github.com/python/mypy/tree/release-1.9.0 Increase the dev version. --- mypy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/version.py b/mypy/version.py index 74e80839308c..93ab6463c573 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.10.0+dev" base_version = __version__ mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) From 517f5aee23ba218f615bcd4427bca62f120bc222 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Fri, 9 Feb 2024 13:27:33 +0000 Subject: [PATCH 082/172] Stubtest: ignore a new protocol dunder (#16895) 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 --- 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 d8e3d591048cfe16dbc9cfa2ff88db38c587e3d0 Mon Sep 17 00:00:00 2001 From: jhance Date: Fri, 9 Feb 2024 18:28:10 -0800 Subject: [PATCH 083/172] Unsupport targetting 3.7. (#16883) 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> --- 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 996544fe21aa21ee29d1ed5a178e2026edbe6bce Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Sat, 10 Feb 2024 15:53:39 +0100 Subject: [PATCH 084/172] Update CI actions (#16901) Update `actions/setup-python` from `v4` to `v5` and `actions/github-script` from `v6` to `v7`. https://github.com/actions/setup-python/releases/tag/v5.0.0 https://github.com/actions/github-script/releases/tag/v7.0.0 --- .github/workflows/build_wheels.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/mypy_primer.yml | 2 +- .github/workflows/mypy_primer_comment.yml | 2 +- .github/workflows/sync_typeshed.yml | 2 +- .github/workflows/test.yml | 2 +- .github/workflows/test_stubgenc.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index f1438279673d..8055cfd24180 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.11' - name: Trigger script diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ad6b57c53fd9..f13a3de1f2e3 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,7 +34,7 @@ jobs: VERIFY_MYPY_ERROR_CODES: 1 steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.8' - name: Install tox diff --git a/.github/workflows/mypy_primer.yml b/.github/workflows/mypy_primer.yml index f8991e27970a..07a1d0863eb2 100644 --- a/.github/workflows/mypy_primer.yml +++ b/.github/workflows/mypy_primer.yml @@ -37,7 +37,7 @@ jobs: with: path: mypy_to_test fetch-depth: 0 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: Install dependencies diff --git a/.github/workflows/mypy_primer_comment.yml b/.github/workflows/mypy_primer_comment.yml index 6e3bb590364f..492e03aff16e 100644 --- a/.github/workflows/mypy_primer_comment.yml +++ b/.github/workflows/mypy_primer_comment.yml @@ -44,7 +44,7 @@ jobs: - name: Post comment id: post-comment - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/sync_typeshed.yml b/.github/workflows/sync_typeshed.yml index de9e0aad599f..b545e7b0662b 100644 --- a/.github/workflows/sync_typeshed.yml +++ b/.github/workflows/sync_typeshed.yml @@ -20,7 +20,7 @@ jobs: fetch-depth: 0 # TODO: use whatever solution ends up working for # https://github.com/python/typeshed/issues/8434 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: git config diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4613605425c3..e4e44c671287 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -120,7 +120,7 @@ jobs: PYTEST_ADDOPTS: --color=yes steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} architecture: ${{ matrix.arch }} diff --git a/.github/workflows/test_stubgenc.yml b/.github/workflows/test_stubgenc.yml index 7bdcfdb305bb..519f63ac2bd7 100644 --- a/.github/workflows/test_stubgenc.yml +++ b/.github/workflows/test_stubgenc.yml @@ -30,7 +30,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup 🐍 3.8 - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.8 From 837f7e0ed4f87869f314ec102c0d6e47ec3272ec Mon Sep 17 00:00:00 2001 From: Sam Xifaras Date: Sun, 11 Feb 2024 04:04:28 -0500 Subject: [PATCH 085/172] stubtest: correct type annotations in _Arguments (#16897) Two fields in the `_Arguments` class, `mypy_config_file` and `custom_typeshed_dir`, can take on a None value, but they are not marked as such. Calling `stubtest.parse_options` on an empty list of arguments reproduces the situation where these two fields are None. --- mypy/stubtest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mypy/stubtest.py b/mypy/stubtest.py index c2f82c98d089..dd43c472d67f 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -1878,8 +1878,8 @@ class _Arguments: allowlist: list[str] generate_allowlist: bool ignore_unused_allowlist: bool - mypy_config_file: str - custom_typeshed_dir: str + mypy_config_file: str | None + custom_typeshed_dir: str | None check_typeshed: bool version: str @@ -1922,7 +1922,7 @@ def test_stubs(args: _Arguments, use_builtins_fixtures: bool = False) -> int: options.incremental = False options.custom_typeshed_dir = args.custom_typeshed_dir if options.custom_typeshed_dir: - options.abs_custom_typeshed_dir = os.path.abspath(args.custom_typeshed_dir) + options.abs_custom_typeshed_dir = os.path.abspath(options.custom_typeshed_dir) options.config_file = args.mypy_config_file options.use_builtins_fixtures = use_builtins_fixtures From 4a9c1e95457f253f87ef5db970ad8d59209c4715 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 11 Feb 2024 16:55:59 +0100 Subject: [PATCH 086/172] stubgen: Add support for PEP 570 positional-only parameters (#16904) This only adds support for Python modules (x-ref #14138) --- mypy/stubgen.py | 9 +++++++++ test-data/unit/stubgen.test | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index c314fabc882d..36e8bd2acfb4 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -110,6 +110,7 @@ Var, ) from mypy.options import Options as MypyOptions +from mypy.sharedparse import MAGIC_METHODS_POS_ARGS_ONLY from mypy.stubdoc import ArgSig, FunctionSig from mypy.stubgenc import InspectionStubGenerator, generate_stub_for_c_module from mypy.stubutil import ( @@ -480,6 +481,9 @@ def get_default_function_sig(self, func_def: FuncDef, ctx: FunctionContext) -> F def _get_func_args(self, o: FuncDef, ctx: FunctionContext) -> list[ArgSig]: args: list[ArgSig] = [] + # Ignore pos-only status of magic methods whose args names are elided by mypy at parse + actually_pos_only_args = o.name not in MAGIC_METHODS_POS_ARGS_ONLY + pos_only_marker_position = 0 # Where to insert "/", if any for i, arg_ in enumerate(o.arguments): var = arg_.variable kind = arg_.kind @@ -500,6 +504,9 @@ def _get_func_args(self, o: FuncDef, ctx: FunctionContext) -> list[ArgSig]: if not isinstance(get_proper_type(annotated_type), AnyType): typename = self.print_annotation(annotated_type) + if actually_pos_only_args and arg_.pos_only: + pos_only_marker_position += 1 + if kind.is_named() and not any(arg.name.startswith("*") for arg in args): args.append(ArgSig("*")) @@ -518,6 +525,8 @@ def _get_func_args(self, o: FuncDef, ctx: FunctionContext) -> list[ArgSig]: args.append( ArgSig(name, typename, default=bool(arg_.initializer), default_value=default) ) + if pos_only_marker_position: + args.insert(pos_only_marker_position, ArgSig("/")) if ctx.class_info is not None and all( arg.type is None and arg.default is False for arg in args diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 3b3bc658a14a..b5bccaa4cdbd 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4231,3 +4231,25 @@ o = int | None def f1(a: int | tuple[int, int | None] | None) -> int: ... def f2(a: int | x.Union[int, int] | float | None) -> int: ... + +[case testPEP570PosOnlyParams] +def f(x=0, /): ... +def f1(x: int, /): ... +def f2(x: int, y: float = 1, /): ... +def f3(x: int, /, y: float): ... +def f4(x: int, /, y: float = 1): ... +def f5(x: int, /, *, y: float): ... +def f6(x: int = 0, /, *, y: float): ... +def f7(x: int, /, *, y: float = 1): ... +def f8(x: int = 0, /, *, y: float = 1): ... + +[out] +def f(x: int = 0, /) -> None: ... +def f1(x: int, /): ... +def f2(x: int, y: float = 1, /): ... +def f3(x: int, /, y: float): ... +def f4(x: int, /, y: float = 1): ... +def f5(x: int, /, *, y: float): ... +def f6(x: int = 0, /, *, y: float): ... +def f7(x: int, /, *, y: float = 1): ... +def f8(x: int = 0, /, *, y: float = 1): ... From b6e91d46b299bfd0af36b37586d3337a20e14b0e Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 11 Feb 2024 23:09:22 +0100 Subject: [PATCH 087/172] stubgen: Preserve empty tuple annotation (#16907) --- mypy/stubutil.py | 2 ++ test-data/unit/stubgen.test | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/mypy/stubutil.py b/mypy/stubutil.py index 1a9c2357c58e..69af643efab2 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -250,6 +250,8 @@ def visit_unbound_type(self, t: UnboundType) -> str: self.stubgen.import_tracker.require_name(s) if t.args: s += f"[{self.args_str(t.args)}]" + elif t.empty_tuple_index: + s += "[()]" return s def visit_none_type(self, t: NoneType) -> str: diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index b5bccaa4cdbd..c56f6b40b74d 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4253,3 +4253,17 @@ def f5(x: int, /, *, y: float): ... def f6(x: int = 0, /, *, y: float): ... def f7(x: int, /, *, y: float = 1): ... def f8(x: int = 0, /, *, y: float = 1): ... + +[case testPreserveEmptyTuple] +ann: tuple[()] +alias = tuple[()] +def f(x: tuple[()]): ... +class C(tuple[()]): ... + +[out] +ann: tuple[()] +alias = tuple[()] + +def f(x: tuple[()]): ... + +class C(tuple[()]): ... From c26f1297d4f19d2d1124a30efc97caebb8c28616 Mon Sep 17 00:00:00 2001 From: Spencer Brown Date: Tue, 13 Feb 2024 00:19:09 +1000 Subject: [PATCH 088/172] Allow inferring +int to be a Literal (#16910) This makes unary positive on integers preserve the literal value of the integer, allowing `var: Literal[1] = +1` to be accepted. Basically I looked for code handling `__neg__` and added a branch for `__pos__` as well. Fixes #16728. --- mypy/checkexpr.py | 4 ++++ mypy/exprtotype.py | 9 ++++++--- mypy/plugins/default.py | 25 +++++++++++++++++++------ test-data/unit/check-literal.test | 13 ++++++++++++- test-data/unit/check-tuples.test | 4 +++- test-data/unit/fixtures/tuple.pyi | 1 + 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index ff7b7fa2ff58..2842606b7b18 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4437,6 +4437,10 @@ def try_getting_int_literals(self, index: Expression) -> list[int] | None: operand = index.expr if isinstance(operand, IntExpr): return [-1 * operand.value] + if index.op == "+": + operand = index.expr + if isinstance(operand, IntExpr): + return [operand.value] typ = get_proper_type(self.accept(index)) if isinstance(typ, Instance) and typ.last_known_value is not None: typ = typ.last_known_value diff --git a/mypy/exprtotype.py b/mypy/exprtotype.py index 7a50429b81d1..2218a950788c 100644 --- a/mypy/exprtotype.py +++ b/mypy/exprtotype.py @@ -183,9 +183,12 @@ def expr_to_unanalyzed_type( elif isinstance(expr, UnaryExpr): typ = expr_to_unanalyzed_type(expr.expr, options, allow_new_syntax) if isinstance(typ, RawExpressionType): - if isinstance(typ.literal_value, int) and expr.op == "-": - typ.literal_value *= -1 - return typ + if isinstance(typ.literal_value, int): + if expr.op == "-": + typ.literal_value *= -1 + return typ + elif expr.op == "+": + return typ raise TypeTranslationError() elif isinstance(expr, IntExpr): return RawExpressionType(expr.value, "builtins.int", line=expr.line, column=expr.column) diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index ddcc37f465fe..93fff5320cd5 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -100,6 +100,8 @@ def get_method_hook(self, fullname: str) -> Callable[[MethodContext], Type] | No return int_pow_callback elif fullname == "builtins.int.__neg__": return int_neg_callback + elif fullname == "builtins.int.__pos__": + return int_pos_callback elif fullname in ("builtins.tuple.__mul__", "builtins.tuple.__rmul__"): return tuple_mul_callback elif fullname in {n + ".setdefault" for n in TPDICT_FB_NAMES}: @@ -471,32 +473,43 @@ def int_pow_callback(ctx: MethodContext) -> Type: return ctx.default_return_type -def int_neg_callback(ctx: MethodContext) -> Type: - """Infer a more precise return type for int.__neg__. +def int_neg_callback(ctx: MethodContext, multiplier: int = -1) -> Type: + """Infer a more precise return type for int.__neg__ and int.__pos__. This is mainly used to infer the return type as LiteralType - if the original underlying object is a LiteralType object + if the original underlying object is a LiteralType object. """ if isinstance(ctx.type, Instance) and ctx.type.last_known_value is not None: value = ctx.type.last_known_value.value fallback = ctx.type.last_known_value.fallback if isinstance(value, int): if is_literal_type_like(ctx.api.type_context[-1]): - return LiteralType(value=-value, fallback=fallback) + return LiteralType(value=multiplier * value, fallback=fallback) else: return ctx.type.copy_modified( last_known_value=LiteralType( - value=-value, fallback=ctx.type, line=ctx.type.line, column=ctx.type.column + value=multiplier * value, + fallback=ctx.type, + line=ctx.type.line, + column=ctx.type.column, ) ) elif isinstance(ctx.type, LiteralType): value = ctx.type.value fallback = ctx.type.fallback if isinstance(value, int): - return LiteralType(value=-value, fallback=fallback) + return LiteralType(value=multiplier * value, fallback=fallback) return ctx.default_return_type +def int_pos_callback(ctx: MethodContext) -> Type: + """Infer a more precise return type for int.__pos__. + + This is identical to __neg__, except the value is not inverted. + """ + return int_neg_callback(ctx, +1) + + def tuple_mul_callback(ctx: MethodContext) -> Type: """Infer a more precise return type for tuple.__mul__ and tuple.__rmul__. diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index de4440ce7f49..5604cc4b5893 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -397,29 +397,36 @@ from typing_extensions import Literal a1: Literal[4] b1: Literal[0x2a] c1: Literal[-300] +d1: Literal[+8] reveal_type(a1) # N: Revealed type is "Literal[4]" reveal_type(b1) # N: Revealed type is "Literal[42]" reveal_type(c1) # N: Revealed type is "Literal[-300]" +reveal_type(d1) # N: Revealed type is "Literal[8]" a2t = Literal[4] b2t = Literal[0x2a] c2t = Literal[-300] +d2t = Literal[+8] a2: a2t b2: b2t c2: c2t +d2: d2t reveal_type(a2) # N: Revealed type is "Literal[4]" reveal_type(b2) # N: Revealed type is "Literal[42]" reveal_type(c2) # N: Revealed type is "Literal[-300]" +reveal_type(d2) # N: Revealed type is "Literal[8]" def f1(x: Literal[4]) -> Literal[4]: pass def f2(x: Literal[0x2a]) -> Literal[0x2a]: pass def f3(x: Literal[-300]) -> Literal[-300]: pass +def f4(x: Literal[+8]) -> Literal[+8]: pass reveal_type(f1) # N: Revealed type is "def (x: Literal[4]) -> Literal[4]" reveal_type(f2) # N: Revealed type is "def (x: Literal[42]) -> Literal[42]" reveal_type(f3) # N: Revealed type is "def (x: Literal[-300]) -> Literal[-300]" +reveal_type(f4) # N: Revealed type is "def (x: Literal[8]) -> Literal[8]" [builtins fixtures/tuple.pyi] [out] @@ -2747,6 +2754,9 @@ d: Literal[1] = 1 e: Literal[2] = 2 f: Literal[+1] = 1 g: Literal[+2] = 2 +h: Literal[1] = +1 +i: Literal[+2] = 2 +j: Literal[+3] = +3 x: Literal[+True] = True # E: Invalid type: Literal[...] cannot contain arbitrary expressions y: Literal[-True] = -1 # E: Invalid type: Literal[...] cannot contain arbitrary expressions @@ -2759,6 +2769,7 @@ from typing_extensions import Literal, Final ONE: Final = 1 x: Literal[-1] = -ONE +y: Literal[+1] = +ONE TWO: Final = 2 THREE: Final = 3 @@ -2766,7 +2777,7 @@ THREE: Final = 3 err_code = -TWO if bool(): err_code = -THREE -[builtins fixtures/float.pyi] +[builtins fixtures/ops.pyi] [case testAliasForEnumTypeAsLiteral] from typing_extensions import Literal diff --git a/test-data/unit/check-tuples.test b/test-data/unit/check-tuples.test index 66115ca0c30d..ad4893c2890a 100644 --- a/test-data/unit/check-tuples.test +++ b/test-data/unit/check-tuples.test @@ -337,10 +337,12 @@ if int(): b = t1[-1] if int(): a = t1[(0)] +if int(): + b = t1[+1] if int(): x = t3[0:3] # type (A, B, C) if int(): - y = t3[0:5:2] # type (A, C, E) + y = t3[0:+5:2] # type (A, C, E) if int(): x = t3[:-2] # type (A, B, C) diff --git a/test-data/unit/fixtures/tuple.pyi b/test-data/unit/fixtures/tuple.pyi index cb6347e9f2fd..eb89de8c86ef 100644 --- a/test-data/unit/fixtures/tuple.pyi +++ b/test-data/unit/fixtures/tuple.pyi @@ -32,6 +32,7 @@ class classmethod: pass # We need int and slice for indexing tuples. class int: def __neg__(self) -> 'int': pass + def __pos__(self) -> 'int': pass class float: pass class slice: pass class bool(int): pass From 5ffa6dde6e295c7cd1bc237dcc252672a39c625e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:09:41 -0800 Subject: [PATCH 089/172] Sync typeshed (#16918) Source commit: https://github.com/python/typeshed/commit/48a0497b2310e8e4bcb81c72aed7517b2a3a3bfd --- mypy/typeshed/stdlib/_ast.pyi | 6 +- mypy/typeshed/stdlib/_curses.pyi | 1 + mypy/typeshed/stdlib/_msi.pyi | 1 + mypy/typeshed/stdlib/_thread.pyi | 1 + mypy/typeshed/stdlib/asyncio/sslproto.pyi | 4 +- mypy/typeshed/stdlib/asyncio/unix_events.pyi | 3 + .../stdlib/asyncio/windows_events.pyi | 2 + mypy/typeshed/stdlib/calendar.pyi | 4 +- mypy/typeshed/stdlib/contextlib.pyi | 1 + mypy/typeshed/stdlib/dbm/gnu.pyi | 1 + mypy/typeshed/stdlib/dbm/ndbm.pyi | 1 + mypy/typeshed/stdlib/enum.pyi | 3 + mypy/typeshed/stdlib/ftplib.pyi | 12 +- mypy/typeshed/stdlib/grp.pyi | 1 + .../stdlib/importlib/metadata/__init__.pyi | 1 + mypy/typeshed/stdlib/inspect.pyi | 1 + mypy/typeshed/stdlib/io.pyi | 42 +- mypy/typeshed/stdlib/msilib/__init__.pyi | 1 + .../stdlib/multiprocessing/reduction.pyi | 1 + mypy/typeshed/stdlib/os/__init__.pyi | 7 + mypy/typeshed/stdlib/pstats.pyi | 1 + mypy/typeshed/stdlib/pwd.pyi | 1 + mypy/typeshed/stdlib/pyexpat/__init__.pyi | 9 +- mypy/typeshed/stdlib/resource.pyi | 2 + mypy/typeshed/stdlib/select.pyi | 3 + mypy/typeshed/stdlib/signal.pyi | 3 + mypy/typeshed/stdlib/spwd.pyi | 1 + mypy/typeshed/stdlib/string.pyi | 2 +- mypy/typeshed/stdlib/subprocess.pyi | 9 +- mypy/typeshed/stdlib/sys/__init__.pyi | 2 + mypy/typeshed/stdlib/time.pyi | 1 + mypy/typeshed/stdlib/tkinter/__init__.pyi | 707 +++++++++--------- mypy/typeshed/stdlib/tkinter/ttk.pyi | 357 ++++----- mypy/typeshed/stdlib/typing.pyi | 3 + mypy/typeshed/stdlib/unicodedata.pyi | 10 +- mypy/typeshed/stdlib/unittest/result.pyi | 1 + 36 files changed, 653 insertions(+), 553 deletions(-) diff --git a/mypy/typeshed/stdlib/_ast.pyi b/mypy/typeshed/stdlib/_ast.pyi index fc3f035cc779..0758450dfa7c 100644 --- a/mypy/typeshed/stdlib/_ast.pyi +++ b/mypy/typeshed/stdlib/_ast.pyi @@ -6,6 +6,10 @@ PyCF_ONLY_AST: Literal[1024] PyCF_TYPE_COMMENTS: Literal[4096] PyCF_ALLOW_TOP_LEVEL_AWAIT: Literal[8192] +# Alias used for fields that must always be valid identifiers +# A string `x` counts as a valid identifier if both the following are True +# (1) `x.isidentifier()` evaluates to `True` +# (2) `keyword.iskeyword(x)` evaluates to `False` _Identifier: typing_extensions.TypeAlias = str class AST: @@ -499,7 +503,7 @@ class keyword(AST): class alias(AST): if sys.version_info >= (3, 10): __match_args__ = ("name", "asname") - name: _Identifier + name: str asname: _Identifier | None class withitem(AST): diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index adb09a50f47c..20189cb285c5 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -553,5 +553,6 @@ if sys.platform != "win32": major: int minor: int patch: int + ncurses_version: _ncurses_version window = _CursesWindow # undocumented diff --git a/mypy/typeshed/stdlib/_msi.pyi b/mypy/typeshed/stdlib/_msi.pyi index 160406a6d8d5..22239cbfff04 100644 --- a/mypy/typeshed/stdlib/_msi.pyi +++ b/mypy/typeshed/stdlib/_msi.pyi @@ -45,6 +45,7 @@ if sys.platform == "win32": # Don't exist at runtime __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] + def UuidCreate() -> str: ... def FCICreate(__cabname: str, __files: list[str]) -> None: ... def OpenDatabase(__path: str, __persist: int) -> _Database: ... diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index 8b43a81cac8a..ff9bd1a12eb1 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -32,6 +32,7 @@ def get_native_id() -> int: ... # only available on some platforms 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 diff --git a/mypy/typeshed/stdlib/asyncio/sslproto.pyi b/mypy/typeshed/stdlib/asyncio/sslproto.pyi index 5dcca950e819..04197c8d2978 100644 --- a/mypy/typeshed/stdlib/asyncio/sslproto.pyi +++ b/mypy/typeshed/stdlib/asyncio/sslproto.pyi @@ -25,6 +25,7 @@ if sys.version_info >= (3, 11): STATE_CON_MADE: str STATE_EOF: str STATE_CON_LOST: str + def add_flowcontrol_defaults(high: int | None, low: int | None, kb: int) -> tuple[int, int]: ... else: @@ -155,9 +156,10 @@ class SSLProtocol(_SSLProtocolBase): def _check_handshake_timeout(self) -> None: ... def _on_handshake_complete(self, handshake_exc: BaseException | None) -> None: ... def _fatal_error(self, exc: BaseException, message: str = "Fatal error on transport") -> None: ... - def _abort(self) -> None: ... if sys.version_info >= (3, 11): + def _abort(self, exc: BaseException | None) -> None: ... def get_buffer(self, n: int) -> memoryview: ... else: + def _abort(self) -> None: ... def _finalize(self) -> None: ... def _process_write_backlog(self) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index d2a2fef5c33b..2fbc0a4e6049 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -96,6 +96,7 @@ if sys.platform != "win32": def __exit__(self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None) -> 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: ... @@ -120,6 +121,7 @@ if sys.platform != "win32": else: def get_child_watcher(self) -> AbstractChildWatcher: ... def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ... + SelectorEventLoop = _UnixSelectorEventLoop DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy @@ -136,6 +138,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: ... + else: class MultiLoopChildWatcher(AbstractChildWatcher): def is_active(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/asyncio/windows_events.pyi b/mypy/typeshed/stdlib/asyncio/windows_events.pyi index fdf43d3ea91c..9c150ee16beb 100644 --- a/mypy/typeshed/stdlib/asyncio/windows_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/windows_events.pyi @@ -69,6 +69,7 @@ if sys.platform == "win32": def recvfrom_into( self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0 ) -> futures.Future[tuple[int, socket._RetAddress]]: ... + SelectorEventLoop = _WindowsSelectorEventLoop class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): @@ -80,4 +81,5 @@ if sys.platform == "win32": _loop_factory: ClassVar[type[ProactorEventLoop]] def get_child_watcher(self) -> NoReturn: ... def set_child_watcher(self, watcher: Any) -> NoReturn: ... + DefaultEventLoopPolicy = WindowsSelectorEventLoopPolicy diff --git a/mypy/typeshed/stdlib/calendar.pyi b/mypy/typeshed/stdlib/calendar.pyi index cac39a498ac9..5cc49e102fdf 100644 --- a/mypy/typeshed/stdlib/calendar.pyi +++ b/mypy/typeshed/stdlib/calendar.pyi @@ -124,7 +124,7 @@ class HTMLCalendar(Calendar): def formatyear(self, theyear: int, width: int = 3) -> str: ... def formatyearpage( self, theyear: int, width: int = 3, css: str | None = "calendar.css", encoding: str | None = None - ) -> str: ... + ) -> bytes: ... class different_locale: def __init__(self, locale: _LocaleType) -> None: ... @@ -166,6 +166,7 @@ if sys.version_info >= (3, 12): OCTOBER: Literal[10] NOVEMBER: Literal[11] DECEMBER: Literal[12] + JANUARY = Month.JANUARY FEBRUARY = Month.FEBRUARY MARCH = Month.MARCH @@ -187,6 +188,7 @@ if sys.version_info >= (3, 12): FRIDAY: Literal[4] SATURDAY: Literal[5] SUNDAY: Literal[6] + MONDAY = Day.MONDAY TUESDAY = Day.TUESDAY WEDNESDAY = Day.WEDNESDAY diff --git a/mypy/typeshed/stdlib/contextlib.pyi b/mypy/typeshed/stdlib/contextlib.pyi index ce46d0d39830..eb4e95b33509 100644 --- a/mypy/typeshed/stdlib/contextlib.pyi +++ b/mypy/typeshed/stdlib/contextlib.pyi @@ -118,6 +118,7 @@ class closing(AbstractContextManager[_SupportsCloseT]): if sys.version_info >= (3, 10): class _SupportsAclose(Protocol): def aclose(self) -> Awaitable[object]: ... + _SupportsAcloseT = TypeVar("_SupportsAcloseT", bound=_SupportsAclose) class aclosing(AbstractAsyncContextManager[_SupportsAcloseT]): diff --git a/mypy/typeshed/stdlib/dbm/gnu.pyi b/mypy/typeshed/stdlib/dbm/gnu.pyi index 3dc66a30c370..0f818ed5e7f5 100644 --- a/mypy/typeshed/stdlib/dbm/gnu.pyi +++ b/mypy/typeshed/stdlib/dbm/gnu.pyi @@ -37,4 +37,5 @@ if sys.platform != "win32": # Don't exist at runtime __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] + def open(__filename: str, __flags: str = "r", __mode: int = 0o666) -> _gdbm: ... diff --git a/mypy/typeshed/stdlib/dbm/ndbm.pyi b/mypy/typeshed/stdlib/dbm/ndbm.pyi index 1106fb2a8e7e..a7a6d52d8f19 100644 --- a/mypy/typeshed/stdlib/dbm/ndbm.pyi +++ b/mypy/typeshed/stdlib/dbm/ndbm.pyi @@ -33,4 +33,5 @@ if sys.platform != "win32": # Don't exist at runtime __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] + def open(__filename: str, __flags: str = "r", __mode: int = 0o666) -> _dbm: ... diff --git a/mypy/typeshed/stdlib/enum.pyi b/mypy/typeshed/stdlib/enum.pyi index 42d0c19d39e7..96cb2264ea20 100644 --- a/mypy/typeshed/stdlib/enum.pyi +++ b/mypy/typeshed/stdlib/enum.pyi @@ -175,6 +175,7 @@ if sys.version_info >= (3, 11): name: str clsname: str member: Enum | None + _magic_enum_attr = property else: _magic_enum_attr = types.DynamicClassAttribute @@ -261,6 +262,7 @@ if sys.version_info >= (3, 11): CONTINUOUS: str NAMED_FLAGS: str UNIQUE: str + CONTINUOUS = EnumCheck.CONTINUOUS NAMED_FLAGS = EnumCheck.NAMED_FLAGS UNIQUE = EnumCheck.UNIQUE @@ -274,6 +276,7 @@ if sys.version_info >= (3, 11): CONFORM: str EJECT: str KEEP: str + STRICT = FlagBoundary.STRICT CONFORM = FlagBoundary.CONFORM EJECT = FlagBoundary.EJECT diff --git a/mypy/typeshed/stdlib/ftplib.pyi b/mypy/typeshed/stdlib/ftplib.pyi index 3bc03a0ff121..9e7097ddc56e 100644 --- a/mypy/typeshed/stdlib/ftplib.pyi +++ b/mypy/typeshed/stdlib/ftplib.pyi @@ -31,7 +31,7 @@ class FTP: sock: socket | None welcome: str | None passiveserver: int - timeout: int + timeout: float | None af: int lastresp: str file: TextIO | None @@ -48,7 +48,7 @@ class FTP: user: str = "", passwd: str = "", acct: str = "", - timeout: float = ..., + timeout: float | None = ..., source_address: tuple[str, int] | None = None, *, encoding: str = "utf-8", @@ -60,7 +60,7 @@ class FTP: user: str = "", passwd: str = "", acct: str = "", - timeout: float = ..., + timeout: float | None = ..., source_address: tuple[str, int] | None = None, ) -> None: ... @@ -127,7 +127,7 @@ class FTP_TLS(FTP): acct: str = "", *, context: SSLContext | None = None, - timeout: float = ..., + timeout: float | None = ..., source_address: tuple[str, int] | None = None, encoding: str = "utf-8", ) -> None: ... @@ -141,7 +141,7 @@ class FTP_TLS(FTP): keyfile: str | None = None, certfile: str | None = None, context: SSLContext | None = None, - timeout: float = ..., + timeout: float | None = ..., source_address: tuple[str, int] | None = None, *, encoding: str = "utf-8", @@ -156,7 +156,7 @@ class FTP_TLS(FTP): keyfile: str | None = None, certfile: str | None = None, context: SSLContext | None = None, - timeout: float = ..., + timeout: float | None = ..., source_address: tuple[str, int] | None = None, ) -> None: ... ssl_version: int diff --git a/mypy/typeshed/stdlib/grp.pyi b/mypy/typeshed/stdlib/grp.pyi index bb0d65180918..965ecece2a56 100644 --- a/mypy/typeshed/stdlib/grp.pyi +++ b/mypy/typeshed/stdlib/grp.pyi @@ -7,6 +7,7 @@ if sys.platform != "win32": class struct_group(structseq[Any], tuple[str, str | None, int, list[str]]): if sys.version_info >= (3, 10): __match_args__: Final = ("gr_name", "gr_passwd", "gr_gid", "gr_mem") + @property def gr_name(self) -> str: ... @property diff --git a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi index a936eece1d3f..eb4db39ebf40 100644 --- a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi @@ -43,6 +43,7 @@ class PackageNotFoundError(ModuleNotFoundError): if sys.version_info >= (3, 11): class DeprecatedTuple: def __getitem__(self, item: int) -> str: ... + _EntryPointBase = DeprecatedTuple else: class _EntryPointBase(NamedTuple): diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index a26dc67f9945..06a8ff6a3462 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -430,6 +430,7 @@ if sys.version_info < (3, 11): varargs: str | None keywords: str | None defaults: tuple[Any, ...] + def getargspec(func: object) -> ArgSpec: ... class FullArgSpec(NamedTuple): diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index d949971048b0..659b216c43dc 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -6,7 +6,7 @@ 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, Literal, TextIO, TypeVar, overload +from typing import IO, Any, BinaryIO, Literal, Protocol, TextIO, TypeVar, overload, type_check_only from typing_extensions import Self __all__ = [ @@ -94,7 +94,10 @@ class BufferedIOBase(IOBase): class FileIO(RawIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of writelines in the base classes mode: str - name: FileDescriptorOrPath + # The type of "name" equals the argument passed in to the constructor, + # but that can make FileIO incompatible with other I/O types that assume + # "name" is a str. In the future, making FileIO generic might help. + name: Any def __init__( self, file: FileDescriptorOrPath, mode: str = ..., closefd: bool = ..., opener: _Opener | None = ... ) -> None: ... @@ -146,16 +149,43 @@ class TextIOBase(IOBase): def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] def read(self, __size: int | None = ...) -> str: ... +@type_check_only +class _WrappedBuffer(Protocol): + # "name" is wrapped by TextIOWrapper. Its type is inconsistent between + # the various I/O types, see the comments on TextIOWrapper.name and + # TextIO.name. + @property + def name(self) -> Any: ... + @property + def closed(self) -> bool: ... + def read(self, size: int = ..., /) -> ReadableBuffer: ... + # Optional: def read1(self, size: int, /) -> ReadableBuffer: ... + def write(self, b: bytes, /) -> object: ... + def flush(self) -> object: ... + def close(self) -> object: ... + def seekable(self) -> bool: ... + def readable(self) -> bool: ... + def writable(self) -> bool: ... + def truncate(self, size: int, /) -> int: ... + def fileno(self) -> int: ... + def isatty(self) -> int: ... + # Optional: Only needs to be present if seekable() returns True. + # def seek(self, offset: Literal[0], whence: Literal[2]) -> int: ... + # def tell(self) -> int: ... + +# TODO: Should be generic over the buffer type, but needs to wait for +# TypeVar defaults. class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible definitions of write in the base classes def __init__( self, - buffer: IO[bytes], + buffer: _WrappedBuffer, encoding: str | None = ..., errors: str | None = ..., newline: str | None = ..., line_buffering: bool = ..., write_through: bool = ..., ) -> None: ... + # Equals the "buffer" argument passed in to the constructor. @property def buffer(self) -> BinaryIO: ... @property @@ -180,7 +210,11 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] def readline(self, __size: int = -1) -> str: ... # type: ignore[override] def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] - def seek(self, __cookie: int, __whence: int = 0) -> int: ... # stubtest needs this + # Equals the "buffer" argument passed in to the constructor. + def detach(self) -> BinaryIO: ... + # TextIOWrapper's version of seek only supports a limited subset of + # operations. + def seek(self, __cookie: int, __whence: int = 0) -> int: ... class StringIO(TextIOWrapper): def __init__(self, initial_value: str | None = ..., newline: str | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/msilib/__init__.pyi b/mypy/typeshed/stdlib/msilib/__init__.pyi index 106805dab931..3e43cbc44f52 100644 --- a/mypy/typeshed/stdlib/msilib/__init__.pyi +++ b/mypy/typeshed/stdlib/msilib/__init__.pyi @@ -56,6 +56,7 @@ if sys.platform == "win32": def gen_id(self, file: str) -> str: ... def append(self, full: str, file: str, logical: str) -> tuple[int, str]: ... def commit(self, db: _Database) -> None: ... + _directories: set[str] class Directory: diff --git a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi index ad80169b463c..91532633e1b9 100644 --- a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi @@ -86,4 +86,5 @@ class AbstractReducer(metaclass=ABCMeta): sendfds = _sendfds recvfds = _recvfds DupFd = _DupFd + def __init__(self, *args: Unused) -> None: ... diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 3b277460d8f6..b57678635c07 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -341,6 +341,7 @@ class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, flo # More items may be added at the end by some implementations. if sys.version_info >= (3, 10): __match_args__: Final = ("st_mode", "st_ino", "st_dev", "st_nlink", "st_uid", "st_gid", "st_size") + @property def st_mode(self) -> int: ... # protection bits, @property @@ -446,6 +447,7 @@ class statvfs_result(structseq[int], tuple[int, int, int, int, int, int, int, in "f_flag", "f_namemax", ) + @property def f_bsize(self) -> int: ... @property @@ -488,6 +490,7 @@ def umask(__mask: int) -> int: ... class uname_result(structseq[str], tuple[str, str, str, str, str]): if sys.version_info >= (3, 10): __match_args__: Final = ("sysname", "nodename", "release", "version", "machine") + @property def sysname(self) -> str: ... @property @@ -704,6 +707,7 @@ if sys.platform != "win32": class terminal_size(structseq[int], tuple[int, int]): if sys.version_info >= (3, 10): __match_args__: Final = ("columns", "lines") + @property def columns(self) -> int: ... @property @@ -925,6 +929,7 @@ def system(command: StrOrBytesPath) -> int: ... class times_result(structseq[float], tuple[float, float, float, float, float]): if sys.version_info >= (3, 10): __match_args__: Final = ("user", "system", "children_user", "children_system", "elapsed") + @property def user(self) -> float: ... @property @@ -962,6 +967,7 @@ else: class waitid_result(structseq[int], tuple[int, int, int, int, int]): if sys.version_info >= (3, 10): __match_args__: Final = ("si_pid", "si_uid", "si_signo", "si_status", "si_code") + @property def si_pid(self) -> int: ... @property @@ -1022,6 +1028,7 @@ if sys.platform != "win32": class sched_param(structseq[int], tuple[int]): if sys.version_info >= (3, 10): __match_args__: Final = ("sched_priority",) + def __new__(cls, sched_priority: int) -> Self: ... @property def sched_priority(self) -> int: ... diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index a6ffd54de005..86f88da9e712 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -36,6 +36,7 @@ if sys.version_info >= (3, 9): percall_cumtime: float file_name: str line_number: int + @dataclass(unsafe_hash=True) class StatsProfile: total_tt: float diff --git a/mypy/typeshed/stdlib/pwd.pyi b/mypy/typeshed/stdlib/pwd.pyi index 64e831bcecce..9a8e1036e550 100644 --- a/mypy/typeshed/stdlib/pwd.pyi +++ b/mypy/typeshed/stdlib/pwd.pyi @@ -7,6 +7,7 @@ if sys.platform != "win32": class struct_passwd(structseq[Any], tuple[str, str, int, int, str, str, str]): if sys.version_info >= (3, 10): __match_args__: Final = ("pw_name", "pw_passwd", "pw_uid", "pw_gid", "pw_gecos", "pw_dir", "pw_shell") + @property def pw_name(self) -> str: ... @property diff --git a/mypy/typeshed/stdlib/pyexpat/__init__.pyi b/mypy/typeshed/stdlib/pyexpat/__init__.pyi index 92d926ebd332..2188e458474c 100644 --- a/mypy/typeshed/stdlib/pyexpat/__init__.pyi +++ b/mypy/typeshed/stdlib/pyexpat/__init__.pyi @@ -52,9 +52,12 @@ class XMLParserType: EndDoctypeDeclHandler: Callable[[], Any] | None ElementDeclHandler: Callable[[str, _Model], Any] | None AttlistDeclHandler: Callable[[str, str, str, str | None, bool], Any] | None - StartElementHandler: Callable[[str, dict[str, str]], Any] | Callable[[str, list[str]], Any] | Callable[ - [str, dict[str, str], list[str]], Any - ] | None + StartElementHandler: ( + Callable[[str, dict[str, str]], Any] + | Callable[[str, list[str]], Any] + | Callable[[str, dict[str, str], list[str]], Any] + | None + ) EndElementHandler: Callable[[str], Any] | None ProcessingInstructionHandler: Callable[[str, str], Any] | None CharacterDataHandler: Callable[[str], Any] | None diff --git a/mypy/typeshed/stdlib/resource.pyi b/mypy/typeshed/stdlib/resource.pyi index 31c55111360a..f40e5ec1ea55 100644 --- a/mypy/typeshed/stdlib/resource.pyi +++ b/mypy/typeshed/stdlib/resource.pyi @@ -24,6 +24,7 @@ if sys.platform != "win32": RLIMIT_RTTIME: int RLIMIT_SIGPENDING: int RUSAGE_THREAD: int + @final class struct_rusage( structseq[float], tuple[float, float, int, int, int, int, int, int, int, int, int, int, int, int, int, int] @@ -47,6 +48,7 @@ if sys.platform != "win32": "ru_nvcsw", "ru_nivcsw", ) + @property def ru_utime(self) -> float: ... @property diff --git a/mypy/typeshed/stdlib/select.pyi b/mypy/typeshed/stdlib/select.pyi index f2cfc881c1da..afab88e18453 100644 --- a/mypy/typeshed/stdlib/select.pyi +++ b/mypy/typeshed/stdlib/select.pyi @@ -52,6 +52,7 @@ if sys.platform != "linux" and sys.platform != "win32": data: Any = ..., udata: Any = ..., ) -> None: ... + # BSD only @final class kqueue: @@ -64,6 +65,7 @@ if sys.platform != "linux" and sys.platform != "win32": def fileno(self) -> int: ... @classmethod def fromfd(cls, __fd: FileDescriptorLike) -> kqueue: ... + KQ_EV_ADD: int KQ_EV_CLEAR: int KQ_EV_DELETE: int @@ -123,6 +125,7 @@ if sys.platform == "linux": def poll(self, timeout: float | None = None, maxevents: int = -1) -> list[tuple[int, int]]: ... @classmethod def fromfd(cls, __fd: FileDescriptorLike) -> epoll: ... + EPOLLERR: int EPOLLEXCLUSIVE: int EPOLLET: int diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index 910424c01c31..544473df9932 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -126,6 +126,7 @@ else: SIG_BLOCK: int SIG_UNBLOCK: int SIG_SETMASK: int + SIG_BLOCK = Sigmasks.SIG_BLOCK SIG_UNBLOCK = Sigmasks.SIG_UNBLOCK SIG_SETMASK = Sigmasks.SIG_SETMASK @@ -153,10 +154,12 @@ else: SIGRTMIN: Signals if sys.version_info >= (3, 11): SIGSTKFLT: Signals + @final class struct_siginfo(structseq[int], tuple[int, int, int, int, int, int, int]): if sys.version_info >= (3, 10): __match_args__: Final = ("si_signo", "si_code", "si_errno", "si_pid", "si_uid", "si_status", "si_band") + @property def si_signo(self) -> int: ... @property diff --git a/mypy/typeshed/stdlib/spwd.pyi b/mypy/typeshed/stdlib/spwd.pyi index 93dfad3b38cc..d362a0b77573 100644 --- a/mypy/typeshed/stdlib/spwd.pyi +++ b/mypy/typeshed/stdlib/spwd.pyi @@ -17,6 +17,7 @@ if sys.platform != "win32": "sp_expire", "sp_flag", ) + @property def sp_namp(self) -> str: ... @property diff --git a/mypy/typeshed/stdlib/string.pyi b/mypy/typeshed/stdlib/string.pyi index 1a875a071bf5..8b60243f2333 100644 --- a/mypy/typeshed/stdlib/string.pyi +++ b/mypy/typeshed/stdlib/string.pyi @@ -80,4 +80,4 @@ class Formatter: def get_value(self, key: int | str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any: ... def check_unused_args(self, used_args: set[int | str], args: Sequence[Any], kwargs: Mapping[str, Any]) -> None: ... def format_field(self, value: Any, format_spec: str) -> Any: ... - def convert_field(self, value: Any, conversion: str) -> Any: ... + def convert_field(self, value: Any, conversion: str | None) -> Any: ... diff --git a/mypy/typeshed/stdlib/subprocess.pyi b/mypy/typeshed/stdlib/subprocess.pyi index df1db5c82eea..d3302aba5e10 100644 --- a/mypy/typeshed/stdlib/subprocess.pyi +++ b/mypy/typeshed/stdlib/subprocess.pyi @@ -2564,12 +2564,12 @@ class Popen(Generic[AnyStr]): # The result really is always a str. if sys.version_info >= (3, 11): - def getstatusoutput(cmd: str | bytes, *, encoding: str | None = None, errors: str | None = None) -> tuple[int, str]: ... - def getoutput(cmd: str | bytes, *, encoding: str | None = None, errors: str | None = None) -> str: ... + def getstatusoutput(cmd: _CMD, *, encoding: str | None = None, errors: str | None = None) -> tuple[int, str]: ... + def getoutput(cmd: _CMD, *, encoding: str | None = None, errors: str | None = None) -> str: ... else: - def getstatusoutput(cmd: str | bytes) -> tuple[int, str]: ... - def getoutput(cmd: str | bytes) -> str: ... + def getstatusoutput(cmd: _CMD) -> tuple[int, str]: ... + def getoutput(cmd: _CMD) -> str: ... def list2cmdline(seq: Iterable[StrOrBytesPath]) -> str: ... # undocumented @@ -2592,6 +2592,7 @@ if sys.platform == "win32": wShowWindow: int lpAttributeList: Mapping[str, Any] def copy(self) -> STARTUPINFO: ... + from _winapi import ( ABOVE_NORMAL_PRIORITY_CLASS as ABOVE_NORMAL_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS as BELOW_NORMAL_PRIORITY_CLASS, diff --git a/mypy/typeshed/stdlib/sys/__init__.pyi b/mypy/typeshed/stdlib/sys/__init__.pyi index 2f847498214b..bb1d244bdac9 100644 --- a/mypy/typeshed/stdlib/sys/__init__.pyi +++ b/mypy/typeshed/stdlib/sys/__init__.pyi @@ -42,6 +42,8 @@ hexversion: int last_type: type[BaseException] | None last_value: BaseException | None last_traceback: TracebackType | None +if sys.version_info >= (3, 12): + last_exc: BaseException # or undefined. maxsize: int maxunicode: int meta_path: list[_MetaPathFinder] diff --git a/mypy/typeshed/stdlib/time.pyi b/mypy/typeshed/stdlib/time.pyi index 28752bddc4dd..b7962f0751d6 100644 --- a/mypy/typeshed/stdlib/time.pyi +++ b/mypy/typeshed/stdlib/time.pyi @@ -39,6 +39,7 @@ if sys.version_info >= (3, 9) and sys.platform == "linux": class struct_time(structseq[Any | int], _TimeTuple): if sys.version_info >= (3, 10): __match_args__: Final = ("tm_year", "tm_mon", "tm_mday", "tm_hour", "tm_min", "tm_sec", "tm_wday", "tm_yday", "tm_isdst") + @property def tm_year(self) -> int: ... @property diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index ff876d0bb88c..4733c31b5bae 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -178,13 +178,12 @@ _Compound: TypeAlias = Literal["top", "left", "center", "right", "bottom", "none _Cursor: TypeAlias = str | tuple[str] | tuple[str, str] | tuple[str, str, str] | tuple[str, str, str, str] # example when it's sequence: entry['invalidcommand'] = [entry.register(print), '%P'] _EntryValidateCommand: TypeAlias = str | list[str] | tuple[str, ...] | Callable[[], bool] -_GridIndex: TypeAlias = int | str _ImageSpec: TypeAlias = _Image | str # str can be from e.g. tkinter.image_names() _Relief: TypeAlias = Literal["raised", "sunken", "flat", "ridge", "solid", "groove"] # manual page: Tk_GetRelief _ScreenUnits: TypeAlias = str | float # Often the right type instead of int. Manual page: Tk_GetPixels # -xscrollcommand and -yscrollcommand in 'options' manual page _XYScrollCommand: TypeAlias = str | Callable[[float, float], object] -_TakeFocusValue: TypeAlias = int | Literal[""] | Callable[[str], bool | None] # -takefocus in manual page named 'options' +_TakeFocusValue: TypeAlias = bool | Literal[0, 1, ""] | Callable[[str], bool | None] # -takefocus in manual page named 'options' if sys.version_info >= (3, 11): class _VersionInfoType(NamedTuple): @@ -262,16 +261,14 @@ class Event(Generic[_W_co]): def NoDefaultRoot() -> None: ... -_TraceMode: TypeAlias = Literal["array", "read", "write", "unset"] - class Variable: def __init__(self, master: Misc | None = None, value: Incomplete | None = None, name: str | None = None) -> None: ... def set(self, value) -> None: ... initialize = set def get(self): ... - def trace_add(self, mode: _TraceMode, callback: Callable[[str, str, str], object]) -> str: ... - def trace_remove(self, mode: _TraceMode, cbname: str) -> None: ... - def trace_info(self) -> list[tuple[tuple[_TraceMode, ...], str]]: ... + def trace_add(self, mode: Literal["array", "read", "write", "unset"], callback: Callable[[str, str, str], object]) -> str: ... + def trace_remove(self, mode: Literal["array", "read", "write", "unset"], cbname: str) -> None: ... + def trace_info(self) -> list[tuple[tuple[Literal["array", "read", "write", "unset"], ...], str]]: ... @deprecated("use trace_add() instead of trace()") def trace(self, mode, callback): ... @deprecated("use trace_add() instead of trace_variable()") @@ -505,7 +502,7 @@ class Misc: bbox = grid_bbox def grid_columnconfigure( self, - index: _GridIndex | list[int] | tuple[int, ...], + index: int | str | list[int] | tuple[int, ...], cnf: _GridIndexInfo = {}, *, minsize: _ScreenUnits = ..., @@ -515,7 +512,7 @@ class Misc: ) -> _GridIndexInfo | Any: ... # can be None but annoying to check def grid_rowconfigure( self, - index: _GridIndex | list[int] | tuple[int, ...], + index: int | str | list[int] | tuple[int, ...], cnf: _GridIndexInfo = {}, *, minsize: _ScreenUnits = ..., @@ -829,7 +826,7 @@ class Pack: after: Misc = ..., anchor: _Anchor = ..., before: Misc = ..., - expand: int = ..., + expand: bool | Literal[0, 1] = 0, fill: Literal["none", "x", "y", "both"] = ..., side: Literal["left", "right", "top", "bottom"] = ..., ipadx: _ScreenUnits = ..., @@ -949,28 +946,28 @@ class Toplevel(BaseWidget, Wm): cnf: dict[str, Any] | None = {}, *, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 0, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - class_: str = ..., - colormap: Literal["new", ""] | Misc = ..., - container: bool = ..., - cursor: _Cursor = ..., - height: _ScreenUnits = ..., + border: _ScreenUnits = 0, + borderwidth: _ScreenUnits = 0, + class_: str = "Toplevel", + colormap: Literal["new", ""] | Misc = "", + container: bool = False, + cursor: _Cursor = "", + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., + highlightthickness: _ScreenUnits = 0, menu: Menu = ..., name: str = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., - screen: str = ..., # can't be changed after creating widget - takefocus: _TakeFocusValue = ..., + padx: _ScreenUnits = 0, + pady: _ScreenUnits = 0, + relief: _Relief = "flat", + screen: str = "", # can't be changed after creating widget + takefocus: _TakeFocusValue = 0, use: int = ..., - visual: str | tuple[str, int] = ..., - width: _ScreenUnits = ..., + visual: str | tuple[str, int] = "", + width: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -1006,46 +1003,46 @@ class Button(Widget): *, activebackground: str = ..., activeforeground: str = ..., - anchor: _Anchor = ..., + anchor: _Anchor = "center", background: str = ..., bd: _ScreenUnits = ..., # same as borderwidth bg: str = ..., # same as background - bitmap: str = ..., + bitmap: str = "", border: _ScreenUnits = ..., # same as borderwidth borderwidth: _ScreenUnits = ..., - command: _ButtonCommand = ..., - compound: _Compound = ..., - cursor: _Cursor = ..., - default: Literal["normal", "active", "disabled"] = ..., + command: _ButtonCommand = "", + compound: _Compound = "none", + cursor: _Cursor = "", + default: Literal["normal", "active", "disabled"] = "disabled", disabledforeground: str = ..., fg: str = ..., # same as foreground - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., # width and height must be int for buttons containing just text, but # ints are also valid _ScreenUnits - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - image: _ImageSpec = ..., - justify: Literal["left", "center", "right"] = ..., + highlightthickness: _ScreenUnits = 1, + image: _ImageSpec = "", + justify: Literal["left", "center", "right"] = "center", name: str = ..., - overrelief: _Relief = ..., + overrelief: _Relief | Literal[""] = "", padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., relief: _Relief = ..., repeatdelay: int = ..., repeatinterval: int = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", + text: float | str = "", # We allow the textvariable to be any Variable, not necessarily # StringVar. This is useful for e.g. a button that displays the value # of an IntVar. textvariable: Variable = ..., - underline: int = ..., - width: _ScreenUnits = ..., - wraplength: _ScreenUnits = ..., + underline: int = -1, + width: _ScreenUnits = 0, + wraplength: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -1075,7 +1072,7 @@ class Button(Widget): highlightthickness: _ScreenUnits = ..., image: _ImageSpec = ..., justify: Literal["left", "center", "right"] = ..., - overrelief: _Relief = ..., + overrelief: _Relief | Literal[""] = ..., padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., relief: _Relief = ..., @@ -1102,13 +1099,13 @@ class Canvas(Widget, XView, YView): cnf: dict[str, Any] | None = {}, *, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 0, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - closeenough: float = ..., - confine: bool = ..., - cursor: _Cursor = ..., + border: _ScreenUnits = 0, + borderwidth: _ScreenUnits = 0, + closeenough: float = 1.0, + confine: bool = True, + cursor: _Cursor = "", # canvas manual page has a section named COORDINATES, and the first # part of it describes _ScreenUnits. height: _ScreenUnits = ..., @@ -1116,27 +1113,27 @@ class Canvas(Widget, XView, YView): highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., insertbackground: str = ..., - insertborderwidth: _ScreenUnits = ..., - insertofftime: int = ..., - insertontime: int = ..., - insertwidth: _ScreenUnits = ..., + insertborderwidth: _ScreenUnits = 0, + insertofftime: int = 300, + insertontime: int = 600, + insertwidth: _ScreenUnits = 2, name: str = ..., offset=..., # undocumented - relief: _Relief = ..., + relief: _Relief = "flat", # Setting scrollregion to None doesn't reset it back to empty, # but setting it to () does. - scrollregion: tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits] | tuple[()] = ..., + scrollregion: tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits] | tuple[()] = (), selectbackground: str = ..., - selectborderwidth: _ScreenUnits = ..., + selectborderwidth: _ScreenUnits = 1, selectforeground: str = ..., # man page says that state can be 'hidden', but it can't - state: Literal["normal", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., + state: Literal["normal", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", width: _ScreenUnits = ..., - xscrollcommand: _XYScrollCommand = ..., - xscrollincrement: _ScreenUnits = ..., - yscrollcommand: _XYScrollCommand = ..., - yscrollincrement: _ScreenUnits = ..., + xscrollcommand: _XYScrollCommand = "", + xscrollincrement: _ScreenUnits = 0, + yscrollcommand: _XYScrollCommand = "", + yscrollincrement: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -1732,7 +1729,7 @@ class Canvas(Widget, XView, YView): def select_from(self, tagOrId, index) -> None: ... def select_item(self): ... def select_to(self, tagOrId, index) -> None: ... - def type(self, tagOrId): ... + def type(self, tagOrId: str | int) -> int | None: ... class Checkbutton(Widget): def __init__( @@ -1742,27 +1739,27 @@ class Checkbutton(Widget): *, activebackground: str = ..., activeforeground: str = ..., - anchor: _Anchor = ..., + anchor: _Anchor = "center", background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., - bitmap: str = ..., + bitmap: str = "", border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - command: _ButtonCommand = ..., - compound: _Compound = ..., - cursor: _Cursor = ..., + command: _ButtonCommand = "", + compound: _Compound = "none", + cursor: _Cursor = "", disabledforeground: str = ..., fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - image: _ImageSpec = ..., - indicatoron: bool = ..., - justify: Literal["left", "center", "right"] = ..., + highlightthickness: _ScreenUnits = 1, + image: _ImageSpec = "", + indicatoron: bool = True, + justify: Literal["left", "center", "right"] = "center", name: str = ..., offrelief: _Relief = ..., # The checkbutton puts a value to its variable when it's checked or @@ -1775,24 +1772,24 @@ class Checkbutton(Widget): # and list[int] are incompatible. Also, we would need a way to # specify "Checkbutton not associated with any variable", which is # done by setting variable to empty string (the default). - offvalue: Any = ..., - onvalue: Any = ..., - overrelief: _Relief = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., + offvalue: Any = 0, + onvalue: Any = 1, + overrelief: _Relief | Literal[""] = "", + padx: _ScreenUnits = 1, + pady: _ScreenUnits = 1, + relief: _Relief = "flat", selectcolor: str = ..., - selectimage: _ImageSpec = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + selectimage: _ImageSpec = "", + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", + text: float | str = "", textvariable: Variable = ..., - tristateimage: _ImageSpec = ..., - tristatevalue: Any = ..., - underline: int = ..., + tristateimage: _ImageSpec = "", + tristatevalue: Any = "", + underline: int = -1, variable: Variable | Literal[""] = ..., - width: _ScreenUnits = ..., - wraplength: _ScreenUnits = ..., + width: _ScreenUnits = 0, + wraplength: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -1825,7 +1822,7 @@ class Checkbutton(Widget): offrelief: _Relief = ..., offvalue: Any = ..., onvalue: Any = ..., - overrelief: _Relief = ..., + overrelief: _Relief | Literal[""] = ..., padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., relief: _Relief = ..., @@ -1851,8 +1848,6 @@ class Checkbutton(Widget): def select(self) -> None: ... def toggle(self) -> None: ... -_EntryIndex: TypeAlias = str | int # "INDICES" in manual page - class Entry(Widget, XView): def __init__( self, @@ -1864,39 +1859,39 @@ class Entry(Widget, XView): bg: str = ..., border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., + cursor: _Cursor = "xterm", disabledbackground: str = ..., disabledforeground: str = ..., - exportselection: bool = ..., + exportselection: bool = True, fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkTextFont", foreground: str = ..., highlightbackground: str = ..., highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., insertbackground: str = ..., - insertborderwidth: _ScreenUnits = ..., - insertofftime: int = ..., - insertontime: int = ..., + insertborderwidth: _ScreenUnits = 0, + insertofftime: int = 300, + insertontime: int = 600, insertwidth: _ScreenUnits = ..., - invalidcommand: _EntryValidateCommand = ..., - invcmd: _EntryValidateCommand = ..., # same as invalidcommand - justify: Literal["left", "center", "right"] = ..., + invalidcommand: _EntryValidateCommand = "", + invcmd: _EntryValidateCommand = "", # same as invalidcommand + justify: Literal["left", "center", "right"] = "left", name: str = ..., readonlybackground: str = ..., - relief: _Relief = ..., + relief: _Relief = "sunken", selectbackground: str = ..., selectborderwidth: _ScreenUnits = ..., selectforeground: str = ..., - show: str = ..., - state: Literal["normal", "disabled", "readonly"] = ..., - takefocus: _TakeFocusValue = ..., + show: str = "", + state: Literal["normal", "disabled", "readonly"] = "normal", + takefocus: _TakeFocusValue = "", textvariable: Variable = ..., - validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., - validatecommand: _EntryValidateCommand = ..., - vcmd: _EntryValidateCommand = ..., # same as validatecommand - width: int = ..., - xscrollcommand: _XYScrollCommand = ..., + validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = "none", + validatecommand: _EntryValidateCommand = "", + vcmd: _EntryValidateCommand = "", # same as validatecommand + width: int = 20, + xscrollcommand: _XYScrollCommand = "", ) -> None: ... @overload def configure( @@ -1944,19 +1939,19 @@ class Entry(Widget, XView): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... config = configure - def delete(self, first: _EntryIndex, last: _EntryIndex | None = None) -> None: ... + def delete(self, first: str | int, last: str | int | None = None) -> None: ... def get(self) -> str: ... - def icursor(self, index: _EntryIndex) -> None: ... - def index(self, index: _EntryIndex) -> int: ... - def insert(self, index: _EntryIndex, string: str) -> None: ... + def icursor(self, index: str | int) -> None: ... + def index(self, index: str | int) -> int: ... + def insert(self, index: str | int, string: str) -> None: ... def scan_mark(self, x) -> None: ... def scan_dragto(self, x) -> None: ... - def selection_adjust(self, index: _EntryIndex) -> None: ... + def selection_adjust(self, index: str | int) -> None: ... def selection_clear(self) -> None: ... # type: ignore[override] - def selection_from(self, index: _EntryIndex) -> None: ... + def selection_from(self, index: str | int) -> None: ... def selection_present(self) -> bool: ... - def selection_range(self, start: _EntryIndex, end: _EntryIndex) -> None: ... - def selection_to(self, index: _EntryIndex) -> None: ... + def selection_range(self, start: str | int, end: str | int) -> None: ... + def selection_to(self, index: str | int) -> None: ... select_adjust = selection_adjust select_clear = selection_clear select_from = selection_from @@ -1971,25 +1966,25 @@ class Frame(Widget): cnf: dict[str, Any] | None = {}, *, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 0, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - class_: str = ..., # can't be changed with configure() - colormap: Literal["new", ""] | Misc = ..., # can't be changed with configure() - container: bool = ..., # can't be changed with configure() - cursor: _Cursor = ..., - height: _ScreenUnits = ..., + border: _ScreenUnits = 0, + borderwidth: _ScreenUnits = 0, + class_: str = "Frame", # can't be changed with configure() + colormap: Literal["new", ""] | Misc = "", # can't be changed with configure() + container: bool = False, # can't be changed with configure() + cursor: _Cursor = "", + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., + highlightthickness: _ScreenUnits = 0, name: str = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., - takefocus: _TakeFocusValue = ..., - visual: str | tuple[str, int] = ..., # can't be changed with configure() - width: _ScreenUnits = ..., + padx: _ScreenUnits = 0, + pady: _ScreenUnits = 0, + relief: _Relief = "flat", + takefocus: _TakeFocusValue = 0, + visual: str | tuple[str, int] = "", # can't be changed with configure() + width: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -2024,36 +2019,36 @@ class Label(Widget): *, activebackground: str = ..., activeforeground: str = ..., - anchor: _Anchor = ..., + anchor: _Anchor = "center", background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., - bitmap: str = ..., + bitmap: str = "", border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - compound: _Compound = ..., - cursor: _Cursor = ..., + compound: _Compound = "none", + cursor: _Cursor = "", disabledforeground: str = ..., fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - image: _ImageSpec = ..., - justify: Literal["left", "center", "right"] = ..., + highlightthickness: _ScreenUnits = 0, + image: _ImageSpec = "", + justify: Literal["left", "center", "right"] = "center", name: str = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + padx: _ScreenUnits = 1, + pady: _ScreenUnits = 1, + relief: _Relief = "flat", + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = 0, + text: float | str = "", textvariable: Variable = ..., - underline: int = ..., - width: _ScreenUnits = ..., - wraplength: _ScreenUnits = ..., + underline: int = -1, + width: _ScreenUnits = 0, + wraplength: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -2104,21 +2099,21 @@ class Listbox(Widget, XView, YView): *, activestyle: Literal["dotbox", "none", "underline"] = ..., background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 1, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., + border: _ScreenUnits = 1, + borderwidth: _ScreenUnits = 1, + cursor: _Cursor = "", disabledforeground: str = ..., - exportselection: int = ..., + exportselection: bool | Literal[0, 1] = 1, fg: str = ..., font: _FontDescription = ..., foreground: str = ..., - height: int = ..., + height: int = 10, highlightbackground: str = ..., highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., - justify: Literal["left", "center", "right"] = ..., + justify: Literal["left", "center", "right"] = "left", # There's no tkinter.ListVar, but seems like bare tkinter.Variable # actually works for this: # @@ -2132,20 +2127,20 @@ class Listbox(Widget, XView, YView): name: str = ..., relief: _Relief = ..., selectbackground: str = ..., - selectborderwidth: _ScreenUnits = ..., + selectborderwidth: _ScreenUnits = 0, selectforeground: str = ..., # from listbox man page: "The value of the [selectmode] option may be # arbitrary, but the default bindings expect it to be ..." # # I have never seen anyone setting this to something else than what # "the default bindings expect", but let's support it anyway. - selectmode: str = ..., - setgrid: bool = ..., - state: Literal["normal", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - width: int = ..., - xscrollcommand: _XYScrollCommand = ..., - yscrollcommand: _XYScrollCommand = ..., + selectmode: str = "browse", + setgrid: bool = False, + state: Literal["normal", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", + width: int = 20, + xscrollcommand: _XYScrollCommand = "", + yscrollcommand: _XYScrollCommand = "", ) -> None: ... @overload def configure( @@ -2223,23 +2218,23 @@ class Menu(Widget): bg: str = ..., border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., + cursor: _Cursor = "arrow", disabledforeground: str = ..., fg: str = ..., font: _FontDescription = ..., foreground: str = ..., name: str = ..., - postcommand: Callable[[], object] | str = ..., + postcommand: Callable[[], object] | str = "", relief: _Relief = ..., selectcolor: str = ..., - takefocus: _TakeFocusValue = ..., - tearoff: int = ..., + takefocus: _TakeFocusValue = 0, + tearoff: bool | Literal[0, 1] = 1, # I guess tearoffcommand arguments are supposed to be widget objects, # but they are widget name strings. Use nametowidget() to handle the # arguments of tearoffcommand. - tearoffcommand: Callable[[str, str], object] | str = ..., - title: str = ..., - type: Literal["menubar", "tearoff", "normal"] = ..., + tearoffcommand: Callable[[str, str], object] | str = "", + title: str = "", + type: Literal["menubar", "tearoff", "normal"] = "normal", ) -> None: ... @overload def configure( @@ -2491,35 +2486,35 @@ class Menubutton(Widget): background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., - bitmap: str = ..., + bitmap: str = "", border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - compound: _Compound = ..., - cursor: _Cursor = ..., - direction: Literal["above", "below", "left", "right", "flush"] = ..., + compound: _Compound = "none", + cursor: _Cursor = "", + direction: Literal["above", "below", "left", "right", "flush"] = "below", disabledforeground: str = ..., fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - image: _ImageSpec = ..., + highlightthickness: _ScreenUnits = 0, + image: _ImageSpec = "", indicatoron: bool = ..., justify: Literal["left", "center", "right"] = ..., menu: Menu = ..., name: str = ..., padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., - relief: _Relief = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + relief: _Relief = "flat", + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = 0, + text: float | str = "", textvariable: Variable = ..., - underline: int = ..., - width: _ScreenUnits = ..., - wraplength: _ScreenUnits = ..., + underline: int = -1, + width: _ScreenUnits = 0, + wraplength: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -2571,30 +2566,30 @@ class Message(Widget): master: Misc | None = None, cnf: dict[str, Any] | None = {}, *, - anchor: _Anchor = ..., - aspect: int = ..., + anchor: _Anchor = "center", + aspect: int = 150, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 1, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., + border: _ScreenUnits = 1, + borderwidth: _ScreenUnits = 1, + cursor: _Cursor = "", fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - justify: Literal["left", "center", "right"] = ..., + highlightthickness: _ScreenUnits = 0, + justify: Literal["left", "center", "right"] = "left", name: str = ..., padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., - relief: _Relief = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + relief: _Relief = "flat", + takefocus: _TakeFocusValue = 0, + text: float | str = "", textvariable: Variable = ..., # there's width but no height - width: _ScreenUnits = ..., + width: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -2636,46 +2631,46 @@ class Radiobutton(Widget): *, activebackground: str = ..., activeforeground: str = ..., - anchor: _Anchor = ..., + anchor: _Anchor = "center", background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., - bitmap: str = ..., + bitmap: str = "", border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - command: _ButtonCommand = ..., - compound: _Compound = ..., - cursor: _Cursor = ..., + command: _ButtonCommand = "", + compound: _Compound = "none", + cursor: _Cursor = "", disabledforeground: str = ..., fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - image: _ImageSpec = ..., - indicatoron: bool = ..., - justify: Literal["left", "center", "right"] = ..., + highlightthickness: _ScreenUnits = 1, + image: _ImageSpec = "", + indicatoron: bool = True, + justify: Literal["left", "center", "right"] = "center", name: str = ..., offrelief: _Relief = ..., - overrelief: _Relief = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., + overrelief: _Relief | Literal[""] = "", + padx: _ScreenUnits = 1, + pady: _ScreenUnits = 1, + relief: _Relief = "flat", selectcolor: str = ..., - selectimage: _ImageSpec = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., + selectimage: _ImageSpec = "", + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", + text: float | str = "", textvariable: Variable = ..., - tristateimage: _ImageSpec = ..., - tristatevalue: Any = ..., - underline: int = ..., - value: Any = ..., + tristateimage: _ImageSpec = "", + tristatevalue: Any = "", + underline: int = -1, + value: Any = "", variable: Variable | Literal[""] = ..., - width: _ScreenUnits = ..., - wraplength: _ScreenUnits = ..., + width: _ScreenUnits = 0, + wraplength: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -2706,7 +2701,7 @@ class Radiobutton(Widget): indicatoron: bool = ..., justify: Literal["left", "center", "right"] = ..., offrelief: _Relief = ..., - overrelief: _Relief = ..., + overrelief: _Relief | Literal[""] = ..., padx: _ScreenUnits = ..., pady: _ScreenUnits = ..., relief: _Relief = ..., @@ -2740,40 +2735,40 @@ class Scale(Widget): *, activebackground: str = ..., background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 1, bg: str = ..., - bigincrement: float = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., + bigincrement: float = 0.0, + border: _ScreenUnits = 1, + borderwidth: _ScreenUnits = 1, # don't know why the callback gets string instead of float - command: str | Callable[[str], object] = ..., - cursor: _Cursor = ..., - digits: int = ..., + command: str | Callable[[str], object] = "", + cursor: _Cursor = "", + digits: int = 0, fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - from_: float = ..., + from_: float = 0.0, highlightbackground: str = ..., highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., - label: str = ..., - length: _ScreenUnits = ..., + label: str = "", + length: _ScreenUnits = 100, name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., - relief: _Relief = ..., - repeatdelay: int = ..., - repeatinterval: int = ..., - resolution: float = ..., - showvalue: bool = ..., - sliderlength: _ScreenUnits = ..., - sliderrelief: _Relief = ..., - state: Literal["normal", "active", "disabled"] = ..., - takefocus: _TakeFocusValue = ..., - tickinterval: float = ..., - to: float = ..., + orient: Literal["horizontal", "vertical"] = "vertical", + relief: _Relief = "flat", + repeatdelay: int = 300, + repeatinterval: int = 100, + resolution: float = 1.0, + showvalue: bool = True, + sliderlength: _ScreenUnits = 30, + sliderrelief: _Relief = "raised", + state: Literal["normal", "active", "disabled"] = "normal", + takefocus: _TakeFocusValue = "", + tickinterval: float = 0.0, + to: float = 100.0, troughcolor: str = ..., variable: IntVar | DoubleVar = ..., - width: _ScreenUnits = ..., + width: _ScreenUnits = 15, ) -> None: ... @overload def configure( @@ -2830,7 +2825,7 @@ class Scrollbar(Widget): cnf: dict[str, Any] | None = {}, *, activebackground: str = ..., - activerelief: _Relief = ..., + activerelief: _Relief = "raised", background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., @@ -2840,19 +2835,19 @@ class Scrollbar(Widget): # 'SCROLLING COMMANDS' in scrollbar man page. There doesn't seem to # be any way to specify an overloaded callback function, so we say # that it can take any args while it can't in reality. - command: Callable[..., tuple[float, float] | None] | str = ..., - cursor: _Cursor = ..., - elementborderwidth: _ScreenUnits = ..., + command: Callable[..., tuple[float, float] | None] | str = "", + cursor: _Cursor = "", + elementborderwidth: _ScreenUnits = -1, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., - jump: bool = ..., + highlightthickness: _ScreenUnits = 0, + jump: bool = False, name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., + orient: Literal["horizontal", "vertical"] = "vertical", relief: _Relief = ..., - repeatdelay: int = ..., - repeatinterval: int = ..., - takefocus: _TakeFocusValue = ..., + repeatdelay: int = 300, + repeatinterval: int = 100, + takefocus: _TakeFocusValue = "", troughcolor: str = ..., width: _ScreenUnits = ..., ) -> None: ... @@ -2901,56 +2896,56 @@ class Text(Widget, XView, YView): master: Misc | None = None, cnf: dict[str, Any] | None = {}, *, - autoseparators: bool = ..., + autoseparators: bool = True, background: str = ..., bd: _ScreenUnits = ..., bg: str = ..., - blockcursor: bool = ..., + blockcursor: bool = False, border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., - endline: int | Literal[""] = ..., - exportselection: bool = ..., + cursor: _Cursor = "xterm", + endline: int | Literal[""] = "", + exportselection: bool = True, fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkFixedFont", foreground: str = ..., # width is always int, but height is allowed to be ScreenUnits. # This doesn't make any sense to me, and this isn't documented. # The docs seem to say that both should be integers. - height: _ScreenUnits = ..., + height: _ScreenUnits = 24, highlightbackground: str = ..., highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., inactiveselectbackground: str = ..., insertbackground: str = ..., - insertborderwidth: _ScreenUnits = ..., - insertofftime: int = ..., - insertontime: int = ..., - insertunfocussed: Literal["none", "hollow", "solid"] = ..., + insertborderwidth: _ScreenUnits = 0, + insertofftime: int = 300, + insertontime: int = 600, + insertunfocussed: Literal["none", "hollow", "solid"] = "none", insertwidth: _ScreenUnits = ..., - maxundo: int = ..., + maxundo: int = 0, name: str = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., + padx: _ScreenUnits = 1, + pady: _ScreenUnits = 1, relief: _Relief = ..., selectbackground: str = ..., selectborderwidth: _ScreenUnits = ..., selectforeground: str = ..., - setgrid: bool = ..., - spacing1: _ScreenUnits = ..., - spacing2: _ScreenUnits = ..., - spacing3: _ScreenUnits = ..., - startline: int | Literal[""] = ..., - state: Literal["normal", "disabled"] = ..., + setgrid: bool = False, + spacing1: _ScreenUnits = 0, + spacing2: _ScreenUnits = 0, + spacing3: _ScreenUnits = 0, + startline: int | Literal[""] = "", + state: Literal["normal", "disabled"] = "normal", # Literal inside Tuple doesn't actually work - tabs: _ScreenUnits | str | tuple[_ScreenUnits | str, ...] = ..., - tabstyle: Literal["tabular", "wordprocessor"] = ..., - takefocus: _TakeFocusValue = ..., - undo: bool = ..., - width: int = ..., - wrap: Literal["none", "char", "word"] = ..., - xscrollcommand: _XYScrollCommand = ..., - yscrollcommand: _XYScrollCommand = ..., + tabs: _ScreenUnits | str | tuple[_ScreenUnits | str, ...] = "", + tabstyle: Literal["tabular", "wordprocessor"] = "tabular", + takefocus: _TakeFocusValue = "", + undo: bool = False, + width: int = 80, + wrap: Literal["none", "char", "word"] = "char", + xscrollcommand: _XYScrollCommand = "", + yscrollcommand: _XYScrollCommand = "", ) -> None: ... @overload def configure( @@ -3371,51 +3366,51 @@ class Spinbox(Widget, XView): border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., buttonbackground: str = ..., - buttoncursor: _Cursor = ..., + buttoncursor: _Cursor = "", buttondownrelief: _Relief = ..., buttonuprelief: _Relief = ..., # percent substitutions don't seem to be supported, it's similar to Entry's validation stuff - command: Callable[[], object] | str | list[str] | tuple[str, ...] = ..., - cursor: _Cursor = ..., + command: Callable[[], object] | str | list[str] | tuple[str, ...] = "", + cursor: _Cursor = "xterm", disabledbackground: str = ..., disabledforeground: str = ..., - exportselection: bool = ..., + exportselection: bool = True, fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkTextFont", foreground: str = ..., - format: str = ..., - from_: float = ..., + format: str = "", + from_: float = 0.0, highlightbackground: str = ..., highlightcolor: str = ..., highlightthickness: _ScreenUnits = ..., - increment: float = ..., + increment: float = 1.0, insertbackground: str = ..., - insertborderwidth: _ScreenUnits = ..., - insertofftime: int = ..., - insertontime: int = ..., + insertborderwidth: _ScreenUnits = 0, + insertofftime: int = 300, + insertontime: int = 600, insertwidth: _ScreenUnits = ..., - invalidcommand: _EntryValidateCommand = ..., - invcmd: _EntryValidateCommand = ..., - justify: Literal["left", "center", "right"] = ..., + invalidcommand: _EntryValidateCommand = "", + invcmd: _EntryValidateCommand = "", + justify: Literal["left", "center", "right"] = "left", name: str = ..., readonlybackground: str = ..., - relief: _Relief = ..., - repeatdelay: int = ..., - repeatinterval: int = ..., + relief: _Relief = "sunken", + repeatdelay: int = 400, + repeatinterval: int = 100, selectbackground: str = ..., selectborderwidth: _ScreenUnits = ..., selectforeground: str = ..., - state: Literal["normal", "disabled", "readonly"] = ..., - takefocus: _TakeFocusValue = ..., + state: Literal["normal", "disabled", "readonly"] = "normal", + takefocus: _TakeFocusValue = "", textvariable: Variable = ..., - to: float = ..., - validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., - validatecommand: _EntryValidateCommand = ..., - vcmd: _EntryValidateCommand = ..., + to: float = 0.0, + validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = "none", + validatecommand: _EntryValidateCommand = "", + vcmd: _EntryValidateCommand = "", values: list[str] | tuple[str, ...] = ..., - width: int = ..., - wrap: bool = ..., - xscrollcommand: _XYScrollCommand = ..., + width: int = 20, + wrap: bool = False, + xscrollcommand: _XYScrollCommand = "", ) -> None: ... @overload def configure( @@ -3481,8 +3476,8 @@ class Spinbox(Widget, XView): def get(self) -> str: ... def icursor(self, index): ... def identify(self, x: int, y: int) -> Literal["", "buttondown", "buttonup", "entry"]: ... - def index(self, index: _EntryIndex) -> int: ... - def insert(self, index: _EntryIndex, s: str) -> Literal[""]: ... + def index(self, index: str | int) -> int: ... + def insert(self, index: str | int, s: str) -> Literal[""]: ... # spinbox.invoke("asdf") gives error mentioning .invoke("none"), but it's not documented def invoke(self, element: Literal["none", "buttonup", "buttondown"]) -> Literal[""]: ... def scan(self, *args): ... @@ -3504,32 +3499,32 @@ class LabelFrame(Widget): cnf: dict[str, Any] | None = {}, *, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 2, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - class_: str = ..., # can't be changed with configure() - colormap: Literal["new", ""] | Misc = ..., # can't be changed with configure() - container: bool = ..., # undocumented, can't be changed with configure() - cursor: _Cursor = ..., + border: _ScreenUnits = 2, + borderwidth: _ScreenUnits = 2, + class_: str = "Labelframe", # can't be changed with configure() + colormap: Literal["new", ""] | Misc = "", # can't be changed with configure() + container: bool = False, # undocumented, can't be changed with configure() + cursor: _Cursor = "", fg: str = ..., - font: _FontDescription = ..., + font: _FontDescription = "TkDefaultFont", foreground: str = ..., - height: _ScreenUnits = ..., + height: _ScreenUnits = 0, highlightbackground: str = ..., highlightcolor: str = ..., - highlightthickness: _ScreenUnits = ..., + highlightthickness: _ScreenUnits = 0, # 'ne' and 'en' are valid labelanchors, but only 'ne' is a valid _Anchor. - labelanchor: Literal["nw", "n", "ne", "en", "e", "es", "se", "s", "sw", "ws", "w", "wn"] = ..., + labelanchor: Literal["nw", "n", "ne", "en", "e", "es", "se", "s", "sw", "ws", "w", "wn"] = "nw", labelwidget: Misc = ..., name: str = ..., - padx: _ScreenUnits = ..., - pady: _ScreenUnits = ..., - relief: _Relief = ..., - takefocus: _TakeFocusValue = ..., - text: float | str = ..., - visual: str | tuple[str, int] = ..., # can't be changed with configure() - width: _ScreenUnits = ..., + padx: _ScreenUnits = 0, + pady: _ScreenUnits = 0, + relief: _Relief = "groove", + takefocus: _TakeFocusValue = 0, + text: float | str = "", + visual: str | tuple[str, int] = "", # can't be changed with configure() + width: _ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -3569,27 +3564,27 @@ class PanedWindow(Widget): cnf: dict[str, Any] | None = {}, *, background: str = ..., - bd: _ScreenUnits = ..., + bd: _ScreenUnits = 1, bg: str = ..., - border: _ScreenUnits = ..., - borderwidth: _ScreenUnits = ..., - cursor: _Cursor = ..., - handlepad: _ScreenUnits = ..., - handlesize: _ScreenUnits = ..., - height: _ScreenUnits = ..., + border: _ScreenUnits = 1, + borderwidth: _ScreenUnits = 1, + cursor: _Cursor = "", + handlepad: _ScreenUnits = 8, + handlesize: _ScreenUnits = 8, + height: _ScreenUnits = "", name: str = ..., - opaqueresize: bool = ..., - orient: Literal["horizontal", "vertical"] = ..., - proxybackground: str = ..., - proxyborderwidth: _ScreenUnits = ..., - proxyrelief: _Relief = ..., - relief: _Relief = ..., - sashcursor: _Cursor = ..., - sashpad: _ScreenUnits = ..., - sashrelief: _Relief = ..., - sashwidth: _ScreenUnits = ..., - showhandle: bool = ..., - width: _ScreenUnits = ..., + opaqueresize: bool = True, + orient: Literal["horizontal", "vertical"] = "horizontal", + proxybackground: str = "", + proxyborderwidth: _ScreenUnits = 2, + proxyrelief: _Relief = "flat", + relief: _Relief = "flat", + sashcursor: _Cursor = "", + sashpad: _ScreenUnits = 0, + sashrelief: _Relief = "flat", + sashwidth: _ScreenUnits = 3, + showhandle: bool = False, + width: _ScreenUnits = "", ) -> None: ... @overload def configure( diff --git a/mypy/typeshed/stdlib/tkinter/ttk.pyi b/mypy/typeshed/stdlib/tkinter/ttk.pyi index ac5accb73d9f..f1b132b33657 100644 --- a/mypy/typeshed/stdlib/tkinter/ttk.pyi +++ b/mypy/typeshed/stdlib/tkinter/ttk.pyi @@ -46,7 +46,7 @@ _Padding: TypeAlias = ( ) # from ttk_widget (aka ttk::widget) manual page, differs from tkinter._Compound -_TtkCompound: TypeAlias = Literal["text", "image", tkinter._Compound] +_TtkCompound: TypeAlias = Literal["", "text", "image", tkinter._Compound] class Style: master: Incomplete @@ -78,21 +78,21 @@ class Button(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - command: tkinter._ButtonCommand = ..., - compound: _TtkCompound = ..., - cursor: tkinter._Cursor = ..., - default: Literal["normal", "active", "disabled"] = ..., - image: tkinter._ImageSpec = ..., + class_: str = "", + command: tkinter._ButtonCommand = "", + compound: _TtkCompound = "", + cursor: tkinter._Cursor = "", + default: Literal["normal", "active", "disabled"] = "normal", + image: tkinter._ImageSpec = "", name: str = ..., padding=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., + text: float | str = "", textvariable: tkinter.Variable = ..., - underline: int = ..., - width: int | Literal[""] = ..., + underline: int = -1, + width: int | Literal[""] = "", ) -> None: ... @overload def configure( @@ -123,26 +123,26 @@ class Checkbutton(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - command: tkinter._ButtonCommand = ..., - compound: _TtkCompound = ..., - cursor: tkinter._Cursor = ..., - image: tkinter._ImageSpec = ..., + class_: str = "", + command: tkinter._ButtonCommand = "", + compound: _TtkCompound = "", + cursor: tkinter._Cursor = "", + image: tkinter._ImageSpec = "", name: str = ..., - offvalue: Any = ..., - onvalue: Any = ..., + offvalue: Any = 0, + onvalue: Any = 1, padding=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., + text: float | str = "", textvariable: tkinter.Variable = ..., - underline: int = ..., + underline: int = -1, # Seems like variable can be empty string, but actually setting it to # empty string segfaults before Tcl 8.6.9. Search for ttk::checkbutton # here: https://sourceforge.net/projects/tcl/files/Tcl/8.6.9/tcltk-release-notes-8.6.9.txt/view variable: tkinter.Variable = ..., - width: int | Literal[""] = ..., + width: int | Literal[""] = "", ) -> None: ... @overload def configure( @@ -177,23 +177,23 @@ class Entry(Widget, tkinter.Entry): widget: str | None = None, *, background: str = ..., # undocumented - class_: str = ..., + class_: str = "", cursor: tkinter._Cursor = ..., - exportselection: bool = ..., - font: _FontDescription = ..., - foreground: str = ..., - invalidcommand: tkinter._EntryValidateCommand = ..., - justify: Literal["left", "center", "right"] = ..., + exportselection: bool = True, + font: _FontDescription = "TkTextFont", + foreground: str = "", + invalidcommand: tkinter._EntryValidateCommand = "", + justify: Literal["left", "center", "right"] = "left", name: str = ..., - show: str = ..., - state: str = ..., - style: str = ..., + show: str = "", + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., textvariable: tkinter.Variable = ..., - validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., - validatecommand: tkinter._EntryValidateCommand = ..., - width: int = ..., - xscrollcommand: tkinter._XYScrollCommand = ..., + validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = "none", + validatecommand: tkinter._EntryValidateCommand = "", + width: int = 20, + xscrollcommand: tkinter._XYScrollCommand = "", ) -> None: ... @overload # type: ignore[override] def configure( @@ -254,25 +254,25 @@ class Combobox(Entry): master: tkinter.Misc | None = None, *, background: str = ..., # undocumented - class_: str = ..., - cursor: tkinter._Cursor = ..., - exportselection: bool = ..., + class_: str = "", + cursor: tkinter._Cursor = "", + exportselection: bool = True, font: _FontDescription = ..., # undocumented foreground: str = ..., # undocumented - height: int = ..., + height: int = 10, invalidcommand: tkinter._EntryValidateCommand = ..., # undocumented - justify: Literal["left", "center", "right"] = ..., + justify: Literal["left", "center", "right"] = "left", name: str = ..., - postcommand: Callable[[], object] | str = ..., + postcommand: Callable[[], object] | str = "", show=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., textvariable: tkinter.Variable = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., # undocumented validatecommand: tkinter._EntryValidateCommand = ..., # undocumented values: list[str] | tuple[str, ...] = ..., - width: int = ..., + width: int = 20, xscrollcommand: tkinter._XYScrollCommand = ..., # undocumented ) -> None: ... @overload # type: ignore[override] @@ -334,21 +334,23 @@ class Combobox(Entry): def set(self, value: Any) -> None: ... class Frame(Widget): + # This should be kept in sync with tkinter.ttk.LabeledScale.__init__() + # (all of these keyword-only arguments are also present there) def __init__( self, master: tkinter.Misc | None = None, *, border: tkinter._ScreenUnits = ..., borderwidth: tkinter._ScreenUnits = ..., - class_: str = ..., - cursor: tkinter._Cursor = ..., - height: tkinter._ScreenUnits = ..., + class_: str = "", + cursor: tkinter._Cursor = "", + height: tkinter._ScreenUnits = 0, name: str = ..., padding: _Padding = ..., relief: tkinter._Relief = ..., - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., - width: tkinter._ScreenUnits = ..., + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + width: tkinter._ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -375,26 +377,26 @@ class Label(Widget): master: tkinter.Misc | None = None, *, anchor: tkinter._Anchor = ..., - background: str = ..., + background: str = "", border: tkinter._ScreenUnits = ..., # alias for borderwidth borderwidth: tkinter._ScreenUnits = ..., # undocumented - class_: str = ..., - compound: _TtkCompound = ..., - cursor: tkinter._Cursor = ..., + class_: str = "", + compound: _TtkCompound = "", + cursor: tkinter._Cursor = "", font: _FontDescription = ..., - foreground: str = ..., - image: tkinter._ImageSpec = ..., + foreground: str = "", + image: tkinter._ImageSpec = "", justify: Literal["left", "center", "right"] = ..., name: str = ..., padding: _Padding = ..., relief: tkinter._Relief = ..., - state: str = ..., - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., + state: str = "normal", + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + text: float | str = "", textvariable: tkinter.Variable = ..., - underline: int = ..., - width: int | Literal[""] = ..., + underline: int = -1, + width: int | Literal[""] = "", wraplength: tkinter._ScreenUnits = ..., ) -> None: ... @overload @@ -434,19 +436,19 @@ class Labelframe(Widget): *, border: tkinter._ScreenUnits = ..., borderwidth: tkinter._ScreenUnits = ..., # undocumented - class_: str = ..., - cursor: tkinter._Cursor = ..., - height: tkinter._ScreenUnits = ..., + class_: str = "", + cursor: tkinter._Cursor = "", + height: tkinter._ScreenUnits = 0, labelanchor: Literal["nw", "n", "ne", "en", "e", "es", "se", "s", "sw", "ws", "w", "wn"] = ..., labelwidget: tkinter.Misc = ..., name: str = ..., padding: _Padding = ..., relief: tkinter._Relief = ..., # undocumented - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., - underline: int = ..., - width: tkinter._ScreenUnits = ..., + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + text: float | str = "", + underline: int = -1, + width: tkinter._ScreenUnits = 0, ) -> None: ... @overload def configure( @@ -478,21 +480,21 @@ class Menubutton(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - compound: _TtkCompound = ..., - cursor: tkinter._Cursor = ..., - direction: Literal["above", "below", "left", "right", "flush"] = ..., - image: tkinter._ImageSpec = ..., + class_: str = "", + compound: _TtkCompound = "", + cursor: tkinter._Cursor = "", + direction: Literal["above", "below", "left", "right", "flush"] = "below", + image: tkinter._ImageSpec = "", menu: tkinter.Menu = ..., name: str = ..., padding=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., + text: float | str = "", textvariable: tkinter.Variable = ..., - underline: int = ..., - width: int | Literal[""] = ..., + underline: int = -1, + width: int | Literal[""] = "", ) -> None: ... @overload def configure( @@ -522,14 +524,14 @@ class Notebook(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - cursor: tkinter._Cursor = ..., - height: int = ..., + class_: str = "", + cursor: tkinter._Cursor = "", + height: int = 0, name: str = ..., padding: _Padding = ..., - style: str = ..., + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - width: int = ..., + width: int = 0, ) -> None: ... @overload def configure( @@ -573,15 +575,15 @@ class Panedwindow(Widget, tkinter.PanedWindow): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - cursor: tkinter._Cursor = ..., + class_: str = "", + cursor: tkinter._Cursor = "", # width and height for tkinter.ttk.Panedwindow are int but for tkinter.PanedWindow they are screen units - height: int = ..., + height: int = 0, name: str = ..., - orient: Literal["vertical", "horizontal"] = ..., # can't be changed with configure() - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., - width: int = ..., + orient: Literal["vertical", "horizontal"] = "vertical", # can't be changed with configure() + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + width: int = 0, ) -> None: ... def add(self, child: tkinter.Widget, *, weight: int = ..., **kw) -> None: ... @overload # type: ignore[override] @@ -623,17 +625,17 @@ class Progressbar(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - cursor: tkinter._Cursor = ..., - length: tkinter._ScreenUnits = ..., - maximum: float = ..., - mode: Literal["determinate", "indeterminate"] = ..., + class_: str = "", + cursor: tkinter._Cursor = "", + length: tkinter._ScreenUnits = 100, + maximum: float = 100, + mode: Literal["determinate", "indeterminate"] = "determinate", name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., - phase: int = ..., # docs say read-only but assigning int to this works - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., - value: float = ..., + orient: Literal["horizontal", "vertical"] = "horizontal", + phase: int = 0, # docs say read-only but assigning int to this works + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + value: float = 0.0, variable: tkinter.IntVar | tkinter.DoubleVar = ..., ) -> None: ... @overload @@ -664,22 +666,22 @@ class Radiobutton(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - command: tkinter._ButtonCommand = ..., - compound: _TtkCompound = ..., - cursor: tkinter._Cursor = ..., - image: tkinter._ImageSpec = ..., + class_: str = "", + command: tkinter._ButtonCommand = "", + compound: _TtkCompound = "", + cursor: tkinter._Cursor = "", + image: tkinter._ImageSpec = "", name: str = ..., padding=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - text: float | str = ..., + text: float | str = "", textvariable: tkinter.Variable = ..., - underline: int = ..., - value: Any = ..., + underline: int = -1, + value: Any = "1", variable: tkinter.Variable | Literal[""] = ..., - width: int | Literal[""] = ..., + width: int | Literal[""] = "", ) -> None: ... @overload def configure( @@ -712,18 +714,18 @@ class Scale(Widget, tkinter.Scale): # type: ignore[misc] self, master: tkinter.Misc | None = None, *, - class_: str = ..., - command: str | Callable[[str], object] = ..., - cursor: tkinter._Cursor = ..., - from_: float = ..., - length: tkinter._ScreenUnits = ..., + class_: str = "", + command: str | Callable[[str], object] = "", + cursor: tkinter._Cursor = "", + from_: float = 0, + length: tkinter._ScreenUnits = 100, name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., + orient: Literal["horizontal", "vertical"] = "horizontal", state: str = ..., # undocumented - style: str = ..., + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - to: float = ..., - value: float = ..., + to: float = 1.0, + value: float = 0, variable: tkinter.IntVar | tkinter.DoubleVar = ..., ) -> None: ... @overload # type: ignore[override] @@ -773,13 +775,13 @@ class Scrollbar(Widget, tkinter.Scrollbar): # type: ignore[misc] self, master: tkinter.Misc | None = None, *, - class_: str = ..., - command: Callable[..., tuple[float, float] | None] | str = ..., - cursor: tkinter._Cursor = ..., + class_: str = "", + command: Callable[..., tuple[float, float] | None] | str = "", + cursor: tkinter._Cursor = "", name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., + orient: Literal["horizontal", "vertical"] = "vertical", + style: str = "", + takefocus: tkinter._TakeFocusValue = "", ) -> None: ... @overload # type: ignore[override] def configure( @@ -814,12 +816,12 @@ class Separator(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - cursor: tkinter._Cursor = ..., + class_: str = "", + cursor: tkinter._Cursor = "", name: str = ..., - orient: Literal["horizontal", "vertical"] = ..., - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., + orient: Literal["horizontal", "vertical"] = "horizontal", + style: str = "", + takefocus: tkinter._TakeFocusValue = "", ) -> None: ... @overload def configure( @@ -840,11 +842,11 @@ class Sizegrip(Widget): self, master: tkinter.Misc | None = None, *, - class_: str = ..., + class_: str = "", cursor: tkinter._Cursor = ..., name: str = ..., - style: str = ..., - takefocus: tkinter._TakeFocusValue = ..., + style: str = "", + takefocus: tkinter._TakeFocusValue = "", ) -> None: ... @overload def configure( @@ -865,30 +867,30 @@ class Spinbox(Entry): master: tkinter.Misc | None = None, *, background: str = ..., # undocumented - class_: str = ..., - command: Callable[[], object] | str | list[str] | tuple[str, ...] = ..., - cursor: tkinter._Cursor = ..., + class_: str = "", + command: Callable[[], object] | str | list[str] | tuple[str, ...] = "", + cursor: tkinter._Cursor = "", exportselection: bool = ..., # undocumented font: _FontDescription = ..., # undocumented foreground: str = ..., # undocumented - format: str = ..., - from_: float = ..., - increment: float = ..., + format: str = "", + from_: float = 0, + increment: float = 1, invalidcommand: tkinter._EntryValidateCommand = ..., # undocumented justify: Literal["left", "center", "right"] = ..., # undocumented name: str = ..., show=..., # undocumented - state: str = ..., - style: str = ..., + state: str = "normal", + style: str = "", takefocus: tkinter._TakeFocusValue = ..., textvariable: tkinter.Variable = ..., # undocumented - to: float = ..., - validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., - validatecommand: tkinter._EntryValidateCommand = ..., + to: float = 0, + validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = "none", + validatecommand: tkinter._EntryValidateCommand = "", values: list[str] | tuple[str, ...] = ..., width: int = ..., # undocumented - wrap: bool = ..., - xscrollcommand: tkinter._XYScrollCommand = ..., + wrap: bool = False, + xscrollcommand: tkinter._XYScrollCommand = "", ) -> None: ... @overload # type: ignore[override] def configure( @@ -957,23 +959,23 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): self, master: tkinter.Misc | None = None, *, - class_: str = ..., - columns: str | list[str] | list[int] | list[str | int] | tuple[str | int, ...] = ..., - cursor: tkinter._Cursor = ..., - displaycolumns: str | int | list[str] | tuple[str, ...] | list[int] | tuple[int, ...] = ..., - height: int = ..., + class_: str = "", + columns: str | list[str] | list[int] | list[str | int] | tuple[str | int, ...] = "", + cursor: tkinter._Cursor = "", + displaycolumns: str | int | list[str] | tuple[str, ...] | list[int] | tuple[int, ...] = ("#all",), + height: int = 10, name: str = ..., padding: _Padding = ..., - selectmode: Literal["extended", "browse", "none"] = ..., + selectmode: Literal["extended", "browse", "none"] = "extended", # list/tuple of Literal don't actually work in mypy # # 'tree headings' is same as ['tree', 'headings'], and I wouldn't be # surprised if someone is using it. - show: Literal["tree", "headings", "tree headings", ""] | list[str] | tuple[str, ...] = ..., - style: str = ..., + show: Literal["tree", "headings", "tree headings", ""] | list[str] | tuple[str, ...] = ("tree", "headings"), + style: str = "", takefocus: tkinter._TakeFocusValue = ..., - xscrollcommand: tkinter._XYScrollCommand = ..., - yscrollcommand: tkinter._XYScrollCommand = ..., + xscrollcommand: tkinter._XYScrollCommand = "", + yscrollcommand: tkinter._XYScrollCommand = "", ) -> None: ... @overload def configure( @@ -1158,9 +1160,10 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): def tag_has(self, tagname: str, item: str | int) -> bool: ... class LabeledScale(Frame): - label: Incomplete - scale: Incomplete - # TODO: don't any-type **kw. That goes to Frame.__init__. + label: Label + scale: Scale + # This should be kept in sync with tkinter.ttk.Frame.__init__() + # (all the keyword-only args except compound are from there) def __init__( self, master: tkinter.Misc | None = None, @@ -1168,8 +1171,18 @@ class LabeledScale(Frame): from_: float = 0, to: float = 10, *, - compound: Literal["top", "bottom"] = ..., - **kw, + border: tkinter._ScreenUnits = ..., + borderwidth: tkinter._ScreenUnits = ..., + class_: str = "", + compound: Literal["top", "bottom"] = "top", + cursor: tkinter._Cursor = "", + height: tkinter._ScreenUnits = 0, + name: str = ..., + padding: _Padding = ..., + relief: tkinter._Relief = ..., + style: str = "", + takefocus: tkinter._TakeFocusValue = "", + width: tkinter._ScreenUnits = 0, ) -> None: ... # destroy is overridden, signature does not change value: Any @@ -1177,15 +1190,15 @@ class LabeledScale(Frame): class OptionMenu(Menubutton): def __init__( self, - master, - variable, + master: tkinter.Misc | None, + variable: tkinter.StringVar, default: str | None = None, *values: str, # rest of these are keyword-only because *args syntax used above - style: str = ..., - direction: Literal["above", "below", "left", "right", "flush"] = ..., - command: Callable[[tkinter.StringVar], object] | None = ..., + style: str = "", + direction: Literal["above", "below", "left", "right", "flush"] = "below", + command: Callable[[tkinter.StringVar], object] | None = None, ) -> None: ... # configure, config, cget, destroy are inherited from Menubutton # destroy and __setitem__ are overridden, signature does not change - def set_menu(self, default: Incomplete | None = None, *values) -> None: ... + def set_menu(self, default: str | None = None, *values: str) -> None: ... diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 9fef9d3922f5..5d01be539016 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -273,6 +273,7 @@ if sys.version_info >= (3, 10): def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... + Concatenate: _SpecialForm TypeAlias: _SpecialForm TypeGuard: _SpecialForm @@ -864,6 +865,7 @@ class NamedTuple(tuple[Any, ...]): # So we only add it to the stub on 3.12+. if sys.version_info >= (3, 12): __orig_bases__: ClassVar[tuple[Any, ...]] + @overload def __init__(self, __typename: str, __fields: Iterable[tuple[str, Any]]) -> None: ... @overload @@ -885,6 +887,7 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): # so we only add it to the stub on 3.12+ if sys.version_info >= (3, 12): __orig_bases__: ClassVar[tuple[Any, ...]] + def copy(self) -> typing_extensions.Self: ... # Using Never so that only calls using mypy plugin hook that specialize the signature # can go through. diff --git a/mypy/typeshed/stdlib/unicodedata.pyi b/mypy/typeshed/stdlib/unicodedata.pyi index 35ab6d609a19..5c6749c8a1ae 100644 --- a/mypy/typeshed/stdlib/unicodedata.pyi +++ b/mypy/typeshed/stdlib/unicodedata.pyi @@ -11,6 +11,8 @@ if sys.version_info < (3, 10): _T = TypeVar("_T") +_NormalizationForm: TypeAlias = Literal["NFC", "NFD", "NFKC", "NFKD"] + def bidirectional(__chr: str) -> str: ... def category(__chr: str) -> str: ... def combining(__chr: str) -> int: ... @@ -27,14 +29,14 @@ def digit(__chr: str, __default: _T) -> int | _T: ... _EastAsianWidth: TypeAlias = Literal["F", "H", "W", "Na", "A", "N"] def east_asian_width(__chr: str) -> _EastAsianWidth: ... -def is_normalized(__form: str, __unistr: str) -> bool: ... +def is_normalized(__form: _NormalizationForm, __unistr: str) -> bool: ... def lookup(__name: str | ReadOnlyBuffer) -> str: ... def mirrored(__chr: str) -> int: ... @overload def name(__chr: str) -> str: ... @overload def name(__chr: str, __default: _T) -> str | _T: ... -def normalize(__form: str, __unistr: str) -> str: ... +def normalize(__form: _NormalizationForm, __unistr: str) -> str: ... @overload def numeric(__chr: str) -> float: ... @overload @@ -57,14 +59,14 @@ class UCD: @overload def digit(self, __chr: str, __default: _T) -> int | _T: ... def east_asian_width(self, __chr: str) -> _EastAsianWidth: ... - def is_normalized(self, __form: str, __unistr: str) -> bool: ... + def is_normalized(self, __form: _NormalizationForm, __unistr: str) -> bool: ... def lookup(self, __name: str | ReadOnlyBuffer) -> str: ... def mirrored(self, __chr: str) -> int: ... @overload def name(self, __chr: str) -> str: ... @overload def name(self, __chr: str, __default: _T) -> str | _T: ... - def normalize(self, __form: str, __unistr: str) -> str: ... + def normalize(self, __form: _NormalizationForm, __unistr: str) -> str: ... @overload def numeric(self, __chr: str) -> float: ... @overload diff --git a/mypy/typeshed/stdlib/unittest/result.pyi b/mypy/typeshed/stdlib/unittest/result.pyi index dfc505936f59..436fabf20c65 100644 --- a/mypy/typeshed/stdlib/unittest/result.pyi +++ b/mypy/typeshed/stdlib/unittest/result.pyi @@ -27,6 +27,7 @@ class TestResult: tb_locals: bool if sys.version_info >= (3, 12): collectedDurations: _DurationsType + def __init__(self, stream: TextIO | None = None, descriptions: bool | None = None, verbosity: int | None = None) -> None: ... def printErrors(self) -> None: ... def wasSuccessful(self) -> bool: ... From 2e5174c82317068645ec888c36902bd19ffcd49d Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:01:15 +0100 Subject: [PATCH 090/172] Add basic support for recursive TypeVar defaults (PEP 696) (#16878) Ref: https://github.com/python/mypy/issues/14851 --- mypy/applytype.py | 13 +++- mypy/expandtype.py | 9 +++ mypy/semanal.py | 9 +++ mypy/tvar_scope.py | 22 ++++++ mypy/typetraverser.py | 6 +- test-data/unit/check-typevar-defaults.test | 78 ++++++++++++++++++++++ 6 files changed, 133 insertions(+), 4 deletions(-) diff --git a/mypy/applytype.py b/mypy/applytype.py index b00372855d9c..e14906fa2772 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -147,7 +147,18 @@ def apply_generic_arguments( # TODO: move apply_poly() logic from checkexpr.py here when new inference # becomes universally used (i.e. in all passes + in unification). # With this new logic we can actually *add* some new free variables. - remaining_tvars = [tv for tv in tvars if tv.id not in id_to_type] + remaining_tvars: list[TypeVarLikeType] = [] + for tv in tvars: + if tv.id in id_to_type: + continue + if not tv.has_default(): + remaining_tvars.append(tv) + continue + # TypeVarLike isn't in id_to_type mapping. + # Only expand the TypeVar default here. + typ = expand_type(tv, id_to_type) + assert isinstance(typ, TypeVarLikeType) + remaining_tvars.append(typ) return callable.copy_modified( ret_type=expand_type(callable.ret_type, id_to_type), diff --git a/mypy/expandtype.py b/mypy/expandtype.py index d2d294fb77f3..3bf45854b2a0 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -179,6 +179,7 @@ class ExpandTypeVisitor(TrivialSyntheticTypeTranslator): def __init__(self, variables: Mapping[TypeVarId, Type]) -> None: self.variables = variables + self.recursive_tvar_guard: dict[TypeVarId, Type | None] = {} def visit_unbound_type(self, t: UnboundType) -> Type: return t @@ -226,6 +227,14 @@ def visit_type_var(self, t: TypeVarType) -> Type: # TODO: do we really need to do this? # If I try to remove this special-casing ~40 tests fail on reveal_type(). return repl.copy_modified(last_known_value=None) + if isinstance(repl, TypeVarType) and repl.has_default(): + if (tvar_id := repl.id) in self.recursive_tvar_guard: + return self.recursive_tvar_guard[tvar_id] or repl + self.recursive_tvar_guard[tvar_id] = None + repl = repl.accept(self) + if isinstance(repl, TypeVarType): + repl.default = repl.default.accept(self) + self.recursive_tvar_guard[tvar_id] = repl return repl def visit_param_spec(self, t: ParamSpecType) -> Type: diff --git a/mypy/semanal.py b/mypy/semanal.py index 4bf9f0c3eabb..aeceb644fe52 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1954,6 +1954,15 @@ class Foo(Bar, Generic[T]): ... del base_type_exprs[i] tvar_defs: list[TypeVarLikeType] = [] for name, tvar_expr in declared_tvars: + tvar_expr_default = tvar_expr.default + if isinstance(tvar_expr_default, UnboundType): + # TODO: - detect out of order and self-referencing TypeVars + # - nested default types, e.g. list[T1] + n = self.lookup_qualified( + tvar_expr_default.name, tvar_expr_default, suppress_errors=True + ) + if n is not None and (default := self.tvar_scope.get_binding(n)) is not None: + tvar_expr.default = default tvar_def = self.tvar_scope.bind_new(name, tvar_expr) tvar_defs.append(tvar_def) return base_type_exprs, tvar_defs, is_protocol diff --git a/mypy/tvar_scope.py b/mypy/tvar_scope.py index c7a653a1552d..4dc663df0399 100644 --- a/mypy/tvar_scope.py +++ b/mypy/tvar_scope.py @@ -15,6 +15,26 @@ TypeVarTupleType, TypeVarType, ) +from mypy.typetraverser import TypeTraverserVisitor + + +class TypeVarLikeNamespaceSetter(TypeTraverserVisitor): + """Set namespace for all TypeVarLikeTypes types.""" + + def __init__(self, namespace: str) -> None: + self.namespace = namespace + + def visit_type_var(self, t: TypeVarType) -> None: + t.id.namespace = self.namespace + super().visit_type_var(t) + + def visit_param_spec(self, t: ParamSpecType) -> None: + t.id.namespace = self.namespace + return super().visit_param_spec(t) + + def visit_type_var_tuple(self, t: TypeVarTupleType) -> None: + t.id.namespace = self.namespace + super().visit_type_var_tuple(t) class TypeVarLikeScope: @@ -88,6 +108,8 @@ def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType: i = self.func_id # TODO: Consider also using namespaces for functions namespace = "" + tvar_expr.default.accept(TypeVarLikeNamespaceSetter(namespace)) + if isinstance(tvar_expr, TypeVarExpr): tvar_def: TypeVarLikeType = TypeVarType( name=name, diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py index d9ab54871f4a..1ff5f6685eb8 100644 --- a/mypy/typetraverser.py +++ b/mypy/typetraverser.py @@ -61,16 +61,16 @@ def visit_type_var(self, t: TypeVarType) -> None: # Note that type variable values and upper bound aren't treated as # components, since they are components of the type variable # definition. We want to traverse everything just once. - pass + t.default.accept(self) def visit_param_spec(self, t: ParamSpecType) -> None: - pass + t.default.accept(self) def visit_parameters(self, t: Parameters) -> None: self.traverse_types(t.arg_types) def visit_type_var_tuple(self, t: TypeVarTupleType) -> None: - pass + t.default.accept(self) def visit_literal_type(self, t: LiteralType) -> None: t.fallback.accept(self) diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 544bc59494b3..1a08823cb692 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -349,6 +349,84 @@ def func_c4( reveal_type(m) # N: Revealed type is "__main__.ClassC4[builtins.int, builtins.float]" [builtins fixtures/tuple.pyi] +[case testTypeVarDefaultsClassRecursive1] +# flags: --disallow-any-generics +from typing import Generic, TypeVar + +T1 = TypeVar("T1", default=str) +T2 = TypeVar("T2", default=T1) +T3 = TypeVar("T3", default=T2) + +class ClassD1(Generic[T1, T2]): ... + +def func_d1( + a: ClassD1, + b: ClassD1[int], + c: ClassD1[int, float] +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassD1[builtins.str, builtins.str]" + reveal_type(b) # N: Revealed type is "__main__.ClassD1[builtins.int, builtins.int]" + reveal_type(c) # N: Revealed type is "__main__.ClassD1[builtins.int, builtins.float]" + + k = ClassD1() + reveal_type(k) # N: Revealed type is "__main__.ClassD1[builtins.str, builtins.str]" + l = ClassD1[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassD1[builtins.int, builtins.int]" + m = ClassD1[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassD1[builtins.int, builtins.float]" + +class ClassD2(Generic[T1, T2, T3]): ... + +def func_d2( + a: ClassD2, + b: ClassD2[int], + c: ClassD2[int, float], + d: ClassD2[int, float, str], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.str]" + reveal_type(b) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.int]" + reveal_type(c) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.float]" + reveal_type(d) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.str]" + + k = ClassD2() + reveal_type(k) # N: Revealed type is "__main__.ClassD2[builtins.str, builtins.str, builtins.str]" + l = ClassD2[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.int, builtins.int]" + m = ClassD2[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.float]" + n = ClassD2[int, float, str]() + reveal_type(n) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.str]" + +[case testTypeVarDefaultsClassRecursiveMultipleFiles] +# flags: --disallow-any-generics +from typing import Generic, TypeVar +from file2 import T as T2 + +T = TypeVar('T', default=T2) + +class ClassG1(Generic[T2, T]): + pass + +def func( + a: ClassG1, + b: ClassG1[str], + c: ClassG1[str, float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassG1[builtins.int, builtins.int]" + reveal_type(b) # N: Revealed type is "__main__.ClassG1[builtins.str, builtins.str]" + reveal_type(c) # N: Revealed type is "__main__.ClassG1[builtins.str, builtins.float]" + + k = ClassG1() + reveal_type(k) # N: Revealed type is "__main__.ClassG1[builtins.int, builtins.int]" + l = ClassG1[str]() + reveal_type(l) # N: Revealed type is "__main__.ClassG1[builtins.str, builtins.str]" + m = ClassG1[str, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassG1[builtins.str, builtins.float]" + +[file file2.py] +from typing import TypeVar +T = TypeVar('T', default=int) + [case testTypeVarDefaultsTypeAlias1] # flags: --disallow-any-generics from typing import Any, Dict, List, Tuple, TypeVar, Union From bfbac5efbad32305b2948b82f95c9a8c34d44d34 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Fri, 16 Feb 2024 23:34:44 +0100 Subject: [PATCH 091/172] stubgen: Fix generated dataclass `__init__` signature (#16906) Fixes #16811 stubgen was swallowing default values for `__init__` methods generated by the dataclass plugin making their signature incorrect. This is because the plugin does not include the argument's initializer in the generated signature. I changed it to include a dummy ellipsis so that stubgen can generate correct code. I also fixed arguments added by the dataclass plugin with the invalid names `*` and `**` to have the valid and unique names `*generated_args` and `**generated_kwargs` (with extra underscores to make them unique if necessary). This removes the need for the hack to special case them in stubgen and is less confusing for someone looking at them in a stub file. --- mypy/plugins/dataclasses.py | 17 +++++++--- mypy/stubgen.py | 11 ------- test-data/unit/check-dataclasses.test | 6 ++++ test-data/unit/stubgen.test | 47 ++++++++++++++++++--------- 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index 685d1b342055..dead512a2202 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -24,6 +24,7 @@ Context, DataclassTransformSpec, Decorator, + EllipsisExpr, Expression, FuncDef, FuncItem, @@ -149,13 +150,13 @@ def to_argument( return Argument( variable=self.to_var(current_info), type_annotation=self.expand_type(current_info), - initializer=None, + initializer=EllipsisExpr() if self.has_default else None, # Only used by stubgen kind=arg_kind, ) def expand_type(self, current_info: TypeInfo) -> Type | None: if self.type is not None and self.info.self_type is not None: - # In general, it is not safe to call `expand_type()` during semantic analyzis, + # In general, it is not safe to call `expand_type()` during semantic analysis, # however this plugin is called very late, so all types should be fully ready. # Also, it is tricky to avoid eager expansion of Self types here (e.g. because # we serialize attributes). @@ -269,11 +270,17 @@ def transform(self) -> bool: if arg.kind == ARG_POS: arg.kind = ARG_OPT - nameless_var = Var("") + existing_args_names = {arg.variable.name for arg in args} + gen_args_name = "generated_args" + while gen_args_name in existing_args_names: + gen_args_name += "_" + gen_kwargs_name = "generated_kwargs" + while gen_kwargs_name in existing_args_names: + gen_kwargs_name += "_" args = [ - Argument(nameless_var, AnyType(TypeOfAny.explicit), None, ARG_STAR), + Argument(Var(gen_args_name), AnyType(TypeOfAny.explicit), None, ARG_STAR), *args, - Argument(nameless_var, AnyType(TypeOfAny.explicit), None, ARG_STAR2), + Argument(Var(gen_kwargs_name), AnyType(TypeOfAny.explicit), None, ARG_STAR2), ] add_method_to_class( diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 36e8bd2acfb4..279f0569174a 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -537,17 +537,6 @@ def _get_func_args(self, o: FuncDef, ctx: FunctionContext) -> list[ArgSig]: if new_args is not None: args = new_args - is_dataclass_generated = ( - self.analyzed and self.processing_dataclass and o.info.names[o.name].plugin_generated - ) - if o.name == "__init__" and is_dataclass_generated and "**" in [a.name for a in args]: - # The dataclass plugin generates invalid nameless "*" and "**" arguments - new_name = "".join(a.name.strip("*") for a in args) - for arg in args: - if arg.name == "*": - arg.name = f"*{new_name}_" # this name is guaranteed to be unique - elif arg.name == "**": - arg.name = f"**{new_name}__" # same here return args def _get_func_return(self, o: FuncDef, ctx: FunctionContext) -> str | None: diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index b57fe8f548c4..a055507cdd78 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1610,10 +1610,16 @@ B: Any @dataclass class A(B): a: int +@dataclass +class C(B): + generated_args: int + generated_kwargs: int A(a=1, b=2) A(1) A(a="foo") # E: Argument "a" to "A" has incompatible type "str"; expected "int" +C(generated_args="foo", generated_kwargs="bar") # E: Argument "generated_args" to "C" has incompatible type "str"; expected "int" \ + # E: Argument "generated_kwargs" to "C" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] [case testDataclassesCallableFrozen] diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index c56f6b40b74d..3503fd4ad808 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4083,20 +4083,21 @@ class W: ... class V: ... [case testDataclass_semanal] -from dataclasses import dataclass, InitVar +from dataclasses import InitVar, dataclass, field from typing import ClassVar @dataclass class X: a: int - b: str = "hello" - c: ClassVar - d: ClassVar = 200 + b: InitVar[str] + c: str = "hello" + d: ClassVar + e: ClassVar = 200 f: list[int] = field(init=False, default_factory=list) g: int = field(default=2, kw_only=True) h: int = 1 - i: InitVar[str] - j: InitVar = 100 + i: InitVar = 100 + j: list[int] = field(default_factory=list) non_field = None @dataclass(init=False, repr=False, frozen=True) @@ -4109,23 +4110,24 @@ from typing import ClassVar @dataclass class X: a: int - b: str = ... - c: ClassVar - d: ClassVar = ... + b: InitVar[str] + c: str = ... + d: ClassVar + e: ClassVar = ... f: list[int] = ... g: int = ... h: int = ... - i: InitVar[str] - j: InitVar = ... + i: InitVar = ... + j: list[int] = ... non_field = ... - def __init__(self, a, b, f, g, h, i, j) -> None: ... + def __init__(self, a, b, c=..., *, g=..., h=..., i=..., j=...) -> None: ... @dataclass(init=False, repr=False, frozen=True) class Y: ... [case testDataclassWithKwOnlyField_semanal] # flags: --python-version=3.10 -from dataclasses import dataclass, InitVar, KW_ONLY +from dataclasses import dataclass, field, InitVar, KW_ONLY from typing import ClassVar @dataclass @@ -4162,7 +4164,7 @@ class X: i: InitVar[str] j: InitVar = ... non_field = ... - def __init__(self, a, b, f, g, *, h, i, j) -> None: ... + def __init__(self, a, b=..., *, g=..., h=..., i, j=...) -> None: ... @dataclass(init=False, repr=False, frozen=True) class Y: ... @@ -4193,6 +4195,13 @@ import missing class X(missing.Base): a: int +@dataclass +class Y(missing.Base): + generated_args: str + generated_args_: str + generated_kwargs: float + generated_kwargs_: float + [out] import missing from dataclasses import dataclass @@ -4200,7 +4209,15 @@ from dataclasses import dataclass @dataclass class X(missing.Base): a: int - def __init__(self, *selfa_, a, **selfa__) -> None: ... + def __init__(self, *generated_args, a, **generated_kwargs) -> None: ... + +@dataclass +class Y(missing.Base): + generated_args: str + generated_args_: str + generated_kwargs: float + generated_kwargs_: float + def __init__(self, *generated_args__, generated_args, generated_args_, generated_kwargs, generated_kwargs_, **generated_kwargs__) -> None: ... [case testAlwaysUsePEP604Union] import typing From 17271e57cfce5c441c3e481d20b28ca7484db231 Mon Sep 17 00:00:00 2001 From: Edward Paget Date: Sat, 17 Feb 2024 17:32:11 -0600 Subject: [PATCH 092/172] Fix narrowing on match with function subject (#16503) Fixes #12998 mypy can't narrow match statements with functions subjects because the callexpr node is not a literal node. This adds a 'dummy' literal node that the match statement visitor can use to do the type narrowing. The python grammar describes the the match subject as a named expression so this uses that nameexpr node as it's literal. --------- Co-authored-by: hauntsaninja --- mypy/checker.py | 19 ++++++++++++++++--- test-data/unit/check-python310.test | 15 +++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 391f28e93b1d..56be3db3f9e7 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -5053,6 +5053,19 @@ def visit_continue_stmt(self, s: ContinueStmt) -> None: return def visit_match_stmt(self, s: MatchStmt) -> None: + named_subject: Expression + if isinstance(s.subject, CallExpr): + # Create a dummy subject expression to handle cases where a match statement's subject + # is not a literal value. This lets us correctly narrow types and check exhaustivity + # This is hack! + id = s.subject.callee.fullname if isinstance(s.subject.callee, RefExpr) else "" + name = "dummy-match-" + id + v = Var(name) + named_subject = NameExpr(name) + named_subject.node = v + else: + named_subject = s.subject + with self.binder.frame_context(can_skip=False, fall_through=0): subject_type = get_proper_type(self.expr_checker.accept(s.subject)) @@ -5071,7 +5084,7 @@ def visit_match_stmt(self, s: MatchStmt) -> None: # The second pass narrows down the types and type checks bodies. for p, g, b in zip(s.patterns, s.guards, s.bodies): current_subject_type = self.expr_checker.narrow_type_from_binder( - s.subject, subject_type + named_subject, subject_type ) pattern_type = self.pattern_checker.accept(p, current_subject_type) with self.binder.frame_context(can_skip=True, fall_through=2): @@ -5082,7 +5095,7 @@ def visit_match_stmt(self, s: MatchStmt) -> None: else_map: TypeMap = {} else: pattern_map, else_map = conditional_types_to_typemaps( - s.subject, pattern_type.type, pattern_type.rest_type + named_subject, pattern_type.type, pattern_type.rest_type ) self.remove_capture_conflicts(pattern_type.captures, inferred_types) self.push_type_map(pattern_map) @@ -5110,7 +5123,7 @@ def visit_match_stmt(self, s: MatchStmt) -> None: and expr.fullname == case_target.fullname ): continue - type_map[s.subject] = type_map[expr] + type_map[named_subject] = type_map[expr] self.push_type_map(guard_map) self.accept(b) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index cbb26a130738..b0e27fe1e3a0 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1139,6 +1139,21 @@ match m: reveal_type(a) # N: Revealed type is "builtins.str" +[case testMatchCapturePatternFromFunctionReturningUnion] +def func1(arg: bool) -> str | int: ... +def func2(arg: bool) -> bytes | int: ... + +def main() -> None: + match func1(True): + case str(a): + match func2(True): + case c: + reveal_type(a) # N: Revealed type is "builtins.str" + reveal_type(c) # N: Revealed type is "Union[builtins.bytes, builtins.int]" + reveal_type(a) # N: Revealed type is "builtins.str" + case a: + reveal_type(a) # N: Revealed type is "builtins.int" + -- Guards -- [case testMatchSimplePatternGuard] From eb84794bd02b20e051103f91b6d1dcb01c0e342c Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sun, 18 Feb 2024 13:33:59 +0000 Subject: [PATCH 093/172] FIx stubtest's tests to work with the latest version of `typing_extensions` (#16928) Stubtest's tests will start failing when `typing_extensions==4.10.0` comes out, due to some new `ClassVar`s on `typing_extensions.TypedDict`. This PR fixes that. Fixes https://github.com/python/typing_extensions/issues/339. Note: there's no need to cherry-pick this to the `release-1.9.0` branch, since the daily workflow `typing_extensions` uses runs mypy's tests using the mypy `master` branch. --- test-data/unit/lib-stub/typing_extensions.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 7aca6fad1b42..68dd985cfe2a 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -61,6 +61,8 @@ class _TypedDict(Mapping[str, object]): __optional_keys__: frozenset[str] __readonly_keys__: frozenset[str] __mutable_keys__: frozenset[str] + __closed__: bool + __extra_items__: Any __total__: bool def TypedDict(typename: str, fields: Dict[str, Type[_T]], *, total: Any = ...) -> Type[dict]: ... From 46ebacae0ca5b464a7d422ac1e3370cae32c135a Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 18 Feb 2024 22:32:19 +0100 Subject: [PATCH 094/172] stubgen: Replace obsolete typing aliases with builtin containers (#16780) Addresses part of #16737 This only replaces typing symbols that have equivalents in the `builtins` module. Replacing other symbols, like those from the `collections.abc` module, are a bit more complicated so I suggest we handle them separately. I also changed the default `TypedDict` module from `typing_extensions` to `typing` as typeshed dropped support for Python 3.7. --- mypy/stubgen.py | 51 ++++++---- mypy/stubutil.py | 33 ++++++- .../pybind11_fixtures/__init__.pyi | 6 +- .../pybind11_fixtures/demo.pyi | 4 +- .../pybind11_fixtures/__init__.pyi | 6 +- .../pybind11_fixtures/demo.pyi | 4 +- test-data/unit/stubgen.test | 94 +++++++++++++++---- 7 files changed, 148 insertions(+), 50 deletions(-) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 279f0569174a..7721366f5c0c 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -47,7 +47,7 @@ import os.path import sys import traceback -from typing import Final, Iterable +from typing import Final, Iterable, Iterator import mypy.build import mypy.mixedtraverser @@ -114,6 +114,7 @@ from mypy.stubdoc import ArgSig, FunctionSig from mypy.stubgenc import InspectionStubGenerator, generate_stub_for_c_module from mypy.stubutil import ( + TYPING_BUILTIN_REPLACEMENTS, BaseStubGenerator, CantImport, ClassInfo, @@ -289,20 +290,19 @@ def visit_call_expr(self, node: CallExpr) -> str: raise ValueError(f"Unknown argument kind {kind} in call") return f"{callee}({', '.join(args)})" + def _visit_ref_expr(self, node: NameExpr | MemberExpr) -> str: + fullname = self.stubgen.get_fullname(node) + if fullname in TYPING_BUILTIN_REPLACEMENTS: + return self.stubgen.add_name(TYPING_BUILTIN_REPLACEMENTS[fullname], require=False) + qualname = get_qualified_name(node) + self.stubgen.import_tracker.require_name(qualname) + return qualname + def visit_name_expr(self, node: NameExpr) -> str: - self.stubgen.import_tracker.require_name(node.name) - return node.name + return self._visit_ref_expr(node) def visit_member_expr(self, o: MemberExpr) -> str: - node: Expression = o - trailer = "" - while isinstance(node, MemberExpr): - trailer = "." + node.name + trailer - node = node.expr - if not isinstance(node, NameExpr): - return ERROR_MARKER - self.stubgen.import_tracker.require_name(node.name) - return node.name + trailer + return self._visit_ref_expr(o) def visit_str_expr(self, node: StrExpr) -> str: return repr(node.value) @@ -351,11 +351,17 @@ def find_defined_names(file: MypyFile) -> set[str]: return finder.names +def get_assigned_names(lvalues: Iterable[Expression]) -> Iterator[str]: + for lvalue in lvalues: + if isinstance(lvalue, NameExpr): + yield lvalue.name + elif isinstance(lvalue, TupleExpr): + yield from get_assigned_names(lvalue.items) + + class DefinitionFinder(mypy.traverser.TraverserVisitor): """Find names of things defined at the top level of a module.""" - # TODO: Assignment statements etc. - def __init__(self) -> None: # Short names of things defined at the top level. self.names: set[str] = set() @@ -368,6 +374,10 @@ def visit_func_def(self, o: FuncDef) -> None: # Don't recurse, as we only keep track of top-level definitions. self.names.add(o.name) + def visit_assignment_stmt(self, o: AssignmentStmt) -> None: + for name in get_assigned_names(o.lvalues): + self.names.add(name) + def find_referenced_names(file: MypyFile) -> set[str]: finder = ReferenceFinder() @@ -1023,10 +1033,15 @@ def is_alias_expression(self, expr: Expression, top_level: bool = True) -> bool: and isinstance(expr.node, (FuncDef, Decorator, MypyFile)) or isinstance(expr.node, TypeInfo) ) and not self.is_private_member(expr.node.fullname) - elif ( - isinstance(expr, IndexExpr) - and isinstance(expr.base, NameExpr) - and not self.is_private_name(expr.base.name) + elif isinstance(expr, IndexExpr) and ( + (isinstance(expr.base, NameExpr) and not self.is_private_name(expr.base.name)) + or ( # Also some known aliases that could be member expression + isinstance(expr.base, MemberExpr) + and not self.is_private_member(get_qualified_name(expr.base)) + and self.get_fullname(expr.base).startswith( + ("builtins.", "typing.", "typing_extensions.", "collections.abc.") + ) + ) ): if isinstance(expr.index, TupleExpr): indices = expr.index.items diff --git a/mypy/stubutil.py b/mypy/stubutil.py index 69af643efab2..410672f89d09 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -22,6 +22,26 @@ # Modules that may fail when imported, or that may have side effects (fully qualified). NOT_IMPORTABLE_MODULES = () +# Typing constructs to be replaced by their builtin equivalents. +TYPING_BUILTIN_REPLACEMENTS: Final = { + # From typing + "typing.Text": "builtins.str", + "typing.Tuple": "builtins.tuple", + "typing.List": "builtins.list", + "typing.Dict": "builtins.dict", + "typing.Set": "builtins.set", + "typing.FrozenSet": "builtins.frozenset", + "typing.Type": "builtins.type", + # From typing_extensions + "typing_extensions.Text": "builtins.str", + "typing_extensions.Tuple": "builtins.tuple", + "typing_extensions.List": "builtins.list", + "typing_extensions.Dict": "builtins.dict", + "typing_extensions.Set": "builtins.set", + "typing_extensions.FrozenSet": "builtins.frozenset", + "typing_extensions.Type": "builtins.type", +} + class CantImport(Exception): def __init__(self, module: str, message: str) -> None: @@ -229,6 +249,8 @@ def visit_unbound_type(self, t: UnboundType) -> str: return " | ".join([item.accept(self) for item in t.args]) if fullname == "typing.Optional": return f"{t.args[0].accept(self)} | None" + if fullname in TYPING_BUILTIN_REPLACEMENTS: + s = self.stubgen.add_name(TYPING_BUILTIN_REPLACEMENTS[fullname], require=True) 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". @@ -476,7 +498,7 @@ def reexport(self, name: str) -> None: def import_lines(self) -> list[str]: """The list of required import lines (as strings with python code). - In order for a module be included in this output, an indentifier must be both + In order for a module be included in this output, an identifier must be both 'required' via require_name() and 'imported' via add_import_from() or add_import() """ @@ -585,9 +607,9 @@ def __init__( # a corresponding import statement. self.known_imports = { "_typeshed": ["Incomplete"], - "typing": ["Any", "TypeVar", "NamedTuple"], + "typing": ["Any", "TypeVar", "NamedTuple", "TypedDict"], "collections.abc": ["Generator"], - "typing_extensions": ["TypedDict", "ParamSpec", "TypeVarTuple"], + "typing_extensions": ["ParamSpec", "TypeVarTuple"], } def get_sig_generators(self) -> list[SignatureGenerator]: @@ -613,7 +635,10 @@ def add_name(self, fullname: str, require: bool = True) -> str: """ module, name = fullname.rsplit(".", 1) alias = "_" + name if name in self.defined_names else None - self.import_tracker.add_import_from(module, [(name, alias)], require=require) + while alias in self.defined_names: + alias = "_" + alias + if module != "builtins" or alias: # don't import from builtins unless needed + self.import_tracker.add_import_from(module, [(name, alias)], require=require) return alias or name def add_import_line(self, line: str) -> None: 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 bb939aa5a5e7..90afb46d6d94 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, Tuple, overload +from typing import overload class StaticMethods: def __init__(self, *args, **kwargs) -> None: ... @@ -22,6 +22,6 @@ class TestStruct: def func_incomplete_signature(*args, **kwargs): ... def func_returning_optional() -> int | None: ... -def func_returning_pair() -> Tuple[int, float]: ... +def func_returning_pair() -> tuple[int, float]: ... def func_returning_path() -> os.PathLike: ... -def func_returning_vector() -> List[float]: ... +def func_returning_vector() -> list[float]: ... diff --git a/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi index 6f164a03edcc..87b8ec0e4ad6 100644 --- a/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_no_docs/pybind11_fixtures/demo.pyi @@ -1,4 +1,4 @@ -from typing import ClassVar, List, overload +from typing import ClassVar, overload PI: float __version__: str @@ -47,7 +47,7 @@ class Point: def __init__(self) -> None: ... @overload def __init__(self, x: float, y: float) -> None: ... - def as_list(self) -> List[float]: ... + def as_list(self) -> list[float]: ... @overload def distance_to(self, x: float, y: float) -> float: ... @overload 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 622e5881a147..db04bccab028 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, Tuple, overload +from typing import overload class StaticMethods: def __init__(self, *args, **kwargs) -> None: @@ -44,9 +44,9 @@ def func_incomplete_signature(*args, **kwargs): """func_incomplete_signature() -> dummy_sub_namespace::HasNoBinding""" def func_returning_optional() -> int | None: """func_returning_optional() -> Optional[int]""" -def func_returning_pair() -> Tuple[int, float]: +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]: +def func_returning_vector() -> list[float]: """func_returning_vector() -> List[float]""" diff --git a/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi index 1527225ed009..1be0bc905a43 100644 --- a/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi +++ b/test-data/pybind11_fixtures/expected_stubs_with_docs/pybind11_fixtures/demo.pyi @@ -1,4 +1,4 @@ -from typing import ClassVar, List, overload +from typing import ClassVar, overload PI: float __version__: str @@ -73,7 +73,7 @@ class Point: 2. __init__(self: pybind11_fixtures.demo.Point, x: float, y: float) -> None """ - def as_list(self) -> List[float]: + def as_list(self) -> list[float]: """as_list(self: pybind11_fixtures.demo.Point) -> List[float]""" @overload def distance_to(self, x: float, y: float) -> float: diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 3503fd4ad808..53baa2c0ca06 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -1376,9 +1376,8 @@ x: List[collections.defaultdict] [out] import collections -from typing import List -x: List[collections.defaultdict] +x: list[collections.defaultdict] [case testAnnotationFwRefs] @@ -2216,9 +2215,9 @@ funcs: Dict[Any, Any] f = funcs[a.f] [out] from _typeshed import Incomplete -from typing import Any, Dict +from typing import Any -funcs: Dict[Any, Any] +funcs: dict[Any, Any] f: Incomplete [case testAbstractMethodNameExpr] @@ -3290,18 +3289,18 @@ def f(*args: Union[int, Tuple[int, int]]) -> int: [out] -from typing import Tuple, overload +from typing import overload class A: @overload def f(self, x: int, y: int) -> int: ... @overload - def f(self, x: Tuple[int, int]) -> int: ... + def f(self, x: tuple[int, int]) -> int: ... @overload def f(x: int, y: int) -> int: ... @overload -def f(x: Tuple[int, int]) -> int: ... +def f(x: tuple[int, int]) -> int: ... [case testOverload_fromTypingExtensionsImport] from typing import Tuple, Union @@ -3332,19 +3331,18 @@ def f(*args: Union[int, Tuple[int, int]]) -> int: [out] -from typing import Tuple from typing_extensions import overload class A: @overload def f(self, x: int, y: int) -> int: ... @overload - def f(self, x: Tuple[int, int]) -> int: ... + def f(self, x: tuple[int, int]) -> int: ... @overload def f(x: int, y: int) -> int: ... @overload -def f(x: Tuple[int, int]) -> int: ... +def f(x: tuple[int, int]) -> int: ... [case testOverload_importTyping] import typing @@ -3407,22 +3405,22 @@ class A: @typing.overload def f(self, x: int, y: int) -> int: ... @typing.overload - def f(self, x: typing.Tuple[int, int]) -> int: ... + def f(self, x: tuple[int, int]) -> int: ... @typing.overload @classmethod def g(cls, x: int, y: int) -> int: ... @typing.overload @classmethod - def g(cls, x: typing.Tuple[int, int]) -> int: ... + def g(cls, x: tuple[int, int]) -> int: ... @typing.overload def f(x: int, y: int) -> int: ... @typing.overload -def f(x: typing.Tuple[int, int]) -> int: ... +def f(x: tuple[int, int]) -> int: ... @typing_extensions.overload def g(x: int, y: int) -> int: ... @typing_extensions.overload -def g(x: typing.Tuple[int, int]) -> int: ... +def g(x: tuple[int, int]) -> int: ... [case testOverload_importTypingAs] import typing as t @@ -3485,22 +3483,22 @@ class A: @t.overload def f(self, x: int, y: int) -> int: ... @t.overload - def f(self, x: t.Tuple[int, int]) -> int: ... + def f(self, x: tuple[int, int]) -> int: ... @t.overload @classmethod def g(cls, x: int, y: int) -> int: ... @t.overload @classmethod - def g(cls, x: t.Tuple[int, int]) -> int: ... + def g(cls, x: tuple[int, int]) -> int: ... @t.overload def f(x: int, y: int) -> int: ... @t.overload -def f(x: t.Tuple[int, int]) -> int: ... +def f(x: tuple[int, int]) -> int: ... @te.overload def g(x: int, y: int) -> int: ... @te.overload -def g(x: t.Tuple[int, int]) -> int: ... +def g(x: tuple[int, int]) -> int: ... [case testOverloadFromImportAlias] from typing import overload as t_overload @@ -4249,6 +4247,66 @@ o = int | None def f1(a: int | tuple[int, int | None] | None) -> int: ... def f2(a: int | x.Union[int, int] | float | None) -> int: ... +[case testTypingBuiltinReplacements] +import typing +import typing as t +from typing import Tuple +import typing_extensions +import typing_extensions as te +from typing_extensions import List, Type + +# builtins are not builtins +tuple = int +[list,] = float +dict, set, frozenset = str, float, int + +x: Tuple[t.Text, t.FrozenSet[typing.Type[float]]] +y: typing.List[int] +z: t.Dict[str, float] +v: typing.Set[int] +w: List[typing_extensions.Dict[te.FrozenSet[Type[int]], te.Tuple[te.Set[te.Text], ...]]] + +x_alias = Tuple[str, ...] +y_alias = typing.List[int] +z_alias = t.Dict[str, float] +v_alias = typing.Set[int] +w_alias = List[typing_extensions.Dict[str, te.Tuple[int, ...]]] + +[out] +from _typeshed import Incomplete +from builtins import dict as _dict, frozenset as _frozenset, list as _list, set as _set, tuple as _tuple + +tuple = int +list: Incomplete +dict: Incomplete +set: Incomplete +frozenset: Incomplete +x: _tuple[str, _frozenset[type[float]]] +y: _list[int] +z: _dict[str, float] +v: _set[int] +w: _list[_dict[_frozenset[type[int]], _tuple[_set[str], ...]]] +x_alias = _tuple[str, ...] +y_alias = _list[int] +z_alias = _dict[str, float] +v_alias = _set[int] +w_alias = _list[_dict[str, _tuple[int, ...]]] + +[case testHandlingNameCollisions] +# flags: --include-private +from typing import Tuple +tuple = int +_tuple = range +__tuple = map +x: Tuple[int, str] +[out] +from builtins import tuple as ___tuple + +tuple = int +_tuple = range +__tuple = map +x: ___tuple[int, str] + [case testPEP570PosOnlyParams] def f(x=0, /): ... def f1(x: int, /): ... From 790e8a73d8671a41cae419b4ea07579bfb2bc292 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Tue, 20 Feb 2024 01:02:49 +0100 Subject: [PATCH 095/172] Error handling for recursive TypeVar defaults (PEP 696) (#16925) This PR adds some additional error handling for recursive TypeVar defaults. Open issue for future PRs: - Expanding nested recursive defaults, e.g. `T2 = list[T1 = str]` - Scope binding, especially for TypeAliasTypes Ref: https://github.com/python/mypy/issues/14851 --- mypy/messages.py | 9 ++ mypy/semanal.py | 47 ++++++-- mypy/typeanal.py | 36 +++++- mypy/types.py | 9 ++ test-data/unit/check-typevar-defaults.test | 134 ++++++++++++++++++++- 5 files changed, 223 insertions(+), 12 deletions(-) diff --git a/mypy/messages.py b/mypy/messages.py index c107e874f4fc..db6c91ba9008 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2059,6 +2059,15 @@ def impossible_intersection( template.format(formatted_base_class_list, reason), context, code=codes.UNREACHABLE ) + def tvar_without_default_type( + self, tvar_name: str, last_tvar_name_with_default: str, context: Context + ) -> None: + self.fail( + f'"{tvar_name}" cannot appear after "{last_tvar_name_with_default}" ' + "in type parameter list because it has no default type", + context, + ) + def report_protocol_problems( self, subtype: Instance | TupleType | TypedDictType | TypeType | CallableType, diff --git a/mypy/semanal.py b/mypy/semanal.py index aeceb644fe52..38d5ddec0818 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -226,6 +226,7 @@ SELF_TYPE_NAMES, FindTypeVarVisitor, TypeAnalyser, + TypeVarDefaultTranslator, TypeVarLikeList, analyze_type_alias, check_for_explicit_any, @@ -252,6 +253,7 @@ TPDICT_NAMES, TYPE_ALIAS_NAMES, TYPE_CHECK_ONLY_NAMES, + TYPE_VAR_LIKE_NAMES, TYPED_NAMEDTUPLE_NAMES, AnyType, CallableType, @@ -1953,17 +1955,19 @@ class Foo(Bar, Generic[T]): ... defn.removed_base_type_exprs.append(defn.base_type_exprs[i]) del base_type_exprs[i] tvar_defs: list[TypeVarLikeType] = [] + last_tvar_name_with_default: str | None = None for name, tvar_expr in declared_tvars: - tvar_expr_default = tvar_expr.default - if isinstance(tvar_expr_default, UnboundType): - # TODO: - detect out of order and self-referencing TypeVars - # - nested default types, e.g. list[T1] - n = self.lookup_qualified( - tvar_expr_default.name, tvar_expr_default, suppress_errors=True - ) - if n is not None and (default := self.tvar_scope.get_binding(n)) is not None: - tvar_expr.default = default + tvar_expr.default = tvar_expr.default.accept( + TypeVarDefaultTranslator(self, tvar_expr.name, context) + ) tvar_def = self.tvar_scope.bind_new(name, tvar_expr) + if last_tvar_name_with_default is not None and not tvar_def.has_default(): + self.msg.tvar_without_default_type( + tvar_def.name, last_tvar_name_with_default, context + ) + tvar_def.default = AnyType(TypeOfAny.from_error) + elif tvar_def.has_default(): + last_tvar_name_with_default = tvar_def.name tvar_defs.append(tvar_def) return base_type_exprs, tvar_defs, is_protocol @@ -2855,6 +2859,10 @@ def visit_assignment_stmt(self, s: AssignmentStmt) -> None: with self.allow_unbound_tvars_set(): s.rvalue.accept(self) self.basic_type_applications = old_basic_type_applications + elif self.can_possibly_be_typevarlike_declaration(s): + # Allow unbound tvars inside TypeVarLike defaults to be evaluated later + with self.allow_unbound_tvars_set(): + s.rvalue.accept(self) else: s.rvalue.accept(self) @@ -3031,6 +3039,16 @@ def can_possibly_be_type_form(self, s: AssignmentStmt) -> bool: # Something that looks like Foo = Bar[Baz, ...] return True + def can_possibly_be_typevarlike_declaration(self, s: AssignmentStmt) -> bool: + """Check if r.h.s. can be a TypeVarLike declaration.""" + if len(s.lvalues) != 1 or not isinstance(s.lvalues[0], NameExpr): + return False + if not isinstance(s.rvalue, CallExpr) or not isinstance(s.rvalue.callee, NameExpr): + return False + ref = s.rvalue.callee + ref.accept(self) + return ref.fullname in TYPE_VAR_LIKE_NAMES + def is_type_ref(self, rv: Expression, bare: bool = False) -> bool: """Does this expression refer to a type? @@ -3515,9 +3533,20 @@ def analyze_alias( found_type_vars = self.find_type_var_likes(typ) tvar_defs: list[TypeVarLikeType] = [] namespace = self.qualified_name(name) + last_tvar_name_with_default: str | None = None with self.tvar_scope_frame(self.tvar_scope.class_frame(namespace)): for name, tvar_expr in found_type_vars: + tvar_expr.default = tvar_expr.default.accept( + TypeVarDefaultTranslator(self, tvar_expr.name, typ) + ) tvar_def = self.tvar_scope.bind_new(name, tvar_expr) + if last_tvar_name_with_default is not None and not tvar_def.has_default(): + self.msg.tvar_without_default_type( + tvar_def.name, last_tvar_name_with_default, typ + ) + tvar_def.default = AnyType(TypeOfAny.from_error) + elif tvar_def.has_default(): + last_tvar_name_with_default = tvar_def.name tvar_defs.append(tvar_def) analyzed, depends_on = analyze_type_alias( diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 530793730f35..9cc0114df333 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -38,7 +38,12 @@ ) from mypy.options import Options from mypy.plugin import AnalyzeTypeContext, Plugin, TypeAnalyzerPluginInterface -from mypy.semanal_shared import SemanticAnalyzerCoreInterface, paramspec_args, paramspec_kwargs +from mypy.semanal_shared import ( + SemanticAnalyzerCoreInterface, + SemanticAnalyzerInterface, + paramspec_args, + paramspec_kwargs, +) from mypy.state import state from mypy.tvar_scope import TypeVarLikeScope from mypy.types import ( @@ -2508,3 +2513,32 @@ def process_types(self, types: list[Type] | tuple[Type, ...]) -> None: else: for t in types: t.accept(self) + + +class TypeVarDefaultTranslator(TrivialSyntheticTypeTranslator): + """Type translate visitor that replaces UnboundTypes with in-scope TypeVars.""" + + def __init__( + self, api: SemanticAnalyzerInterface, tvar_expr_name: str, context: Context + ) -> None: + self.api = api + self.tvar_expr_name = tvar_expr_name + self.context = context + + def visit_unbound_type(self, t: UnboundType) -> Type: + sym = self.api.lookup_qualified(t.name, t, suppress_errors=True) + if sym is not None: + if type_var := self.api.tvar_scope.get_binding(sym): + return type_var + if isinstance(sym.node, TypeVarLikeExpr): + self.api.fail( + f'Type parameter "{self.tvar_expr_name}" has a default type ' + "that refers to one or more type variables that are out of scope", + self.context, + ) + return AnyType(TypeOfAny.from_error) + return super().visit_unbound_type(t) + + def visit_type_alias_type(self, t: TypeAliasType) -> Type: + # TypeAliasTypes are analyzed separately already, just return it + return t diff --git a/mypy/types.py b/mypy/types.py index b1119c9447e2..f76e35784d8f 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -85,6 +85,15 @@ TypeVisitor as TypeVisitor, ) +TYPE_VAR_LIKE_NAMES: Final = ( + "typing.TypeVar", + "typing_extensions.TypeVar", + "typing.ParamSpec", + "typing_extensions.ParamSpec", + "typing.TypeVarTuple", + "typing_extensions.TypeVarTuple", +) + TYPED_NAMEDTUPLE_NAMES: Final = ("typing.NamedTuple", "typing_extensions.NamedTuple") # Supported names of TypedDict type constructors. diff --git a/test-data/unit/check-typevar-defaults.test b/test-data/unit/check-typevar-defaults.test index 1a08823cb692..9ca67376da26 100644 --- a/test-data/unit/check-typevar-defaults.test +++ b/test-data/unit/check-typevar-defaults.test @@ -82,6 +82,74 @@ T3 = TypeVar("T3", int, str, default=bytes) # E: TypeVar default must be one of T4 = TypeVar("T4", int, str, default=Union[int, str]) # E: TypeVar default must be one of the constraint types T5 = TypeVar("T5", float, str, default=int) # E: TypeVar default must be one of the constraint types +[case testTypeVarDefaultsInvalid3] +from typing import Dict, Generic, TypeVar + +T1 = TypeVar("T1") +T2 = TypeVar("T2", default=T3) # E: Name "T3" is used before definition +T3 = TypeVar("T3", default=str) +T4 = TypeVar("T4", default=T3) + +class ClassError1(Generic[T3, T1]): ... # E: "T1" cannot appear after "T3" in type parameter list because it has no default type + +def func_error1( + a: ClassError1, + b: ClassError1[int], + c: ClassError1[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassError1[builtins.str, Any]" + reveal_type(b) # N: Revealed type is "__main__.ClassError1[builtins.int, Any]" + reveal_type(c) # N: Revealed type is "__main__.ClassError1[builtins.int, builtins.float]" + + k = ClassError1() + reveal_type(k) # N: Revealed type is "__main__.ClassError1[builtins.str, Any]" + l = ClassError1[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassError1[builtins.int, Any]" + m = ClassError1[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassError1[builtins.int, builtins.float]" + +class ClassError2(Generic[T4, T3]): ... # E: Type parameter "T4" has a default type that refers to one or more type variables that are out of scope + +def func_error2( + a: ClassError2, + b: ClassError2[int], + c: ClassError2[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassError2[Any, builtins.str]" + reveal_type(b) # N: Revealed type is "__main__.ClassError2[builtins.int, builtins.str]" + reveal_type(c) # N: Revealed type is "__main__.ClassError2[builtins.int, builtins.float]" + + k = ClassError2() + reveal_type(k) # N: Revealed type is "__main__.ClassError2[Any, builtins.str]" + l = ClassError2[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassError2[builtins.int, builtins.str]" + m = ClassError2[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassError2[builtins.int, builtins.float]" + +TERR1 = Dict[T3, T1] # E: "T1" cannot appear after "T3" in type parameter list because it has no default type + +def func_error_alias1( + a: TERR1, + b: TERR1[int], + c: TERR1[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "builtins.dict[builtins.str, Any]" + reveal_type(b) # N: Revealed type is "builtins.dict[builtins.int, Any]" + reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.float]" + +TERR2 = Dict[T4, T3] # TODO should be an error \ + # Type parameter "T4" has a default type that refers to one or more type variables that are out of scope + +def func_error_alias2( + a: TERR2, + b: TERR2[int], + c: TERR2[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "builtins.dict[Any, builtins.str]" + reveal_type(b) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" + reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.float]" +[builtins fixtures/dict.pyi] + [case testTypeVarDefaultsFunctions] from typing import TypeVar, ParamSpec, List, Union, Callable, Tuple from typing_extensions import TypeVarTuple, Unpack @@ -351,11 +419,12 @@ def func_c4( [case testTypeVarDefaultsClassRecursive1] # flags: --disallow-any-generics -from typing import Generic, TypeVar +from typing import Generic, TypeVar, List T1 = TypeVar("T1", default=str) T2 = TypeVar("T2", default=T1) T3 = TypeVar("T3", default=T2) +T4 = TypeVar("T4", default=List[T1]) class ClassD1(Generic[T1, T2]): ... @@ -397,12 +466,30 @@ def func_d2( n = ClassD2[int, float, str]() reveal_type(n) # N: Revealed type is "__main__.ClassD2[builtins.int, builtins.float, builtins.str]" +class ClassD3(Generic[T1, T4]): ... + +def func_d3( + a: ClassD3, + b: ClassD3[int], + c: ClassD3[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.ClassD3[builtins.str, builtins.list[builtins.str]]" + reveal_type(b) # N: Revealed type is "__main__.ClassD3[builtins.int, builtins.list[builtins.int]]" + reveal_type(c) # N: Revealed type is "__main__.ClassD3[builtins.int, builtins.float]" + + # k = ClassD3() + # reveal_type(k) # Revealed type is "__main__.ClassD3[builtins.str, builtins.list[builtins.str]]" # TODO + l = ClassD3[int]() + reveal_type(l) # N: Revealed type is "__main__.ClassD3[builtins.int, builtins.list[builtins.int]]" + m = ClassD3[int, float]() + reveal_type(m) # N: Revealed type is "__main__.ClassD3[builtins.int, builtins.float]" + [case testTypeVarDefaultsClassRecursiveMultipleFiles] # flags: --disallow-any-generics from typing import Generic, TypeVar from file2 import T as T2 -T = TypeVar('T', default=T2) +T = TypeVar("T", default=T2) class ClassG1(Generic[T2, T]): pass @@ -587,3 +674,46 @@ def func_c4( # 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] + +[case testTypeVarDefaultsTypeAliasRecursive1] +# flags: --disallow-any-generics +from typing import Dict, List, TypeVar + +T1 = TypeVar("T1") +T2 = TypeVar("T2", default=T1) + +TD1 = Dict[T1, T2] + +def func_d1( + a: TD1, # E: Missing type parameters for generic type "TD1" + b: TD1[int], + c: TD1[int, float], +) -> None: + reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" + reveal_type(b) # N: Revealed type is "builtins.dict[builtins.int, builtins.int]" + reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.float]" +[builtins fixtures/dict.pyi] + +[case testTypeVarDefaultsTypeAliasRecursive2] +from typing import Any, Dict, Generic, TypeVar + +T1 = TypeVar("T1", default=str) +T2 = TypeVar("T2", default=T1) +Alias1 = Dict[T1, T2] +T3 = TypeVar("T3") +class A(Generic[T3]): ... + +T4 = TypeVar("T4", default=A[Alias1]) +class B(Generic[T4]): ... + +def func_d3( + a: B, + b: B[A[Alias1[int]]], + c: B[A[Alias1[int, float]]], + d: B[int], +) -> None: + reveal_type(a) # N: Revealed type is "__main__.B[__main__.A[builtins.dict[builtins.str, builtins.str]]]" + reveal_type(b) # N: Revealed type is "__main__.B[__main__.A[builtins.dict[builtins.int, builtins.int]]]" + reveal_type(c) # N: Revealed type is "__main__.B[__main__.A[builtins.dict[builtins.int, builtins.float]]]" + reveal_type(d) # N: Revealed type is "__main__.B[builtins.int]" +[builtins fixtures/dict.pyi] From 2037e4a068df6e1dcc8f76c37f53e04d62d64e80 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sun, 25 Feb 2024 14:44:49 -0800 Subject: [PATCH 096/172] Workaround parenthesised context manager issue (#16949) Fixes #16945 --- mypy/checker.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 56be3db3f9e7..9f987cb5ccdf 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -4,7 +4,7 @@ import itertools from collections import defaultdict -from contextlib import contextmanager, nullcontext +from contextlib import ExitStack, contextmanager from typing import ( AbstractSet, Callable, @@ -526,17 +526,11 @@ 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() - ): - self.check_partial(node) + with ExitStack() as stack: + if active_typeinfo: + stack.enter_context(self.tscope.class_scope(active_typeinfo)) + stack.enter_context(self.scope.push_class(active_typeinfo)) + self.check_partial(node) return True def check_partial(self, node: DeferredNodeType | FineGrainedDeferredNodeType) -> None: From a91151c46fb0407c9220db9630826634793b9697 Mon Sep 17 00:00:00 2001 From: hesam <97763520+hesam-ghamary@users.noreply.github.com> Date: Mon, 26 Feb 2024 18:28:41 +0330 Subject: [PATCH 097/172] Fix duplicate word in protocols.rst (#16950) --- docs/source/protocols.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/protocols.rst b/docs/source/protocols.rst index 3336d77cb397..067f4d9dcfac 100644 --- a/docs/source/protocols.rst +++ b/docs/source/protocols.rst @@ -9,7 +9,7 @@ compatible as types: nominal subtyping and structural subtyping. *Nominal* subtyping is strictly based on the class hierarchy. If class ``Dog`` inherits class ``Animal``, it's a subtype of ``Animal``. Instances of ``Dog`` can be used when ``Animal`` instances are expected. This form of subtyping -subtyping is what Python's type system predominantly uses: it's easy to +is what Python's type system predominantly uses: it's easy to understand and produces clear and concise error messages, and matches how the native :py:func:`isinstance ` check works -- based on class hierarchy. From 5a8cd80857fd7a1771d5f714c3e3ad69af4070c8 Mon Sep 17 00:00:00 2001 From: Srinivas Lade Date: Wed, 28 Feb 2024 11:16:23 -0500 Subject: [PATCH 098/172] [mypyc] Optimize TYPE_CHECKING to False at Runtime (#16263) Fixes [mypyc/mypyc#902](https://github.com/mypyc/mypyc/issues/902) This PR finds references of `typing.TYPE_CHECKING` or `typing_extensions.TYPE_CHECKING` and optimizes them to `False` in mypyc. --- mypyc/irbuild/expression.py | 6 ++++++ mypyc/test-data/irbuild-basic.test | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 8d205b432d2d..5cdd9a432a12 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -126,6 +126,8 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value: return builder.true() if fullname == "builtins.False": return builder.false() + if fullname in ("typing.TYPE_CHECKING", "typing_extensions.TYPE_CHECKING"): + return builder.false() math_literal = transform_math_literal(builder, fullname) if math_literal is not None: @@ -185,6 +187,10 @@ def transform_name_expr(builder: IRBuilder, expr: NameExpr) -> Value: def transform_member_expr(builder: IRBuilder, expr: MemberExpr) -> Value: + # Special Cases + if expr.fullname in ("typing.TYPE_CHECKING", "typing_extensions.TYPE_CHECKING"): + return builder.false() + # First check if this is maybe a final attribute. final = builder.get_final_ref(expr) if final is not None: diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index bf608abb87ad..d6c47814cb7f 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -3688,3 +3688,33 @@ def f(arg): arg :: __main__.A L0: return arg + +[case testTypeCheckingFlag] +from typing import TYPE_CHECKING, List + +def f(arg: List[int]) -> int: + if TYPE_CHECKING: + from collections.abc import Sized + s: Sized = arg + return len(s) + +[out] +def f(arg): + arg :: list + r0 :: bool + r1 :: int + r2 :: bit + s :: object + r3 :: int +L0: + r0 = 0 << 1 + r1 = extend r0: builtins.bool to builtins.int + r2 = r1 != 0 + if r2 goto L1 else goto L2 :: bool +L1: + goto L3 +L2: +L3: + s = arg + r3 = CPyObject_Size(s) + return r3 From 162c74d2af77070c6983e0f97fcb593eda4d29d1 Mon Sep 17 00:00:00 2001 From: Richard Si Date: Wed, 28 Feb 2024 11:52:42 -0500 Subject: [PATCH 099/172] [mypyc] Remangle redefined names produced by async with (#16408) Fixes mypyc/mypyc#1001. --------- Co-authored-by: Jelle Zijlstra --- mypyc/irbuild/builder.py | 7 ++++--- mypyc/test-data/run-async.test | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 9d160b08505d..69f3ad9c495f 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -1246,14 +1246,15 @@ def add_var_to_env_class( ) -> AssignmentTarget: # First, define the variable name as an attribute of the environment class, and then # construct a target for that attribute. - self.fn_info.env_class.attributes[var.name] = rtype - attr_target = AssignmentTargetAttr(base.curr_env_reg, var.name) + name = remangle_redefinition_name(var.name) + self.fn_info.env_class.attributes[name] = rtype + attr_target = AssignmentTargetAttr(base.curr_env_reg, name) if reassign: # Read the local definition of the variable, and set the corresponding attribute of # the environment class' variable to be that value. reg = self.read(self.lookup(var), self.fn_info.fitem.line) - self.add(SetAttr(base.curr_env_reg, var.name, reg, self.fn_info.fitem.line)) + self.add(SetAttr(base.curr_env_reg, name, reg, self.fn_info.fitem.line)) # Override the local definition of the variable to instead point at the variable in # the environment class. diff --git a/mypyc/test-data/run-async.test b/mypyc/test-data/run-async.test index 85ad172d61df..8488632e6574 100644 --- a/mypyc/test-data/run-async.test +++ b/mypyc/test-data/run-async.test @@ -143,3 +143,31 @@ async def foo() -> AsyncIterable[int]: yields, val = run_generator(async_iter(foo())) assert yields == (0,1,2), yields assert val == 'lol no', val + +[case testAsyncWithVarReuse] +class ConMan: + async def __aenter__(self) -> int: + return 1 + async def __aexit__(self, *exc: object): + pass + +class ConManB: + async def __aenter__(self) -> int: + return 2 + async def __aexit__(self, *exc: object): + pass + +async def x() -> None: + value = 2 + async with ConMan() as f: + value += f + assert value == 3, value + async with ConManB() as f: + value += f + assert value == 5, value + +[typing fixtures/typing-full.pyi] +[file driver.py] +import asyncio +import native +asyncio.run(native.x()) From 9f1c90a072c1bbbbb8260ad7181fc1f1acb99137 Mon Sep 17 00:00:00 2001 From: Richard Si Date: Wed, 28 Feb 2024 12:06:35 -0500 Subject: [PATCH 100/172] [mypyc] Don't crash on non-inlinable final local reads (#15719) Fixes mypyc/mypyc#852. Fixes mypyc/mypyc#990. --- mypyc/irbuild/builder.py | 4 ++-- mypyc/test-data/irbuild-basic.test | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 69f3ad9c495f..f201a4737f89 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -60,7 +60,7 @@ UnionType, get_proper_type, ) -from mypy.util import split_target +from mypy.util import module_prefix, split_target from mypy.visitor import ExpressionVisitor, StatementVisitor from mypyc.common import BITMAP_BITS, SELF_NAME, TEMP_ATTR_NAME from mypyc.crash import catch_errors @@ -1023,7 +1023,7 @@ def emit_load_final( """ if final_var.final_value is not None: # this is safe even for non-native names return self.load_literal_value(final_var.final_value) - elif native: + elif native and module_prefix(self.graph, fullname): return self.load_final_static(fullname, self.mapper.type_to_rtype(typ), line, name) else: return None diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index d6c47814cb7f..cd952ef2ebfd 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -3337,6 +3337,32 @@ def foo(z): L0: return 1 +[case testFinalLocals] +from typing import Final + +def inlined() -> str: + # XXX: the final type must be declared explicitly for Var.final_value to be set. + const: Final[str] = "Oppenheimer" + return const + +def local() -> str: + const: Final[str] = inlined() + return const +[out] +def inlined(): + r0, const, r1 :: str +L0: + r0 = 'Oppenheimer' + const = r0 + r1 = 'Oppenheimer' + return r1 +def local(): + r0, const :: str +L0: + r0 = inlined() + const = r0 + return const + [case testDirectlyCall__bool__] class A: def __bool__(self) -> bool: From f19b5d3a026319687dd81a5c7c976698bbe948a8 Mon Sep 17 00:00:00 2001 From: Richard Si Date: Wed, 28 Feb 2024 13:01:10 -0500 Subject: [PATCH 101/172] [mypyc] Fix compilation of unreachable comprehensions (#15721) Fixes mypyc/mypyc#816. Admittedly hacky. --- mypyc/irbuild/expression.py | 4 ++++ mypyc/irbuild/for_helpers.py | 29 +++++++++++++++++++++++++++++ mypyc/test-data/run-misc.test | 6 ++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 5cdd9a432a12..81e37953809f 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -80,6 +80,7 @@ from mypyc.irbuild.constant_fold import constant_fold_expr from mypyc.irbuild.for_helpers import ( comprehension_helper, + raise_error_if_contains_unreachable_names, translate_list_comprehension, translate_set_comprehension, ) @@ -1020,6 +1021,9 @@ def transform_set_comprehension(builder: IRBuilder, o: SetComprehension) -> Valu def transform_dictionary_comprehension(builder: IRBuilder, o: DictionaryComprehension) -> Value: + if raise_error_if_contains_unreachable_names(builder, o): + return builder.none() + d = builder.maybe_spill(builder.call_c(dict_new_op, [], o.line)) loop_params = list(zip(o.indices, o.sequences, o.condlists, o.is_async)) diff --git a/mypyc/irbuild/for_helpers.py b/mypyc/irbuild/for_helpers.py index 61dbbe960eb2..5d8315e88f72 100644 --- a/mypyc/irbuild/for_helpers.py +++ b/mypyc/irbuild/for_helpers.py @@ -12,10 +12,12 @@ from mypy.nodes import ( ARG_POS, CallExpr, + DictionaryComprehension, Expression, GeneratorExpr, Lvalue, MemberExpr, + NameExpr, RefExpr, SetExpr, TupleExpr, @@ -28,6 +30,7 @@ IntOp, LoadAddress, LoadMem, + RaiseStandardError, Register, TupleGet, TupleSet, @@ -229,6 +232,9 @@ def set_item(item_index: Value) -> None: def translate_list_comprehension(builder: IRBuilder, gen: GeneratorExpr) -> Value: + if raise_error_if_contains_unreachable_names(builder, gen): + return builder.none() + # Try simplest list comprehension, otherwise fall back to general one val = sequence_from_generator_preallocate_helper( builder, @@ -251,7 +257,30 @@ def gen_inner_stmts() -> None: return builder.read(list_ops) +def raise_error_if_contains_unreachable_names( + builder: IRBuilder, gen: GeneratorExpr | DictionaryComprehension +) -> bool: + """Raise a runtime error and return True if generator contains unreachable names. + + False is returned if the generator can be safely transformed without crashing. + (It may still be unreachable!) + """ + if any(isinstance(s, NameExpr) and s.node is None for s in gen.indices): + error = RaiseStandardError( + RaiseStandardError.RUNTIME_ERROR, + "mypyc internal error: should be unreachable", + gen.line, + ) + builder.add(error) + return True + + return False + + def translate_set_comprehension(builder: IRBuilder, gen: GeneratorExpr) -> Value: + if raise_error_if_contains_unreachable_names(builder, gen): + return builder.none() + set_ops = builder.maybe_spill(builder.new_set_op([], gen.line)) loop_params = list(zip(gen.indices, gen.sequences, gen.condlists, gen.is_async)) diff --git a/mypyc/test-data/run-misc.test b/mypyc/test-data/run-misc.test index f77ba3a1302b..14bb5be979ae 100644 --- a/mypyc/test-data/run-misc.test +++ b/mypyc/test-data/run-misc.test @@ -1097,8 +1097,10 @@ B = sys.platform == 'x' and sys.foobar C = sys.platform == 'x' and f(a, -b, 'y') > [c + e, g(y=2)] C = sys.platform == 'x' and cast(a, b[c]) C = sys.platform == 'x' and (lambda x: y + x) -# TODO: This still doesn't work -# C = sys.platform == 'x' and (x for y in z) +C = sys.platform == 'x' and (x for y in z) +C = sys.platform == 'x' and [x for y in z] +C = sys.platform == 'x' and {x: x for y in z} +C = sys.platform == 'x' and {x for y in z} assert not A assert not B From 02c50bcbc0ee26ec682c7356a1b3b9ecd9c11a3c Mon Sep 17 00:00:00 2001 From: Riccardo Di Maio <35903974+rdimaio@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:18:33 +0100 Subject: [PATCH 102/172] Docs: Update `TypedDict` import statements (#16958) Since Python 3.8, `TypedDict` has been available from the `typing` module. As Python 3.8+ is needed to use mypy (https://github.com/python/mypy/blob/master/setup.py#L12), then it's best for the docs to reflect Python 3.8+ usage. For previous versions, there's already a disclaimer on the page that explains that `typing_extensions` must be used: https://github.com/python/mypy/blob/master/docs/source/typed_dict.rst?plain=1#L102-L110 Co-authored-by: Alex Waygood --- docs/source/common_issues.rst | 4 ++-- docs/source/error_code_list.rst | 8 ++++---- docs/source/generics.rst | 3 +-- docs/source/protocols.rst | 14 +++++--------- docs/source/stubs.rst | 2 +- docs/source/typed_dict.rst | 4 ++-- 6 files changed, 15 insertions(+), 20 deletions(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index 8cc18c863e45..4a1d1b437153 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -541,7 +541,7 @@ Consider this example: .. code-block:: python - from typing_extensions import Protocol + from typing import Protocol class P(Protocol): x: float @@ -561,7 +561,7 @@ the protocol definition: .. code-block:: python - from typing_extensions import Protocol + from typing import Protocol class P(Protocol): @property diff --git a/docs/source/error_code_list.rst b/docs/source/error_code_list.rst index 4decd37e6e8a..48b3b689884f 100644 --- a/docs/source/error_code_list.rst +++ b/docs/source/error_code_list.rst @@ -537,7 +537,7 @@ Example: .. code-block:: python - from typing_extensions import TypedDict + from typing import TypedDict class Point(TypedDict): x: int @@ -562,7 +562,7 @@ to have been validated at the point of construction. Example: .. code-block:: python - from typing_extensions import TypedDict + from typing import TypedDict class Point(TypedDict): x: int @@ -868,7 +868,7 @@ the return type affects which lines mypy thinks are reachable after a ``True`` may swallow exceptions. An imprecise return type can result in mysterious errors reported near ``with`` statements. -To fix this, use either ``typing_extensions.Literal[False]`` or +To fix this, use either ``typing.Literal[False]`` or ``None`` as the return type. Returning ``None`` is equivalent to returning ``False`` in this context, since both are treated as false values. @@ -897,7 +897,7 @@ You can use ``Literal[False]`` to fix the error: .. code-block:: python - from typing_extensions import Literal + from typing import Literal class MyContext: ... diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 9ac79f90121d..01ae7534ba93 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -770,8 +770,7 @@ protocols mostly follow the normal rules for generic classes. Example: .. code-block:: python - from typing import TypeVar - from typing_extensions import Protocol + from typing import Protocol, TypeVar T = TypeVar('T') diff --git a/docs/source/protocols.rst b/docs/source/protocols.rst index 067f4d9dcfac..731562867691 100644 --- a/docs/source/protocols.rst +++ b/docs/source/protocols.rst @@ -68,8 +68,7 @@ class: .. code-block:: python - from typing import Iterable - from typing_extensions import Protocol + from typing import Iterable, Protocol class SupportsClose(Protocol): # Empty method body (explicit '...') @@ -226,8 +225,7 @@ such as trees and linked lists: .. code-block:: python - from typing import TypeVar, Optional - from typing_extensions import Protocol + from typing import TypeVar, Optional, Protocol class TreeLike(Protocol): value: int @@ -255,7 +253,7 @@ rudimentary support for runtime structural checks: .. code-block:: python - from typing_extensions import Protocol, runtime_checkable + from typing import Protocol, runtime_checkable @runtime_checkable class Portable(Protocol): @@ -298,8 +296,7 @@ member: .. code-block:: python - from typing import Optional, Iterable - from typing_extensions import Protocol + from typing import Optional, Iterable, Protocol class Combiner(Protocol): def __call__(self, *vals: bytes, maxlen: Optional[int] = None) -> list[bytes]: ... @@ -323,8 +320,7 @@ a double underscore prefix is used. For example: .. code-block:: python - from typing import Callable, TypeVar - from typing_extensions import Protocol + from typing import Callable, Protocol, TypeVar T = TypeVar('T') diff --git a/docs/source/stubs.rst b/docs/source/stubs.rst index 7c84a9718b3e..c0a3f8b88111 100644 --- a/docs/source/stubs.rst +++ b/docs/source/stubs.rst @@ -114,7 +114,7 @@ For example: .. code-block:: python - from typing_extensions import Protocol + from typing import Protocol class Resource(Protocol): def ok_1(self, foo: list[str] = ...) -> None: ... diff --git a/docs/source/typed_dict.rst b/docs/source/typed_dict.rst index 19a717d7feb7..e5ce2927db4d 100644 --- a/docs/source/typed_dict.rst +++ b/docs/source/typed_dict.rst @@ -25,7 +25,7 @@ dictionary value depends on the key: .. code-block:: python - from typing_extensions import TypedDict + from typing import TypedDict Movie = TypedDict('Movie', {'name': str, 'year': int}) @@ -189,7 +189,7 @@ in Python 3.6 and later: .. code-block:: python - from typing_extensions import TypedDict + from typing import TypedDict # "from typing_extensions" in Python 3.7 and earlier class Movie(TypedDict): name: str From ab0bd8cac3f4183ca0c67ab7f9235c6b515ac2f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 16:47:00 -0800 Subject: [PATCH 103/172] Sync typeshed (#16969) Source commit: https://github.com/python/typeshed/commit/e05098681f326b98c635853a40287ac21f771fa2 --- mypy/typeshed/stdlib/VERSIONS | 1 + mypy/typeshed/stdlib/_ctypes.pyi | 6 +- mypy/typeshed/stdlib/_dummy_thread.pyi | 10 +- mypy/typeshed/stdlib/_lsprof.pyi | 35 ++++ mypy/typeshed/stdlib/_operator.pyi | 12 +- mypy/typeshed/stdlib/_thread.pyi | 10 +- mypy/typeshed/stdlib/abc.pyi | 6 +- mypy/typeshed/stdlib/argparse.pyi | 30 ++- mypy/typeshed/stdlib/asyncio/events.pyi | 16 +- mypy/typeshed/stdlib/asyncio/tasks.pyi | 4 +- mypy/typeshed/stdlib/builtins.pyi | 8 +- mypy/typeshed/stdlib/cProfile.pyi | 8 +- mypy/typeshed/stdlib/datetime.pyi | 18 +- mypy/typeshed/stdlib/difflib.pyi | 4 +- mypy/typeshed/stdlib/distutils/sysconfig.pyi | 11 +- mypy/typeshed/stdlib/email/utils.pyi | 6 +- mypy/typeshed/stdlib/functools.pyi | 11 +- .../stdlib/importlib/metadata/__init__.pyi | 24 ++- .../stdlib/importlib/metadata/_meta.pyi | 23 ++- mypy/typeshed/stdlib/itertools.pyi | 16 +- mypy/typeshed/stdlib/numbers.pyi | 171 ++++++++++++------ mypy/typeshed/stdlib/os/__init__.pyi | 21 ++- mypy/typeshed/stdlib/posix.pyi | 4 +- mypy/typeshed/stdlib/queue.pyi | 8 + mypy/typeshed/stdlib/shlex.pyi | 34 +++- mypy/typeshed/stdlib/shutil.pyi | 14 +- mypy/typeshed/stdlib/sqlite3/dbapi2.pyi | 73 +++++--- mypy/typeshed/stdlib/sysconfig.pyi | 7 +- mypy/typeshed/stdlib/tarfile.pyi | 3 + mypy/typeshed/stdlib/tkinter/__init__.pyi | 6 +- mypy/typeshed/stdlib/types.pyi | 12 +- mypy/typeshed/stdlib/typing_extensions.pyi | 10 +- .../typeshed/stdlib/xml/etree/ElementTree.pyi | 6 +- 33 files changed, 437 insertions(+), 191 deletions(-) create mode 100644 mypy/typeshed/stdlib/_lsprof.pyi diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index da395f797881..deb940395e1e 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -36,6 +36,7 @@ _heapq: 3.0- _imp: 3.0- _json: 3.0- _locale: 3.0- +_lsprof: 3.0- _markupbase: 3.0- _msi: 3.0- _operator: 3.4- diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index ec3d86e41687..e0cc87814609 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -64,6 +64,7 @@ class _CData(metaclass=_CDataMeta): # Structure.from_buffer(...) # valid at runtime # Structure(...).from_buffer(...) # invalid at runtime # + @classmethod def from_buffer(cls, source: WriteableBuffer, offset: int = ...) -> Self: ... @classmethod @@ -106,14 +107,15 @@ class _CArgObject: ... def byref(obj: _CData, offset: int = ...) -> _CArgObject: ... -_ECT: TypeAlias = Callable[[type[_CData] | None, CFuncPtr, tuple[_CData, ...]], _CData] +_ECT: TypeAlias = Callable[[_CData | None, CFuncPtr, tuple[_CData, ...]], _CData] _PF: TypeAlias = tuple[int] | tuple[int, str | None] | tuple[int, str | None, Any] class CFuncPtr(_PointerLike, _CData): restype: type[_CData] | Callable[[int], Any] | None argtypes: Sequence[type[_CData]] errcheck: _ECT - _flags_: ClassVar[int] # Abstract attribute that must be defined on subclasses + # Abstract attribute that must be defined on subclasses + _flags_: ClassVar[int] @overload def __init__(self) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/_dummy_thread.pyi b/mypy/typeshed/stdlib/_dummy_thread.pyi index 541096734a91..1182e53c66c3 100644 --- a/mypy/typeshed/stdlib/_dummy_thread.pyi +++ b/mypy/typeshed/stdlib/_dummy_thread.pyi @@ -1,13 +1,19 @@ from collections.abc import Callable from types import TracebackType -from typing import Any, NoReturn +from typing import Any, NoReturn, overload +from typing_extensions import TypeVarTuple, Unpack __all__ = ["error", "start_new_thread", "exit", "get_ident", "allocate_lock", "interrupt_main", "LockType", "RLock"] +_Ts = TypeVarTuple("_Ts") + TIMEOUT_MAX: int error = RuntimeError -def start_new_thread(function: Callable[..., object], args: tuple[Any, ...], kwargs: dict[str, Any] = {}) -> None: ... +@overload +def start_new_thread(function: Callable[[Unpack[_Ts]], object], args: tuple[Unpack[_Ts]]) -> None: ... +@overload +def start_new_thread(function: Callable[..., object], args: tuple[Any, ...], kwargs: dict[str, Any]) -> None: ... def exit() -> NoReturn: ... def get_ident() -> int: ... def allocate_lock() -> LockType: ... diff --git a/mypy/typeshed/stdlib/_lsprof.pyi b/mypy/typeshed/stdlib/_lsprof.pyi new file mode 100644 index 000000000000..8a6934162c92 --- /dev/null +++ b/mypy/typeshed/stdlib/_lsprof.pyi @@ -0,0 +1,35 @@ +import sys +from _typeshed import structseq +from collections.abc import Callable +from types import CodeType +from typing import Any, Final, final + +class Profiler: + def __init__( + self, timer: Callable[[], float] | None = None, timeunit: float = 0.0, subcalls: bool = True, builtins: bool = True + ) -> None: ... + def getstats(self) -> list[profiler_entry]: ... + def enable(self, subcalls: bool = True, builtins: bool = True) -> None: ... + def disable(self) -> None: ... + def clear(self) -> None: ... + +@final +class profiler_entry(structseq[Any], tuple[CodeType | str, int, int, float, float, list[profiler_subentry]]): + if sys.version_info >= (3, 10): + __match_args__: Final = ("code", "callcount", "reccallcount", "totaltime", "inlinetime", "calls") + code: CodeType | str + callcount: int + reccallcount: int + totaltime: float + inlinetime: float + calls: list[profiler_subentry] + +@final +class profiler_subentry(structseq[Any], tuple[CodeType | str, int, int, float, float]): + if sys.version_info >= (3, 10): + __match_args__: Final = ("code", "callcount", "reccallcount", "totaltime", "inlinetime") + code: CodeType | str + callcount: int + reccallcount: int + totaltime: float + inlinetime: float diff --git a/mypy/typeshed/stdlib/_operator.pyi b/mypy/typeshed/stdlib/_operator.pyi index acc4a6fb59ca..9b24e086adff 100644 --- a/mypy/typeshed/stdlib/_operator.pyi +++ b/mypy/typeshed/stdlib/_operator.pyi @@ -95,16 +95,16 @@ def length_hint(__obj: object, __default: int = 0) -> int: ... @final class attrgetter(Generic[_T_co]): @overload - def __new__(cls, attr: str) -> attrgetter[Any]: ... + def __new__(cls, attr: str, /) -> attrgetter[Any]: ... @overload - def __new__(cls, attr: str, __attr2: str) -> attrgetter[tuple[Any, Any]]: ... + def __new__(cls, attr: str, attr2: str, /) -> attrgetter[tuple[Any, Any]]: ... @overload - def __new__(cls, attr: str, __attr2: str, __attr3: str) -> attrgetter[tuple[Any, Any, Any]]: ... + def __new__(cls, attr: str, attr2: str, attr3: str, /) -> attrgetter[tuple[Any, Any, Any]]: ... @overload - def __new__(cls, attr: str, __attr2: str, __attr3: str, __attr4: str) -> attrgetter[tuple[Any, Any, Any, Any]]: ... + def __new__(cls, attr: str, attr2: str, attr3: str, attr4: str, /) -> attrgetter[tuple[Any, Any, Any, Any]]: ... @overload - def __new__(cls, attr: str, *attrs: str) -> attrgetter[tuple[Any, ...]]: ... - def __call__(self, obj: Any) -> _T_co: ... + def __new__(cls, attr: str, /, *attrs: str) -> attrgetter[tuple[Any, ...]]: ... + def __call__(self, obj: Any, /) -> _T_co: ... @final class itemgetter(Generic[_T_co]): diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index ff9bd1a12eb1..e69f9d2359aa 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -3,7 +3,10 @@ from _typeshed import structseq from collections.abc import Callable from threading import Thread from types import TracebackType -from typing import Any, Final, NoReturn, final +from typing import Any, Final, NoReturn, final, overload +from typing_extensions import TypeVarTuple, Unpack + +_Ts = TypeVarTuple("_Ts") error = RuntimeError @@ -18,7 +21,10 @@ class LockType: self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... -def start_new_thread(function: Callable[..., object], args: tuple[Any, ...], kwargs: dict[str, Any] = ...) -> int: ... +@overload +def start_new_thread(function: Callable[[Unpack[_Ts]], object], args: tuple[Unpack[_Ts]]) -> int: ... +@overload +def start_new_thread(function: Callable[..., object], args: tuple[Any, ...], kwargs: dict[str, Any]) -> int: ... def interrupt_main() -> None: ... def exit() -> NoReturn: ... def allocate_lock() -> LockType: ... diff --git a/mypy/typeshed/stdlib/abc.pyi b/mypy/typeshed/stdlib/abc.pyi index c642f8b9f123..e4e7f59b58ca 100644 --- a/mypy/typeshed/stdlib/abc.pyi +++ b/mypy/typeshed/stdlib/abc.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import SupportsWrite from collections.abc import Callable from typing import Any, Literal, TypeVar -from typing_extensions import Concatenate, ParamSpec +from typing_extensions import Concatenate, ParamSpec, deprecated _T = TypeVar("_T") _R_co = TypeVar("_R_co", covariant=True) @@ -28,15 +28,17 @@ class ABCMeta(type): def register(cls: ABCMeta, subclass: type[_T]) -> type[_T]: ... def abstractmethod(funcobj: _FuncT) -> _FuncT: ... - +@deprecated("Deprecated, use 'classmethod' with 'abstractmethod' instead") class abstractclassmethod(classmethod[_T, _P, _R_co]): __isabstractmethod__: Literal[True] def __init__(self, callable: Callable[Concatenate[type[_T], _P], _R_co]) -> None: ... +@deprecated("Deprecated, use 'staticmethod' with 'abstractmethod' instead") class abstractstaticmethod(staticmethod[_P, _R_co]): __isabstractmethod__: Literal[True] def __init__(self, callable: Callable[_P, _R_co]) -> None: ... +@deprecated("Deprecated, use 'property' with 'abstractmethod' instead") class abstractproperty(property): __isabstractmethod__: Literal[True] diff --git a/mypy/typeshed/stdlib/argparse.pyi b/mypy/typeshed/stdlib/argparse.pyi index 489cc6b16634..c34aca1f8c20 100644 --- a/mypy/typeshed/stdlib/argparse.pyi +++ b/mypy/typeshed/stdlib/argparse.pyi @@ -3,7 +3,7 @@ from _typeshed import sentinel from collections.abc import Callable, Generator, Iterable, Sequence from re import Pattern from typing import IO, Any, Generic, Literal, NewType, NoReturn, Protocol, TypeVar, overload -from typing_extensions import Self, TypeAlias +from typing_extensions import Self, TypeAlias, deprecated __all__ = [ "ArgumentParser", @@ -339,11 +339,23 @@ class Action(_AttributeHolder): if sys.version_info >= (3, 12): class BooleanOptionalAction(Action): + @overload def __init__( self, option_strings: Sequence[str], dest: str, - default: _T | str | None = None, + default: bool | None = None, + *, + required: bool = False, + help: str | None = None, + ) -> None: ... + @overload + @deprecated("The `type`, `choices`, and `metavar` parameters are ignored and will be removed in Python 3.14.") + def __init__( + self, + option_strings: Sequence[str], + dest: str, + default: _T | bool | None = None, type: Callable[[str], _T] | FileType | None = sentinel, choices: Iterable[_T] | None = sentinel, required: bool = False, @@ -353,11 +365,23 @@ if sys.version_info >= (3, 12): elif sys.version_info >= (3, 9): class BooleanOptionalAction(Action): + @overload + def __init__( + self, + option_strings: Sequence[str], + dest: str, + default: bool | None = None, + *, + required: bool = False, + help: str | None = None, + ) -> None: ... + @overload + @deprecated("The `type`, `choices`, and `metavar` parameters are ignored and will be removed in Python 3.14.") def __init__( self, option_strings: Sequence[str], dest: str, - default: _T | str | None = None, + default: _T | bool | None = None, type: Callable[[str], _T] | FileType | None = None, choices: Iterable[_T] | None = None, required: bool = False, diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 649771df8bf1..16f5296e2125 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -543,10 +543,18 @@ class AbstractEventLoopPolicy: @abstractmethod def new_event_loop(self) -> AbstractEventLoop: ... # Child processes handling (Unix only). - @abstractmethod - def get_child_watcher(self) -> AbstractChildWatcher: ... - @abstractmethod - def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ... + if sys.version_info >= (3, 12): + @abstractmethod + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def get_child_watcher(self) -> AbstractChildWatcher: ... + @abstractmethod + @deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14") + def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ... + else: + @abstractmethod + def get_child_watcher(self) -> AbstractChildWatcher: ... + @abstractmethod + def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ... class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy, metaclass=ABCMeta): def get_event_loop(self) -> AbstractEventLoop: ... diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index 23447ba27aa5..028a7571bb79 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -375,6 +375,8 @@ else: if sys.version_info >= (3, 12): _TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co] +elif sys.version_info >= (3, 9): + _TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co] else: _TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Awaitable[_T_co] @@ -382,7 +384,7 @@ else: # While this is true in general, here it's sort-of okay to have a covariant subclass, # since the only reason why `asyncio.Future` is invariant is the `set_result()` method, # and `asyncio.Task.set_result()` always raises. -class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportGeneralTypeIssues] +class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportInvalidTypeArguments] if sys.version_info >= (3, 12): def __init__( self, diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 09f082f2fe48..02e128234dc1 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -437,7 +437,7 @@ class str(Sequence[str]): def capitalize(self) -> str: ... # type: ignore[misc] def casefold(self) -> str: ... # type: ignore[misc] def center(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] - def count(self, x: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... + def count(self, __sub: 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 = ... @@ -1130,7 +1130,7 @@ class property: class _NotImplementedType(Any): # A little weird, but typing the __call__ as NotImplemented makes the error message # for NotImplemented() much better - __call__: NotImplemented # type: ignore[valid-type] # pyright: ignore[reportGeneralTypeIssues] + __call__: NotImplemented # type: ignore[valid-type] # pyright: ignore[reportInvalidTypeForm] NotImplemented: _NotImplementedType @@ -1544,9 +1544,9 @@ def quit(code: sys._ExitCode = None) -> NoReturn: ... class reversed(Iterator[_T]): @overload - def __init__(self, __sequence: Reversible[_T]) -> None: ... + def __new__(cls, __sequence: Reversible[_T]) -> Iterator[_T]: ... # type: ignore[misc] @overload - def __init__(self, __sequence: SupportsLenAndGetItem[_T]) -> None: ... + def __new__(cls, __sequence: SupportsLenAndGetItem[_T]) -> Iterator[_T]: ... # type: ignore[misc] def __iter__(self) -> Self: ... def __next__(self) -> _T: ... def __length_hint__(self) -> int: ... diff --git a/mypy/typeshed/stdlib/cProfile.pyi b/mypy/typeshed/stdlib/cProfile.pyi index 7d97fa22c394..c212f0383eaf 100644 --- a/mypy/typeshed/stdlib/cProfile.pyi +++ b/mypy/typeshed/stdlib/cProfile.pyi @@ -1,3 +1,4 @@ +import _lsprof from _typeshed import StrOrBytesPath, Unused from collections.abc import Callable from types import CodeType @@ -15,13 +16,8 @@ _T = TypeVar("_T") _P = ParamSpec("_P") _Label: TypeAlias = tuple[str, int, str] -class Profile: +class Profile(_lsprof.Profiler): stats: dict[_Label, tuple[int, int, int, int, dict[_Label, tuple[int, int, int, int]]]] # undocumented - def __init__( - self, timer: Callable[[], float] = ..., timeunit: float = ..., subcalls: bool = ..., builtins: bool = ... - ) -> None: ... - def enable(self) -> None: ... - def disable(self) -> None: ... def print_stats(self, sort: str | int = -1) -> None: ... def dump_stats(self, file: StrOrBytesPath) -> None: ... def create_stats(self) -> None: ... diff --git a/mypy/typeshed/stdlib/datetime.pyi b/mypy/typeshed/stdlib/datetime.pyi index 54ecddec3a9a..852208cd83a1 100644 --- a/mypy/typeshed/stdlib/datetime.pyi +++ b/mypy/typeshed/stdlib/datetime.pyi @@ -1,16 +1,14 @@ import sys from abc import abstractmethod from time import struct_time -from typing import ClassVar, Literal, NamedTuple, NoReturn, SupportsIndex, TypeVar, final, overload -from typing_extensions import Self, TypeAlias +from typing import ClassVar, Literal, NamedTuple, NoReturn, SupportsIndex, final, overload +from typing_extensions import Self, TypeAlias, deprecated if sys.version_info >= (3, 11): __all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR", "UTC") elif sys.version_info >= (3, 9): __all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR") -_D = TypeVar("_D", bound=date) - MINYEAR: Literal[1] MAXYEAR: Literal[9999] @@ -90,11 +88,11 @@ class date: 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 __sub__(self, __value: Self) -> timedelta: ... + @overload + def __sub__(self, __value: timedelta) -> Self: ... def __hash__(self) -> int: ... def weekday(self) -> int: ... def isoweekday(self) -> int: ... @@ -251,10 +249,12 @@ class datetime(date): def fromtimestamp(cls, __timestamp: float, tz: _TzInfo | None = ...) -> Self: ... @classmethod + @deprecated("Use timezone-aware objects to represent datetimes in UTC; e.g. by calling .fromtimestamp(datetime.UTC)") def utcfromtimestamp(cls, __t: float) -> Self: ... @classmethod def now(cls, tz: _TzInfo | None = None) -> Self: ... @classmethod + @deprecated("Use timezone-aware objects to represent datetimes in UTC; e.g. by calling .now(datetime.UTC)") def utcnow(cls) -> Self: ... @classmethod def combine(cls, date: _Date, time: _Time, tzinfo: _TzInfo | None = ...) -> Self: ... @@ -290,6 +290,6 @@ class datetime(date): def __eq__(self, __value: object) -> bool: ... def __hash__(self) -> int: ... @overload # type: ignore[override] - def __sub__(self, __value: timedelta) -> Self: ... + def __sub__(self, __value: Self) -> timedelta: ... @overload - def __sub__(self: _D, __value: _D) -> timedelta: ... + def __sub__(self, __value: timedelta) -> Self: ... diff --git a/mypy/typeshed/stdlib/difflib.pyi b/mypy/typeshed/stdlib/difflib.pyi index 894ebaaeca98..d5b77b8f0e2c 100644 --- a/mypy/typeshed/stdlib/difflib.pyi +++ b/mypy/typeshed/stdlib/difflib.pyi @@ -1,6 +1,6 @@ import sys from collections.abc import Callable, Iterable, Iterator, Sequence -from typing import Any, AnyStr, Generic, NamedTuple, TypeVar, overload +from typing import Any, AnyStr, Generic, Literal, NamedTuple, TypeVar, overload if sys.version_info >= (3, 9): from types import GenericAlias @@ -49,7 +49,7 @@ class SequenceMatcher(Generic[_T]): def find_longest_match(self, alo: int, ahi: int, blo: int, bhi: int) -> Match: ... def get_matching_blocks(self) -> list[Match]: ... - def get_opcodes(self) -> list[tuple[str, int, int, int, int]]: ... + def get_opcodes(self) -> list[tuple[Literal["replace", "delete", "insert", "equal"], int, int, int, int]]: ... def get_grouped_opcodes(self, n: int = 3) -> Iterable[list[tuple[str, int, int, int, int]]]: ... def ratio(self) -> float: ... def quick_ratio(self) -> float: ... diff --git a/mypy/typeshed/stdlib/distutils/sysconfig.pyi b/mypy/typeshed/stdlib/distutils/sysconfig.pyi index 464cfb639c6d..e2399a6cf36b 100644 --- a/mypy/typeshed/stdlib/distutils/sysconfig.pyi +++ b/mypy/typeshed/stdlib/distutils/sysconfig.pyi @@ -1,6 +1,8 @@ import sys from collections.abc import Mapping from distutils.ccompiler import CCompiler +from typing import Literal, overload +from typing_extensions import deprecated PREFIX: str EXEC_PREFIX: str @@ -10,8 +12,15 @@ project_base: str python_build: bool def expand_makefile_vars(s: str, vars: Mapping[str, str]) -> str: ... +@overload +@deprecated("SO is deprecated, use EXT_SUFFIX. Support is removed in Python 3.11") +def get_config_var(name: Literal["SO"]) -> int | str | None: ... +@overload def get_config_var(name: str) -> int | str | None: ... -def get_config_vars(*args: str) -> Mapping[str, int | str]: ... +@overload +def get_config_vars() -> dict[str, str | int]: ... +@overload +def get_config_vars(arg: str, /, *args: str) -> list[str | int]: ... def get_config_h_filename() -> str: ... def get_makefile_filename() -> str: ... def get_python_inc(plat_specific: bool = ..., prefix: str | None = None) -> str: ... diff --git a/mypy/typeshed/stdlib/email/utils.pyi b/mypy/typeshed/stdlib/email/utils.pyi index 186e768050be..0b62647532db 100644 --- a/mypy/typeshed/stdlib/email/utils.pyi +++ b/mypy/typeshed/stdlib/email/utils.pyi @@ -4,7 +4,7 @@ from _typeshed import Unused from email import _ParamType from email.charset import Charset from typing import overload -from typing_extensions import TypeAlias +from typing_extensions import TypeAlias, deprecated __all__ = [ "collapse_rfc2231_value", @@ -54,6 +54,10 @@ def formatdate(timeval: float | None = None, localtime: bool = False, usegmt: bo def format_datetime(dt: datetime.datetime, usegmt: bool = False) -> str: ... if sys.version_info >= (3, 12): + @overload + def localtime(dt: datetime.datetime | None = None) -> datetime.datetime: ... + @overload + @deprecated("The `isdst` parameter does nothing and will be removed in Python 3.14.") def localtime(dt: datetime.datetime | None = None, isdst: Unused = None) -> datetime.datetime: ... else: diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 0f1666024f84..991182486113 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -30,6 +30,7 @@ if sys.version_info >= (3, 9): _AnyCallable: TypeAlias = Callable[..., object] _T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) _S = TypeVar("_S") @overload @@ -171,17 +172,17 @@ class singledispatchmethod(Generic[_T]): 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] +class cached_property(Generic[_T_co]): + func: Callable[[Any], _T_co] attrname: str | None - def __init__(self, func: Callable[[Any], _T]) -> None: ... + def __init__(self, func: Callable[[Any], _T_co]) -> 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 __get__(self, instance: object, owner: type[Any] | None = None) -> _T_co: ... 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: ... + def __set__(self, instance: object, value: _T_co) -> None: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues] if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi index eb4db39ebf40..b2fe14777056 100644 --- a/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi @@ -10,7 +10,7 @@ from os import PathLike from pathlib import Path from re import Pattern from typing import Any, ClassVar, Generic, NamedTuple, TypeVar, overload -from typing_extensions import Self +from typing_extensions import Self, TypeAlias _T = TypeVar("_T") _KT = TypeVar("_KT") @@ -33,9 +33,17 @@ if sys.version_info >= (3, 10): __all__ += ["PackageMetadata", "packages_distributions"] if sys.version_info >= (3, 10): - from importlib.metadata._meta import PackageMetadata as PackageMetadata + from importlib.metadata._meta import PackageMetadata as PackageMetadata, SimplePath def packages_distributions() -> Mapping[str, list[str]]: ... + if sys.version_info >= (3, 12): + # It's generic but shouldn't be + _SimplePath: TypeAlias = SimplePath[Any] + else: + _SimplePath: TypeAlias = SimplePath +else: + _SimplePath: TypeAlias = Path + class PackageNotFoundError(ModuleNotFoundError): @property def name(self) -> str: ... # type: ignore[override] @@ -184,7 +192,7 @@ class Distribution(_distribution_parent): @abc.abstractmethod def read_text(self, filename: str) -> str | None: ... @abc.abstractmethod - def locate_file(self, path: StrPath) -> PathLike[str]: ... + def locate_file(self, path: StrPath) -> _SimplePath: ... @classmethod def from_name(cls, name: str) -> Distribution: ... @overload @@ -233,14 +241,14 @@ class MetadataPathFinder(DistributionFinder): @classmethod def find_distributions(cls, context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... if sys.version_info >= (3, 10): - # Yes, this is an instance method that has argumend named "cls" + # Yes, this is an instance method that has a parameter named "cls" def invalidate_caches(cls) -> None: ... class PathDistribution(Distribution): - _path: Path - def __init__(self, path: Path) -> None: ... - def read_text(self, filename: StrPath) -> str: ... - def locate_file(self, path: StrPath) -> PathLike[str]: ... + _path: _SimplePath + def __init__(self, path: _SimplePath) -> None: ... + def read_text(self, filename: StrPath) -> str | None: ... + def locate_file(self, path: StrPath) -> _SimplePath: ... def distribution(distribution_name: str) -> Distribution: ... @overload diff --git a/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi b/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi index 64fefa9a84e2..3eac226b7065 100644 --- a/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi @@ -3,6 +3,7 @@ from collections.abc import Iterator from typing import Any, Protocol, TypeVar, overload _T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) class PackageMetadata(Protocol): def __len__(self) -> int: ... @@ -22,19 +23,27 @@ class PackageMetadata(Protocol): def get(self, name: str, failobj: _T) -> _T | str: ... if sys.version_info >= (3, 12): - class SimplePath(Protocol[_T]): - def joinpath(self) -> _T: ... + class SimplePath(Protocol[_T_co]): + # At runtime this is defined as taking `str | _T`, but that causes trouble. + # See #11436. + def joinpath(self, other: str, /) -> _T_co: ... @property - def parent(self) -> _T: ... + def parent(self) -> _T_co: ... def read_text(self) -> str: ... - def __truediv__(self, other: _T | str) -> _T: ... + # As with joinpath(), this is annotated as taking `str | _T` at runtime. + def __truediv__(self, other: str, /) -> _T_co: ... else: class SimplePath(Protocol): - def joinpath(self) -> SimplePath: ... - def parent(self) -> SimplePath: ... + # Actually takes only self at runtime, but that's clearly wrong + def joinpath(self, other: Any, /) -> SimplePath: ... + # Not defined as a property at runtime, but it should be + @property + def parent(self) -> Any: ... def read_text(self) -> str: ... # There was a bug in `SimplePath` definition in cpython, see #8451 # Strictly speaking `__div__` was defined in 3.10, not __truediv__, # but it should have always been `__truediv__`. - def __truediv__(self) -> SimplePath: ... + # Also, the runtime defines this method as taking no arguments, + # which is obviously wrong. + def __truediv__(self, other: Any, /) -> SimplePath: ... diff --git a/mypy/typeshed/stdlib/itertools.pyi b/mypy/typeshed/stdlib/itertools.pyi index 1fa76399444a..0e501e1ade4d 100644 --- a/mypy/typeshed/stdlib/itertools.pyi +++ b/mypy/typeshed/stdlib/itertools.pyi @@ -220,21 +220,7 @@ class product(Iterator[_T_co]): __iter6: Iterable[_T6], ) -> product[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... @overload - def __new__( - cls, - __iter1: Iterable[Any], - __iter2: Iterable[Any], - __iter3: Iterable[Any], - __iter4: Iterable[Any], - __iter5: Iterable[Any], - __iter6: Iterable[Any], - __iter7: Iterable[Any], - *iterables: Iterable[Any], - ) -> product[tuple[Any, ...]]: ... - @overload - def __new__(cls, *iterables: Iterable[_T1], repeat: int) -> product[tuple[_T1, ...]]: ... - @overload - def __new__(cls, *iterables: Iterable[Any], repeat: int = ...) -> product[tuple[Any, ...]]: ... + def __new__(cls, *iterables: Iterable[_T1], repeat: int = 1) -> product[tuple[_T1, ...]]: ... def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... diff --git a/mypy/typeshed/stdlib/numbers.pyi b/mypy/typeshed/stdlib/numbers.pyi index 9f507d8335cf..e129de2cdc67 100644 --- a/mypy/typeshed/stdlib/numbers.pyi +++ b/mypy/typeshed/stdlib/numbers.pyi @@ -1,27 +1,62 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. # -# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module +# Use _ComplexLike, _RealLike and _IntegralLike 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 Literal, SupportsFloat, SupportsIndex, overload -from typing_extensions import TypeAlias +from typing import Literal, Protocol, overload -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 +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] - _SupportsComplex: TypeAlias = typing.SupportsComplex | complex +############################ +# Protocols for return types +############################ -__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] +# `_ComplexLike` is a structural-typing approximation +# of the `Complex` ABC, which is not (and cannot be) a protocol +# +# NOTE: We can't include `__complex__` here, +# as we want `int` to be seen as a subtype of `_ComplexLike`, +# and `int.__complex__` does not exist :( +class _ComplexLike(Protocol): + def __neg__(self) -> _ComplexLike: ... + def __pos__(self) -> _ComplexLike: ... + def __abs__(self) -> _RealLike: ... + +# _RealLike is a structural-typing approximation +# of the `Real` ABC, which is not (and cannot be) a protocol +class _RealLike(_ComplexLike, Protocol): + def __trunc__(self) -> _IntegralLike: ... + def __floor__(self) -> _IntegralLike: ... + def __ceil__(self) -> _IntegralLike: ... + def __float__(self) -> float: ... + # Overridden from `_ComplexLike` + # for a more precise return type: + def __neg__(self) -> _RealLike: ... + def __pos__(self) -> _RealLike: ... + +# _IntegralLike is a structural-typing approximation +# of the `Integral` ABC, which is not (and cannot be) a protocol +class _IntegralLike(_RealLike, Protocol): + def __invert__(self) -> _IntegralLike: ... + def __int__(self) -> int: ... + def __index__(self) -> int: ... + # Overridden from `_ComplexLike` + # for a more precise return type: + def __abs__(self) -> _IntegralLike: ... + # Overridden from `RealLike` + # for a more precise return type: + def __neg__(self) -> _IntegralLike: ... + def __pos__(self) -> _IntegralLike: ... + +################# +# Module "proper" +################# class Number(metaclass=ABCMeta): @abstractmethod @@ -29,126 +64,146 @@ class Number(metaclass=ABCMeta): # See comment at the top of the file # for why some of these return types are purposefully vague -class Complex(Number): +class Complex(Number, _ComplexLike): @abstractmethod def __complex__(self) -> complex: ... def __bool__(self) -> bool: ... @property @abstractmethod - def real(self) -> SupportsFloat: ... + def real(self) -> _RealLike: ... @property @abstractmethod - def imag(self) -> SupportsFloat: ... + def imag(self) -> _RealLike: ... @abstractmethod - def __add__(self, other) -> _SupportsComplex: ... + def __add__(self, other) -> _ComplexLike: ... @abstractmethod - def __radd__(self, other) -> _SupportsComplex: ... + def __radd__(self, other) -> _ComplexLike: ... @abstractmethod - def __neg__(self) -> _SupportsComplex: ... + def __neg__(self) -> _ComplexLike: ... @abstractmethod - def __pos__(self) -> _SupportsComplex: ... - def __sub__(self, other) -> _SupportsComplex: ... - def __rsub__(self, other) -> _SupportsComplex: ... + def __pos__(self) -> _ComplexLike: ... + def __sub__(self, other) -> _ComplexLike: ... + def __rsub__(self, other) -> _ComplexLike: ... @abstractmethod - def __mul__(self, other) -> _SupportsComplex: ... + def __mul__(self, other) -> _ComplexLike: ... @abstractmethod - def __rmul__(self, other) -> _SupportsComplex: ... + def __rmul__(self, other) -> _ComplexLike: ... @abstractmethod - def __truediv__(self, other) -> _SupportsComplex: ... + def __truediv__(self, other) -> _ComplexLike: ... @abstractmethod - def __rtruediv__(self, other) -> _SupportsComplex: ... + def __rtruediv__(self, other) -> _ComplexLike: ... @abstractmethod - def __pow__(self, exponent) -> _SupportsComplex: ... + def __pow__(self, exponent) -> _ComplexLike: ... @abstractmethod - def __rpow__(self, base) -> _SupportsComplex: ... + def __rpow__(self, base) -> _ComplexLike: ... @abstractmethod - def __abs__(self) -> SupportsFloat: ... + def __abs__(self) -> _RealLike: ... @abstractmethod - def conjugate(self) -> _SupportsComplex: ... + def conjugate(self) -> _ComplexLike: ... @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): +class Real(Complex, _RealLike): @abstractmethod def __float__(self) -> float: ... @abstractmethod - def __trunc__(self) -> SupportsIndex: ... + def __trunc__(self) -> _IntegralLike: ... @abstractmethod - def __floor__(self) -> SupportsIndex: ... + def __floor__(self) -> _IntegralLike: ... @abstractmethod - def __ceil__(self) -> SupportsIndex: ... + def __ceil__(self) -> _IntegralLike: ... @abstractmethod @overload - def __round__(self, ndigits: None = None) -> SupportsIndex: ... + def __round__(self, ndigits: None = None) -> _IntegralLike: ... @abstractmethod @overload - def __round__(self, ndigits: int) -> SupportsFloat: ... - def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... - def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... + def __round__(self, ndigits: int) -> _RealLike: ... + def __divmod__(self, other) -> tuple[_RealLike, _RealLike]: ... + def __rdivmod__(self, other) -> tuple[_RealLike, _RealLike]: ... @abstractmethod - def __floordiv__(self, other) -> SupportsFloat: ... + def __floordiv__(self, other) -> _RealLike: ... @abstractmethod - def __rfloordiv__(self, other) -> SupportsFloat: ... + def __rfloordiv__(self, other) -> _RealLike: ... @abstractmethod - def __mod__(self, other) -> SupportsFloat: ... + def __mod__(self, other) -> _RealLike: ... @abstractmethod - def __rmod__(self, other) -> SupportsFloat: ... + def __rmod__(self, other) -> _RealLike: ... @abstractmethod def __lt__(self, other) -> bool: ... @abstractmethod def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self) -> SupportsFloat: ... + def real(self) -> _RealLike: ... @property def imag(self) -> Literal[0]: ... - def conjugate(self) -> SupportsFloat: ... # type: ignore[override] + def conjugate(self) -> _RealLike: ... + # Not actually overridden at runtime, + # but we override these in the stub to give them more precise return types: + @abstractmethod + def __pos__(self) -> _RealLike: ... + @abstractmethod + def __neg__(self) -> _RealLike: ... # 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) -> SupportsIndex: ... + def numerator(self) -> _IntegralLike: ... @property @abstractmethod - def denominator(self) -> SupportsIndex: ... + def denominator(self) -> _IntegralLike: ... 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): +class Integral(Rational, _IntegralLike): @abstractmethod def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] + def __pow__(self, exponent, modulus: Incomplete | None = None) -> _IntegralLike: ... @abstractmethod - def __lshift__(self, other) -> SupportsIndex: ... + def __lshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rlshift__(self, other) -> SupportsIndex: ... + def __rlshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rshift__(self, other) -> SupportsIndex: ... + def __rshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rrshift__(self, other) -> SupportsIndex: ... + def __rrshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __and__(self, other) -> SupportsIndex: ... + def __and__(self, other) -> _IntegralLike: ... @abstractmethod - def __rand__(self, other) -> SupportsIndex: ... + def __rand__(self, other) -> _IntegralLike: ... @abstractmethod - def __xor__(self, other) -> SupportsIndex: ... + def __xor__(self, other) -> _IntegralLike: ... @abstractmethod - def __rxor__(self, other) -> SupportsIndex: ... + def __rxor__(self, other) -> _IntegralLike: ... @abstractmethod - def __or__(self, other) -> SupportsIndex: ... + def __or__(self, other) -> _IntegralLike: ... @abstractmethod - def __ror__(self, other) -> SupportsIndex: ... + def __ror__(self, other) -> _IntegralLike: ... @abstractmethod - def __invert__(self) -> SupportsIndex: ... + def __invert__(self) -> _IntegralLike: ... def __float__(self) -> float: ... @property - def numerator(self) -> SupportsIndex: ... + def numerator(self) -> _IntegralLike: ... @property def denominator(self) -> Literal[1]: ... + # Not actually overridden at runtime, + # but we override these in the stub to give them more precise return types: + @abstractmethod + def __pos__(self) -> _IntegralLike: ... + @abstractmethod + def __neg__(self) -> _IntegralLike: ... + @abstractmethod + def __abs__(self) -> _IntegralLike: ... + @abstractmethod + @overload + def __round__(self, ndigits: None = None) -> _IntegralLike: ... + @abstractmethod + @overload + def __round__(self, ndigits: int) -> _IntegralLike: ... diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index b57678635c07..eef52e7a8b3b 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -40,7 +40,7 @@ from typing import ( overload, runtime_checkable, ) -from typing_extensions import Self, TypeAlias, Unpack +from typing_extensions import Self, TypeAlias, Unpack, deprecated from . import path as _path @@ -308,7 +308,8 @@ if sys.platform != "win32": EX_NOPERM: int EX_CONFIG: int -if sys.platform != "win32" and sys.platform != "darwin": +# Exists on some Unix platforms, e.g. Solaris. +if sys.platform != "win32" and sys.platform != "darwin" and sys.platform != "linux": EX_NOTFOUND: int P_NOWAIT: int @@ -361,8 +362,16 @@ class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, flo @property def st_mtime(self) -> float: ... # time of most recent content modification, # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows) - @property - def st_ctime(self) -> float: ... + if sys.version_info >= (3, 12) and sys.platform == "win32": + @property + @deprecated( + "Use st_birthtime instead to retrieve the file creation time. In the future, this property will contain the last metadata change time." + ) + def st_ctime(self) -> float: ... + else: + @property + def st_ctime(self) -> float: ... + @property def st_atime_ns(self) -> int: ... # time of most recent access, in nanoseconds @property @@ -860,8 +869,8 @@ if sys.platform != "win32": def abort() -> NoReturn: ... # These are defined as execl(file, *args) but the first *arg is mandatory. -def execl(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: StrOrBytesPath) -> NoReturn: ... -def execlp(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: StrOrBytesPath) -> NoReturn: ... +def execl(file: StrOrBytesPath, *args: Unpack[tuple[StrOrBytesPath, Unpack[tuple[StrOrBytesPath, ...]]]]) -> NoReturn: ... +def execlp(file: StrOrBytesPath, *args: Unpack[tuple[StrOrBytesPath, Unpack[tuple[StrOrBytesPath, ...]]]]) -> NoReturn: ... # These are: execle(file, *args, env) but env is pulled from the last element of the args. def execle( diff --git a/mypy/typeshed/stdlib/posix.pyi b/mypy/typeshed/stdlib/posix.pyi index 6cba003bbd5f..b31b8f3d3524 100644 --- a/mypy/typeshed/stdlib/posix.pyi +++ b/mypy/typeshed/stdlib/posix.pyi @@ -239,9 +239,11 @@ if sys.platform != "win32": if sys.platform != "linux": from os import chflags as chflags, lchflags as lchflags, lchmod as lchmod + if sys.platform != "linux" and sys.platform != "darwin": + from os import EX_NOTFOUND as EX_NOTFOUND + 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, diff --git a/mypy/typeshed/stdlib/queue.pyi b/mypy/typeshed/stdlib/queue.pyi index 3537e445ed97..d7cae5f2ac79 100644 --- a/mypy/typeshed/stdlib/queue.pyi +++ b/mypy/typeshed/stdlib/queue.pyi @@ -12,6 +12,9 @@ _T = TypeVar("_T") class Empty(Exception): ... class Full(Exception): ... +if sys.version_info >= (3, 13): + class ShutDown(Exception): ... + class Queue(Generic[_T]): maxsize: int @@ -20,6 +23,8 @@ class Queue(Generic[_T]): not_full: Condition # undocumented all_tasks_done: Condition # undocumented unfinished_tasks: int # undocumented + if sys.version_info >= (3, 13): + is_shutdown: bool # undocumented # Despite the fact that `queue` has `deque` type, # we treat it as `Any` to allow different implementations in subtypes. queue: Any # undocumented @@ -29,6 +34,9 @@ class Queue(Generic[_T]): def full(self) -> bool: ... def get(self, block: bool = True, timeout: float | None = None) -> _T: ... def get_nowait(self) -> _T: ... + if sys.version_info >= (3, 13): + def shutdown(self, immediate: bool = False) -> None: ... + def _get(self) -> _T: ... def put(self, item: _T, block: bool = True, timeout: float | None = None) -> None: ... def put_nowait(self, item: _T) -> None: ... diff --git a/mypy/typeshed/stdlib/shlex.pyi b/mypy/typeshed/stdlib/shlex.pyi index 3fda03b5694a..daa8df439b26 100644 --- a/mypy/typeshed/stdlib/shlex.pyi +++ b/mypy/typeshed/stdlib/shlex.pyi @@ -1,13 +1,32 @@ +import sys +from collections import deque from collections.abc import Iterable -from typing import TextIO -from typing_extensions import Self +from io import TextIOWrapper +from typing import Literal, Protocol, overload, type_check_only +from typing_extensions import Self, deprecated __all__ = ["shlex", "split", "quote", "join"] -def split(s: str, comments: bool = False, posix: bool = True) -> list[str]: ... +@type_check_only +class _ShlexInstream(Protocol): + def read(self, size: Literal[1], /) -> str: ... + def readline(self) -> object: ... + def close(self) -> object: ... + +if sys.version_info >= (3, 12): + def split(s: str | _ShlexInstream, comments: bool = False, posix: bool = True) -> list[str]: ... + +else: + @overload + def split(s: str | _ShlexInstream, comments: bool = False, posix: bool = True) -> list[str]: ... + @overload + @deprecated("Passing None for 's' to shlex.split() is deprecated and will raise an error in Python 3.12.") + def split(s: None, comments: bool = False, posix: bool = True) -> list[str]: ... + def join(split_command: Iterable[str]) -> str: ... def quote(s: str) -> str: ... +# TODO: Make generic over infile once PEP 696 is implemented. class shlex(Iterable[str]): commenters: str wordchars: str @@ -17,17 +36,18 @@ class shlex(Iterable[str]): escapedquotes: str whitespace_split: bool infile: str | None - instream: TextIO + instream: _ShlexInstream source: str debug: int lineno: int token: str + filestack: deque[tuple[str | None, _ShlexInstream, int]] eof: str | None @property def punctuation_chars(self) -> str: ... def __init__( self, - instream: str | TextIO | None = None, + instream: str | _ShlexInstream | None = None, infile: str | None = None, posix: bool = False, punctuation_chars: bool | str = False, @@ -35,8 +55,8 @@ class shlex(Iterable[str]): def get_token(self) -> str | None: ... def push_token(self, tok: str) -> None: ... def read_token(self) -> str | None: ... - def sourcehook(self, newfile: str) -> tuple[str, TextIO] | None: ... - def push_source(self, newstream: str | TextIO, newfile: str | None = None) -> None: ... + def sourcehook(self, newfile: str) -> tuple[str, TextIOWrapper] | None: ... + def push_source(self, newstream: str | _ShlexInstream, newfile: str | None = None) -> None: ... def pop_source(self) -> None: ... def error_leader(self, infile: str | None = None, lineno: int | None = None) -> str: ... def __iter__(self) -> Self: ... diff --git a/mypy/typeshed/stdlib/shutil.pyi b/mypy/typeshed/stdlib/shutil.pyi index f6440aa27513..a06181ce876d 100644 --- a/mypy/typeshed/stdlib/shutil.pyi +++ b/mypy/typeshed/stdlib/shutil.pyi @@ -4,7 +4,7 @@ from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, from collections.abc import Callable, Iterable, Sequence from tarfile import _TarfileFilter from typing import Any, AnyStr, NamedTuple, Protocol, TypeVar, overload -from typing_extensions import TypeAlias +from typing_extensions import TypeAlias, deprecated __all__ = [ "copyfileobj", @@ -78,24 +78,20 @@ class _RmtreeType(Protocol): avoids_symlink_attacks: bool if sys.version_info >= (3, 12): @overload + def __call__(self, path: StrOrBytesPath, ignore_errors: bool = False, *, dir_fd: int | None = None) -> None: ... + @overload + @deprecated("The `onerror` parameter is deprecated and will be removed in Python 3.14. Use `onexc` instead.") def __call__( self, path: StrOrBytesPath, ignore_errors: bool = False, onerror: _OnErrorCallback | None = None, *, - onexc: None = None, dir_fd: int | None = None, ) -> None: ... @overload def __call__( - self, - path: StrOrBytesPath, - ignore_errors: bool = False, - onerror: None = None, - *, - onexc: _OnExcCallback, - dir_fd: int | None = None, + self, path: StrOrBytesPath, ignore_errors: bool = False, *, onexc: _OnExcCallback, dir_fd: int | None = None ) -> None: ... elif sys.version_info >= (3, 11): def __call__( diff --git a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi index 659545c50b41..7cf75bbc33c5 100644 --- a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi +++ b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi @@ -221,16 +221,32 @@ def adapt(__obj: Any, __proto: Any) -> Any: ... @overload def adapt(__obj: Any, __proto: Any, __alt: _T) -> Any | _T: ... def complete_statement(statement: str) -> bool: ... -def connect( - database: StrOrBytesPath, - timeout: float = ..., - detect_types: int = ..., - isolation_level: str | None = ..., - check_same_thread: bool = ..., - factory: type[Connection] | None = ..., - cached_statements: int = ..., - uri: bool = ..., -) -> Connection: ... + +if sys.version_info >= (3, 12): + def connect( + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + autocommit: bool = ..., + ) -> Connection: ... + +else: + def connect( + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + ) -> Connection: ... + def enable_callback_tracebacks(__enable: bool) -> None: ... if sys.version_info < (3, 12): @@ -300,17 +316,32 @@ class Connection: def autocommit(self, val: int) -> None: ... row_factory: Any text_factory: Any - def __init__( - self, - database: StrOrBytesPath, - timeout: float = ..., - detect_types: int = ..., - isolation_level: str | None = ..., - check_same_thread: bool = ..., - factory: type[Connection] | None = ..., - cached_statements: int = ..., - uri: bool = ..., - ) -> None: ... + if sys.version_info >= (3, 12): + def __init__( + self, + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + autocommit: bool = ..., + ) -> None: ... + else: + def __init__( + self, + database: StrOrBytesPath, + timeout: float = ..., + detect_types: int = ..., + isolation_level: str | None = ..., + check_same_thread: bool = ..., + factory: type[Connection] | None = ..., + cached_statements: int = ..., + uri: bool = ..., + ) -> None: ... + def close(self) -> None: ... if sys.version_info >= (3, 11): def blobopen(self, __table: str, __column: str, __row: int, *, readonly: bool = False, name: str = "main") -> Blob: ... diff --git a/mypy/typeshed/stdlib/sysconfig.pyi b/mypy/typeshed/stdlib/sysconfig.pyi index 2edb71d78cdd..807a979050e8 100644 --- a/mypy/typeshed/stdlib/sysconfig.pyi +++ b/mypy/typeshed/stdlib/sysconfig.pyi @@ -1,5 +1,6 @@ import sys from typing import IO, Any, Literal, overload +from typing_extensions import deprecated __all__ = [ "get_config_h_filename", @@ -15,11 +16,15 @@ __all__ = [ "parse_config_h", ] +@overload +@deprecated("SO is deprecated, use EXT_SUFFIX. Support is removed in Python 3.11") +def get_config_var(name: Literal["SO"]) -> Any: ... +@overload def get_config_var(name: str) -> Any: ... @overload def get_config_vars() -> dict[str, Any]: ... @overload -def get_config_vars(arg: str, *args: str) -> list[Any]: ... +def get_config_vars(arg: str, /, *args: str) -> list[Any]: ... def get_scheme_names() -> tuple[str, ...]: ... if sys.version_info >= (3, 10): diff --git a/mypy/typeshed/stdlib/tarfile.pyi b/mypy/typeshed/stdlib/tarfile.pyi index 0bfd91ce2161..47c831190286 100644 --- a/mypy/typeshed/stdlib/tarfile.pyi +++ b/mypy/typeshed/stdlib/tarfile.pyi @@ -292,6 +292,8 @@ class TarFile: def getnames(self) -> _list[str]: ... def list(self, verbose: bool = True, *, members: _list[TarInfo] | None = None) -> None: ... def next(self) -> TarInfo | None: ... + # Calling this method without `filter` is deprecated, but it may be set either on the class or in an + # individual call, so we can't mark it as @deprecated here. def extractall( self, path: StrOrBytesPath = ".", @@ -300,6 +302,7 @@ class TarFile: numeric_owner: bool = False, filter: _TarfileFilter | None = ..., ) -> None: ... + # Same situation as for `extractall`. def extract( self, member: str | TarInfo, diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index 4733c31b5bae..3f65eb2c8fe4 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -665,7 +665,7 @@ class Wm: iconmask = wm_iconmask def wm_iconname(self, newName: Incomplete | None = None) -> str: ... iconname = wm_iconname - def wm_iconphoto(self, default: bool, __image1: _PhotoImageLike | str, *args: _PhotoImageLike | str) -> None: ... + def wm_iconphoto(self, default: bool, image1: _PhotoImageLike | str, /, *args: _PhotoImageLike | str) -> None: ... iconphoto = wm_iconphoto def wm_iconposition(self, x: int | None = None, y: int | None = None) -> tuple[int, int] | None: ... iconposition = wm_iconposition @@ -1721,7 +1721,9 @@ class Canvas(Widget, XView, YView): def tag_raise(self, __first: str | int, __second: str | int | None = ...) -> None: ... def tkraise(self, __first: str | int, __second: str | int | None = ...) -> None: ... # type: ignore[override] def lift(self, __first: str | int, __second: str | int | None = ...) -> None: ... # type: ignore[override] - def scale(self, *args) -> None: ... + def scale( + self, __tagOrId: str | int, __xOrigin: _ScreenUnits, __yOrigin: _ScreenUnits, __xScale: float, __yScale: float + ) -> None: ... def scan_mark(self, x, y) -> None: ... def scan_dragto(self, x, y, gain: int = 10) -> None: ... def select_adjust(self, tagOrId, index) -> None: ... diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index 05ffc2143233..05c5e85e4a9e 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -17,7 +17,7 @@ from importlib.machinery import ModuleSpec # pytype crashes if types.MappingProxyType inherits from collections.abc.Mapping instead of typing.Mapping from typing import Any, ClassVar, Literal, Mapping, Protocol, TypeVar, final, overload # noqa: Y022 -from typing_extensions import ParamSpec, Self, TypeVarTuple +from typing_extensions import ParamSpec, Self, TypeVarTuple, deprecated __all__ = [ "FunctionType", @@ -138,8 +138,14 @@ class CodeType: def co_name(self) -> str: ... @property def co_firstlineno(self) -> int: ... - @property - def co_lnotab(self) -> bytes: ... + if sys.version_info >= (3, 10): + @property + @deprecated("Will be removed in Python 3.14. Use the co_lines() method instead.") + def co_lnotab(self) -> bytes: ... + else: + @property + def co_lnotab(self) -> bytes: ... + @property def co_freevars(self) -> tuple[str, ...]: ... @property diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index ea5c7b21aa87..921c1334cfe4 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -182,6 +182,7 @@ __all__ = [ "no_type_check", "no_type_check_decorator", "ReadOnly", + "TypeIs", ] _T = typing.TypeVar("_T") @@ -220,10 +221,14 @@ def IntVar(name: str) -> Any: ... # returns a new TypeVar class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): __required_keys__: ClassVar[frozenset[str]] __optional_keys__: ClassVar[frozenset[str]] - __readonly_keys__: ClassVar[frozenset[str]] - __mutable_keys__: ClassVar[frozenset[str]] __total__: ClassVar[bool] __orig_bases__: ClassVar[tuple[Any, ...]] + # PEP 705 + __readonly_keys__: ClassVar[frozenset[str]] + __mutable_keys__: ClassVar[frozenset[str]] + # PEP 728 + __closed__: ClassVar[bool] + __extra_items__: ClassVar[Any] def copy(self) -> Self: ... # Using Never so that only calls using mypy plugin hook that specialize the signature # can go through. @@ -501,3 +506,4 @@ class Doc: def __eq__(self, other: object) -> bool: ... ReadOnly: _SpecialForm +TypeIs: _SpecialForm diff --git a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi index c508f72892c1..2a363a504dec 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi @@ -3,7 +3,7 @@ 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, Literal, SupportsIndex, TypeVar, overload -from typing_extensions import TypeAlias, TypeGuard +from typing_extensions import TypeAlias, TypeGuard, deprecated __all__ = [ "C14NWriterTarget", @@ -121,6 +121,10 @@ class Element: def __setitem__(self, __key: SupportsIndex, __value: Element) -> None: ... @overload def __setitem__(self, __key: slice, __value: Iterable[Element]) -> None: ... + + # Doesn't really exist in earlier versions, where __len__ is called implicitly instead + @deprecated("Testing an element's truth value is deprecated.") + def __bool__(self) -> bool: ... if sys.version_info < (3, 9): def getchildren(self) -> list[Element]: ... def getiterator(self, tag: str | None = None) -> list[Element]: ... From 055184f28dd83f20ba36cadbb7a75e5f30cf36d8 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Thu, 29 Feb 2024 22:02:54 -0800 Subject: [PATCH 104/172] Fix override checking for decorated property (#16856) Fixes #16855 --- mypy/checker.py | 39 +++++++++++++++----------- test-data/unit/check-functions.test | 43 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 9f987cb5ccdf..a272a3aaac3d 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2020,22 +2020,29 @@ def check_method_override_for_base_with_name( if original_node and is_property(original_node): original_type = get_property_type(original_type) - if isinstance(typ, FunctionLike) and is_property(defn): - typ = get_property_type(typ) - if ( - isinstance(original_node, Var) - and not original_node.is_final - and (not original_node.is_property or original_node.is_settable_property) - and isinstance(defn, Decorator) - ): - # We only give an error where no other similar errors will be given. - if not isinstance(original_type, AnyType): - self.msg.fail( - "Cannot override writeable attribute with read-only property", - # Give an error on function line to match old behaviour. - defn.func, - code=codes.OVERRIDE, - ) + if is_property(defn): + inner: FunctionLike | None + if isinstance(typ, FunctionLike): + inner = typ + else: + inner = self.extract_callable_type(typ, context) + if inner is not None: + typ = inner + typ = get_property_type(typ) + if ( + isinstance(original_node, Var) + and not original_node.is_final + and (not original_node.is_property or original_node.is_settable_property) + and isinstance(defn, Decorator) + ): + # We only give an error where no other similar errors will be given. + if not isinstance(original_type, AnyType): + self.msg.fail( + "Cannot override writeable attribute with read-only property", + # Give an error on function line to match old behaviour. + defn.func, + code=codes.OVERRIDE, + ) if isinstance(original_type, AnyType) or isinstance(typ, AnyType): pass diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index b3df5fddafba..3aecbe065c27 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2730,6 +2730,49 @@ f: Callable[[Sequence[TI]], None] g: Callable[[Union[Sequence[TI], Sequence[TS]]], None] f = g +[case testOverrideDecoratedProperty] +class Base: + @property + def foo(self) -> int: ... + +class decorator: + def __init__(self, fn): + self.fn = fn + def __call__(self, decorated_self) -> int: + return self.fn(decorated_self) + +class Child(Base): + @property + @decorator + def foo(self) -> int: + return 42 + +reveal_type(Child().foo) # N: Revealed type is "builtins.int" + +class BadChild1(Base): + @decorator + def foo(self) -> int: # E: Signature of "foo" incompatible with supertype "Base" \ + # N: Superclass: \ + # N: int \ + # N: Subclass: \ + # N: decorator + return 42 + +class not_a_decorator: + def __init__(self, fn): ... + +class BadChild2(Base): + @property + @not_a_decorator + def foo(self) -> int: # E: "not_a_decorator" not callable \ + # E: Signature of "foo" incompatible with supertype "Base" \ + # N: Superclass: \ + # N: int \ + # N: Subclass: \ + # N: not_a_decorator + return 42 +[builtins fixtures/property.pyi] + [case explicitOverride] # flags: --python-version 3.12 from typing import override From 3c87af272cbf7c49699b7508c7f51365da139c05 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:08:22 +0100 Subject: [PATCH 105/172] Allow TypedDict initialization from Type (#16963) Fixes #11644 --- mypy/checkexpr.py | 2 ++ test-data/unit/check-typeddict.test | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 2842606b7b18..e893410e2b7d 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1855,6 +1855,8 @@ def analyze_type_type_callee(self, item: ProperType, context: Context) -> Type: # We support Type of namedtuples but not of tuples in general if isinstance(item, TupleType) and tuple_fallback(item).type.fullname != "builtins.tuple": return self.analyze_type_type_callee(tuple_fallback(item), context) + if isinstance(item, TypedDictType): + return self.typeddict_callable_from_context(item) self.msg.unsupported_type_type(item, context) return AnyType(TypeOfAny.from_error) diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index adf4d210ed0c..639be7bde8d8 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -3447,3 +3447,19 @@ class Params(TypedDict("Params", {'x': int})): p: Params = {'x': 2} reveal_type(p) # N: Revealed type is "TypedDict('__main__.Params', {'x': builtins.int})" [builtins fixtures/dict.pyi] + +[case testInitTypedDictFromType] +from typing import TypedDict, Type + +class Point(TypedDict): + x: int + y: int + +def func(cls: Type[Point]) -> None: + reveal_type(cls) # N: Revealed type is "Type[TypedDict('__main__.Point', {'x': builtins.int, 'y': builtins.int})]" + cls(x=1, y=2) + cls(1, 2) # E: Too many positional arguments + cls(x=1) # E: Missing named argument "y" + cls(x=1, y=2, error="") # E: Unexpected keyword argument "error" +[typing fixtures/typing-full.pyi] +[builtins fixtures/tuple.pyi] From bcb3747f277745f7a0035bb92cc95ee83f6778dc Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 1 Mar 2024 06:01:34 -0800 Subject: [PATCH 106/172] Implement TypeIs (PEP 742) (#16898) Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> --- docs/source/error_code_list2.rst | 16 + mypy/applytype.py | 7 +- mypy/checker.py | 42 +- mypy/checkexpr.py | 13 +- mypy/constraints.py | 16 +- mypy/errorcodes.py | 6 + mypy/expandtype.py | 2 + mypy/fixup.py | 2 + mypy/message_registry.py | 5 +- mypy/messages.py | 4 + mypy/nodes.py | 3 + mypy/semanal.py | 7 + mypy/subtypes.py | 13 + mypy/typeanal.py | 27 +- mypy/types.py | 9 + test-data/unit/check-errorcodes.test | 8 + test-data/unit/check-typeguard.test | 2 +- test-data/unit/check-typeis.test | 798 ++++++++++++++++++ test-data/unit/lib-stub/typing_extensions.pyi | 1 + 19 files changed, 962 insertions(+), 19 deletions(-) create mode 100644 test-data/unit/check-typeis.test diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index c966fe1f7ea6..465d1c7a6583 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -555,3 +555,19 @@ Correct usage: When this code is enabled, using ``reveal_locals`` is always an error, because there's no way one can import it. + +.. _code-narrowed-type-not-subtype: + +Check that ``TypeIs`` narrows types [narrowed-type-not-subtype] +--------------------------------------------------------------- + +:pep:`742` requires that when ``TypeIs`` is used, the narrowed +type must be a subtype of the original type:: + + from typing_extensions import TypeIs + + def f(x: int) -> TypeIs[str]: # Error, str is not a subtype of int + ... + + def g(x: object) -> TypeIs[str]: # OK + ... diff --git a/mypy/applytype.py b/mypy/applytype.py index e14906fa2772..eecd555bf90d 100644 --- a/mypy/applytype.py +++ b/mypy/applytype.py @@ -137,11 +137,15 @@ def apply_generic_arguments( arg_types=[expand_type(at, id_to_type) for at in callable.arg_types] ) - # Apply arguments to TypeGuard if any. + # Apply arguments to TypeGuard and TypeIs if any. if callable.type_guard is not None: type_guard = expand_type(callable.type_guard, id_to_type) else: type_guard = None + if callable.type_is is not None: + type_is = expand_type(callable.type_is, id_to_type) + else: + type_is = None # The callable may retain some type vars if only some were applied. # TODO: move apply_poly() logic from checkexpr.py here when new inference @@ -164,4 +168,5 @@ def apply_generic_arguments( ret_type=expand_type(callable.ret_type, id_to_type), variables=remaining_tvars, type_guard=type_guard, + type_is=type_is, ) diff --git a/mypy/checker.py b/mypy/checker.py index a272a3aaac3d..941dc06f1c71 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -1203,6 +1203,22 @@ def check_func_def( # visible from *inside* of this function/method. ref_type: Type | None = self.scope.active_self_type() + if typ.type_is: + arg_index = 0 + # For methods and classmethods, we want the second parameter + if ref_type is not None and (not defn.is_static or defn.name == "__new__"): + arg_index = 1 + if arg_index < len(typ.arg_types) and not is_subtype( + typ.type_is, typ.arg_types[arg_index] + ): + self.fail( + message_registry.NARROWED_TYPE_NOT_SUBTYPE.format( + format_type(typ.type_is, self.options), + format_type(typ.arg_types[arg_index], self.options), + ), + item, + ) + # Store argument types. for i in range(len(typ.arg_types)): arg_type = typ.arg_types[i] @@ -2178,6 +2194,8 @@ def check_override( elif isinstance(original, CallableType) and isinstance(override, CallableType): if original.type_guard is not None and override.type_guard is None: fail = True + if original.type_is is not None and override.type_is is None: + fail = True if is_private(name): fail = False @@ -5643,7 +5661,7 @@ def combine_maps(list_maps: list[TypeMap]) -> TypeMap: def find_isinstance_check(self, node: Expression) -> tuple[TypeMap, TypeMap]: """Find any isinstance checks (within a chain of ands). Includes implicit and explicit checks for None and calls to callable. - Also includes TypeGuard functions. + Also includes TypeGuard and TypeIs functions. Return value is a map of variables to their types if the condition is true and a map of variables to their types if the condition is false. @@ -5695,7 +5713,7 @@ def find_isinstance_check_helper(self, node: Expression) -> tuple[TypeMap, TypeM if literal(expr) == LITERAL_TYPE and attr and len(attr) == 1: return self.hasattr_type_maps(expr, self.lookup_type(expr), attr[0]) elif isinstance(node.callee, RefExpr): - if node.callee.type_guard is not None: + if node.callee.type_guard is not None or node.callee.type_is is not None: # TODO: Follow *args, **kwargs if node.arg_kinds[0] != nodes.ARG_POS: # the first argument might be used as a kwarg @@ -5721,7 +5739,12 @@ def find_isinstance_check_helper(self, node: Expression) -> tuple[TypeMap, TypeM # we want the idx-th variable to be narrowed expr = collapse_walrus(node.args[idx]) else: - self.fail(message_registry.TYPE_GUARD_POS_ARG_REQUIRED, node) + kind = ( + "guard" if node.callee.type_guard is not None else "narrower" + ) + self.fail( + message_registry.TYPE_GUARD_POS_ARG_REQUIRED.format(kind), node + ) return {}, {} if literal(expr) == LITERAL_TYPE: # Note: we wrap the target type, so that we can special case later. @@ -5729,7 +5752,18 @@ def find_isinstance_check_helper(self, node: Expression) -> tuple[TypeMap, TypeM # considered "always right" (i.e. even if the types are not overlapping). # Also note that a care must be taken to unwrap this back at read places # where we use this to narrow down declared type. - return {expr: TypeGuardedType(node.callee.type_guard)}, {} + if node.callee.type_guard is not None: + return {expr: TypeGuardedType(node.callee.type_guard)}, {} + else: + assert node.callee.type_is is not None + return conditional_types_to_typemaps( + expr, + *self.conditional_types_with_intersection( + self.lookup_type(expr), + [TypeRange(node.callee.type_is, is_upper_bound=False)], + expr, + ), + ) elif isinstance(node, ComparisonExpr): # Step 1: Obtain the types of each operand and whether or not we can # narrow their types. (For example, we shouldn't try narrowing the diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index e893410e2b7d..37a90ce55b9e 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -1451,13 +1451,12 @@ def check_call_expr_with_callee_type( object_type=object_type, ) proper_callee = get_proper_type(callee_type) - if ( - isinstance(e.callee, RefExpr) - and isinstance(proper_callee, CallableType) - and proper_callee.type_guard is not None - ): + if isinstance(e.callee, RefExpr) and isinstance(proper_callee, CallableType): # Cache it for find_isinstance_check() - e.callee.type_guard = proper_callee.type_guard + if proper_callee.type_guard is not None: + e.callee.type_guard = proper_callee.type_guard + if proper_callee.type_is is not None: + e.callee.type_is = proper_callee.type_is return ret_type def check_union_call_expr(self, e: CallExpr, object_type: UnionType, member: str) -> Type: @@ -5283,7 +5282,7 @@ def infer_lambda_type_using_context( # is a constructor -- but this fallback doesn't make sense for lambdas. callable_ctx = callable_ctx.copy_modified(fallback=self.named_type("builtins.function")) - if callable_ctx.type_guard is not None: + if callable_ctx.type_guard is not None or callable_ctx.type_is is not None: # Lambda's return type cannot be treated as a `TypeGuard`, # because it is implicit. And `TypeGuard`s must be explicit. # See https://github.com/python/mypy/issues/9927 diff --git a/mypy/constraints.py b/mypy/constraints.py index c4eba2ca1ede..cdfa39ac45f3 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -1018,10 +1018,22 @@ def visit_callable_type(self, template: CallableType) -> list[Constraint]: param_spec = template.param_spec() template_ret_type, cactual_ret_type = template.ret_type, cactual.ret_type - if template.type_guard is not None: + if template.type_guard is not None and cactual.type_guard is not None: template_ret_type = template.type_guard - if cactual.type_guard is not None: cactual_ret_type = cactual.type_guard + elif template.type_guard is not None: + template_ret_type = AnyType(TypeOfAny.special_form) + elif cactual.type_guard is not None: + cactual_ret_type = AnyType(TypeOfAny.special_form) + + if template.type_is is not None and cactual.type_is is not None: + template_ret_type = template.type_is + cactual_ret_type = cactual.type_is + elif template.type_is is not None: + template_ret_type = AnyType(TypeOfAny.special_form) + elif cactual.type_is is not None: + cactual_ret_type = AnyType(TypeOfAny.special_form) + res.extend(infer_constraints(template_ret_type, cactual_ret_type, self.direction)) if param_spec is None: diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index 72ee63a6a897..688bd6a4ddd5 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -281,5 +281,11 @@ def __hash__(self) -> int: sub_code_of=MISC, ) +NARROWED_TYPE_NOT_SUBTYPE: Final[ErrorCode] = ErrorCode( + "narrowed-type-not-subtype", + "Warn if a TypeIs function's narrowed type is not a subtype of the original type", + "General", +) + # This copy will not include any error codes defined later in the plugins. mypy_error_codes = error_codes.copy() diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 3bf45854b2a0..ec6a2ecfd0d2 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -351,6 +351,7 @@ def visit_callable_type(self, t: CallableType) -> CallableType: arg_names=t.arg_names[:-2] + repl.arg_names, ret_type=t.ret_type.accept(self), type_guard=(t.type_guard.accept(self) if t.type_guard is not None else None), + type_is=(t.type_is.accept(self) if t.type_is is not None else None), imprecise_arg_kinds=(t.imprecise_arg_kinds or repl.imprecise_arg_kinds), variables=[*repl.variables, *t.variables], ) @@ -384,6 +385,7 @@ def visit_callable_type(self, t: CallableType) -> CallableType: arg_types=arg_types, ret_type=t.ret_type.accept(self), type_guard=(t.type_guard.accept(self) if t.type_guard is not None else None), + type_is=(t.type_is.accept(self) if t.type_is is not None else None), ) if needs_normalization: return expanded.with_normalized_var_args() diff --git a/mypy/fixup.py b/mypy/fixup.py index 02c6ab93f29e..849a6483d724 100644 --- a/mypy/fixup.py +++ b/mypy/fixup.py @@ -270,6 +270,8 @@ def visit_callable_type(self, ct: CallableType) -> None: arg.accept(self) if ct.type_guard is not None: ct.type_guard.accept(self) + if ct.type_is is not None: + ct.type_is.accept(self) def visit_overloaded(self, t: Overloaded) -> None: for ct in t.items: diff --git a/mypy/message_registry.py b/mypy/message_registry.py index fb430b63c74b..ccc1443dacf0 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -262,7 +262,7 @@ def with_additional_msg(self, info: str) -> ErrorMessage: CONTIGUOUS_ITERABLE_EXPECTED: Final = ErrorMessage("Contiguous iterable with same type expected") ITERABLE_TYPE_EXPECTED: Final = ErrorMessage("Invalid type '{}' for *expr (iterable expected)") -TYPE_GUARD_POS_ARG_REQUIRED: Final = ErrorMessage("Type guard requires positional argument") +TYPE_GUARD_POS_ARG_REQUIRED: Final = ErrorMessage("Type {} requires positional argument") # Match Statement MISSING_MATCH_ARGS: Final = 'Class "{}" doesn\'t define "__match_args__"' @@ -324,3 +324,6 @@ def with_additional_msg(self, info: str) -> ErrorMessage: ARG_NAME_EXPECTED_STRING_LITERAL: Final = ErrorMessage( "Expected string literal for argument name, got {}", codes.SYNTAX ) +NARROWED_TYPE_NOT_SUBTYPE: Final = ErrorMessage( + "Narrowed type {} is not a subtype of input type {}", codes.NARROWED_TYPE_NOT_SUBTYPE +) diff --git a/mypy/messages.py b/mypy/messages.py index db6c91ba9008..92b57ef781a2 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -2643,6 +2643,8 @@ def format_literal_value(typ: LiteralType) -> str: elif isinstance(func, CallableType): if func.type_guard is not None: return_type = f"TypeGuard[{format(func.type_guard)}]" + elif func.type_is is not None: + return_type = f"TypeIs[{format(func.type_is)}]" else: return_type = format(func.ret_type) if func.is_ellipsis_args: @@ -2859,6 +2861,8 @@ def [T <: int] f(self, x: int, y: T) -> None s += " -> " if tp.type_guard is not None: s += f"TypeGuard[{format_type_bare(tp.type_guard, options)}]" + elif tp.type_is is not None: + s += f"TypeIs[{format_type_bare(tp.type_is, options)}]" else: s += format_type_bare(tp.ret_type, options) diff --git a/mypy/nodes.py b/mypy/nodes.py index 1c781320580a..bb278d92392d 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -1755,6 +1755,7 @@ class RefExpr(Expression): "is_inferred_def", "is_alias_rvalue", "type_guard", + "type_is", ) def __init__(self) -> None: @@ -1776,6 +1777,8 @@ def __init__(self) -> None: self.is_alias_rvalue = False # Cache type guard from callable_type.type_guard self.type_guard: mypy.types.Type | None = None + # And same for TypeIs + self.type_is: mypy.types.Type | None = None @property def fullname(self) -> str: diff --git a/mypy/semanal.py b/mypy/semanal.py index 38d5ddec0818..6bf02382a036 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -881,6 +881,13 @@ def analyze_func_def(self, defn: FuncDef) -> None: ) # in this case, we just kind of just ... remove the type guard. result = result.copy_modified(type_guard=None) + if result.type_is and ARG_POS not in result.arg_kinds[skip_self:]: + self.fail( + '"TypeIs" functions must have a positional argument', + result, + code=codes.VALID_TYPE, + ) + result = result.copy_modified(type_is=None) result = self.remove_unpack_kwargs(defn, result) if has_self_type and self.type is not None: diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 2d536f892a2a..4d5e7335b14f 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -683,10 +683,23 @@ def visit_callable_type(self, left: CallableType) -> bool: if left.type_guard is not None and right.type_guard is not None: if not self._is_subtype(left.type_guard, right.type_guard): return False + elif left.type_is is not None and right.type_is is not None: + # For TypeIs we have to check both ways; it is unsafe to pass + # a TypeIs[Child] when a TypeIs[Parent] is expected, because + # if the narrower returns False, we assume that the narrowed value is + # *not* a Parent. + if not self._is_subtype(left.type_is, right.type_is) or not self._is_subtype( + right.type_is, left.type_is + ): + return False elif right.type_guard is not None and left.type_guard is None: # This means that one function has `TypeGuard` and other does not. # They are not compatible. See https://github.com/python/mypy/issues/11307 return False + elif right.type_is is not None and left.type_is is None: + # Similarly, if one function has `TypeIs` and the other does not, + # they are not compatible. + return False return is_callable_compatible( left, right, diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 9cc0114df333..8a9ac8f4ac31 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -668,7 +668,10 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Typ ) return AnyType(TypeOfAny.from_error) return RequiredType(self.anal_type(t.args[0]), required=False) - elif self.anal_type_guard_arg(t, fullname) is not None: + elif ( + self.anal_type_guard_arg(t, fullname) is not None + or self.anal_type_is_arg(t, fullname) is not None + ): # In most contexts, TypeGuard[...] acts as an alias for bool (ignoring its args) return self.named_type("builtins.bool") elif fullname in ("typing.Unpack", "typing_extensions.Unpack"): @@ -986,7 +989,8 @@ def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type: variables = t.variables else: variables, _ = self.bind_function_type_variables(t, t) - special = self.anal_type_guard(t.ret_type) + type_guard = self.anal_type_guard(t.ret_type) + type_is = self.anal_type_is(t.ret_type) arg_kinds = t.arg_kinds if len(arg_kinds) >= 2 and arg_kinds[-2] == ARG_STAR and arg_kinds[-1] == ARG_STAR2: arg_types = self.anal_array(t.arg_types[:-2], nested=nested) + [ @@ -1041,7 +1045,8 @@ def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type: # its type will be the falsey FakeInfo fallback=(t.fallback if t.fallback.type else self.named_type("builtins.function")), variables=self.anal_var_defs(variables), - type_guard=special, + type_guard=type_guard, + type_is=type_is, unpack_kwargs=unpacked_kwargs, ) return ret @@ -1064,6 +1069,22 @@ def anal_type_guard_arg(self, t: UnboundType, fullname: str) -> Type | None: return self.anal_type(t.args[0]) return None + def anal_type_is(self, t: Type) -> Type | None: + if isinstance(t, UnboundType): + sym = self.lookup_qualified(t.name, t) + if sym is not None and sym.node is not None: + return self.anal_type_is_arg(t, sym.node.fullname) + # TODO: What if it's an Instance? Then use t.type.fullname? + return None + + def anal_type_is_arg(self, t: UnboundType, fullname: str) -> Type | None: + if fullname in ("typing_extensions.TypeIs", "typing.TypeIs"): + if len(t.args) != 1: + self.fail("TypeIs must have exactly one type argument", t, code=codes.VALID_TYPE) + return AnyType(TypeOfAny.from_error) + return self.anal_type(t.args[0]) + return None + def anal_star_arg_type(self, t: Type, kind: ArgKind, nested: bool) -> Type: """Analyze signature argument type for *args and **kwargs argument.""" if isinstance(t, UnboundType) and t.name and "." in t.name and not t.args: diff --git a/mypy/types.py b/mypy/types.py index f76e35784d8f..b34efde15b31 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1800,6 +1800,7 @@ class CallableType(FunctionLike): "def_extras", # Information about original definition we want to serialize. # This is used for more detailed error messages. "type_guard", # T, if -> TypeGuard[T] (ret_type is bool in this case). + "type_is", # T, if -> TypeIs[T] (ret_type is bool in this case). "from_concatenate", # whether this callable is from a concatenate object # (this is used for error messages) "imprecise_arg_kinds", @@ -1826,6 +1827,7 @@ def __init__( bound_args: Sequence[Type | None] = (), def_extras: dict[str, Any] | None = None, type_guard: Type | None = None, + type_is: Type | None = None, from_concatenate: bool = False, imprecise_arg_kinds: bool = False, unpack_kwargs: bool = False, @@ -1875,6 +1877,7 @@ def __init__( else: self.def_extras = {} self.type_guard = type_guard + self.type_is = type_is self.unpack_kwargs = unpack_kwargs def copy_modified( @@ -1896,6 +1899,7 @@ def copy_modified( bound_args: Bogus[list[Type | None]] = _dummy, def_extras: Bogus[dict[str, Any]] = _dummy, type_guard: Bogus[Type | None] = _dummy, + type_is: Bogus[Type | None] = _dummy, from_concatenate: Bogus[bool] = _dummy, imprecise_arg_kinds: Bogus[bool] = _dummy, unpack_kwargs: Bogus[bool] = _dummy, @@ -1920,6 +1924,7 @@ def copy_modified( bound_args=bound_args if bound_args is not _dummy else self.bound_args, def_extras=def_extras if def_extras is not _dummy else dict(self.def_extras), type_guard=type_guard if type_guard is not _dummy else self.type_guard, + type_is=type_is if type_is is not _dummy else self.type_is, from_concatenate=( from_concatenate if from_concatenate is not _dummy else self.from_concatenate ), @@ -2233,6 +2238,7 @@ def serialize(self) -> JsonDict: "bound_args": [(None if t is None else t.serialize()) for t in self.bound_args], "def_extras": dict(self.def_extras), "type_guard": self.type_guard.serialize() if self.type_guard is not None else None, + "type_is": (self.type_is.serialize() if self.type_is is not None else None), "from_concatenate": self.from_concatenate, "imprecise_arg_kinds": self.imprecise_arg_kinds, "unpack_kwargs": self.unpack_kwargs, @@ -2257,6 +2263,7 @@ def deserialize(cls, data: JsonDict) -> CallableType: type_guard=( deserialize_type(data["type_guard"]) if data["type_guard"] is not None else None ), + type_is=(deserialize_type(data["type_is"]) if data["type_is"] is not None else None), from_concatenate=data["from_concatenate"], imprecise_arg_kinds=data["imprecise_arg_kinds"], unpack_kwargs=data["unpack_kwargs"], @@ -3315,6 +3322,8 @@ def visit_callable_type(self, t: CallableType) -> str: if not isinstance(get_proper_type(t.ret_type), NoneType): if t.type_guard is not None: s += f" -> TypeGuard[{t.type_guard.accept(self)}]" + elif t.type_is is not None: + s += f" -> TypeIs[{t.type_is.accept(self)}]" else: s += f" -> {t.ret_type.accept(self)}" diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 7f5f05d37595..9d49480539e0 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -1182,3 +1182,11 @@ class D(C): def other(self) -> None: self.bad2: int = 5 # E: Covariant override of a mutable attribute (base class "C" defined the type as "float", expression has type "int") [mutable-override] [builtins fixtures/property.pyi] + +[case testNarrowedTypeNotSubtype] +from typing_extensions import TypeIs + +def f(x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of input type "str" [narrowed-type-not-subtype] + pass + +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-typeguard.test b/test-data/unit/check-typeguard.test index c48887bb016a..66c21bf3abe1 100644 --- a/test-data/unit/check-typeguard.test +++ b/test-data/unit/check-typeguard.test @@ -504,7 +504,7 @@ def with_bool(o: object) -> bool: pass accepts_typeguard(with_bool_typeguard) accepts_typeguard(with_str_typeguard) -accepts_typeguard(with_bool) # E: Argument 1 to "accepts_typeguard" has incompatible type "Callable[[object], bool]"; expected "Callable[[object], TypeGuard[bool]]" +accepts_typeguard(with_bool) # E: Argument 1 to "accepts_typeguard" has incompatible type "Callable[[object], bool]"; expected "Callable[[object], TypeGuard[Never]]" [builtins fixtures/tuple.pyi] [case testTypeGuardAsOverloadedFunctionArg] diff --git a/test-data/unit/check-typeis.test b/test-data/unit/check-typeis.test new file mode 100644 index 000000000000..04b64a45c8c1 --- /dev/null +++ b/test-data/unit/check-typeis.test @@ -0,0 +1,798 @@ +[case testTypeIsBasic] +from typing_extensions import TypeIs +class Point: pass +def is_point(a: object) -> TypeIs[Point]: pass +def main(a: object) -> None: + if is_point(a): + reveal_type(a) # N: Revealed type is "__main__.Point" + else: + reveal_type(a) # N: Revealed type is "builtins.object" +[builtins fixtures/tuple.pyi] + +[case testTypeIsElif] +from typing_extensions import TypeIs +from typing import Union +class Point: pass +def is_point(a: object) -> TypeIs[Point]: pass +class Line: pass +def is_line(a: object) -> TypeIs[Line]: pass +def main(a: Union[Point, Line, int]) -> None: + if is_point(a): + reveal_type(a) # N: Revealed type is "__main__.Point" + elif is_line(a): + reveal_type(a) # N: Revealed type is "__main__.Line" + else: + reveal_type(a) # N: Revealed type is "builtins.int" + +[builtins fixtures/tuple.pyi] + +[case testTypeIsTypeArgsNone] +from typing_extensions import TypeIs +def foo(a: object) -> TypeIs: # E: TypeIs must have exactly one type argument + pass +[builtins fixtures/tuple.pyi] + +[case testTypeIsTypeArgsTooMany] +from typing_extensions import TypeIs +def foo(a: object) -> TypeIs[int, int]: # E: TypeIs must have exactly one type argument + pass +[builtins fixtures/tuple.pyi] + +[case testTypeIsTypeArgType] +from typing_extensions import TypeIs +def foo(a: object) -> TypeIs[42]: # E: Invalid type: try using Literal[42] instead? + pass +[builtins fixtures/tuple.pyi] + +[case testTypeIsRepr] +from typing_extensions import TypeIs +def foo(a: object) -> TypeIs[int]: + pass +reveal_type(foo) # N: Revealed type is "def (a: builtins.object) -> TypeIs[builtins.int]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsCallArgsNone] +from typing_extensions import TypeIs +class Point: pass + +def is_point() -> TypeIs[Point]: pass # E: "TypeIs" functions must have a positional argument +def main(a: object) -> None: + if is_point(): + reveal_type(a) # N: Revealed type is "builtins.object" +[builtins fixtures/tuple.pyi] + +[case testTypeIsCallArgsMultiple] +from typing_extensions import TypeIs +class Point: pass +def is_point(a: object, b: object) -> TypeIs[Point]: pass +def main(a: object, b: object) -> None: + if is_point(a, b): + reveal_type(a) # N: Revealed type is "__main__.Point" + reveal_type(b) # N: Revealed type is "builtins.object" +[builtins fixtures/tuple.pyi] + +[case testTypeIsIsBool] +from typing_extensions import TypeIs +def f(a: TypeIs[int]) -> None: pass +reveal_type(f) # N: Revealed type is "def (a: builtins.bool)" +a: TypeIs[int] +reveal_type(a) # N: Revealed type is "builtins.bool" +class C: + a: TypeIs[int] +reveal_type(C().a) # N: Revealed type is "builtins.bool" +[builtins fixtures/tuple.pyi] + +[case testTypeIsWithTypeVar] +from typing import TypeVar, Tuple, Type +from typing_extensions import TypeIs +T = TypeVar('T') +def is_tuple_of_type(a: Tuple[object, ...], typ: Type[T]) -> TypeIs[Tuple[T, ...]]: pass +def main(a: Tuple[object, ...]): + if is_tuple_of_type(a, int): + reveal_type(a) # N: Revealed type is "builtins.tuple[builtins.int, ...]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsUnionIn] +from typing import Union +from typing_extensions import TypeIs +def is_foo(a: Union[int, str]) -> TypeIs[str]: pass +def main(a: Union[str, int]) -> None: + if is_foo(a): + reveal_type(a) # N: Revealed type is "builtins.str" + else: + reveal_type(a) # N: Revealed type is "builtins.int" + reveal_type(a) # N: Revealed type is "Union[builtins.str, builtins.int]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsUnionOut] +from typing import Union +from typing_extensions import TypeIs +def is_foo(a: object) -> TypeIs[Union[int, str]]: pass +def main(a: object) -> None: + if is_foo(a): + reveal_type(a) # N: Revealed type is "Union[builtins.int, builtins.str]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsNonzeroFloat] +from typing_extensions import TypeIs +def is_nonzero(a: object) -> TypeIs[float]: pass +def main(a: int): + if is_nonzero(a): + reveal_type(a) # N: Revealed type is "builtins.int" +[builtins fixtures/tuple.pyi] + +[case testTypeIsHigherOrder] +from typing import Callable, TypeVar, Iterable, List +from typing_extensions import TypeIs +T = TypeVar('T') +R = TypeVar('R') +def filter(f: Callable[[T], TypeIs[R]], it: Iterable[T]) -> Iterable[R]: pass +def is_float(a: object) -> TypeIs[float]: pass +a: List[object] = ["a", 0, 0.0] +b = filter(is_float, a) +reveal_type(b) # N: Revealed type is "typing.Iterable[builtins.float]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsMethod] +from typing_extensions import TypeIs +class C: + def main(self, a: object) -> None: + if self.is_float(a): + reveal_type(self) # N: Revealed type is "__main__.C" + reveal_type(a) # N: Revealed type is "builtins.float" + def is_float(self, a: object) -> TypeIs[float]: pass +[builtins fixtures/tuple.pyi] + +[case testTypeIsCrossModule] +import guard +from points import Point +def main(a: object) -> None: + if guard.is_point(a): + reveal_type(a) # N: Revealed type is "points.Point" +[file guard.py] +from typing_extensions import TypeIs +import points +def is_point(a: object) -> TypeIs[points.Point]: pass +[file points.py] +class Point: pass +[builtins fixtures/tuple.pyi] + +[case testTypeIsBodyRequiresBool] +from typing_extensions import TypeIs +def is_float(a: object) -> TypeIs[float]: + return "not a bool" # E: Incompatible return value type (got "str", expected "bool") +[builtins fixtures/tuple.pyi] + +[case testTypeIsNarrowToTypedDict] +from typing import Mapping, TypedDict +from typing_extensions import TypeIs +class User(TypedDict): + name: str + id: int +def is_user(a: Mapping[str, object]) -> TypeIs[User]: + return isinstance(a.get("name"), str) and isinstance(a.get("id"), int) +def main(a: Mapping[str, object]) -> None: + if is_user(a): + reveal_type(a) # N: Revealed type is "TypedDict('__main__.User', {'name': builtins.str, 'id': builtins.int})" +[builtins fixtures/dict.pyi] +[typing fixtures/typing-typeddict.pyi] + +[case testTypeIsInAssert] +from typing_extensions import TypeIs +def is_float(a: object) -> TypeIs[float]: pass +def main(a: object) -> None: + assert is_float(a) + reveal_type(a) # N: Revealed type is "builtins.float" +[builtins fixtures/tuple.pyi] + +[case testTypeIsFromAny] +from typing import Any +from typing_extensions import TypeIs +def is_objfloat(a: object) -> TypeIs[float]: pass +def is_anyfloat(a: Any) -> TypeIs[float]: pass +def objmain(a: object) -> None: + if is_objfloat(a): + reveal_type(a) # N: Revealed type is "builtins.float" + if is_anyfloat(a): + reveal_type(a) # N: Revealed type is "builtins.float" +def anymain(a: Any) -> None: + if is_objfloat(a): + reveal_type(a) # N: Revealed type is "builtins.float" + if is_anyfloat(a): + reveal_type(a) # N: Revealed type is "builtins.float" +[builtins fixtures/tuple.pyi] + +[case testTypeIsNegatedAndElse] +from typing import Union +from typing_extensions import TypeIs +def is_int(a: object) -> TypeIs[int]: pass +def is_str(a: object) -> TypeIs[str]: pass +def intmain(a: Union[int, str]) -> None: + if not is_int(a): + reveal_type(a) # N: Revealed type is "builtins.str" + else: + reveal_type(a) # N: Revealed type is "builtins.int" +def strmain(a: Union[int, str]) -> None: + if is_str(a): + reveal_type(a) # N: Revealed type is "builtins.str" + else: + reveal_type(a) # N: Revealed type is "builtins.int" +[builtins fixtures/tuple.pyi] + +[case testTypeIsClassMethod] +from typing_extensions import TypeIs +class C: + @classmethod + def is_float(cls, a: object) -> TypeIs[float]: pass + def method(self, a: object) -> None: + if self.is_float(a): + reveal_type(a) # N: Revealed type is "builtins.float" +def main(a: object) -> None: + if C.is_float(a): + reveal_type(a) # N: Revealed type is "builtins.float" +[builtins fixtures/classmethod.pyi] + +[case testTypeIsRequiresPositionalArgs] +from typing_extensions import TypeIs +def is_float(a: object, b: object = 0) -> TypeIs[float]: pass +def main1(a: object) -> None: + if is_float(a=a, b=1): + reveal_type(a) # N: Revealed type is "builtins.float" + + if is_float(b=1, a=a): + reveal_type(a) # N: Revealed type is "builtins.float" + +[builtins fixtures/tuple.pyi] + +[case testTypeIsOverload] +from typing import overload, Any, Callable, Iterable, Iterator, List, Optional, TypeVar +from typing_extensions import TypeIs + +T = TypeVar("T") +R = TypeVar("R") + +@overload +def filter(f: Callable[[T], TypeIs[R]], it: Iterable[T]) -> Iterator[R]: ... +@overload +def filter(f: Callable[[T], bool], it: Iterable[T]) -> Iterator[T]: ... +def filter(*args): pass + +def is_int_typeis(a: object) -> TypeIs[int]: pass +def is_int_bool(a: object) -> bool: pass + +def main(a: List[Optional[int]]) -> None: + bb = filter(lambda x: x is not None, a) + reveal_type(bb) # N: Revealed type is "typing.Iterator[Union[builtins.int, None]]" + # Also, if you replace 'bool' with 'Any' in the second overload, bb is Iterator[Any] + cc = filter(is_int_typeis, a) + reveal_type(cc) # N: Revealed type is "typing.Iterator[builtins.int]" + dd = filter(is_int_bool, a) + reveal_type(dd) # N: Revealed type is "typing.Iterator[Union[builtins.int, None]]" + +[builtins fixtures/tuple.pyi] +[typing fixtures/typing-full.pyi] + +[case testTypeIsDecorated] +from typing import TypeVar +from typing_extensions import TypeIs +T = TypeVar("T") +def decorator(f: T) -> T: pass +@decorator +def is_float(a: object) -> TypeIs[float]: + pass +def main(a: object) -> None: + if is_float(a): + reveal_type(a) # N: Revealed type is "builtins.float" +[builtins fixtures/tuple.pyi] + +[case testTypeIsMethodOverride] +from typing_extensions import TypeIs +class C: + def is_float(self, a: object) -> TypeIs[float]: pass +class D(C): + def is_float(self, a: object) -> bool: pass # Fail +[builtins fixtures/tuple.pyi] +[out] +main:5: error: Signature of "is_float" incompatible with supertype "C" +main:5: note: Superclass: +main:5: note: def is_float(self, a: object) -> TypeIs[float] +main:5: note: Subclass: +main:5: note: def is_float(self, a: object) -> bool + +[case testTypeIsInAnd] +from typing import Any +from typing_extensions import TypeIs +def isclass(a: object) -> bool: + pass +def isfloat(a: object) -> TypeIs[float]: + pass +def isstr(a: object) -> TypeIs[str]: + pass + +def coverage1(obj: Any) -> bool: + if isfloat(obj) and obj.__self__ is not None and isclass(obj.__self__): # E: "float" has no attribute "__self__" + reveal_type(obj) # N: Revealed type is "builtins.float" + return True + reveal_type(obj) # N: Revealed type is "Any" + return False + +def coverage2(obj: Any) -> bool: + if not (isfloat(obj) or isstr(obj)): + reveal_type(obj) # N: Revealed type is "Any" + return True + reveal_type(obj) # N: Revealed type is "Union[builtins.float, builtins.str]" + return False +[builtins fixtures/classmethod.pyi] + +[case testAssignToTypeIsedVariable1] +from typing_extensions import TypeIs + +class A: pass +class B(A): pass + +def guard(a: A) -> TypeIs[B]: + pass + +a = A() +if not guard(a): + a = A() +[builtins fixtures/tuple.pyi] + +[case testAssignToTypeIsedVariable2] +from typing_extensions import TypeIs + +class A: pass +class B: pass + +def guard(a: object) -> TypeIs[B]: + pass + +a = A() +if not guard(a): + a = A() +[builtins fixtures/tuple.pyi] + +[case testAssignToTypeIsedVariable3] +from typing_extensions import TypeIs + +class A: pass +class B: pass + +def guard(a: object) -> TypeIs[B]: + pass + +a = A() +if guard(a): + reveal_type(a) # N: Revealed type is "__main__." + a = B() # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(a) # N: Revealed type is "__main__." + a = A() + reveal_type(a) # N: Revealed type is "__main__.A" +reveal_type(a) # N: Revealed type is "__main__.A" +[builtins fixtures/tuple.pyi] + +[case testTypeIsNestedRestrictionAny] +from typing_extensions import TypeIs +from typing import Any + +class A: ... +def f(x: object) -> TypeIs[A]: ... +def g(x: object) -> None: ... + +def test(x: Any) -> None: + if not(f(x) or x): + return + g(reveal_type(x)) # N: Revealed type is "Union[__main__.A, Any]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsNestedRestrictionUnionOther] +from typing_extensions import TypeIs +from typing import Any + +class A: ... +class B: ... +def f(x: object) -> TypeIs[A]: ... +def f2(x: object) -> TypeIs[B]: ... +def g(x: object) -> None: ... + +def test(x: object) -> None: + if not(f(x) or f2(x)): + return + g(reveal_type(x)) # N: Revealed type is "Union[__main__.A, __main__.B]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsComprehensionSubtype] +from typing import List +from typing_extensions import TypeIs + +class Base: ... +class Foo(Base): ... +class Bar(Base): ... + +def is_foo(item: object) -> TypeIs[Foo]: + return isinstance(item, Foo) + +def is_bar(item: object) -> TypeIs[Bar]: + return isinstance(item, Bar) + +def foobar(items: List[object]): + a: List[Base] = [x for x in items if is_foo(x) or is_bar(x)] + b: List[Base] = [x for x in items if is_foo(x)] + c: List[Foo] = [x for x in items if is_foo(x)] + d: List[Bar] = [x for x in items if is_foo(x)] # E: List comprehension has incompatible type List[Foo]; expected List[Bar] +[builtins fixtures/tuple.pyi] + +[case testTypeIsNestedRestrictionUnionIsInstance] +from typing_extensions import TypeIs +from typing import Any, List + +class A: ... +def f(x: List[Any]) -> TypeIs[List[str]]: ... +def g(x: object) -> None: ... + +def test(x: List[Any]) -> None: + if not(f(x) or isinstance(x, A)): + return + g(reveal_type(x)) # N: Revealed type is "Union[builtins.list[builtins.str], __main__.]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsMultipleCondition] +from typing_extensions import TypeIs +from typing import Any, List + +class Foo: ... +class Bar: ... + +def is_foo(item: object) -> TypeIs[Foo]: + return isinstance(item, Foo) + +def is_bar(item: object) -> TypeIs[Bar]: + return isinstance(item, Bar) + +def foobar(x: object): + if not isinstance(x, Foo) or not isinstance(x, Bar): + return + reveal_type(x) # N: Revealed type is "__main__." + +def foobar_typeis(x: object): + if not is_foo(x) or not is_bar(x): + return + # Looks like a typo but this is what our unique name generation produces + reveal_type(x) # N: Revealed type is "__main__.1" +[builtins fixtures/tuple.pyi] + +[case testTypeIsAsFunctionArgAsBoolSubtype] +from typing import Callable +from typing_extensions import TypeIs + +def accepts_bool(f: Callable[[object], bool]): pass + +def with_bool_typeis(o: object) -> TypeIs[bool]: pass +def with_str_typeis(o: object) -> TypeIs[str]: pass +def with_bool(o: object) -> bool: pass + +accepts_bool(with_bool_typeis) +accepts_bool(with_str_typeis) +accepts_bool(with_bool) +[builtins fixtures/tuple.pyi] + +[case testTypeIsAsFunctionArg] +from typing import Callable +from typing_extensions import TypeIs + +def accepts_typeis(f: Callable[[object], TypeIs[bool]]): pass +def different_typeis(f: Callable[[object], TypeIs[str]]): pass + +def with_typeis(o: object) -> TypeIs[bool]: pass +def with_bool(o: object) -> bool: pass + +accepts_typeis(with_typeis) +accepts_typeis(with_bool) # E: Argument 1 to "accepts_typeis" has incompatible type "Callable[[object], bool]"; expected "Callable[[object], TypeIs[bool]]" + +different_typeis(with_typeis) # E: Argument 1 to "different_typeis" has incompatible type "Callable[[object], TypeIs[bool]]"; expected "Callable[[object], TypeIs[str]]" +different_typeis(with_bool) # E: Argument 1 to "different_typeis" has incompatible type "Callable[[object], bool]"; expected "Callable[[object], TypeIs[str]]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsAsGenericFunctionArg] +from typing import Callable, TypeVar +from typing_extensions import TypeIs + +T = TypeVar('T') + +def accepts_typeis(f: Callable[[object], TypeIs[T]]): pass + +def with_bool_typeis(o: object) -> TypeIs[bool]: pass +def with_str_typeis(o: object) -> TypeIs[str]: pass +def with_bool(o: object) -> bool: pass + +accepts_typeis(with_bool_typeis) +accepts_typeis(with_str_typeis) +accepts_typeis(with_bool) # E: Argument 1 to "accepts_typeis" has incompatible type "Callable[[object], bool]"; expected "Callable[[object], TypeIs[Never]]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsAsOverloadedFunctionArg] +# https://github.com/python/mypy/issues/11307 +from typing import Callable, TypeVar, Generic, Any, overload +from typing_extensions import TypeIs + +_T = TypeVar('_T') + +class filter(Generic[_T]): + @overload + def __init__(self, function: Callable[[object], TypeIs[_T]]) -> None: pass + @overload + def __init__(self, function: Callable[[_T], Any]) -> None: pass + def __init__(self, function): pass + +def is_int_typeis(a: object) -> TypeIs[int]: pass +def returns_bool(a: object) -> bool: pass + +reveal_type(filter(is_int_typeis)) # N: Revealed type is "__main__.filter[builtins.int]" +reveal_type(filter(returns_bool)) # N: Revealed type is "__main__.filter[builtins.object]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsSubtypingVariance] +from typing import Callable +from typing_extensions import TypeIs + +class A: pass +class B(A): pass +class C(B): pass + +def accepts_typeis(f: Callable[[object], TypeIs[B]]): pass + +def with_typeis_a(o: object) -> TypeIs[A]: pass +def with_typeis_b(o: object) -> TypeIs[B]: pass +def with_typeis_c(o: object) -> TypeIs[C]: pass + +accepts_typeis(with_typeis_a) # E: Argument 1 to "accepts_typeis" has incompatible type "Callable[[object], TypeIs[A]]"; expected "Callable[[object], TypeIs[B]]" +accepts_typeis(with_typeis_b) +accepts_typeis(with_typeis_c) # E: Argument 1 to "accepts_typeis" has incompatible type "Callable[[object], TypeIs[C]]"; expected "Callable[[object], TypeIs[B]]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsWithIdentityGeneric] +from typing import TypeVar +from typing_extensions import TypeIs + +_T = TypeVar("_T") + +def identity(val: _T) -> TypeIs[_T]: + pass + +def func1(name: _T): + reveal_type(name) # N: Revealed type is "_T`-1" + if identity(name): + reveal_type(name) # N: Revealed type is "_T`-1" + +def func2(name: str): + reveal_type(name) # N: Revealed type is "builtins.str" + if identity(name): + reveal_type(name) # N: Revealed type is "builtins.str" +[builtins fixtures/tuple.pyi] + +[case testTypeIsWithGenericOnSecondParam] +from typing import TypeVar +from typing_extensions import TypeIs + +_R = TypeVar("_R") + +def guard(val: object, param: _R) -> TypeIs[_R]: + pass + +def func1(name: object): + reveal_type(name) # N: Revealed type is "builtins.object" + if guard(name, name): + reveal_type(name) # N: Revealed type is "builtins.object" + if guard(name, 1): + reveal_type(name) # N: Revealed type is "builtins.int" + +def func2(name: int): + reveal_type(name) # N: Revealed type is "builtins.int" + if guard(name, True): + reveal_type(name) # N: Revealed type is "builtins.bool" +[builtins fixtures/tuple.pyi] + +[case testTypeIsWithGenericInstance] +from typing import TypeVar, List, Iterable +from typing_extensions import TypeIs + +_T = TypeVar("_T") + +def is_list_of_str(val: Iterable[_T]) -> TypeIs[List[_T]]: + pass + +def func(name: Iterable[str]): + reveal_type(name) # N: Revealed type is "typing.Iterable[builtins.str]" + if is_list_of_str(name): + reveal_type(name) # N: Revealed type is "builtins.list[builtins.str]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsWithTupleGeneric] +from typing import TypeVar, Tuple +from typing_extensions import TypeIs + +_T = TypeVar("_T") + +def is_two_element_tuple(val: Tuple[_T, ...]) -> TypeIs[Tuple[_T, _T]]: + pass + +def func(names: Tuple[str, ...]): + reveal_type(names) # N: Revealed type is "builtins.tuple[builtins.str, ...]" + if is_two_element_tuple(names): + reveal_type(names) # N: Revealed type is "Tuple[builtins.str, builtins.str]" +[builtins fixtures/tuple.pyi] + +[case testTypeIsErroneousDefinitionFails] +from typing_extensions import TypeIs + +class Z: + def typeis1(self, *, x: object) -> TypeIs[int]: # E: "TypeIs" functions must have a positional argument + ... + + @staticmethod + def typeis2(x: object) -> TypeIs[int]: + ... + + @staticmethod + def typeis3(*, x: object) -> TypeIs[int]: # E: "TypeIs" functions must have a positional argument + ... + +def bad_typeis(*, x: object) -> TypeIs[int]: # E: "TypeIs" functions must have a positional argument + ... + +[builtins fixtures/classmethod.pyi] + +[case testTypeIsWithKeywordArg] +from typing_extensions import TypeIs + +class Z: + def typeis(self, x: object) -> TypeIs[int]: + ... + +def typeis(x: object) -> TypeIs[int]: + ... + +n: object +if typeis(x=n): + reveal_type(n) # N: Revealed type is "builtins.int" + +if Z().typeis(x=n): + reveal_type(n) # N: Revealed type is "builtins.int" +[builtins fixtures/tuple.pyi] + +[case testStaticMethodTypeIs] +from typing_extensions import TypeIs + +class Y: + @staticmethod + def typeis(h: object) -> TypeIs[int]: + ... + +x: object +if Y().typeis(x): + reveal_type(x) # N: Revealed type is "builtins.int" +if Y.typeis(x): + reveal_type(x) # N: Revealed type is "builtins.int" +[builtins fixtures/classmethod.pyi] + +[case testTypeIsKwargFollowingThroughOverloaded] +from typing import overload, Union +from typing_extensions import TypeIs + +@overload +def typeis(x: object, y: str) -> TypeIs[str]: + ... + +@overload +def typeis(x: object, y: int) -> TypeIs[int]: + ... + +def typeis(x: object, y: Union[int, str]) -> Union[TypeIs[int], TypeIs[str]]: + ... + +x: object +if typeis(x=x, y=42): + reveal_type(x) # N: Revealed type is "builtins.int" + +if typeis(y=42, x=x): + reveal_type(x) # N: Revealed type is "builtins.int" + +if typeis(x=x, y="42"): + reveal_type(x) # N: Revealed type is "builtins.str" + +if typeis(y="42", x=x): + reveal_type(x) # N: Revealed type is "builtins.str" +[builtins fixtures/tuple.pyi] + +[case testGenericAliasWithTypeIs] +from typing import Callable, List, TypeVar +from typing_extensions import TypeIs + +T = TypeVar('T') +A = Callable[[object], TypeIs[List[T]]] +def foo(x: object) -> TypeIs[List[str]]: ... + +def test(f: A[T]) -> T: ... +reveal_type(test(foo)) # N: Revealed type is "builtins.str" +[builtins fixtures/list.pyi] + +[case testNoCrashOnDunderCallTypeIs] +from typing_extensions import TypeIs + +class A: + def __call__(self, x) -> TypeIs[int]: + return True + +a: A +assert a(x=1) + +x: object +assert a(x=x) +reveal_type(x) # N: Revealed type is "builtins.int" +[builtins fixtures/tuple.pyi] + +[case testTypeIsMustBeSubtypeFunctions] +from typing_extensions import TypeIs +from typing import List, Sequence, TypeVar + +def f(x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of input type "str" + pass + +T = TypeVar('T') + +def g(x: List[T]) -> TypeIs[Sequence[T]]: # E: Narrowed type "Sequence[T]" is not a subtype of input type "List[T]" + pass + +[builtins fixtures/tuple.pyi] + +[case testTypeIsMustBeSubtypeMethods] +from typing_extensions import TypeIs + +class NarrowHolder: + @classmethod + def cls_narrower_good(cls, x: object) -> TypeIs[int]: + pass + + @classmethod + def cls_narrower_bad(cls, x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of input type "str" + pass + + @staticmethod + def static_narrower_good(x: object) -> TypeIs[int]: + pass + + @staticmethod + def static_narrower_bad(x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of input type "str" + pass + + def inst_narrower_good(self, x: object) -> TypeIs[int]: + pass + + def inst_narrower_bad(self, x: str) -> TypeIs[int]: # E: Narrowed type "int" is not a subtype of input type "str" + pass + + +[builtins fixtures/classmethod.pyi] + +[case testTypeIsTypeGuardNoSubtyping] +from typing_extensions import TypeGuard, TypeIs +from typing import Callable + +def accept_typeis(x: Callable[[object], TypeIs[str]]): + pass + +def accept_typeguard(x: Callable[[object], TypeGuard[str]]): + pass + +def typeis(x: object) -> TypeIs[str]: + pass + +def typeguard(x: object) -> TypeGuard[str]: + pass + +accept_typeis(typeis) +accept_typeis(typeguard) # E: Argument 1 to "accept_typeis" has incompatible type "Callable[[object], TypeGuard[str]]"; expected "Callable[[object], TypeIs[str]]" +accept_typeguard(typeis) # E: Argument 1 to "accept_typeguard" has incompatible type "Callable[[object], TypeIs[str]]"; expected "Callable[[object], TypeGuard[str]]" +accept_typeguard(typeguard) + +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 68dd985cfe2a..18b6c8fc477c 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -34,6 +34,7 @@ Concatenate: _SpecialForm TypeAlias: _SpecialForm TypeGuard: _SpecialForm +TypeIs: _SpecialForm Never: _SpecialForm TypeVarTuple: _SpecialForm From 87437b86129a2d6f88137c014241d3610b39a77a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 1 Mar 2024 10:50:28 -0800 Subject: [PATCH 107/172] Add incremental tests for TypeGuard/TypeIs (#16976) --- test-data/unit/check-incremental.test | 76 +++++++++++++++++++ test-data/unit/lib-stub/typing_extensions.pyi | 5 +- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 69381227ca8e..42faa8c627ba 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -6574,3 +6574,79 @@ class TheClass: [out] [out2] tmp/a.py:3: note: Revealed type is "def (value: builtins.object) -> lib.TheClass.pyenum@6" + +[case testStartUsingTypeGuard] +import a +[file a.py] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] + +[file a.py.2] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] +if guard(x): + assert_type(x, int) +else: + assert_type(x, Union[int, str]) +[file lib.py] +from typing_extensions import TypeGuard +def guard(x: object) -> TypeGuard[int]: + pass +[builtins fixtures/tuple.pyi] + +[case testStartUsingTypeIs] +import a +[file a.py] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] + +[file a.py.2] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] +if guard(x): + assert_type(x, int) +else: + assert_type(x, str) +[file lib.py] +from typing_extensions import TypeIs +def guard(x: object) -> TypeIs[int]: + pass +[builtins fixtures/tuple.pyi] + +[case testTypeGuardToTypeIs] +import a +[file a.py] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] +if guard(x): + assert_type(x, int) +else: + assert_type(x, Union[int, str]) +[file a.py.2] +from lib import guard +from typing import Union +from typing_extensions import assert_type +x: Union[int, str] +if guard(x): + assert_type(x, int) +else: + assert_type(x, str) +[file lib.py] +from typing_extensions import TypeGuard +def guard(x: object) -> TypeGuard[int]: + pass +[file lib.py.2] +from typing_extensions import TypeIs +def guard(x: object) -> TypeIs[int]: + pass +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 18b6c8fc477c..ff55f1b54c7d 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -68,7 +68,8 @@ class _TypedDict(Mapping[str, object]): def TypedDict(typename: str, fields: Dict[str, Type[_T]], *, total: Any = ...) -> Type[dict]: ... -def reveal_type(__obj: T) -> T: pass +def reveal_type(__obj: _T) -> _T: pass +def assert_type(__val: _T, __typ: Any) -> _T: pass def dataclass_transform( *, @@ -77,7 +78,7 @@ def dataclass_transform( kw_only_default: bool = ..., field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = ..., **kwargs: Any, -) -> Callable[[T], T]: ... +) -> Callable[[_T], _T]: ... def override(__arg: _T) -> _T: ... def deprecated(__msg: str) -> Callable[[_T], _T]: ... From 9f36d7c07d251c37f281a6a62d3b96dc12c09e44 Mon Sep 17 00:00:00 2001 From: youkaichao Date: Sat, 2 Mar 2024 03:04:56 +0800 Subject: [PATCH 108/172] docs: Add missing ClassVar import (#16962) --- docs/source/cheat_sheet_py3.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/cheat_sheet_py3.rst b/docs/source/cheat_sheet_py3.rst index 7ae8eeb59d66..b8e43960fd09 100644 --- a/docs/source/cheat_sheet_py3.rst +++ b/docs/source/cheat_sheet_py3.rst @@ -152,6 +152,8 @@ Classes .. code-block:: python + from typing import ClassVar + class BankAccount: # The "__init__" method doesn't return anything, so it gets return # type "None" just like any other method that doesn't return anything From 42afe6715f9487d1776158bebecf5bb235034719 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Mon, 4 Mar 2024 12:13:28 +0300 Subject: [PATCH 109/172] Add `py312` target version to `black` config (#16983) I won't have any effect, but will reflect our target versions better. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fa6cf876b647..ef8acda3f95d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ build-backend = "setuptools.build_meta" [tool.black] line-length = 99 -target-version = ["py38", "py39", "py310", "py311"] +target-version = ["py38", "py39", "py310", "py311", "py312"] skip-magic-trailing-comma = true force-exclude = ''' ^/mypy/typeshed| From 2c66b4821369494e50aa1487e477790d014f8fcc Mon Sep 17 00:00:00 2001 From: jhance Date: Mon, 4 Mar 2024 07:57:27 -0800 Subject: [PATCH 110/172] Add changelog for 1.9.0 (#16978) I did my best to sort them out in a way I thought was reasonable, but feel free to suggest improvements. I also removed a few that were linter version updates etc. --------- Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Co-authored-by: Jelle Zijlstra --- CHANGELOG.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bae881656865..86e4dc91aaec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,64 @@ # Mypy Release Notes -## Next release +## Mypy 1.9 + +We’ve just uploaded mypy 1.9 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). + +#### Breaking Changes + +Because the version of typeshed we use in mypy 1.9 doesn't support 3.7, neither does mypy 1.9. (Jared Hance, PR [16883](https://github.com/python/mypy/pull/16883)) + +#### Basic PEP 696 Support + +This release contains new support for PEP 696 (https://peps.python.org/pep-0696). Please try it out! (Contributed by Marc Mueller). + +#### Type-checking improvements + * Fix duplicated TypeVarTuple test (Jelle Zijlstra, PR [16853](https://github.com/python/mypy/pull/16853)) + * Fix missing type store for overloads (Marc Mueller, PR [16803](https://github.com/python/mypy/pull/16803)) + * Fix `'WriteToConn' object has no attribute 'flush'` (Charlie Denton, PR [16801](https://github.com/python/mypy/pull/16801)) + * Update TypeAlias error messages to remove colon (Marc Mueller, PR [16831](https://github.com/python/mypy/pull/16831)) + * Support narrowing unions that include type[None] (Christoph Tyralla, PR [16315](https://github.com/python/mypy/pull/16315)) + * Support TypedDict functional syntax as class base type (anniel-stripe, PR [16703](https://github.com/python/mypy/pull/16703)) + * Accept multiline quoted annotations (Shantanu, PR [16765](https://github.com/python/mypy/pull/16765)) + * Allow unary + in Literal (Jelle Zijlstra, PR [16729](https://github.com/python/mypy/pull/16729)) + * Speed up finding function type variables (Jukka Lehtosalo, PR [16562](https://github.com/python/mypy/pull/16562)) + * Substitute type variables in return type of static methods (Kouroche Bouchiat, PR [16670](https://github.com/python/mypy/pull/16670)) + * Consider TypeVarTuple to be invariant (Marc Mueller, PR [16759](https://github.com/python/mypy/pull/16759)) + * Add `alias` support to `field()` in `attrs` plugin (Nikita Sobolev, PR [16610](https://github.com/python/mypy/pull/16610)) + * Improve attrs hashability detection (Tin Tvrtković, PR [16556](https://github.com/python/mypy/pull/16556)) + +#### Documentation Updates + * Document --enable-incomplete-feature possible values in "mypy --help" (Froger David, PR [16661](https://github.com/python/mypy/pull/16661)) + * Update new type system discussion links (thomaswhaley, PR [16841](https://github.com/python/mypy/pull/16841)) + * Docs: Add missing class instantiation to cheat sheet (Aleksi Tarvainen, PR [16817](https://github.com/python/mypy/pull/16817)) + * Fix typo in getting_started.rst (zipperer, PR [16700](https://github.com/python/mypy/pull/16700)) + * Document how evil `--no-strict-optional` is (Shantanu, PR [16731](https://github.com/python/mypy/pull/16731)) + * Improve mypy daemon documentation note about local partial types (Makonnen Makonnen, PR [16782](https://github.com/python/mypy/pull/16782)) + * Fix numbering error in docs (Stefanie Molin, PR [16838](https://github.com/python/mypy/pull/16838)) + * Various docs improvements (Shantanu, PR [16836](https://github.com/python/mypy/pull/16836)) + +#### Stubtest Improvements + * 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)). + * Stubtest: ignore a new protocol dunder (Alex Waygood, PR [16895](https://github.com/python/mypy/pull/16895)) + * stubtest: Private parameters can be omitted (Sebastian Rittau, PR [16507](https://github.com/python/mypy/pull/16507)) + * stubtest: Add support for setting enum members to "..." (Jelle Zijlstra, PR [16807](https://github.com/python/mypy/pull/16807)) + * stubtest: adjust symtable logic (Shantanu, PR [16823](https://github.com/python/mypy/pull/16823)) + * stubtest: fix pos-only handling in overload resolution (Shantanu, PR [16750](https://github.com/python/mypy/pull/16750)) + +#### Stubgen Improvements + * stubgen: Fix crash on star unpack of TypeVarTuple (Ali Hamdan, PR [16869](https://github.com/python/mypy/pull/16869)) + * Fix failing stubgen tests (Ali Hamdan, PR [16779](https://github.com/python/mypy/pull/16779)) + * stubgen: use PEP 604 unions everywhere (Ali Hamdan, PR [16519](https://github.com/python/mypy/pull/16519)) + * Improve stubgen tests (Fabian Keller, PR [16760](https://github.com/python/mypy/pull/16760)) + * stubgen: Do not ignore property deleter (Ali Hamdan, PR [16781](https://github.com/python/mypy/pull/16781)) + * Support type stub generation for `staticmethod` (WeilerMarcel, PR [14934](https://github.com/python/mypy/pull/14934)) -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 From d354e763084e3890972c0c912a8290e440959f26 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Mon, 4 Mar 2024 20:18:27 +0000 Subject: [PATCH 111/172] Various 1.9 CHANGELOG updates (#16984) Mostly minor, but also announce that `--local-partial-types` will be enabled by default soon and explain type parameter defaults in more detail. --- CHANGELOG.md | 94 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86e4dc91aaec..59085dea4d1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,51 +12,93 @@ You can read the full documentation for this release on [Read the Docs](http://m Because the version of typeshed we use in mypy 1.9 doesn't support 3.7, neither does mypy 1.9. (Jared Hance, PR [16883](https://github.com/python/mypy/pull/16883)) -#### Basic PEP 696 Support +We are planning to enable +[local partial types](https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-local-partial-types) (enabled via the +`--local-partial-types` flag) later this year by default. This change +was announced years ago, but now it's finally happening. This is a +major backward-incompatible change, so we'll probably include it as +part of the upcoming mypy 2.0 release. This makes daemon and +non-daemon mypy runs have the same behavior by default. + +Local partial types can also be enabled in the mypy config file: +``` +local_partial_types = True +``` + +We are looking at providing a tool to make it easier to migrate +projects to use `--local-partial-types`, but it's not yet clear whether +this is practical. The migration usually involves adding some +explicit type annotations to module-level and class-level variables. + +#### Basic Support for Type Parameter Defaults (PEP 696) + +This release contains new experimental support for type parameter +defaults ([PEP 696](https://peps.python.org/pep-0696)). Please try it +out! This feature was contributed by Marc Mueller. + +Since this feature will be officially introduced in the next Python +feature release (3.13), you will need to import `TypeVar`, `ParamSpec` +or `TypeVarTuple` from `typing_extensions` to use defaults for now. + +This example adapted from the PEP defines a default for `BotT`: +```python +from typing import Generic +from typing_extensions import TypeVar + +class Bot: ... + +BotT = TypeVar("BotT", bound=Bot, default=Bot) -This release contains new support for PEP 696 (https://peps.python.org/pep-0696). Please try it out! (Contributed by Marc Mueller). +class Context(Generic[BotT]): + bot: BotT -#### Type-checking improvements - * Fix duplicated TypeVarTuple test (Jelle Zijlstra, PR [16853](https://github.com/python/mypy/pull/16853)) +class MyBot(Bot): ... + +# type is Bot (the default) +reveal_type(Context().bot) +# type is MyBot +reveal_type(Context[MyBot]().bot) +``` + +#### Type-checking Improvements * Fix missing type store for overloads (Marc Mueller, PR [16803](https://github.com/python/mypy/pull/16803)) * Fix `'WriteToConn' object has no attribute 'flush'` (Charlie Denton, PR [16801](https://github.com/python/mypy/pull/16801)) - * Update TypeAlias error messages to remove colon (Marc Mueller, PR [16831](https://github.com/python/mypy/pull/16831)) - * Support narrowing unions that include type[None] (Christoph Tyralla, PR [16315](https://github.com/python/mypy/pull/16315)) + * Improve TypeAlias error messages (Marc Mueller, PR [16831](https://github.com/python/mypy/pull/16831)) + * Support narrowing unions that include `type[None]` (Christoph Tyralla, PR [16315](https://github.com/python/mypy/pull/16315)) * Support TypedDict functional syntax as class base type (anniel-stripe, PR [16703](https://github.com/python/mypy/pull/16703)) * Accept multiline quoted annotations (Shantanu, PR [16765](https://github.com/python/mypy/pull/16765)) - * Allow unary + in Literal (Jelle Zijlstra, PR [16729](https://github.com/python/mypy/pull/16729)) - * Speed up finding function type variables (Jukka Lehtosalo, PR [16562](https://github.com/python/mypy/pull/16562)) + * Allow unary + in `Literal` (Jelle Zijlstra, PR [16729](https://github.com/python/mypy/pull/16729)) * Substitute type variables in return type of static methods (Kouroche Bouchiat, PR [16670](https://github.com/python/mypy/pull/16670)) * Consider TypeVarTuple to be invariant (Marc Mueller, PR [16759](https://github.com/python/mypy/pull/16759)) * Add `alias` support to `field()` in `attrs` plugin (Nikita Sobolev, PR [16610](https://github.com/python/mypy/pull/16610)) * Improve attrs hashability detection (Tin Tvrtković, PR [16556](https://github.com/python/mypy/pull/16556)) +#### Performance Improvements + + * Speed up finding function type variables (Jukka Lehtosalo, PR [16562](https://github.com/python/mypy/pull/16562)) + #### Documentation Updates - * Document --enable-incomplete-feature possible values in "mypy --help" (Froger David, PR [16661](https://github.com/python/mypy/pull/16661)) + + * Document supported values for `--enable-incomplete-feature` in "mypy --help" (Froger David, PR [16661](https://github.com/python/mypy/pull/16661)) * Update new type system discussion links (thomaswhaley, PR [16841](https://github.com/python/mypy/pull/16841)) - * Docs: Add missing class instantiation to cheat sheet (Aleksi Tarvainen, PR [16817](https://github.com/python/mypy/pull/16817)) - * Fix typo in getting_started.rst (zipperer, PR [16700](https://github.com/python/mypy/pull/16700)) + * Add missing class instantiation to cheat sheet (Aleksi Tarvainen, PR [16817](https://github.com/python/mypy/pull/16817)) * Document how evil `--no-strict-optional` is (Shantanu, PR [16731](https://github.com/python/mypy/pull/16731)) * Improve mypy daemon documentation note about local partial types (Makonnen Makonnen, PR [16782](https://github.com/python/mypy/pull/16782)) - * Fix numbering error in docs (Stefanie Molin, PR [16838](https://github.com/python/mypy/pull/16838)) - * Various docs improvements (Shantanu, PR [16836](https://github.com/python/mypy/pull/16836)) + * Fix numbering error (Stefanie Molin, PR [16838](https://github.com/python/mypy/pull/16838)) + * Various documentation improvements (Shantanu, PR [16836](https://github.com/python/mypy/pull/16836)) #### Stubtest Improvements - * 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)). - * Stubtest: ignore a new protocol dunder (Alex Waygood, PR [16895](https://github.com/python/mypy/pull/16895)) - * stubtest: Private parameters can be omitted (Sebastian Rittau, PR [16507](https://github.com/python/mypy/pull/16507)) - * stubtest: Add support for setting enum members to "..." (Jelle Zijlstra, PR [16807](https://github.com/python/mypy/pull/16807)) - * stubtest: adjust symtable logic (Shantanu, PR [16823](https://github.com/python/mypy/pull/16823)) - * stubtest: fix pos-only handling in overload resolution (Shantanu, PR [16750](https://github.com/python/mypy/pull/16750)) + * Ignore private function/method parameters when they are missing from the stub (private parameter names start with a single underscore and have a default) (PR [16507](https://github.com/python/mypy/pull/16507)) + * Ignore a new protocol dunder (Alex Waygood, PR [16895](https://github.com/python/mypy/pull/16895)) + * Private parameters can be omitted (Sebastian Rittau, PR [16507](https://github.com/python/mypy/pull/16507)) + * Add support for setting enum members to "..." (Jelle Zijlstra, PR [16807](https://github.com/python/mypy/pull/16807)) + * Adjust symbol table logic (Shantanu, PR [16823](https://github.com/python/mypy/pull/16823)) + * Fix posisitional-only handling in overload resolution (Shantanu, PR [16750](https://github.com/python/mypy/pull/16750)) #### Stubgen Improvements - * stubgen: Fix crash on star unpack of TypeVarTuple (Ali Hamdan, PR [16869](https://github.com/python/mypy/pull/16869)) - * Fix failing stubgen tests (Ali Hamdan, PR [16779](https://github.com/python/mypy/pull/16779)) - * stubgen: use PEP 604 unions everywhere (Ali Hamdan, PR [16519](https://github.com/python/mypy/pull/16519)) - * Improve stubgen tests (Fabian Keller, PR [16760](https://github.com/python/mypy/pull/16760)) - * stubgen: Do not ignore property deleter (Ali Hamdan, PR [16781](https://github.com/python/mypy/pull/16781)) + * Fix crash on star unpack of TypeVarTuple (Ali Hamdan, PR [16869](https://github.com/python/mypy/pull/16869)) + * Use PEP 604 unions everywhere (Ali Hamdan, PR [16519](https://github.com/python/mypy/pull/16519)) + * Do not ignore property deleter (Ali Hamdan, PR [16781](https://github.com/python/mypy/pull/16781)) * Support type stub generation for `staticmethod` (WeilerMarcel, PR [14934](https://github.com/python/mypy/pull/14934)) From 2f0f8f26d7aa3dab3c44a621bbed58c7816db2a4 Mon Sep 17 00:00:00 2001 From: jhance Date: Tue, 5 Mar 2024 13:58:22 -0800 Subject: [PATCH 112/172] Update changelog for 1.9 with acknowledgements. (#16989) Co-authored-by: Jukka Lehtosalo Co-authored-by: Alex Waygood --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59085dea4d1f..8bd537d46e9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,41 @@ reveal_type(Context[MyBot]().bot) * Do not ignore property deleter (Ali Hamdan, PR [16781](https://github.com/python/mypy/pull/16781)) * Support type stub generation for `staticmethod` (WeilerMarcel, PR [14934](https://github.com/python/mypy/pull/14934)) +#### Acknowledgements + +​Thanks to all mypy contributors who contributed to this release: + +- Aleksi Tarvainen +- Alex Waygood +- Ali Hamdan +- anniel-stripe +- Charlie Denton +- Christoph Tyralla +- Dheeraj +- Fabian Keller +- Fabian Lewis +- Froger David +- Ihor +- Jared Hance +- Jelle Zijlstra +- Jukka Lehtosalo +- Kouroche Bouchiat +- Lukas Geiger +- Maarten Huijsmans +- Makonnen Makonnen +- Marc Mueller +- Nikita Sobolev +- Sebastian Rittau +- Shantanu +- Stefanie Molin +- Stephen Morton +- thomaswhaley +- Tin Tvrtković +- WeilerMarcel +- Wesley Collin Wright +- zipperer + +I’d also like to thank my employer, Dropbox, for supporting mypy development. ## Mypy 1.8 From 2fbfb6060a4549a1837d5eed4ad7ef1e8da256b9 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Thu, 7 Mar 2024 02:25:06 +0100 Subject: [PATCH 113/172] Fix inference with UninhabitedType (#16994) At the moment, inference fails if an empty dict is used (without annotation) as one of the types. It's because the constraint solver can't resolve `dict[str, int]` and `dict[Never, Never]`. However in this case it's more reasonable to interpret the empty dict as `dict[Any, Any]` and just using the first type instead. That matches the behavior of pyright. ```py T = TypeVar("T") class A(Generic[T]): ... def func1(a: A[T], b: T) -> T: ... def a1(a: A[Dict[str, int]]) -> None: reveal_type(func1(a, {})) ``` ``` # before main: error: Cannot infer type argument 1 of "func1" (diff) main: note: Revealed type is "Any" (diff) # after main: note: Revealed type is "builtins.dict[builtins.str, builtins.int]" ``` --- mypy/join.py | 13 +++++++---- test-data/unit/check-inference.test | 34 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/mypy/join.py b/mypy/join.py index bf88f43d88fe..3603e9fefb7a 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -108,12 +108,17 @@ def join_instances(self, t: Instance, s: Instance) -> ProperType: # TODO: contravariant case should use meet but pass seen instances as # an argument to keep track of recursive checks. elif type_var.variance in (INVARIANT, CONTRAVARIANT): - if not is_equivalent(ta, sa): + if isinstance(ta_proper, UninhabitedType) and not ta_proper.is_noreturn: + new_type = sa + elif isinstance(sa_proper, UninhabitedType) and not sa_proper.is_noreturn: + new_type = ta + elif not is_equivalent(ta, sa): self.seen_instances.pop() return object_from_instance(t) - # If the types are different but equivalent, then an Any is involved - # so using a join in the contravariant case is also OK. - new_type = join_types(ta, sa, self) + else: + # If the types are different but equivalent, then an Any is involved + # so using a join in the contravariant case is also OK. + new_type = join_types(ta, sa, self) elif isinstance(type_var, TypeVarTupleType): new_type = get_proper_type(join_types(ta, sa, self)) # Put the joined arguments back into instance in the normal form: diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 953855e502d6..1b1ce607bf28 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -3813,3 +3813,37 @@ def m1() -> float: ... def m2() -> float: ... reveal_type(Combine(m1, m2)) # N: Revealed type is "builtins.float" [builtins fixtures/list.pyi] + +[case testInferenceWithUninhabitedType] +from typing import Dict, Generic, List, Never, TypeVar + +T = TypeVar("T") + +class A(Generic[T]): ... +class B(Dict[T, T]): ... + +def func1(a: A[T], b: T) -> T: ... +def func2(a: T, b: A[T]) -> T: ... + +def a1(a: A[Dict[str, int]]) -> None: + reveal_type(func1(a, {})) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" + reveal_type(func2({}, a)) # N: Revealed type is "builtins.dict[builtins.str, builtins.int]" + +def a2(check: bool, a: B[str]) -> None: + reveal_type(a if check else {}) # N: Revealed type is "builtins.dict[builtins.str, builtins.str]" + +def a3() -> None: + a = {} # E: Need type annotation for "a" (hint: "a: Dict[, ] = ...") + b = {1: {}} # E: Need type annotation for "b" + c = {1: {}, 2: {"key": {}}} # E: Need type annotation for "c" + reveal_type(a) # N: Revealed type is "builtins.dict[Any, Any]" + reveal_type(b) # N: Revealed type is "builtins.dict[builtins.int, builtins.dict[Any, Any]]" + reveal_type(c) # N: Revealed type is "builtins.dict[builtins.int, builtins.dict[builtins.str, builtins.dict[Any, Any]]]" + +def a4(x: List[str], y: List[Never]) -> None: + z1 = [x, y] + z2 = [y, x] + reveal_type(z1) # N: Revealed type is "builtins.list[builtins.object]" + reveal_type(z2) # N: Revealed type is "builtins.list[builtins.object]" + z1[1].append("asdf") # E: "object" has no attribute "append" +[builtins fixtures/dict.pyi] From 0b8fed526de75284349afbd4b448172b61148931 Mon Sep 17 00:00:00 2001 From: Oskari Lehto Date: Thu, 7 Mar 2024 05:40:10 +0200 Subject: [PATCH 114/172] Fix single item enum match type exhaustion (#16966) Fixes #14109 --------- Co-authored-by: Shantanu Jain --- mypy/checkpattern.py | 2 +- test-data/unit/check-python310.test | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 7b6a55324741..a23be464b825 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -202,7 +202,7 @@ def visit_value_pattern(self, o: ValuePattern) -> PatternType: typ = self.chk.expr_checker.accept(o.expr) typ = coerce_to_literal(typ) narrowed_type, rest_type = self.chk.conditional_types_with_intersection( - current_type, [get_type_range(typ)], o, default=current_type + current_type, [get_type_range(typ)], o, default=get_proper_type(typ) ) if not isinstance(get_proper_type(narrowed_type), (LiteralType, UninhabitedType)): return PatternType(narrowed_type, UnionType.make_union([narrowed_type, rest_type]), {}) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index b0e27fe1e3a0..3a040d94d7ba 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1369,6 +1369,27 @@ match m3: reveal_type(m3) # N: Revealed type is "Tuple[Union[builtins.int, builtins.str]]" [builtins fixtures/tuple.pyi] +[case testMatchEnumSingleChoice] +from enum import Enum +from typing import NoReturn + +def assert_never(x: NoReturn) -> None: ... + +class Medal(Enum): + gold = 1 + +def f(m: Medal) -> None: + always_assigned: int | None = None + match m: + case Medal.gold: + always_assigned = 1 + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]" + case _: + assert_never(m) + + reveal_type(always_assigned) # N: Revealed type is "builtins.int" +[builtins fixtures/bool.pyi] + [case testMatchLiteralPatternEnumNegativeNarrowing] from enum import Enum class Medal(Enum): @@ -1388,10 +1409,13 @@ def f(m: Medal) -> int: def g(m: Medal) -> int: match m: case Medal.gold: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]" return 0 case Medal.silver: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.silver]" return 1 case Medal.bronze: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.bronze]" return 2 [case testMatchLiteralPatternEnumCustomEquals-skip] From e0ad95296037446fccb398b8dadc54ae0751df46 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 8 Mar 2024 07:05:05 -0800 Subject: [PATCH 115/172] Disallow all super calls to methods with trivial bodies (#16756) Relates to: https://discuss.python.org/t/calling-abstract-methods/42576 I think this makes mypy's behaviour more predictable --- mypy/checkmember.py | 8 +------- test-data/unit/check-abstract.test | 12 ++++++------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index c24edacf0ee1..afa8f37ff7d5 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -359,13 +359,7 @@ def validate_super_call(node: FuncBase, mx: MemberContext) -> None: impl = node.impl if isinstance(node.impl, FuncDef) else node.impl.func unsafe_super = impl.is_trivial_body if unsafe_super: - ret_type = ( - impl.type.ret_type - if isinstance(impl.type, CallableType) - else AnyType(TypeOfAny.unannotated) - ) - if not subtypes.is_subtype(NoneType(), ret_type): - mx.msg.unsafe_super(node.name, node.info.name, mx.context) + mx.msg.unsafe_super(node.name, node.info.name, mx.context) def analyze_type_callable_member_access(name: str, typ: FunctionLike, mx: MemberContext) -> Type: diff --git a/test-data/unit/check-abstract.test b/test-data/unit/check-abstract.test index 7f91eb8e7145..3b0b9c520b75 100644 --- a/test-data/unit/check-abstract.test +++ b/test-data/unit/check-abstract.test @@ -896,9 +896,9 @@ class A(metaclass=ABCMeta): class B(A): @property def x(self) -> int: - return super().x.y # E: "int" has no attribute "y" + return super().x.y # E: Call to abstract method "x" of "A" with trivial body via super() is unsafe \ + # E: "int" has no attribute "y" [builtins fixtures/property.pyi] -[out] [case testSuperWithReadWriteAbstractProperty] from abc import abstractproperty, ABCMeta @@ -1659,10 +1659,10 @@ class Abstract: class SubProto(Proto): def meth(self) -> int: - return super().meth() + return super().meth() # E: Call to abstract method "meth" of "Proto" with trivial body via super() is unsafe class SubAbstract(Abstract): def meth(self) -> int: - return super().meth() + return super().meth() # E: Call to abstract method "meth" of "Abstract" with trivial body via super() is unsafe [case testEmptyBodyNoSuperWarningOptionalReturn] from typing import Protocol, Optional @@ -1676,10 +1676,10 @@ class Abstract: class SubProto(Proto): def meth(self) -> Optional[int]: - return super().meth() + return super().meth() # E: Call to abstract method "meth" of "Proto" with trivial body via super() is unsafe class SubAbstract(Abstract): def meth(self) -> Optional[int]: - return super().meth() + return super().meth() # E: Call to abstract method "meth" of "Abstract" with trivial body via super() is unsafe [case testEmptyBodyTypeCheckingOnly] from typing import TYPE_CHECKING From c94d8e3cd02e8be5e4594d84ec77c84b3faf7948 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Sat, 9 Mar 2024 09:16:41 +0000 Subject: [PATCH 116/172] [mypyc] Provide an easier way to define IR-to-IR transforms (#16998) This makes it easy to define simple IR-to-IR transforms by subclassing `IRTansform` and overriding some visit methods. Add an implementation of a simple copy propagation optimization as an example. This will be used by the implementation of mypyc/mypyc#854, and this can also be used for various optimizations. The IR transform preserves the identities of ops that are not modified. This means that the old IR is no longer valid after the transform, but the transform can be fast since we don't need to allocate many objects if only a small subset of ops will be modified by a transform. --- mypyc/codegen/emitmodule.py | 13 +- mypyc/irbuild/builder.py | 6 +- mypyc/irbuild/ll_builder.py | 8 +- mypyc/test-data/opt-copy-propagation.test | 400 ++++++++++++++++++++++ mypyc/test/test_copy_propagation.py | 47 +++ mypyc/transform/copy_propagation.py | 94 +++++ mypyc/transform/ir_transform.py | 353 +++++++++++++++++++ 7 files changed, 904 insertions(+), 17 deletions(-) create mode 100644 mypyc/test-data/opt-copy-propagation.test create mode 100644 mypyc/test/test_copy_propagation.py create mode 100644 mypyc/transform/copy_propagation.py create mode 100644 mypyc/transform/ir_transform.py diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index 6c0dfd43b9af..0035bd53188b 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -56,6 +56,7 @@ from mypyc.irbuild.prepare import load_type_map from mypyc.namegen import NameGenerator, exported_name from mypyc.options import CompilerOptions +from mypyc.transform.copy_propagation import do_copy_propagation from mypyc.transform.exceptions import insert_exception_handling from mypyc.transform.refcount import insert_ref_count_opcodes from mypyc.transform.uninit import insert_uninit_checks @@ -225,18 +226,16 @@ def compile_scc_to_ir( if errors.num_errors > 0: return modules - # Insert uninit checks. for module in modules.values(): for fn in module.functions: + # Insert uninit checks. insert_uninit_checks(fn) - # Insert exception handling. - for module in modules.values(): - for fn in module.functions: + # Insert exception handling. insert_exception_handling(fn) - # Insert refcount handling. - for module in modules.values(): - for fn in module.functions: + # Insert refcount handling. insert_ref_count_opcodes(fn) + # Perform copy propagation optimization. + do_copy_propagation(fn, compiler_options) return modules diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index f201a4737f89..52891d68e3b2 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -160,7 +160,7 @@ def __init__( options: CompilerOptions, singledispatch_impls: dict[FuncDef, list[RegisterImplInfo]], ) -> None: - self.builder = LowLevelIRBuilder(current_module, errors, mapper, options) + self.builder = LowLevelIRBuilder(errors, options) self.builders = [self.builder] self.symtables: list[dict[SymbolNode, SymbolTarget]] = [{}] self.runtime_args: list[list[RuntimeArg]] = [[]] @@ -1111,9 +1111,7 @@ def flatten_classes(self, arg: RefExpr | TupleExpr) -> list[ClassIR] | None: def enter(self, fn_info: FuncInfo | str = "") -> None: if isinstance(fn_info, str): fn_info = FuncInfo(name=fn_info) - self.builder = LowLevelIRBuilder( - self.current_module, self.errors, self.mapper, self.options - ) + self.builder = LowLevelIRBuilder(self.errors, self.options) self.builder.set_module(self.module_name, self.module_path) self.builders.append(self.builder) self.symtables.append({}) diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index d1ea91476a66..45c06e11befd 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -126,7 +126,6 @@ short_int_rprimitive, str_rprimitive, ) -from mypyc.irbuild.mapper import Mapper from mypyc.irbuild.util import concrete_arg_kind from mypyc.options import CompilerOptions from mypyc.primitives.bytes_ops import bytes_compare @@ -220,12 +219,8 @@ class LowLevelIRBuilder: - def __init__( - self, current_module: str, errors: Errors, mapper: Mapper, options: CompilerOptions - ) -> None: - self.current_module = current_module + def __init__(self, errors: Errors | None, options: CompilerOptions) -> None: self.errors = errors - self.mapper = mapper self.options = options self.args: list[Register] = [] self.blocks: list[BasicBlock] = [] @@ -2394,6 +2389,7 @@ def _create_dict(self, keys: list[Value], values: list[Value], line: int) -> Val return self.call_c(dict_new_op, [], line) def error(self, msg: str, line: int) -> None: + assert self.errors is not None, "cannot generate errors in this compiler phase" self.errors.error(msg, self.module_path, line) diff --git a/mypyc/test-data/opt-copy-propagation.test b/mypyc/test-data/opt-copy-propagation.test new file mode 100644 index 000000000000..49b80f4385fc --- /dev/null +++ b/mypyc/test-data/opt-copy-propagation.test @@ -0,0 +1,400 @@ +-- Test cases for copy propagation optimization. This also tests IR transforms in general, +-- as copy propagation was the first IR transform that was implemented. + +[case testCopyPropagationSimple] +def g() -> int: + return 1 + +def f() -> int: + y = g() + return y +[out] +def g(): +L0: + return 2 +def f(): + r0 :: int +L0: + r0 = g() + return r0 + +[case testCopyPropagationChain] +def f(x: int) -> int: + y = x + z = y + return z +[out] +def f(x): + x :: int +L0: + return x + +[case testCopyPropagationChainPartial] +def f(x: int) -> int: + y = x + z = y + x = 2 + return z +[out] +def f(x): + x, y :: int +L0: + y = x + x = 4 + return y + +[case testCopyPropagationChainBad] +def f(x: int) -> int: + y = x + z = y + y = 2 + return z +[out] +def f(x): + x, y, z :: int +L0: + y = x + z = y + y = 4 + return z + +[case testCopyPropagationMutatedSource1] +def f(x: int) -> int: + y = x + x = 1 + return y +[out] +def f(x): + x, y :: int +L0: + y = x + x = 2 + return y + +[case testCopyPropagationMutatedSource2] +def f() -> int: + z = 1 + y = z + z = 2 + return y +[out] +def f(): + z, y :: int +L0: + z = 2 + y = z + z = 4 + return y + +[case testCopyPropagationTooComplex] +def f(b: bool, x: int) -> int: + if b: + y = x + return y + else: + y = 1 + return y +[out] +def f(b, x): + b :: bool + x, y :: int +L0: + if b goto L1 else goto L2 :: bool +L1: + y = x + return y +L2: + y = 2 + return y + +[case testCopyPropagationArg] +def f(x: int) -> int: + x = 2 + return x +[out] +def f(x): + x :: int +L0: + x = 4 + return x + +[case testCopyPropagationPartiallyDefined1] +def f(b: bool) -> int: + if b: + x = 1 + y = x + return y +[out] +def f(b): + b :: bool + r0, x :: int + r1 :: bool + y :: int +L0: + r0 = :: int + x = r0 + if b goto L1 else goto L2 :: bool +L1: + x = 2 +L2: + if is_error(x) goto L3 else goto L4 +L3: + r1 = raise UnboundLocalError('local variable "x" referenced before assignment') + unreachable +L4: + y = x + return y + +-- The remaining test cases test basic IRTransform functionality and are not +-- all needed for testing copy propagation as such. + +[case testIRTransformBranch] +from mypy_extensions import i64 + +def f(x: bool) -> int: + y = x + if y: + return 1 + else: + return 2 +[out] +def f(x): + x :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + return 2 +L2: + return 4 + +[case testIRTransformAssignment] +def f(b: bool, x: int) -> int: + y = x + if b: + return y + else: + return 1 +[out] +def f(b, x): + b :: bool + x :: int +L0: + if b goto L1 else goto L2 :: bool +L1: + return x +L2: + return 2 + +[case testIRTransformRegisterOps1] +from __future__ import annotations +from typing import cast + +class C: + a: int + + def m(self, x: int) -> None: pass + +def get_attr(x: C) -> int: + y = x + return y.a + +def set_attr(x: C) -> None: + y = x + y.a = 1 + +def tuple_get(x: tuple[int, int]) -> int: + y = x + return y[0] + +def tuple_set(x: int, xx: int) -> tuple[int, int]: + y = x + z = xx + return y, z + +def call(x: int) -> int: + y = x + return call(y) + +def method_call(c: C, x: int) -> None: + y = x + c.m(y) + +def cast_op(x: object) -> str: + y = x + return cast(str, y) + +def box(x: int) -> object: + y = x + return y + +def unbox(x: object) -> int: + y = x + return cast(int, y) + +def call_c(x: list[str]) -> None: + y = x + y.append("x") + +def keep_alive(x: C) -> int: + y = x + return y.a + 1 +[out] +def C.m(self, x): + self :: __main__.C + x :: int +L0: + return 1 +def get_attr(x): + x :: __main__.C + r0 :: int +L0: + r0 = x.a + return r0 +def set_attr(x): + x :: __main__.C + r0 :: bool +L0: + x.a = 2; r0 = is_error + return 1 +def tuple_get(x): + x :: tuple[int, int] + r0 :: int +L0: + r0 = x[0] + return r0 +def tuple_set(x, xx): + x, xx :: int + r0 :: tuple[int, int] +L0: + r0 = (x, xx) + return r0 +def call(x): + x, r0 :: int +L0: + r0 = call(x) + return r0 +def method_call(c, x): + c :: __main__.C + x :: int + r0 :: None +L0: + r0 = c.m(x) + return 1 +def cast_op(x): + x :: object + r0 :: str +L0: + r0 = cast(str, x) + return r0 +def box(x): + x :: int + r0 :: object +L0: + r0 = box(int, x) + return r0 +def unbox(x): + x :: object + r0 :: int +L0: + r0 = unbox(int, x) + return r0 +def call_c(x): + x :: list + r0 :: str + r1 :: i32 + r2 :: bit +L0: + r0 = 'x' + r1 = PyList_Append(x, r0) + r2 = r1 >= 0 :: signed + return 1 +def keep_alive(x): + x :: __main__.C + r0, r1 :: int +L0: + r0 = borrow x.a + r1 = CPyTagged_Add(r0, 2) + keep_alive x + return r1 + +[case testIRTransformRegisterOps2] +from mypy_extensions import i32, i64 + +def truncate(x: i64) -> i32: + y = x + return i32(y) + +def extend(x: i32) -> i64: + y = x + return i64(y) + +def int_op(x: i64, xx: i64) -> i64: + y = x + z = xx + return y + z + +def comparison_op(x: i64, xx: i64) -> bool: + y = x + z = xx + return y == z + +def float_op(x: float, xx: float) -> float: + y = x + z = xx + return y + z + +def float_neg(x: float) -> float: + y = x + return -y + +def float_comparison_op(x: float, xx: float) -> bool: + y = x + z = xx + return y == z +[out] +def truncate(x): + x :: i64 + r0 :: i32 +L0: + r0 = truncate x: i64 to i32 + return r0 +def extend(x): + x :: i32 + r0 :: i64 +L0: + r0 = extend signed x: i32 to i64 + return r0 +def int_op(x, xx): + x, xx, r0 :: i64 +L0: + r0 = x + xx + return r0 +def comparison_op(x, xx): + x, xx :: i64 + r0 :: bit +L0: + r0 = x == xx + return r0 +def float_op(x, xx): + x, xx, r0 :: float +L0: + r0 = x + xx + return r0 +def float_neg(x): + x, r0 :: float +L0: + r0 = -x + return r0 +def float_comparison_op(x, xx): + x, xx :: float + r0 :: bit +L0: + r0 = x == xx + return r0 + +-- Note that transforms of these ops aren't tested here: +-- * LoadMem +-- * SetMem +-- * GetElementPtr +-- * LoadAddress +-- * Unborrow diff --git a/mypyc/test/test_copy_propagation.py b/mypyc/test/test_copy_propagation.py new file mode 100644 index 000000000000..c729e3d186c3 --- /dev/null +++ b/mypyc/test/test_copy_propagation.py @@ -0,0 +1,47 @@ +"""Runner for copy propagation optimization tests.""" + +from __future__ import annotations + +import os.path + +from mypy.errors import CompileError +from mypy.test.config import test_temp_dir +from mypy.test.data import DataDrivenTestCase +from mypyc.common import TOP_LEVEL_NAME +from mypyc.ir.pprint import format_func +from mypyc.options import CompilerOptions +from mypyc.test.testutil import ( + ICODE_GEN_BUILTINS, + MypycDataSuite, + assert_test_output, + build_ir_for_single_file, + remove_comment_lines, + use_custom_builtins, +) +from mypyc.transform.copy_propagation import do_copy_propagation +from mypyc.transform.uninit import insert_uninit_checks + +files = ["opt-copy-propagation.test"] + + +class TestCopyPropagation(MypycDataSuite): + files = files + base_path = test_temp_dir + + def run_case(self, testcase: DataDrivenTestCase) -> None: + with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase): + expected_output = remove_comment_lines(testcase.output) + try: + ir = build_ir_for_single_file(testcase.input) + except CompileError as e: + actual = e.messages + else: + actual = [] + for fn in ir: + if fn.name == TOP_LEVEL_NAME and not testcase.name.endswith("_toplevel"): + continue + insert_uninit_checks(fn) + do_copy_propagation(fn, CompilerOptions()) + actual.extend(format_func(fn)) + + assert_test_output(testcase, actual, "Invalid source code output", expected_output) diff --git a/mypyc/transform/copy_propagation.py b/mypyc/transform/copy_propagation.py new file mode 100644 index 000000000000..49de616f85a3 --- /dev/null +++ b/mypyc/transform/copy_propagation.py @@ -0,0 +1,94 @@ +"""Simple copy propagation optimization. + +Example input: + + x = f() + y = x + +The register x is redundant and we can directly assign its value to y: + + y = f() + +This can optimize away registers that are assigned to once. +""" + +from __future__ import annotations + +from mypyc.ir.func_ir import FuncIR +from mypyc.ir.ops import Assign, AssignMulti, LoadAddress, LoadErrorValue, Register, Value +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.options import CompilerOptions +from mypyc.sametype import is_same_type +from mypyc.transform.ir_transform import IRTransform + + +def do_copy_propagation(fn: FuncIR, options: CompilerOptions) -> None: + """Perform copy propagation optimization for fn.""" + + # Anything with an assignment count >1 will not be optimized + # here, as it would be require data flow analysis and we want to + # keep this simple and fast, at least until we've made data flow + # analysis much faster. + counts: dict[Value, int] = {} + replacements: dict[Value, Value] = {} + for arg in fn.arg_regs: + # Arguments are always assigned to initially + counts[arg] = 1 + + for block in fn.blocks: + for op in block.ops: + if isinstance(op, Assign): + c = counts.get(op.dest, 0) + counts[op.dest] = c + 1 + # Does this look like a supported assignment? + # TODO: Something needs LoadErrorValue assignments to be preserved? + if ( + c == 0 + and is_same_type(op.dest.type, op.src.type) + and not isinstance(op.src, LoadErrorValue) + ): + replacements[op.dest] = op.src + elif c == 1: + # Too many assignments -- don't replace this one + replacements.pop(op.dest, 0) + elif isinstance(op, AssignMulti): + # Copy propagation not supported for AssignMulti destinations + counts[op.dest] = 2 + replacements.pop(op.dest, 0) + elif isinstance(op, LoadAddress): + # We don't support taking the address of an arbitrary Value, + # so we'll need to preserve the operands of LoadAddress. + if isinstance(op.src, Register): + counts[op.src] = 2 + replacements.pop(op.src, 0) + + # Follow chains of propagation with more than one assignment. + for src, dst in list(replacements.items()): + if counts.get(dst, 0) > 1: + # Not supported + del replacements[src] + else: + while dst in replacements: + dst = replacements[dst] + if counts.get(dst, 0) > 1: + # Not supported + del replacements[src] + if src in replacements: + replacements[src] = dst + + builder = LowLevelIRBuilder(None, options) + transform = CopyPropagationTransform(builder, replacements) + transform.transform_blocks(fn.blocks) + fn.blocks = builder.blocks + + +class CopyPropagationTransform(IRTransform): + def __init__(self, builder: LowLevelIRBuilder, map: dict[Value, Value]) -> None: + super().__init__(builder) + self.op_map.update(map) + self.removed = set(map) + + def visit_assign(self, op: Assign) -> Value | None: + if op.dest in self.removed: + return None + return self.add(op) diff --git a/mypyc/transform/ir_transform.py b/mypyc/transform/ir_transform.py new file mode 100644 index 000000000000..1bcfc8fb5feb --- /dev/null +++ b/mypyc/transform/ir_transform.py @@ -0,0 +1,353 @@ +"""Helpers for implementing generic IR to IR transforms.""" + +from __future__ import annotations + +from typing import Final, Optional + +from mypyc.ir.ops import ( + Assign, + AssignMulti, + BasicBlock, + Box, + Branch, + Call, + CallC, + Cast, + ComparisonOp, + DecRef, + Extend, + FloatComparisonOp, + FloatNeg, + FloatOp, + GetAttr, + GetElementPtr, + Goto, + IncRef, + InitStatic, + IntOp, + KeepAlive, + LoadAddress, + LoadErrorValue, + LoadGlobal, + LoadLiteral, + LoadMem, + LoadStatic, + MethodCall, + Op, + OpVisitor, + RaiseStandardError, + Return, + SetAttr, + SetMem, + Truncate, + TupleGet, + TupleSet, + Unborrow, + Unbox, + Unreachable, + Value, +) +from mypyc.irbuild.ll_builder import LowLevelIRBuilder + + +class IRTransform(OpVisitor[Optional[Value]]): + """Identity transform. + + Subclass and override to perform changes to IR. + + Subclass IRTransform and override any OpVisitor visit_* methods + that perform any IR changes. The default implementations implement + an identity transform. + + A visit method can return None to remove ops. In this case the + transform must ensure that no op uses the original removed op + as a source after the transform. + + You can retain old BasicBlock and op references in ops. The transform + will automatically patch these for you as needed. + """ + + def __init__(self, builder: LowLevelIRBuilder) -> None: + self.builder = builder + # Subclasses add additional op mappings here. A None value indicates + # that the op/register is deleted. + self.op_map: dict[Value, Value | None] = {} + + def transform_blocks(self, blocks: list[BasicBlock]) -> None: + """Transform basic blocks that represent a single function. + + The result of the transform will be collected at self.builder.blocks. + """ + block_map: dict[BasicBlock, BasicBlock] = {} + op_map = self.op_map + for block in blocks: + new_block = BasicBlock() + block_map[block] = new_block + self.builder.activate_block(new_block) + new_block.error_handler = block.error_handler + for op in block.ops: + new_op = op.accept(self) + if new_op is not op: + op_map[op] = new_op + + # Update all op/block references to point to the transformed ones. + patcher = PatchVisitor(op_map, block_map) + for block in self.builder.blocks: + for op in block.ops: + op.accept(patcher) + if block.error_handler is not None: + block.error_handler = block_map.get(block.error_handler, block.error_handler) + + def add(self, op: Op) -> Value: + return self.builder.add(op) + + def visit_goto(self, op: Goto) -> Value: + return self.add(op) + + def visit_branch(self, op: Branch) -> Value: + return self.add(op) + + def visit_return(self, op: Return) -> Value: + return self.add(op) + + def visit_unreachable(self, op: Unreachable) -> Value: + return self.add(op) + + def visit_assign(self, op: Assign) -> Value | None: + return self.add(op) + + def visit_assign_multi(self, op: AssignMulti) -> Value | None: + return self.add(op) + + def visit_load_error_value(self, op: LoadErrorValue) -> Value | None: + return self.add(op) + + def visit_load_literal(self, op: LoadLiteral) -> Value | None: + return self.add(op) + + def visit_get_attr(self, op: GetAttr) -> Value | None: + return self.add(op) + + def visit_set_attr(self, op: SetAttr) -> Value | None: + return self.add(op) + + def visit_load_static(self, op: LoadStatic) -> Value | None: + return self.add(op) + + def visit_init_static(self, op: InitStatic) -> Value | None: + return self.add(op) + + def visit_tuple_get(self, op: TupleGet) -> Value | None: + return self.add(op) + + def visit_tuple_set(self, op: TupleSet) -> Value | None: + return self.add(op) + + def visit_inc_ref(self, op: IncRef) -> Value | None: + return self.add(op) + + def visit_dec_ref(self, op: DecRef) -> Value | None: + return self.add(op) + + def visit_call(self, op: Call) -> Value | None: + return self.add(op) + + def visit_method_call(self, op: MethodCall) -> Value | None: + return self.add(op) + + def visit_cast(self, op: Cast) -> Value | None: + return self.add(op) + + def visit_box(self, op: Box) -> Value | None: + return self.add(op) + + def visit_unbox(self, op: Unbox) -> Value | None: + return self.add(op) + + def visit_raise_standard_error(self, op: RaiseStandardError) -> Value | None: + return self.add(op) + + def visit_call_c(self, op: CallC) -> Value | None: + return self.add(op) + + def visit_truncate(self, op: Truncate) -> Value | None: + return self.add(op) + + def visit_extend(self, op: Extend) -> Value | None: + return self.add(op) + + def visit_load_global(self, op: LoadGlobal) -> Value | None: + return self.add(op) + + def visit_int_op(self, op: IntOp) -> Value | None: + return self.add(op) + + def visit_comparison_op(self, op: ComparisonOp) -> Value | None: + return self.add(op) + + def visit_float_op(self, op: FloatOp) -> Value | None: + return self.add(op) + + def visit_float_neg(self, op: FloatNeg) -> Value | None: + return self.add(op) + + def visit_float_comparison_op(self, op: FloatComparisonOp) -> Value | None: + return self.add(op) + + def visit_load_mem(self, op: LoadMem) -> Value | None: + return self.add(op) + + def visit_set_mem(self, op: SetMem) -> Value | None: + return self.add(op) + + def visit_get_element_ptr(self, op: GetElementPtr) -> Value | None: + return self.add(op) + + def visit_load_address(self, op: LoadAddress) -> Value | None: + return self.add(op) + + def visit_keep_alive(self, op: KeepAlive) -> Value | None: + return self.add(op) + + def visit_unborrow(self, op: Unborrow) -> Value | None: + return self.add(op) + + +class PatchVisitor(OpVisitor[None]): + def __init__( + self, op_map: dict[Value, Value | None], block_map: dict[BasicBlock, BasicBlock] + ) -> None: + self.op_map: Final = op_map + self.block_map: Final = block_map + + def fix_op(self, op: Value) -> Value: + new = self.op_map.get(op, op) + assert new is not None, "use of removed op" + return new + + def fix_block(self, block: BasicBlock) -> BasicBlock: + return self.block_map.get(block, block) + + def visit_goto(self, op: Goto) -> None: + op.label = self.fix_block(op.label) + + def visit_branch(self, op: Branch) -> None: + op.value = self.fix_op(op.value) + op.true = self.fix_block(op.true) + op.false = self.fix_block(op.false) + + def visit_return(self, op: Return) -> None: + op.value = self.fix_op(op.value) + + def visit_unreachable(self, op: Unreachable) -> None: + pass + + def visit_assign(self, op: Assign) -> None: + op.src = self.fix_op(op.src) + + def visit_assign_multi(self, op: AssignMulti) -> None: + op.src = [self.fix_op(s) for s in op.src] + + def visit_load_error_value(self, op: LoadErrorValue) -> None: + pass + + def visit_load_literal(self, op: LoadLiteral) -> None: + pass + + def visit_get_attr(self, op: GetAttr) -> None: + op.obj = self.fix_op(op.obj) + + def visit_set_attr(self, op: SetAttr) -> None: + op.obj = self.fix_op(op.obj) + op.src = self.fix_op(op.src) + + def visit_load_static(self, op: LoadStatic) -> None: + pass + + def visit_init_static(self, op: InitStatic) -> None: + op.value = self.fix_op(op.value) + + def visit_tuple_get(self, op: TupleGet) -> None: + op.src = self.fix_op(op.src) + + def visit_tuple_set(self, op: TupleSet) -> None: + op.items = [self.fix_op(item) for item in op.items] + + def visit_inc_ref(self, op: IncRef) -> None: + op.src = self.fix_op(op.src) + + def visit_dec_ref(self, op: DecRef) -> None: + op.src = self.fix_op(op.src) + + def visit_call(self, op: Call) -> None: + op.args = [self.fix_op(arg) for arg in op.args] + + def visit_method_call(self, op: MethodCall) -> None: + op.obj = self.fix_op(op.obj) + op.args = [self.fix_op(arg) for arg in op.args] + + def visit_cast(self, op: Cast) -> None: + op.src = self.fix_op(op.src) + + def visit_box(self, op: Box) -> None: + op.src = self.fix_op(op.src) + + def visit_unbox(self, op: Unbox) -> None: + op.src = self.fix_op(op.src) + + def visit_raise_standard_error(self, op: RaiseStandardError) -> None: + if isinstance(op.value, Value): + op.value = self.fix_op(op.value) + + def visit_call_c(self, op: CallC) -> None: + op.args = [self.fix_op(arg) for arg in op.args] + + def visit_truncate(self, op: Truncate) -> None: + op.src = self.fix_op(op.src) + + def visit_extend(self, op: Extend) -> None: + op.src = self.fix_op(op.src) + + def visit_load_global(self, op: LoadGlobal) -> None: + pass + + def visit_int_op(self, op: IntOp) -> None: + op.lhs = self.fix_op(op.lhs) + op.rhs = self.fix_op(op.rhs) + + def visit_comparison_op(self, op: ComparisonOp) -> None: + op.lhs = self.fix_op(op.lhs) + op.rhs = self.fix_op(op.rhs) + + def visit_float_op(self, op: FloatOp) -> None: + op.lhs = self.fix_op(op.lhs) + op.rhs = self.fix_op(op.rhs) + + def visit_float_neg(self, op: FloatNeg) -> None: + op.src = self.fix_op(op.src) + + def visit_float_comparison_op(self, op: FloatComparisonOp) -> None: + op.lhs = self.fix_op(op.lhs) + op.rhs = self.fix_op(op.rhs) + + def visit_load_mem(self, op: LoadMem) -> None: + op.src = self.fix_op(op.src) + + def visit_set_mem(self, op: SetMem) -> None: + op.dest = self.fix_op(op.dest) + op.src = self.fix_op(op.src) + + def visit_get_element_ptr(self, op: GetElementPtr) -> None: + op.src = self.fix_op(op.src) + + def visit_load_address(self, op: LoadAddress) -> None: + if isinstance(op.src, LoadStatic): + new = self.fix_op(op.src) + assert isinstance(new, LoadStatic) + op.src = new + + def visit_keep_alive(self, op: KeepAlive) -> None: + op.src = [self.fix_op(s) for s in op.src] + + def visit_unborrow(self, op: Unborrow) -> None: + op.src = self.fix_op(op.src) From 4259e37875219d30427a66304033f661f8b47f8f Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:31:16 +0200 Subject: [PATCH 117/172] Remove redundant Python 3.7 code (#17004) Some follow on from https://github.com/python/mypy/pull/15566. Also add 3.12 to tox.ini. --- mypy/modulefinder.py | 4 ++-- mypy/stubgenc.py | 2 +- mypy/util.py | 2 +- mypyc/lib-rt/CPy.h | 5 ----- mypyc/lib-rt/pythonsupport.h | 15 --------------- tox.ini | 1 + 6 files changed, 5 insertions(+), 24 deletions(-) diff --git a/mypy/modulefinder.py b/mypy/modulefinder.py index 455aa40e5975..452cfef20f4c 100644 --- a/mypy/modulefinder.py +++ b/mypy/modulefinder.py @@ -870,6 +870,6 @@ def parse_version(version: str) -> tuple[int, int]: def typeshed_py_version(options: Options) -> tuple[int, int]: """Return Python version used for checking whether module supports typeshed.""" - # Typeshed no longer covers Python 3.x versions before 3.7, so 3.7 is + # Typeshed no longer covers Python 3.x versions before 3.8, so 3.8 is # the earliest we can support. - return max(options.python_version, (3, 7)) + return max(options.python_version, (3, 8)) diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 3bec0c246d9a..29b2636d39cc 100755 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -495,7 +495,7 @@ def get_type_annotation(self, obj: object) -> str: if obj is None or obj is type(None): return "None" elif inspect.isclass(obj): - return "type[{}]".format(self.get_type_fullname(obj)) + return f"type[{self.get_type_fullname(obj)}]" elif isinstance(obj, FunctionType): return self.add_name("typing.Callable") elif isinstance(obj, ModuleType): diff --git a/mypy/util.py b/mypy/util.py index 968774ee7c98..bbb5a8610f7f 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -298,7 +298,7 @@ def _generate_junit_contents( text=escape("\n".join(messages)), filename="mypy", time=dt, - name="mypy-py{ver}-{platform}".format(ver=version, platform=platform), + name=f"mypy-py{version}-{platform}", ) xml += JUNIT_FOOTER diff --git a/mypyc/lib-rt/CPy.h b/mypyc/lib-rt/CPy.h index 64b716945b94..1a03f049ecb0 100644 --- a/mypyc/lib-rt/CPy.h +++ b/mypyc/lib-rt/CPy.h @@ -544,13 +544,8 @@ void CPy_AttributeError(const char *filename, const char *funcname, const char * // Misc operations -#if PY_VERSION_HEX >= 0x03080000 #define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc) #define CPy_TRASHCAN_END(op) Py_TRASHCAN_END -#else -#define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op) -#define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op) -#endif // Tweaked version of _PyArg_Parser in CPython typedef struct CPyArg_Parser { diff --git a/mypyc/lib-rt/pythonsupport.h b/mypyc/lib-rt/pythonsupport.h index 1d493b45b89d..f7d501f44a27 100644 --- a/mypyc/lib-rt/pythonsupport.h +++ b/mypyc/lib-rt/pythonsupport.h @@ -354,21 +354,6 @@ list_count(PyListObject *self, PyObject *value) return CPyTagged_ShortFromSsize_t(count); } -#if PY_VERSION_HEX < 0x03080000 -static PyObject * -_PyDict_GetItemStringWithError(PyObject *v, const char *key) -{ - PyObject *kv, *rv; - kv = PyUnicode_FromString(key); - if (kv == NULL) { - return NULL; - } - rv = PyDict_GetItemWithError(v, kv); - Py_DECREF(kv); - return rv; -} -#endif - #define CPyUnicode_EqualToASCIIString(x, y) _PyUnicode_EqualToASCIIString(x, y) // Adapted from genobject.c in Python 3.7.2 diff --git a/tox.ini b/tox.ini index 31aed1a1ef48..c2abd05d7b6c 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,7 @@ envlist = py39, py310, py311, + py312, docs, lint, type, From 16abf5cbe08c8b399381fc38220586cf2e49c2bc Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:40:22 -0800 Subject: [PATCH 118/172] Fix type narrowing for types.EllipsisType (#17003) Fixes #17002 --- mypy/types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/types.py b/mypy/types.py index b34efde15b31..d3c4df8b3b09 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -1524,7 +1524,7 @@ def is_singleton_type(self) -> bool: return ( self.type.is_enum and len(self.get_enum_values()) == 1 - or self.type.fullname == "builtins.ellipsis" + or self.type.fullname in {"builtins.ellipsis", "types.EllipsisType"} ) def get_enum_values(self) -> list[str]: From ea49e1fa488810997d192a36d85357dadb4a7f14 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Mon, 11 Mar 2024 15:18:39 +0100 Subject: [PATCH 119/172] Support `TypeAliasType` (#16926) Builds on top of and supersedes #16644 --------- Co-authored-by: sobolevn --- mypy/semanal.py | 132 +++++++++++++++-- mypy/typeanal.py | 49 ++++-- test-data/unit/check-generics.test | 54 +++---- test-data/unit/check-inference.test | 2 +- .../unit/check-parameter-specification.test | 18 +-- test-data/unit/check-python312.test | 23 +++ test-data/unit/check-type-aliases.test | 139 ++++++++++++++++++ test-data/unit/fixtures/typing-full.pyi | 17 ++- test-data/unit/lib-stub/typing_extensions.pyi | 8 +- 9 files changed, 373 insertions(+), 69 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 6bf02382a036..93e84ced4639 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -52,7 +52,7 @@ from contextlib import contextmanager from typing import Any, Callable, Collection, Final, Iterable, Iterator, List, TypeVar, cast -from typing_extensions import TypeAlias as _TypeAlias +from typing_extensions import TypeAlias as _TypeAlias, TypeGuard from mypy import errorcodes as codes, message_registry from mypy.constant_fold import constant_fold_expr @@ -2018,34 +2018,35 @@ def analyze_class_typevar_declaration(self, base: Type) -> tuple[TypeVarLikeList def analyze_unbound_tvar(self, t: Type) -> tuple[str, TypeVarLikeExpr] | None: if isinstance(t, UnpackType) and isinstance(t.type, UnboundType): - return self.analyze_unbound_tvar_impl(t.type, allow_tvt=True) + return self.analyze_unbound_tvar_impl(t.type, is_unpacked=True) if isinstance(t, UnboundType): sym = self.lookup_qualified(t.name, t) if sym and sym.fullname in ("typing.Unpack", "typing_extensions.Unpack"): inner_t = t.args[0] if isinstance(inner_t, UnboundType): - return self.analyze_unbound_tvar_impl(inner_t, allow_tvt=True) + return self.analyze_unbound_tvar_impl(inner_t, is_unpacked=True) return None return self.analyze_unbound_tvar_impl(t) return None def analyze_unbound_tvar_impl( - self, t: UnboundType, allow_tvt: bool = False + self, t: UnboundType, is_unpacked: bool = False, is_typealias_param: bool = False ) -> tuple[str, TypeVarLikeExpr] | None: + assert not is_unpacked or not is_typealias_param, "Mutually exclusive conditions" sym = self.lookup_qualified(t.name, t) if sym and isinstance(sym.node, PlaceholderNode): self.record_incomplete_ref() - if not allow_tvt and sym and isinstance(sym.node, ParamSpecExpr): + if not is_unpacked and sym and isinstance(sym.node, ParamSpecExpr): if sym.fullname and not self.tvar_scope.allow_binding(sym.fullname): # It's bound by our type variable scope return None return t.name, sym.node - if allow_tvt and sym and isinstance(sym.node, TypeVarTupleExpr): + if (is_unpacked or is_typealias_param) and sym and isinstance(sym.node, TypeVarTupleExpr): if sym.fullname and not self.tvar_scope.allow_binding(sym.fullname): # It's bound by our type variable scope return None return t.name, sym.node - if sym is None or not isinstance(sym.node, TypeVarExpr) or allow_tvt: + if sym is None or not isinstance(sym.node, TypeVarExpr) or is_unpacked: return None elif sym.fullname and not self.tvar_scope.allow_binding(sym.fullname): # It's bound by our type variable scope @@ -3515,7 +3516,11 @@ def analyze_simple_literal_type(self, rvalue: Expression, is_final: bool) -> Typ return typ def analyze_alias( - self, name: str, rvalue: Expression, allow_placeholder: bool = False + self, + name: str, + rvalue: Expression, + allow_placeholder: bool = False, + declared_type_vars: TypeVarLikeList | None = None, ) -> tuple[Type | None, list[TypeVarLikeType], set[str], list[str], bool]: """Check if 'rvalue' is a valid type allowed for aliasing (e.g. not a type variable). @@ -3540,9 +3545,10 @@ def analyze_alias( found_type_vars = self.find_type_var_likes(typ) tvar_defs: list[TypeVarLikeType] = [] namespace = self.qualified_name(name) + alias_type_vars = found_type_vars if declared_type_vars is None else declared_type_vars last_tvar_name_with_default: str | None = None with self.tvar_scope_frame(self.tvar_scope.class_frame(namespace)): - for name, tvar_expr in found_type_vars: + for name, tvar_expr in alias_type_vars: tvar_expr.default = tvar_expr.default.accept( TypeVarDefaultTranslator(self, tvar_expr.name, typ) ) @@ -3567,6 +3573,7 @@ def analyze_alias( in_dynamic_func=dynamic, global_scope=global_scope, allowed_alias_tvars=tvar_defs, + has_type_params=declared_type_vars is not None, ) # There can be only one variadic variable at most, the error is reported elsewhere. @@ -3579,7 +3586,7 @@ def analyze_alias( variadic = True new_tvar_defs.append(td) - qualified_tvars = [node.fullname for _name, node in found_type_vars] + qualified_tvars = [node.fullname for _name, node in alias_type_vars] empty_tuple_index = typ.empty_tuple_index if isinstance(typ, UnboundType) else False return analyzed, new_tvar_defs, depends_on, qualified_tvars, empty_tuple_index @@ -3612,7 +3619,19 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # unless using PEP 613 `cls: TypeAlias = A` return False - if isinstance(s.rvalue, CallExpr) and s.rvalue.analyzed: + # It can be `A = TypeAliasType('A', ...)` call, in this case, + # we just take the second argument and analyze it: + type_params: TypeVarLikeList | None + if self.check_type_alias_type_call(s.rvalue, name=lvalue.name): + rvalue = s.rvalue.args[1] + pep_695 = True + type_params = self.analyze_type_alias_type_params(s.rvalue) + else: + rvalue = s.rvalue + pep_695 = False + type_params = None + + if isinstance(rvalue, CallExpr) and rvalue.analyzed: return False existing = self.current_symbol_table().get(lvalue.name) @@ -3638,7 +3657,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: return False non_global_scope = self.type or self.is_func_scope() - if not pep_613 and isinstance(s.rvalue, RefExpr) and non_global_scope: + if not pep_613 and isinstance(rvalue, RefExpr) and non_global_scope: # Fourth rule (special case): Non-subscripted right hand side creates a variable # at class and function scopes. For example: # @@ -3650,8 +3669,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # without this rule, this typical use case will require a lot of explicit # annotations (see the second rule). return False - rvalue = s.rvalue - if not pep_613 and not self.can_be_type_alias(rvalue): + if not pep_613 and not pep_695 and not self.can_be_type_alias(rvalue): return False if existing and not isinstance(existing.node, (PlaceholderNode, TypeAlias)): @@ -3668,7 +3686,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: else: tag = self.track_incomplete_refs() res, alias_tvars, depends_on, qualified_tvars, empty_tuple_index = self.analyze_alias( - lvalue.name, rvalue, allow_placeholder=True + lvalue.name, rvalue, allow_placeholder=True, declared_type_vars=type_params ) if not res: return False @@ -3698,13 +3716,15 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # so we need to replace it with non-explicit Anys. res = make_any_non_explicit(res) # Note: with the new (lazy) type alias representation we only need to set no_args to True - # if the expected number of arguments is non-zero, so that aliases like A = List work. + # if the expected number of arguments is non-zero, so that aliases like `A = List` work + # but not aliases like `A = TypeAliasType("A", List)` as these need explicit type params. # However, eagerly expanding aliases like Text = str is a nice performance optimization. no_args = ( isinstance(res, ProperType) and isinstance(res, Instance) and not res.args and not empty_tuple_index + and not pep_695 ) if isinstance(res, ProperType) and isinstance(res, Instance): if not validate_instance(res, self.fail, empty_tuple_index): @@ -3771,6 +3791,80 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: self.note("Use variable annotation syntax to define protocol members", s) return True + def check_type_alias_type_call(self, rvalue: Expression, *, name: str) -> TypeGuard[CallExpr]: + if not isinstance(rvalue, CallExpr): + return False + + names = ["typing_extensions.TypeAliasType"] + if self.options.python_version >= (3, 12): + names.append("typing.TypeAliasType") + if not refers_to_fullname(rvalue.callee, tuple(names)): + return False + + return self.check_typevarlike_name(rvalue, name, rvalue) + + def analyze_type_alias_type_params(self, rvalue: CallExpr) -> TypeVarLikeList: + if "type_params" in rvalue.arg_names: + type_params_arg = rvalue.args[rvalue.arg_names.index("type_params")] + if not isinstance(type_params_arg, TupleExpr): + self.fail( + "Tuple literal expected as the type_params argument to TypeAliasType", + type_params_arg, + ) + return [] + type_params = type_params_arg.items + else: + type_params = [] + + declared_tvars: TypeVarLikeList = [] + have_type_var_tuple = False + for tp_expr in type_params: + if isinstance(tp_expr, StarExpr): + tp_expr.valid = False + self.analyze_type_expr(tp_expr) + try: + base = self.expr_to_unanalyzed_type(tp_expr) + except TypeTranslationError: + continue + if not isinstance(base, UnboundType): + continue + + tag = self.track_incomplete_refs() + tvar = self.analyze_unbound_tvar_impl(base, is_typealias_param=True) + if tvar: + if isinstance(tvar[1], TypeVarTupleExpr): + if have_type_var_tuple: + self.fail( + "Can only use one TypeVarTuple in type_params argument to TypeAliasType", + base, + code=codes.TYPE_VAR, + ) + have_type_var_tuple = True + continue + have_type_var_tuple = True + elif not self.found_incomplete_ref(tag): + self.fail( + "Free type variable expected in type_params argument to TypeAliasType", + base, + code=codes.TYPE_VAR, + ) + sym = self.lookup_qualified(base.name, base) + if sym and sym.fullname in ("typing.Unpack", "typing_extensions.Unpack"): + self.note( + "Don't Unpack type variables in type_params", base, code=codes.TYPE_VAR + ) + continue + if tvar in declared_tvars: + self.fail( + f'Duplicate type variable "{tvar[0]}" in type_params argument to TypeAliasType', + base, + code=codes.TYPE_VAR, + ) + continue + if tvar: + declared_tvars.append(tvar) + return declared_tvars + def disable_invalid_recursive_aliases( self, s: AssignmentStmt, current_node: TypeAlias ) -> None: @@ -5187,6 +5281,12 @@ def visit_call_expr(self, expr: CallExpr) -> None: expr.analyzed = OpExpr("divmod", expr.args[0], expr.args[1]) expr.analyzed.line = expr.line expr.analyzed.accept(self) + elif refers_to_fullname( + expr.callee, ("typing.TypeAliasType", "typing_extensions.TypeAliasType") + ): + with self.allow_unbound_tvars_set(): + for a in expr.args: + a.accept(self) else: # Normal call expression. for a in expr.args: diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 8a9ac8f4ac31..470b07948535 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -141,6 +141,7 @@ def analyze_type_alias( in_dynamic_func: bool = False, global_scope: bool = True, allowed_alias_tvars: list[TypeVarLikeType] | None = None, + has_type_params: bool = False, ) -> tuple[Type, set[str]]: """Analyze r.h.s. of a (potential) type alias definition. @@ -158,6 +159,7 @@ def analyze_type_alias( allow_placeholder=allow_placeholder, prohibit_self_type="type alias target", allowed_alias_tvars=allowed_alias_tvars, + has_type_params=has_type_params, ) analyzer.in_dynamic_func = in_dynamic_func analyzer.global_scope = global_scope @@ -210,6 +212,7 @@ def __init__( prohibit_self_type: str | None = None, allowed_alias_tvars: list[TypeVarLikeType] | None = None, allow_type_any: bool = False, + has_type_params: bool = False, ) -> None: self.api = api self.fail_func = api.fail @@ -231,6 +234,7 @@ def __init__( if allowed_alias_tvars is None: allowed_alias_tvars = [] self.allowed_alias_tvars = allowed_alias_tvars + self.has_type_params = has_type_params # If false, record incomplete ref if we generate PlaceholderType. self.allow_placeholder = allow_placeholder # Are we in a context where Required[] is allowed? @@ -325,7 +329,11 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) if tvar_def is None: if self.allow_unbound_tvars: return t - self.fail(f'ParamSpec "{t.name}" is unbound', t, code=codes.VALID_TYPE) + if self.defining_alias and self.has_type_params: + msg = f'ParamSpec "{t.name}" is not included in type_params' + else: + msg = f'ParamSpec "{t.name}" is unbound' + self.fail(msg, t, code=codes.VALID_TYPE) return AnyType(TypeOfAny.from_error) assert isinstance(tvar_def, ParamSpecType) if len(t.args) > 0: @@ -349,11 +357,11 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) and not defining_literal and (tvar_def is None or tvar_def not in self.allowed_alias_tvars) ): - self.fail( - f'Can\'t use bound type variable "{t.name}" to define generic alias', - t, - code=codes.VALID_TYPE, - ) + if self.has_type_params: + msg = f'Type variable "{t.name}" is not included in type_params' + else: + msg = f'Can\'t use bound type variable "{t.name}" to define generic alias' + self.fail(msg, t, code=codes.VALID_TYPE) return AnyType(TypeOfAny.from_error) if isinstance(sym.node, TypeVarExpr) and tvar_def is not None: assert isinstance(tvar_def, TypeVarType) @@ -368,17 +376,21 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) and self.defining_alias and tvar_def not in self.allowed_alias_tvars ): - self.fail( - f'Can\'t use bound type variable "{t.name}" to define generic alias', - t, - code=codes.VALID_TYPE, - ) + if self.has_type_params: + msg = f'Type variable "{t.name}" is not included in type_params' + else: + msg = f'Can\'t use bound type variable "{t.name}" to define generic alias' + self.fail(msg, t, code=codes.VALID_TYPE) return AnyType(TypeOfAny.from_error) if isinstance(sym.node, TypeVarTupleExpr): if tvar_def is None: if self.allow_unbound_tvars: return t - self.fail(f'TypeVarTuple "{t.name}" is unbound', t, code=codes.VALID_TYPE) + if self.defining_alias and self.has_type_params: + msg = f'TypeVarTuple "{t.name}" is not included in type_params' + else: + msg = f'TypeVarTuple "{t.name}" is unbound' + self.fail(msg, t, code=codes.VALID_TYPE) return AnyType(TypeOfAny.from_error) assert isinstance(tvar_def, TypeVarTupleType) if not self.allow_type_var_tuple: @@ -1267,6 +1279,19 @@ def analyze_callable_args_for_paramspec( AnyType(TypeOfAny.explicit), ret_type=ret_type, fallback=fallback ) return None + elif ( + self.defining_alias + and self.has_type_params + and tvar_def not in self.allowed_alias_tvars + ): + self.fail( + f'ParamSpec "{callable_args.name}" is not included in type_params', + callable_args, + code=codes.VALID_TYPE, + ) + return callable_with_ellipsis( + AnyType(TypeOfAny.special_form), ret_type=ret_type, fallback=fallback + ) return CallableType( [ diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test index f4b7c14bd053..b1d1ff3f46a1 100644 --- a/test-data/unit/check-generics.test +++ b/test-data/unit/check-generics.test @@ -3124,8 +3124,8 @@ def dec(f: Callable[P, T]) -> Callable[P, List[T]]: ... def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... def pair(x: U, y: V) -> Tuple[U, V]: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (x: T`2) -> builtins.list[T`2]" -reveal_type(dec(either)) # N: Revealed type is "def [T] (x: T`4, y: T`4) -> builtins.list[T`4]" +reveal_type(dec(id)) # N: Revealed type is "def [T] (x: T`3) -> builtins.list[T`3]" +reveal_type(dec(either)) # N: Revealed type is "def [T] (x: T`5, y: T`5) -> builtins.list[T`5]" reveal_type(dec(pair)) # N: Revealed type is "def [U, V] (x: U`-1, y: V`-2) -> builtins.list[Tuple[U`-1, V`-2]]" [builtins fixtures/list.pyi] @@ -3142,8 +3142,8 @@ V = TypeVar('V') def dec(f: Callable[P, List[T]]) -> Callable[P, T]: ... def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (x: builtins.list[T`2]) -> T`2" -reveal_type(dec(either)) # N: Revealed type is "def [T] (x: builtins.list[T`4], y: builtins.list[T`4]) -> T`4" +reveal_type(dec(id)) # N: Revealed type is "def [T] (x: builtins.list[T`3]) -> T`3" +reveal_type(dec(either)) # N: Revealed type is "def [T] (x: builtins.list[T`5], y: builtins.list[T`5]) -> T`5" [builtins fixtures/list.pyi] [case testInferenceAgainstGenericParamSpecPopOff] @@ -3161,9 +3161,9 @@ def dec(f: Callable[Concatenate[T, P], S]) -> Callable[P, Callable[[T], S]]: ... def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... def pair(x: U, y: V) -> Tuple[U, V]: ... -reveal_type(dec(id)) # N: Revealed type is "def () -> def [T] (T`1) -> T`1" -reveal_type(dec(either)) # N: Revealed type is "def [T] (y: T`4) -> def (T`4) -> T`4" -reveal_type(dec(pair)) # N: Revealed type is "def [V] (y: V`-2) -> def [T] (T`7) -> Tuple[T`7, V`-2]" +reveal_type(dec(id)) # N: Revealed type is "def () -> def [T] (T`2) -> T`2" +reveal_type(dec(either)) # N: Revealed type is "def [T] (y: T`5) -> def (T`5) -> T`5" +reveal_type(dec(pair)) # N: Revealed type is "def [V] (y: V`-2) -> def [T] (T`8) -> Tuple[T`8, V`-2]" reveal_type(dec(dec)) # N: Revealed type is "def () -> def [T, P, S] (def (T`-1, *P.args, **P.kwargs) -> S`-3) -> def (*P.args, **P.kwargs) -> def (T`-1) -> S`-3" [builtins fixtures/list.pyi] @@ -3182,11 +3182,11 @@ def dec(f: Callable[P, Callable[[T], S]]) -> Callable[Concatenate[T, P], S]: ... def id() -> Callable[[U], U]: ... def either(x: U) -> Callable[[U], U]: ... def pair(x: U) -> Callable[[V], Tuple[V, U]]: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (T`2) -> T`2" -reveal_type(dec(either)) # N: Revealed type is "def [T] (T`5, x: T`5) -> T`5" -reveal_type(dec(pair)) # N: Revealed type is "def [T, U] (T`8, x: U`-1) -> Tuple[T`8, U`-1]" +reveal_type(dec(id)) # N: Revealed type is "def [T] (T`3) -> T`3" +reveal_type(dec(either)) # N: Revealed type is "def [T] (T`6, x: T`6) -> T`6" +reveal_type(dec(pair)) # N: Revealed type is "def [T, U] (T`9, x: U`-1) -> Tuple[T`9, U`-1]" # This is counter-intuitive but looks correct, dec matches itself only if P can be empty -reveal_type(dec(dec)) # N: Revealed type is "def [T, S] (T`11, f: def () -> def (T`11) -> S`12) -> S`12" +reveal_type(dec(dec)) # N: Revealed type is "def [T, S] (T`12, f: def () -> def (T`12) -> S`13) -> S`13" [builtins fixtures/list.pyi] [case testInferenceAgainstGenericParamSpecVsParamSpec] @@ -3203,7 +3203,7 @@ class Bar(Generic[P, T]): ... def dec(f: Callable[P, T]) -> Callable[P, List[T]]: ... def f(*args: Q.args, **kwargs: Q.kwargs) -> Foo[Q]: ... -reveal_type(dec(f)) # N: Revealed type is "def [P] (*P.args, **P.kwargs) -> builtins.list[__main__.Foo[P`1]]" +reveal_type(dec(f)) # N: Revealed type is "def [P] (*P.args, **P.kwargs) -> builtins.list[__main__.Foo[P`2]]" g: Callable[Concatenate[int, Q], Foo[Q]] reveal_type(dec(g)) # N: Revealed type is "def [Q] (builtins.int, *Q.args, **Q.kwargs) -> builtins.list[__main__.Foo[Q`-1]]" h: Callable[Concatenate[T, Q], Bar[Q, T]] @@ -3264,8 +3264,8 @@ def transform( def dec(f: Callable[W, U]) -> Callable[W, U]: ... def dec2(f: Callable[Concatenate[str, W], U]) -> Callable[Concatenate[bytes, W], U]: ... -reveal_type(transform(dec)) # N: Revealed type is "def [P, T] (def (builtins.int, *P.args, **P.kwargs) -> T`2) -> def (builtins.int, *P.args, **P.kwargs) -> T`2" -reveal_type(transform(dec2)) # N: Revealed type is "def [W, T] (def (builtins.int, builtins.str, *W.args, **W.kwargs) -> T`6) -> def (builtins.int, builtins.bytes, *W.args, **W.kwargs) -> T`6" +reveal_type(transform(dec)) # N: Revealed type is "def [P, T] (def (builtins.int, *P.args, **P.kwargs) -> T`3) -> def (builtins.int, *P.args, **P.kwargs) -> T`3" +reveal_type(transform(dec2)) # N: Revealed type is "def [W, T] (def (builtins.int, builtins.str, *W.args, **W.kwargs) -> T`7) -> def (builtins.int, builtins.bytes, *W.args, **W.kwargs) -> T`7" [builtins fixtures/tuple.pyi] [case testNoAccidentalVariableClashInNestedGeneric] @@ -3319,8 +3319,8 @@ def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... def pair(x: U, y: V) -> Tuple[U, V]: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (T`2) -> builtins.list[T`2]" -reveal_type(dec(either)) # N: Revealed type is "def [T] (T`4, T`4) -> builtins.list[T`4]" +reveal_type(dec(id)) # N: Revealed type is "def [T] (T`3) -> builtins.list[T`3]" +reveal_type(dec(either)) # N: Revealed type is "def [T] (T`5, T`5) -> builtins.list[T`5]" reveal_type(dec(pair)) # N: Revealed type is "def [U, V] (U`-1, V`-2) -> builtins.list[Tuple[U`-1, V`-2]]" [builtins fixtures/tuple.pyi] @@ -3338,8 +3338,8 @@ V = TypeVar("V") def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (builtins.list[T`2]) -> T`2" -reveal_type(dec(either)) # N: Revealed type is "def [T] (builtins.list[T`4], builtins.list[T`4]) -> T`4" +reveal_type(dec(id)) # N: Revealed type is "def [T] (builtins.list[T`3]) -> T`3" +reveal_type(dec(either)) # N: Revealed type is "def [T] (builtins.list[T`5], builtins.list[T`5]) -> T`5" [builtins fixtures/tuple.pyi] [case testInferenceAgainstGenericVariadicPopOff] @@ -3358,9 +3358,9 @@ def id(x: U) -> U: ... def either(x: U, y: U) -> U: ... def pair(x: U, y: V) -> Tuple[U, V]: ... -reveal_type(dec(id)) # N: Revealed type is "def () -> def [T] (T`1) -> T`1" -reveal_type(dec(either)) # N: Revealed type is "def [T] (T`4) -> def (T`4) -> T`4" -reveal_type(dec(pair)) # N: Revealed type is "def [V] (V`-2) -> def [T] (T`7) -> Tuple[T`7, V`-2]" +reveal_type(dec(id)) # N: Revealed type is "def () -> def [T] (T`2) -> T`2" +reveal_type(dec(either)) # N: Revealed type is "def [T] (T`5) -> def (T`5) -> T`5" +reveal_type(dec(pair)) # N: Revealed type is "def [V] (V`-2) -> def [T] (T`8) -> Tuple[T`8, V`-2]" reveal_type(dec(dec)) # N: Revealed type is "def () -> def [T, Ts, S] (def (T`-1, *Unpack[Ts`-2]) -> S`-3) -> def (*Unpack[Ts`-2]) -> def (T`-1) -> S`-3" [builtins fixtures/list.pyi] @@ -3380,11 +3380,11 @@ def id() -> Callable[[U], U]: ... def either(x: U) -> Callable[[U], U]: ... def pair(x: U) -> Callable[[V], Tuple[V, U]]: ... -reveal_type(dec(id)) # N: Revealed type is "def [T] (T`2) -> T`2" -reveal_type(dec(either)) # N: Revealed type is "def [T] (T`5, T`5) -> T`5" -reveal_type(dec(pair)) # N: Revealed type is "def [T, U] (T`8, U`-1) -> Tuple[T`8, U`-1]" +reveal_type(dec(id)) # N: Revealed type is "def [T] (T`3) -> T`3" +reveal_type(dec(either)) # N: Revealed type is "def [T] (T`6, T`6) -> T`6" +reveal_type(dec(pair)) # N: Revealed type is "def [T, U] (T`9, U`-1) -> Tuple[T`9, U`-1]" # This is counter-intuitive but looks correct, dec matches itself only if Ts is empty -reveal_type(dec(dec)) # N: Revealed type is "def [T, S] (T`11, def () -> def (T`11) -> S`12) -> S`12" +reveal_type(dec(dec)) # N: Revealed type is "def [T, S] (T`12, def () -> def (T`12) -> S`13) -> S`13" [builtins fixtures/list.pyi] [case testInferenceAgainstGenericVariadicVsVariadic] @@ -3402,9 +3402,9 @@ class Bar(Generic[Unpack[Ts], T]): ... def dec(f: Callable[[Unpack[Ts]], T]) -> Callable[[Unpack[Ts]], List[T]]: ... def f(*args: Unpack[Us]) -> Foo[Unpack[Us]]: ... -reveal_type(dec(f)) # N: Revealed type is "def [Ts] (*Unpack[Ts`1]) -> builtins.list[__main__.Foo[Unpack[Ts`1]]]" +reveal_type(dec(f)) # N: Revealed type is "def [Ts] (*Unpack[Ts`2]) -> builtins.list[__main__.Foo[Unpack[Ts`2]]]" g: Callable[[Unpack[Us]], Foo[Unpack[Us]]] -reveal_type(dec(g)) # N: Revealed type is "def [Ts] (*Unpack[Ts`3]) -> builtins.list[__main__.Foo[Unpack[Ts`3]]]" +reveal_type(dec(g)) # N: Revealed type is "def [Ts] (*Unpack[Ts`4]) -> builtins.list[__main__.Foo[Unpack[Ts`4]]]" [builtins fixtures/list.pyi] [case testInferenceAgainstGenericVariadicVsVariadicConcatenate] diff --git a/test-data/unit/check-inference.test b/test-data/unit/check-inference.test index 1b1ce607bf28..08b53ab16972 100644 --- a/test-data/unit/check-inference.test +++ b/test-data/unit/check-inference.test @@ -3807,7 +3807,7 @@ def Negate(count: int, /, metric: Metric[float]) -> float: ... def Combine(count: int, m1: Metric[T], m2: Metric[T], /, *more: Metric[T]) -> T: ... reveal_type(Negate) # N: Revealed type is "def (metric: __main__.Metric[builtins.float]) -> builtins.float" -reveal_type(Combine) # N: Revealed type is "def [T] (def () -> T`4, def () -> T`4, *more: def () -> T`4) -> T`4" +reveal_type(Combine) # N: Revealed type is "def [T] (def () -> T`5, def () -> T`5, *more: def () -> T`5) -> T`5" def m1() -> float: ... def m2() -> float: ... diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index b212c7585993..8fd9abcb9752 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -901,8 +901,8 @@ class A: def func(self, action: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... -reveal_type(A.func) # N: Revealed type is "def [_P, _R] (self: __main__.A, action: def (*_P.args, **_P.kwargs) -> _R`3, *_P.args, **_P.kwargs) -> _R`3" -reveal_type(A().func) # N: Revealed type is "def [_P, _R] (action: def (*_P.args, **_P.kwargs) -> _R`7, *_P.args, **_P.kwargs) -> _R`7" +reveal_type(A.func) # N: Revealed type is "def [_P, _R] (self: __main__.A, action: def (*_P.args, **_P.kwargs) -> _R`4, *_P.args, **_P.kwargs) -> _R`4" +reveal_type(A().func) # N: Revealed type is "def [_P, _R] (action: def (*_P.args, **_P.kwargs) -> _R`8, *_P.args, **_P.kwargs) -> _R`8" def f(x: int) -> int: ... @@ -933,8 +933,8 @@ class A: def func(self, action: Job[_P, None]) -> Job[_P, None]: ... -reveal_type(A.func) # N: Revealed type is "def [_P] (self: __main__.A, action: __main__.Job[_P`2, None]) -> __main__.Job[_P`2, None]" -reveal_type(A().func) # N: Revealed type is "def [_P] (action: __main__.Job[_P`4, None]) -> __main__.Job[_P`4, None]" +reveal_type(A.func) # N: Revealed type is "def [_P] (self: __main__.A, action: __main__.Job[_P`3, None]) -> __main__.Job[_P`3, None]" +reveal_type(A().func) # N: Revealed type is "def [_P] (action: __main__.Job[_P`5, None]) -> __main__.Job[_P`5, None]" reveal_type(A().func(Job(lambda x: x))) # N: Revealed type is "__main__.Job[[x: Any], None]" def f(x: int, y: int) -> None: ... @@ -1096,7 +1096,7 @@ j = Job(generic_f) reveal_type(j) # N: Revealed type is "__main__.Job[[x: _T`-1]]" jf = j.into_callable() -reveal_type(jf) # N: Revealed type is "def [_T] (x: _T`2)" +reveal_type(jf) # N: Revealed type is "def [_T] (x: _T`3)" reveal_type(jf(1)) # N: Revealed type is "None" [builtins fixtures/paramspec.pyi] @@ -1115,10 +1115,10 @@ class Job(Generic[_P, _T]): def generic_f(x: _T) -> _T: ... j = Job(generic_f) -reveal_type(j) # N: Revealed type is "__main__.Job[[x: _T`2], _T`2]" +reveal_type(j) # N: Revealed type is "__main__.Job[[x: _T`3], _T`3]" jf = j.into_callable() -reveal_type(jf) # N: Revealed type is "def [_T] (x: _T`3) -> _T`3" +reveal_type(jf) # N: Revealed type is "def [_T] (x: _T`4) -> _T`4" reveal_type(jf(1)) # N: Revealed type is "builtins.int" [builtins fixtures/paramspec.pyi] @@ -1619,13 +1619,13 @@ U = TypeVar("U") def dec(f: Callable[P, T]) -> Callable[P, List[T]]: ... def test(x: U) -> U: ... reveal_type(dec) # N: Revealed type is "def [P, T] (f: def (*P.args, **P.kwargs) -> T`-2) -> def (*P.args, **P.kwargs) -> builtins.list[T`-2]" -reveal_type(dec(test)) # N: Revealed type is "def [T] (x: T`2) -> builtins.list[T`2]" +reveal_type(dec(test)) # N: Revealed type is "def [T] (x: T`3) -> builtins.list[T`3]" class A: ... TA = TypeVar("TA", bound=A) def test_with_bound(x: TA) -> TA: ... -reveal_type(dec(test_with_bound)) # N: Revealed type is "def [T <: __main__.A] (x: T`4) -> builtins.list[T`4]" +reveal_type(dec(test_with_bound)) # N: Revealed type is "def [T <: __main__.A] (x: T`5) -> builtins.list[T`5]" dec(test_with_bound)(0) # E: Value of type variable "T" of function cannot be "int" dec(test_with_bound)(A()) # OK [builtins fixtures/paramspec.pyi] diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 285563c19991..188c51f98185 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -60,3 +60,26 @@ def func2[**P](x: Callable[P, int]) -> Callable[P, str]: ... # E: PEP 695 gener def func3[*Ts](x: tuple[*Ts]) -> tuple[int, *Ts]: ... # E: PEP 695 generics are not yet supported \ # E: Name "Ts" is not defined [builtins fixtures/tuple.pyi] + +[case test695TypeAliasType] +from typing import Callable, TypeAliasType, TypeVar, TypeVarTuple + +T = TypeVar("T") +Ts = TypeVarTuple("Ts") + +TestType = TypeAliasType("TestType", int | str) +x: TestType = 42 +y: TestType = 'a' +z: TestType = object() # E: Incompatible types in assignment (expression has type "object", variable has type "Union[int, str]") + +BadAlias1 = TypeAliasType("BadAlias1", tuple[*Ts]) # E: TypeVarTuple "Ts" is not included in type_params +ba1: BadAlias1[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(ba1) # N: Revealed type is "builtins.tuple[Any, ...]" + +# TODO this should report errors on the two following lines +#BadAlias2 = TypeAliasType("BadAlias2", Callable[[*Ts], str]) +#ba2: BadAlias2[int] +#reveal_type(ba2) + +[builtins fixtures/tuple.pyi] +[typing fixtures/typing-full.pyi] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index a43233eed973..79a443dbeedc 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1065,3 +1065,142 @@ def eval(e: Expr) -> int: elif e[0] == 456: return -eval(e[1]) [builtins fixtures/dict-full.pyi] + +[case testTypeAliasType] +from typing import Union +from typing_extensions import TypeAliasType + +TestType = TypeAliasType("TestType", Union[int, str]) +x: TestType = 42 +y: TestType = 'a' +z: TestType = object() # E: Incompatible types in assignment (expression has type "object", variable has type "Union[int, str]") +[builtins fixtures/tuple.pyi] + +[case testTypeAliasTypeInvalid] +from typing_extensions import TypeAliasType + +TestType = TypeAliasType("T", int) # E: String argument 1 "T" to TypeAliasType(...) does not match variable name "TestType" + +T1 = T2 = TypeAliasType("T", int) +t1: T1 # E: Variable "__main__.T1" is not valid as a type \ + # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases + +T3 = TypeAliasType("T3", -1) # E: Invalid type: try using Literal[-1] instead? +t3: T3 +reveal_type(t3) # N: Revealed type is "Any" +[builtins fixtures/tuple.pyi] + +[case testTypeAliasTypeGeneric] +from typing import Callable, Dict, Generic, TypeVar, Tuple +from typing_extensions import TypeAliasType, TypeVarTuple, ParamSpec, Unpack + +K = TypeVar('K') +V = TypeVar('V') +T = TypeVar('T') +Ts = TypeVarTuple("Ts") +Ts1 = TypeVarTuple("Ts1") +P = ParamSpec("P") + +TestType = TypeAliasType("TestType", Dict[K, V], type_params=(K, V)) +x: TestType[int, str] = {1: 'a'} +y: TestType[str, int] = {'a': 1} +z: TestType[str, int] = {1: 'a'} # E: Dict entry 0 has incompatible type "int": "str"; expected "str": "int" +w: TestType[int] # E: Bad number of arguments for type alias, expected 2, given 1 + +InvertedDict = TypeAliasType("InvertedDict", Dict[K, V], type_params=(V, K)) +xi: InvertedDict[str, int] = {1: 'a'} +yi: InvertedDict[str, int] = {'a': 1} # E: Dict entry 0 has incompatible type "str": "int"; expected "int": "str" +zi: InvertedDict[int, str] = {1: 'a'} # E: Dict entry 0 has incompatible type "int": "str"; expected "str": "int" +reveal_type(xi) # N: Revealed type is "builtins.dict[builtins.int, builtins.str]" + +VariadicAlias1 = TypeAliasType("VariadicAlias1", Tuple[Unpack[Ts]], type_params=(Ts,)) +VariadicAlias2 = TypeAliasType("VariadicAlias2", Tuple[Unpack[Ts], K], type_params=(Ts, K)) +VariadicAlias3 = TypeAliasType("VariadicAlias3", Callable[[Unpack[Ts]], int], type_params=(Ts,)) +xv: VariadicAlias1[int, str] = (1, 'a') +yv: VariadicAlias1[str, int] = (1, 'a') # E: Incompatible types in assignment (expression has type "Tuple[int, str]", variable has type "Tuple[str, int]") +zv: VariadicAlias2[int, str] = (1, 'a') +def int_in_int_out(x: int) -> int: return x +wv: VariadicAlias3[int] = int_in_int_out +reveal_type(wv) # N: Revealed type is "def (builtins.int) -> builtins.int" + +ParamAlias = TypeAliasType("ParamAlias", Callable[P, int], type_params=(P,)) +def f(x: str, y: float) -> int: return 1 +def g(x: int, y: float) -> int: return 1 +xp1: ParamAlias[str, float] = f +xp2: ParamAlias[str, float] = g # E: Incompatible types in assignment (expression has type "Callable[[int, float], int]", variable has type "Callable[[str, float], int]") +xp3: ParamAlias[str, float] = lambda x, y: 1 + +class G(Generic[P, T]): ... +ParamAlias2 = TypeAliasType("ParamAlias2", G[P, T], type_params=(P, T)) +xp: ParamAlias2[[int], str] +reveal_type(xp) # N: Revealed type is "__main__.G[[builtins.int], builtins.str]" +[builtins fixtures/dict.pyi] + +[case testTypeAliasTypeInvalidGeneric] +from typing_extensions import TypeAliasType, TypeVarTuple, ParamSpec +from typing import Callable, Dict, Generic, TypeVar, Tuple, Unpack + +K = TypeVar('K') +V = TypeVar('V') +T = TypeVar('T') +Ts = TypeVarTuple("Ts") +Ts1 = TypeVarTuple("Ts1") +P = ParamSpec("P") + +Ta0 = TypeAliasType("Ta0", int, type_params=(T, T)) # E: Duplicate type variable "T" in type_params argument to TypeAliasType + +Ta1 = TypeAliasType("Ta1", int, type_params=K) # E: Tuple literal expected as the type_params argument to TypeAliasType + +Ta2 = TypeAliasType("Ta2", int, type_params=(None,)) # E: Free type variable expected in type_params argument to TypeAliasType + +Ta3 = TypeAliasType("Ta3", Dict[K, V], type_params=(V,)) # E: Type variable "K" is not included in type_params +partially_generic1: Ta3[int] = {"a": 1} +reveal_type(partially_generic1) # N: Revealed type is "builtins.dict[Any, builtins.int]" +partially_generic2: Ta3[int] = {1: "a"} # E: Dict entry 0 has incompatible type "int": "str"; expected "Any": "int" + +Ta4 = TypeAliasType("Ta4", Tuple[Unpack[Ts]], type_params=(Ts, Ts1)) # E: Can only use one TypeVarTuple in type_params argument to TypeAliasType + +Ta5 = TypeAliasType("Ta5", Dict) # Unlike old style aliases, this is not generic +non_generic_dict: Ta5[int, str] # E: Bad number of arguments for type alias, expected 0, given 2 +reveal_type(non_generic_dict) # N: Revealed type is "builtins.dict[Any, Any]" + +Ta6 = TypeAliasType("Ta6", Tuple[Unpack[Ts]]) # E: TypeVarTuple "Ts" is not included in type_params +unbound_tvt_alias: Ta6[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(unbound_tvt_alias) # N: Revealed type is "builtins.tuple[Any, ...]" + +class G(Generic[P, T]): ... +Ta7 = TypeAliasType("Ta7", G[P, T]) # E: ParamSpec "P" is not included in type_params \ + # E: Type variable "T" is not included in type_params +unbound_ps_alias: Ta7[[int], str] # E: Bracketed expression "[...]" is not valid as a type \ + # N: Did you mean "List[...]"? \ + # E: Bad number of arguments for type alias, expected 0, given 2 +reveal_type(unbound_ps_alias) # N: Revealed type is "__main__.G[Any, Any]" + +Ta8 = TypeAliasType("Ta8", Callable[P, int]) # E: ParamSpec "P" is not included in type_params +unbound_ps_alias2: Ta8[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(unbound_ps_alias2) # N: Revealed type is "def [P] (*Any, **Any) -> builtins.int" + +Ta9 = TypeAliasType("Ta9", Callable[P, T]) # E: ParamSpec "P" is not included in type_params \ + # E: Type variable "T" is not included in type_params +unbound_ps_alias3: Ta9[int, str] # E: Bad number of arguments for type alias, expected 0, given 2 +reveal_type(unbound_ps_alias3) # N: Revealed type is "def [P] (*Any, **Any) -> Any" + +# TODO this should report errors on the two following lines +#Ta10 = TypeAliasType("Ta10", Callable[[Unpack[Ts]], str]) +#unbound_tvt_alias2: Ta10[int] +#reveal_type(unbound_tvt_alias2) + +[builtins fixtures/dict.pyi] + +[case testTypeAliasTypeNoUnpackInTypeParams311] +# flags: --python-version 3.11 +from typing_extensions import TypeAliasType, TypeVar, TypeVarTuple, Unpack + +T = TypeVar("T") +Ts = TypeVarTuple("Ts") + +Ta1 = TypeAliasType("Ta1", None, type_params=(*Ts,)) # E: can't use starred expression here +Ta2 = TypeAliasType("Ta2", None, type_params=(Unpack[Ts],)) # E: Free type variable expected in type_params argument to TypeAliasType \ + # N: Don't Unpack type variables in type_params + +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/fixtures/typing-full.pyi b/test-data/unit/fixtures/typing-full.pyi index ca8a2413f05f..f7da75fa4cd0 100644 --- a/test-data/unit/fixtures/typing-full.pyi +++ b/test-data/unit/fixtures/typing-full.pyi @@ -10,13 +10,17 @@ from abc import abstractmethod, ABCMeta class GenericMeta(type): pass +class _SpecialForm: ... +class TypeVar: ... +class ParamSpec: ... +class TypeVarTuple: ... + def cast(t, o): ... def assert_type(o, t): ... overload = 0 Any = 0 Union = 0 Optional = 0 -TypeVar = 0 Generic = 0 Protocol = 0 Tuple = 0 @@ -39,6 +43,8 @@ U = TypeVar('U') V = TypeVar('V') S = TypeVar('S') +def final(x: T) -> T: ... + class NamedTuple(tuple[Any, ...]): ... # Note: definitions below are different from typeshed, variances are declared @@ -182,8 +188,6 @@ class _TypedDict(Mapping[str, object]): def update(self: T, __m: T) -> None: ... def __delitem__(self, k: NoReturn) -> None: ... -class _SpecialForm: pass - def dataclass_transform( *, eq_default: bool = ..., @@ -199,3 +203,10 @@ def reveal_type(__obj: T) -> T: ... # Only exists in type checking time: def type_check_only(__func_or_class: T) -> T: ... + +# Was added in 3.12 +@final +class TypeAliasType: + def __init__( + self, name: str, value: Any, *, type_params: Tuple[Union[TypeVar, ParamSpec, TypeVarTuple], ...] = () + ) -> None: ... diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index ff55f1b54c7d..b7b738f63d92 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -1,5 +1,5 @@ import typing -from typing import Any, Callable, Mapping, Iterable, Iterator, NoReturn as NoReturn, Dict, Tuple, Type +from typing import Any, Callable, Mapping, Iterable, Iterator, NoReturn as NoReturn, Dict, Tuple, Type, Union from typing import TYPE_CHECKING as TYPE_CHECKING from typing import NewType as NewType, overload as overload @@ -40,6 +40,12 @@ Never: _SpecialForm TypeVarTuple: _SpecialForm Unpack: _SpecialForm +@final +class TypeAliasType: + def __init__( + self, name: str, value: Any, *, type_params: Tuple[Union[TypeVar, ParamSpec, TypeVarTuple], ...] = () + ) -> None: ... + # Fallback type for all typed dicts (does not exist at runtime). class _TypedDict(Mapping[str, object]): # Needed to make this class non-abstract. It is explicitly declared abstract in From a00fcba1e77ac944276b8c4ad0a31b7b05ded59f Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Wed, 13 Mar 2024 16:42:20 +0000 Subject: [PATCH 120/172] Revert "Revert use of `ParamSpec` for `functools.wraps`" (#16942) ParamSpec support has improved so it doesn't seem necessary to revert the changes any more. --- misc/generate_changelog.py | 1 - misc/sync-typeshed.py | 1 - mypy/typeshed/stdlib/functools.pyi | 40 +++++++++++++++++++----------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/misc/generate_changelog.py b/misc/generate_changelog.py index 7c7f28b6eeb7..ebab6c569152 100644 --- a/misc/generate_changelog.py +++ b/misc/generate_changelog.py @@ -79,7 +79,6 @@ def filter_omitted_commits(commits: list[CommitInfo]) -> list[CommitInfo]: "Revert sum literal integer change", "Remove use of LiteralString in builtins", "Revert typeshed ctypes change", - "Revert use of `ParamSpec` for `functools.wraps`", ) ): # These are generated by a typeshed sync. diff --git a/misc/sync-typeshed.py b/misc/sync-typeshed.py index ee6414ab7b19..56bc1624d5d0 100644 --- a/misc/sync-typeshed.py +++ b/misc/sync-typeshed.py @@ -182,7 +182,6 @@ def main() -> None: "d25e4a9eb", # LiteralString reverts "d132999ba", # sum reverts "dd12a2d81", # ctypes reverts - "0dd4b6f75", # ParamSpec for functools.wraps ] for commit in commits_to_cherry_pick: try: diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index 991182486113..d3f702bcef4f 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,11 +27,13 @@ __all__ = [ if sys.version_info >= (3, 9): __all__ += ["cache"] -_AnyCallable: TypeAlias = Callable[..., object] - _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) _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: ... @@ -81,31 +83,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]: ... From a18a0db0c77e71050aaf31a53ad1fba8c663fd1a Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Thu, 14 Mar 2024 17:14:59 +0000 Subject: [PATCH 121/172] [mypyc] Optimize away some bool/bit registers (#17022) If a register is always used in a branch immediately after assignment, and it isn't used for anything else, we can replace the assignment with a branch op. This avoids some assignment ops and gotos. This is not a very interesting optimization in general, but it will help a lot with tagged integer operations once I refactor them to be generated in the lowering pass (in follow-up PRs). --- mypyc/codegen/emitmodule.py | 4 +- mypyc/test-data/opt-flag-elimination.test | 300 ++++++++++++++++++ ...y_propagation.py => test_optimizations.py} | 31 +- mypyc/transform/flag_elimination.py | 108 +++++++ mypyc/transform/ir_transform.py | 16 +- 5 files changed, 445 insertions(+), 14 deletions(-) create mode 100644 mypyc/test-data/opt-flag-elimination.test rename mypyc/test/{test_copy_propagation.py => test_optimizations.py} (62%) create mode 100644 mypyc/transform/flag_elimination.py diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index 0035bd53188b..9466bc2cea79 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -58,6 +58,7 @@ from mypyc.options import CompilerOptions from mypyc.transform.copy_propagation import do_copy_propagation from mypyc.transform.exceptions import insert_exception_handling +from mypyc.transform.flag_elimination import do_flag_elimination from mypyc.transform.refcount import insert_ref_count_opcodes from mypyc.transform.uninit import insert_uninit_checks @@ -234,8 +235,9 @@ def compile_scc_to_ir( insert_exception_handling(fn) # Insert refcount handling. insert_ref_count_opcodes(fn) - # Perform copy propagation optimization. + # Perform optimizations. do_copy_propagation(fn, compiler_options) + do_flag_elimination(fn, compiler_options) return modules diff --git a/mypyc/test-data/opt-flag-elimination.test b/mypyc/test-data/opt-flag-elimination.test new file mode 100644 index 000000000000..f047a87dc3fa --- /dev/null +++ b/mypyc/test-data/opt-flag-elimination.test @@ -0,0 +1,300 @@ +-- Test cases for "flag elimination" optimization. Used to optimize away +-- registers that are always used immediately after assignment as branch conditions. + +[case testFlagEliminationSimple] +def c() -> bool: + return True +def d() -> bool: + return True + +def f(x: bool) -> int: + if x: + b = c() + else: + b = d() + if b: + return 1 + else: + return 2 +[out] +def c(): +L0: + return 1 +def d(): +L0: + return 1 +def f(x): + x, r0, r1 :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + r0 = c() + if r0 goto L4 else goto L5 :: bool +L2: + r1 = d() + if r1 goto L4 else goto L5 :: bool +L3: + unreachable +L4: + return 2 +L5: + return 4 + +[case testFlagEliminationOneAssignment] +def c() -> bool: + return True + +def f(x: bool) -> int: + # Not applied here + b = c() + if b: + return 1 + else: + return 2 +[out] +def c(): +L0: + return 1 +def f(x): + x, r0, b :: bool +L0: + r0 = c() + b = r0 + if b goto L1 else goto L2 :: bool +L1: + return 2 +L2: + return 4 + +[case testFlagEliminationThreeCases] +def c(x: int) -> bool: + return True + +def f(x: bool, y: bool) -> int: + if x: + b = c(1) + elif y: + b = c(2) + else: + b = c(3) + if b: + return 1 + else: + return 2 +[out] +def c(x): + x :: int +L0: + return 1 +def f(x, y): + x, y, r0, r1, r2 :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + r0 = c(2) + if r0 goto L6 else goto L7 :: bool +L2: + if y goto L3 else goto L4 :: bool +L3: + r1 = c(4) + if r1 goto L6 else goto L7 :: bool +L4: + r2 = c(6) + if r2 goto L6 else goto L7 :: bool +L5: + unreachable +L6: + return 2 +L7: + return 4 + +[case testFlagEliminationAssignmentNotLastOp] +def f(x: bool) -> int: + y = 0 + if x: + b = True + y = 1 + else: + b = False + if b: + return 1 + else: + return 2 +[out] +def f(x): + x :: bool + y :: int + b :: bool +L0: + y = 0 + if x goto L1 else goto L2 :: bool +L1: + b = 1 + y = 2 + goto L3 +L2: + b = 0 +L3: + if b goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testFlagEliminationAssignmentNoDirectGoto] +def f(x: bool) -> int: + if x: + b = True + else: + b = False + if x: + if b: + return 1 + else: + return 2 + return 4 +[out] +def f(x): + x, b :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + b = 1 + goto L3 +L2: + b = 0 +L3: + if x goto L4 else goto L7 :: bool +L4: + if b goto L5 else goto L6 :: bool +L5: + return 2 +L6: + return 4 +L7: + return 8 + +[case testFlagEliminationBranchNotNextOpAfterGoto] +def f(x: bool) -> int: + if x: + b = True + else: + b = False + y = 1 # Prevents the optimization + if b: + return 1 + else: + return 2 +[out] +def f(x): + x, b :: bool + y :: int +L0: + if x goto L1 else goto L2 :: bool +L1: + b = 1 + goto L3 +L2: + b = 0 +L3: + y = 2 + if b goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testFlagEliminationFlagReadTwice] +def f(x: bool) -> bool: + if x: + b = True + else: + b = False + if b: + return b # Prevents the optimization + else: + return False +[out] +def f(x): + x, b :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + b = 1 + goto L3 +L2: + b = 0 +L3: + if b goto L4 else goto L5 :: bool +L4: + return b +L5: + return 0 + +[case testFlagEliminationArgumentNotEligible] +def f(x: bool, b: bool) -> bool: + if x: + b = True + else: + b = False + if b: + return True + else: + return False +[out] +def f(x, b): + x, b :: bool +L0: + if x goto L1 else goto L2 :: bool +L1: + b = 1 + goto L3 +L2: + b = 0 +L3: + if b goto L4 else goto L5 :: bool +L4: + return 1 +L5: + return 0 + +[case testFlagEliminationFlagNotAlwaysDefined] +def f(x: bool, y: bool) -> bool: + if x: + b = True + elif y: + b = False + else: + bb = False # b not assigned here -> can't optimize + if b: + return True + else: + return False +[out] +def f(x, y): + x, y, r0, b, bb, r1 :: bool +L0: + r0 = :: bool + b = r0 + if x goto L1 else goto L2 :: bool +L1: + b = 1 + goto L5 +L2: + if y goto L3 else goto L4 :: bool +L3: + b = 0 + goto L5 +L4: + bb = 0 +L5: + if is_error(b) goto L6 else goto L7 +L6: + r1 = raise UnboundLocalError('local variable "b" referenced before assignment') + unreachable +L7: + if b goto L8 else goto L9 :: bool +L8: + return 1 +L9: + return 0 diff --git a/mypyc/test/test_copy_propagation.py b/mypyc/test/test_optimizations.py similarity index 62% rename from mypyc/test/test_copy_propagation.py rename to mypyc/test/test_optimizations.py index c729e3d186c3..3f1f46ac1dd7 100644 --- a/mypyc/test/test_copy_propagation.py +++ b/mypyc/test/test_optimizations.py @@ -1,4 +1,4 @@ -"""Runner for copy propagation optimization tests.""" +"""Runner for IR optimization tests.""" from __future__ import annotations @@ -8,6 +8,7 @@ from mypy.test.config import test_temp_dir from mypy.test.data import DataDrivenTestCase from mypyc.common import TOP_LEVEL_NAME +from mypyc.ir.func_ir import FuncIR from mypyc.ir.pprint import format_func from mypyc.options import CompilerOptions from mypyc.test.testutil import ( @@ -19,13 +20,16 @@ use_custom_builtins, ) from mypyc.transform.copy_propagation import do_copy_propagation +from mypyc.transform.flag_elimination import do_flag_elimination from mypyc.transform.uninit import insert_uninit_checks -files = ["opt-copy-propagation.test"] +class OptimizationSuite(MypycDataSuite): + """Base class for IR optimization test suites. + + To use this, add a base class and define "files" and "do_optimizations". + """ -class TestCopyPropagation(MypycDataSuite): - files = files base_path = test_temp_dir def run_case(self, testcase: DataDrivenTestCase) -> None: @@ -41,7 +45,24 @@ def run_case(self, testcase: DataDrivenTestCase) -> None: if fn.name == TOP_LEVEL_NAME and not testcase.name.endswith("_toplevel"): continue insert_uninit_checks(fn) - do_copy_propagation(fn, CompilerOptions()) + self.do_optimizations(fn) actual.extend(format_func(fn)) assert_test_output(testcase, actual, "Invalid source code output", expected_output) + + def do_optimizations(self, fn: FuncIR) -> None: + raise NotImplementedError + + +class TestCopyPropagation(OptimizationSuite): + files = ["opt-copy-propagation.test"] + + def do_optimizations(self, fn: FuncIR) -> None: + do_copy_propagation(fn, CompilerOptions()) + + +class TestFlagElimination(OptimizationSuite): + files = ["opt-flag-elimination.test"] + + def do_optimizations(self, fn: FuncIR) -> None: + do_flag_elimination(fn, CompilerOptions()) diff --git a/mypyc/transform/flag_elimination.py b/mypyc/transform/flag_elimination.py new file mode 100644 index 000000000000..605e5bc46ae4 --- /dev/null +++ b/mypyc/transform/flag_elimination.py @@ -0,0 +1,108 @@ +"""Bool register elimination optimization. + +Example input: + + L1: + r0 = f() + b = r0 + goto L3 + L2: + r1 = g() + b = r1 + goto L3 + L3: + if b goto L4 else goto L5 + +The register b is redundant and we replace the assignments with two copies of +the branch in L3: + + L1: + r0 = f() + if r0 goto L4 else goto L5 + L2: + r1 = g() + if r1 goto L4 else goto L5 + +This helps generate simpler IR for tagged integers comparisons, for example. +""" + +from __future__ import annotations + +from mypyc.ir.func_ir import FuncIR +from mypyc.ir.ops import Assign, BasicBlock, Branch, Goto, Register, Unreachable +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.options import CompilerOptions +from mypyc.transform.ir_transform import IRTransform + + +def do_flag_elimination(fn: FuncIR, options: CompilerOptions) -> None: + # Find registers that are used exactly once as source, and in a branch. + counts: dict[Register, int] = {} + branches: dict[Register, Branch] = {} + labels: dict[Register, BasicBlock] = {} + for block in fn.blocks: + for i, op in enumerate(block.ops): + for src in op.sources(): + if isinstance(src, Register): + counts[src] = counts.get(src, 0) + 1 + if i == 0 and isinstance(op, Branch) and isinstance(op.value, Register): + branches[op.value] = op + labels[op.value] = block + + # Based on these we can find the candidate registers. + candidates: set[Register] = { + r for r in branches if counts.get(r, 0) == 1 and r not in fn.arg_regs + } + + # Remove candidates with invalid assignments. + for block in fn.blocks: + for i, op in enumerate(block.ops): + if isinstance(op, Assign) and op.dest in candidates: + next_op = block.ops[i + 1] + if not (isinstance(next_op, Goto) and next_op.label is labels[op.dest]): + # Not right + candidates.remove(op.dest) + + builder = LowLevelIRBuilder(None, options) + transform = FlagEliminationTransform( + builder, {x: y for x, y in branches.items() if x in candidates} + ) + transform.transform_blocks(fn.blocks) + fn.blocks = builder.blocks + + +class FlagEliminationTransform(IRTransform): + def __init__(self, builder: LowLevelIRBuilder, branch_map: dict[Register, Branch]) -> None: + super().__init__(builder) + self.branch_map = branch_map + self.branches = set(branch_map.values()) + + def visit_assign(self, op: Assign) -> None: + old_branch = self.branch_map.get(op.dest) + if old_branch: + # Replace assignment with a copy of the old branch, which is in a + # separate basic block. The old branch will be deletecd in visit_branch. + new_branch = Branch( + op.src, + old_branch.true, + old_branch.false, + old_branch.op, + old_branch.line, + rare=old_branch.rare, + ) + new_branch.negated = old_branch.negated + new_branch.traceback_entry = old_branch.traceback_entry + self.add(new_branch) + else: + self.add(op) + + def visit_goto(self, op: Goto) -> None: + # This is a no-op if basic block already terminated + self.builder.goto(op.label) + + def visit_branch(self, op: Branch) -> None: + if op in self.branches: + # This branch is optimized away + self.add(Unreachable()) + else: + self.add(op) diff --git a/mypyc/transform/ir_transform.py b/mypyc/transform/ir_transform.py index 1bcfc8fb5feb..254fe3f7771d 100644 --- a/mypyc/transform/ir_transform.py +++ b/mypyc/transform/ir_transform.py @@ -101,17 +101,17 @@ def transform_blocks(self, blocks: list[BasicBlock]) -> None: def add(self, op: Op) -> Value: return self.builder.add(op) - def visit_goto(self, op: Goto) -> Value: - return self.add(op) + def visit_goto(self, op: Goto) -> None: + self.add(op) - def visit_branch(self, op: Branch) -> Value: - return self.add(op) + def visit_branch(self, op: Branch) -> None: + self.add(op) - def visit_return(self, op: Return) -> Value: - return self.add(op) + def visit_return(self, op: Return) -> None: + self.add(op) - def visit_unreachable(self, op: Unreachable) -> Value: - return self.add(op) + def visit_unreachable(self, op: Unreachable) -> None: + self.add(op) def visit_assign(self, op: Assign) -> Value | None: return self.add(op) From 1741c16b73bac748e17e6515f65e08afa7b250c3 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 15 Mar 2024 15:05:34 +0000 Subject: [PATCH 122/172] Use lower-case generics more consistently in error messages (#17035) Suggest `list[x]` instead of `List[x]` on Python 3.9 and later in hints. We already suggest `x | None` instead of `Optional[x]` on 3.10+, so this makes the error messages more consistent. Use lower-case `type[x]` when using `reveal_type` on Python 3.9 and later. --- mypy/messages.py | 2 ++ mypy/types.py | 6 +++++- test-data/unit/check-lowercase.test | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/mypy/messages.py b/mypy/messages.py index 92b57ef781a2..199b7c42b11b 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -1779,6 +1779,8 @@ def need_annotation_for_var( alias = alias.split(".")[-1] if alias == "Dict": type_dec = f"{type_dec}, {type_dec}" + if self.options.use_lowercase_names(): + alias = alias.lower() recommended_type = f"{alias}[{type_dec}]" if recommended_type is not None: hint = f' (hint: "{node.name}: {recommended_type} = ...")' diff --git a/mypy/types.py b/mypy/types.py index d3c4df8b3b09..b4209e9debf4 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -3405,7 +3405,11 @@ def visit_ellipsis_type(self, t: EllipsisType) -> str: return "..." def visit_type_type(self, t: TypeType) -> str: - return f"Type[{t.item.accept(self)}]" + if self.options.use_lowercase_names(): + type_name = "type" + else: + type_name = "Type" + return f"{type_name}[{t.item.accept(self)}]" def visit_placeholder_type(self, t: PlaceholderType) -> str: return f"" diff --git a/test-data/unit/check-lowercase.test b/test-data/unit/check-lowercase.test index d1ebbdd282fa..ab6d68929f8e 100644 --- a/test-data/unit/check-lowercase.test +++ b/test-data/unit/check-lowercase.test @@ -49,3 +49,17 @@ x: type[type] y: int y = x # E: Incompatible types in assignment (expression has type "type[type]", variable has type "int") + +[case testLowercaseSettingOnTypeAnnotationHint] +# flags: --python-version 3.9 --no-force-uppercase-builtins +x = [] # E: Need type annotation for "x" (hint: "x: list[] = ...") +y = {} # E: Need type annotation for "y" (hint: "y: dict[, ] = ...") +z = set() # E: Need type annotation for "z" (hint: "z: set[] = ...") +[builtins fixtures/primitives.pyi] + +[case testLowercaseSettingOnRevealTypeType] +# flags: --python-version 3.9 --no-force-uppercase-builtins +def f(t: type[int]) -> None: + reveal_type(t) # N: Revealed type is "type[builtins.int]" +reveal_type(f) # N: Revealed type is "def (t: type[builtins.int])" +[builtins fixtures/primitives.pyi] From 31dc50371aaa267f258f74275b4bc07f27d70001 Mon Sep 17 00:00:00 2001 From: Hashem Date: Fri, 15 Mar 2024 11:29:48 -0400 Subject: [PATCH 123/172] attrs: Fix emulating hash method logic (#17016) This commit fixes a couple regressions in 1.9.0 from 91be285. Attrs' logic for hashability is slightly complex: * https://www.attrs.org/en/stable/hashing.html * https://github.com/python-attrs/attrs/blob/9e443b18527dc96b194e92805fa751cbf8434ba9/src/attr/_make.py#L1660-L1689 Mypy now properly emulates attrs' logic so that custom `__hash__` implementations are preserved, `@frozen` subclasses are always hashable, and classes are only made unhashable based on the values of `eq` and `unsafe_hash`. Fixes #17015 Fixes https://github.com/python/mypy/pull/16556#issuecomment-1987116488 Based on a patch in #17012 Co-Authored-By: Tin Tvrtkovic Co-authored-by: Hashem Nasarat --- mypy/plugins/attrs.py | 22 ++++- test-data/unit/check-incremental.test | 2 +- test-data/unit/check-plugin-attrs.test | 113 +++++++++++++++++++++-- test-data/unit/fixtures/plugin_attrs.pyi | 2 + 4 files changed, 125 insertions(+), 14 deletions(-) diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index 345ea822ed94..83f685f57a16 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -325,9 +325,6 @@ 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) @@ -371,7 +368,24 @@ def attr_class_maker_callback( _add_order(ctx, adder) if frozen: _make_frozen(ctx, attributes) - elif not hashable: + # Frozen classes are hashable by default, even if inheriting from non-frozen ones. + hashable: bool | None = _get_decorator_bool_argument( + ctx, "hash", True + ) and _get_decorator_bool_argument(ctx, "unsafe_hash", True) + else: + hashable = _get_decorator_optional_bool_argument(ctx, "unsafe_hash") + if hashable is None: # unspecified + hashable = _get_decorator_optional_bool_argument(ctx, "hash") + + eq = _get_decorator_optional_bool_argument(ctx, "eq") + has_own_hash = "__hash__" in ctx.cls.info.names + + if has_own_hash or (hashable is None and eq is False): + pass # Do nothing. + elif hashable: + # We copy the `__hash__` signature from `object` to make them hashable. + ctx.cls.info.names["__hash__"] = ctx.cls.info.mro[-1].names["__hash__"] + else: _remove_hashability(ctx) return True diff --git a/test-data/unit/check-incremental.test b/test-data/unit/check-incremental.test index 42faa8c627ba..a7f4fafc579e 100644 --- a/test-data/unit/check-incremental.test +++ b/test-data/unit/check-incremental.test @@ -3015,7 +3015,7 @@ class NoInit: class NoCmp: x: int -[builtins fixtures/list.pyi] +[builtins fixtures/plugin_attrs.pyi] [rechecked] [stale] [out1] diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index 0f379724553a..39b266dba50e 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -360,7 +360,8 @@ class A: a = A(5) a.a = 16 # E: Property "a" defined in "A" is read-only -[builtins fixtures/bool.pyi] +[builtins fixtures/plugin_attrs.pyi] + [case testAttrsNextGenFrozen] from attr import frozen, field @@ -370,7 +371,7 @@ class A: a = A(5) a.a = 16 # E: Property "a" defined in "A" is read-only -[builtins fixtures/bool.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testAttrsNextGenDetect] from attr import define, field @@ -420,7 +421,7 @@ reveal_type(A) # N: Revealed type is "def (a: builtins.int, b: builtins.bool) - reveal_type(B) # N: Revealed type is "def (a: builtins.bool, b: builtins.int) -> __main__.B" reveal_type(C) # N: Revealed type is "def (a: builtins.int) -> __main__.C" -[builtins fixtures/bool.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testAttrsDataClass] import attr @@ -1155,7 +1156,7 @@ c = NonFrozenFrozen(1, 2) c.a = 17 # E: Property "a" defined in "NonFrozenFrozen" is read-only c.b = 17 # E: Property "b" defined in "NonFrozenFrozen" is read-only -[builtins fixtures/bool.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testAttrsCallableAttributes] from typing import Callable import attr @@ -1178,7 +1179,7 @@ class G: class FFrozen(F): def bar(self) -> bool: return self._cb(5, 6) -[builtins fixtures/callable.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testAttrsWithFactory] from typing import List @@ -1450,7 +1451,7 @@ class C: total = attr.ib(type=Bad) # E: Name "Bad" is not defined C(0).total = 1 # E: Property "total" defined in "C" is read-only -[builtins fixtures/bool.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testTypeInAttrDeferredStar] import lib @@ -1941,7 +1942,7 @@ class C: default=None, converter=default_if_none(factory=dict) \ # E: Unsupported converter, only named functions, types and lambdas are currently supported ) -[builtins fixtures/dict.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testAttrsUnannotatedConverter] import attr @@ -2012,7 +2013,7 @@ class Sub(Base): @property def name(self) -> str: ... -[builtins fixtures/property.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testOverrideWithPropertyInFrozenClassChecked] from attrs import frozen @@ -2035,7 +2036,7 @@ class Sub(Base): # This matches runtime semantics reveal_type(Sub) # N: Revealed type is "def (*, name: builtins.str, first_name: builtins.str, last_name: builtins.str) -> __main__.Sub" -[builtins fixtures/property.pyi] +[builtins fixtures/plugin_attrs.pyi] [case testFinalInstanceAttribute] from attrs import define @@ -2380,3 +2381,97 @@ class B(A): reveal_type(B.__hash__) # N: Revealed type is "None" [builtins fixtures/plugin_attrs.pyi] + +[case testManualOwnHashability] +from attrs import define, frozen + +@define +class A: + a: int + def __hash__(self) -> int: + ... + +reveal_type(A.__hash__) # N: Revealed type is "def (self: __main__.A) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testSubclassDefaultLosesHashability] +from attrs import define, frozen + +@define +class A: + a: int + def __hash__(self) -> int: + ... + +@define +class B(A): + pass + +reveal_type(B.__hash__) # N: Revealed type is "None" + +[builtins fixtures/plugin_attrs.pyi] + +[case testSubclassEqFalseKeepsHashability] +from attrs import define, frozen + +@define +class A: + a: int + def __hash__(self) -> int: + ... + +@define(eq=False) +class B(A): + pass + +reveal_type(B.__hash__) # N: Revealed type is "def (self: __main__.A) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testSubclassingFrozenHashability] +from attrs import define, frozen + +@define +class A: + a: int + +@frozen +class B(A): + pass + +reveal_type(B.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" + +[builtins fixtures/plugin_attrs.pyi] + +[case testSubclassingFrozenHashOffHashability] +from attrs import define, frozen + +@define +class A: + a: int + def __hash__(self) -> int: + ... + +@frozen(unsafe_hash=False) +class B(A): + pass + +reveal_type(B.__hash__) # N: Revealed type is "None" + +[builtins fixtures/plugin_attrs.pyi] + +[case testUnsafeHashPrecedence] +from attrs import define, frozen + +@define(unsafe_hash=True, hash=False) +class A: + pass +reveal_type(A.__hash__) # N: Revealed type is "def (self: builtins.object) -> builtins.int" + +@define(unsafe_hash=False, hash=True) +class B: + 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 5b87c47b5bc8..7fd641727253 100644 --- a/test-data/unit/fixtures/plugin_attrs.pyi +++ b/test-data/unit/fixtures/plugin_attrs.pyi @@ -35,3 +35,5 @@ class tuple(Sequence[Tco], Generic[Tco]): def __iter__(self) -> Iterator[Tco]: pass def __contains__(self, item: object) -> bool: pass def __getitem__(self, x: int) -> Tco: pass + +property = object() # Dummy definition From c591c891f7c5c35c3546ae6b4709ee97ef9e1136 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Sat, 16 Mar 2024 12:54:54 +0000 Subject: [PATCH 124/172] [mypyc] Implement lowering pass and add primitives for int (in)equality (#17027) Add a new `PrimitiveOp` op which can be transformed into lower-level ops in a lowering pass after reference counting op insertion pass. Higher-level ops in IR make it easier to implement various optimizations, and the output of irbuild test cases will be more compact and readable. Implement the lowering pass. Currently it's pretty minimal, and I will add additional primitives and the direct transformation of various primitives to `CallC` ops in follow-up PRs. Currently primitives that map to C calls generate `CallC` ops in the main irbuild pass, but the long-term goal is to only/mostly generate `PrimitiveOp`s instead of `CallC` ops during the main irbuild pass. Also implement primitives for tagged integer equality and inequality as examples. Lowering of primitives is implemented using decorated handler functions in `mypyc.lower` that are found based on the name of the primitive. The name has no other significance, though it's also used in pretty-printed IR output. Work on mypyc/mypyc#854. The issue describes the motivation in more detail. --- mypyc/analysis/dataflow.py | 4 + mypyc/analysis/ircheck.py | 4 + mypyc/analysis/selfleaks.py | 4 + mypyc/codegen/emitfunc.py | 6 + mypyc/codegen/emitmodule.py | 10 +- mypyc/ir/ops.py | 79 ++++++++- mypyc/ir/pprint.py | 17 ++ mypyc/irbuild/ast_helpers.py | 7 +- mypyc/irbuild/expression.py | 4 +- mypyc/irbuild/ll_builder.py | 126 +++++++++++-- mypyc/lower/__init__.py | 0 mypyc/lower/int_ops.py | 15 ++ mypyc/lower/registry.py | 26 +++ mypyc/primitives/int_ops.py | 25 ++- mypyc/primitives/registry.py | 40 +++-- mypyc/test-data/analysis.test | 70 +++----- mypyc/test-data/irbuild-basic.test | 206 +++++++--------------- mypyc/test-data/irbuild-bool.test | 6 +- mypyc/test-data/irbuild-classes.test | 2 +- mypyc/test-data/irbuild-int.test | 28 +-- mypyc/test-data/irbuild-match.test | 45 +++-- mypyc/test-data/irbuild-nested.test | 4 +- mypyc/test-data/irbuild-optional.test | 2 +- mypyc/test-data/irbuild-tuple.test | 87 ++------- mypyc/test-data/lowering-int.test | 126 +++++++++++++ mypyc/test-data/opt-flag-elimination.test | 18 +- mypyc/test-data/refcount.test | 172 ++++++------------ mypyc/test/test_cheader.py | 16 +- mypyc/test/test_emitfunc.py | 2 + mypyc/test/test_lowering.py | 54 ++++++ mypyc/transform/ir_transform.py | 17 +- mypyc/transform/lower.py | 33 ++++ 32 files changed, 772 insertions(+), 483 deletions(-) create mode 100644 mypyc/lower/__init__.py create mode 100644 mypyc/lower/int_ops.py create mode 100644 mypyc/lower/registry.py create mode 100644 mypyc/test-data/lowering-int.test create mode 100644 mypyc/test/test_lowering.py create mode 100644 mypyc/transform/lower.py diff --git a/mypyc/analysis/dataflow.py b/mypyc/analysis/dataflow.py index 57ad2b17fcc5..9babf860fb31 100644 --- a/mypyc/analysis/dataflow.py +++ b/mypyc/analysis/dataflow.py @@ -38,6 +38,7 @@ MethodCall, Op, OpVisitor, + PrimitiveOp, RaiseStandardError, RegisterOp, Return, @@ -234,6 +235,9 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> GenAndKill[T]: def visit_call_c(self, op: CallC) -> GenAndKill[T]: return self.visit_register_op(op) + def visit_primitive_op(self, op: PrimitiveOp) -> GenAndKill[T]: + return self.visit_register_op(op) + def visit_truncate(self, op: Truncate) -> GenAndKill[T]: return self.visit_register_op(op) diff --git a/mypyc/analysis/ircheck.py b/mypyc/analysis/ircheck.py index 127047e02ff5..88737ac208de 100644 --- a/mypyc/analysis/ircheck.py +++ b/mypyc/analysis/ircheck.py @@ -37,6 +37,7 @@ MethodCall, Op, OpVisitor, + PrimitiveOp, RaiseStandardError, Register, Return, @@ -381,6 +382,9 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> None: def visit_call_c(self, op: CallC) -> None: pass + def visit_primitive_op(self, op: PrimitiveOp) -> None: + pass + def visit_truncate(self, op: Truncate) -> None: pass diff --git a/mypyc/analysis/selfleaks.py b/mypyc/analysis/selfleaks.py index 80c2bc348bc2..5d89a9bfc7c6 100644 --- a/mypyc/analysis/selfleaks.py +++ b/mypyc/analysis/selfleaks.py @@ -31,6 +31,7 @@ LoadStatic, MethodCall, OpVisitor, + PrimitiveOp, RaiseStandardError, Register, RegisterOp, @@ -149,6 +150,9 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> GenAndKill: def visit_call_c(self, op: CallC) -> GenAndKill: return self.check_register_op(op) + def visit_primitive_op(self, op: PrimitiveOp) -> GenAndKill: + return self.check_register_op(op) + def visit_truncate(self, op: Truncate) -> GenAndKill: return CLEAN diff --git a/mypyc/codegen/emitfunc.py b/mypyc/codegen/emitfunc.py index c08f1f840fa4..12f57b9cee6f 100644 --- a/mypyc/codegen/emitfunc.py +++ b/mypyc/codegen/emitfunc.py @@ -47,6 +47,7 @@ MethodCall, Op, OpVisitor, + PrimitiveOp, RaiseStandardError, Register, Return, @@ -629,6 +630,11 @@ def visit_call_c(self, op: CallC) -> None: args = ", ".join(self.reg(arg) for arg in op.args) self.emitter.emit_line(f"{dest}{op.function_name}({args});") + def visit_primitive_op(self, op: PrimitiveOp) -> None: + raise RuntimeError( + f"unexpected PrimitiveOp {op.desc.name}: they must be lowered before codegen" + ) + def visit_truncate(self, op: Truncate) -> None: dest = self.reg(op) value = self.reg(op.src) diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index 9466bc2cea79..6c8f5ac91335 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -59,6 +59,7 @@ from mypyc.transform.copy_propagation import do_copy_propagation from mypyc.transform.exceptions import insert_exception_handling from mypyc.transform.flag_elimination import do_flag_elimination +from mypyc.transform.lower import lower_ir from mypyc.transform.refcount import insert_ref_count_opcodes from mypyc.transform.uninit import insert_uninit_checks @@ -235,6 +236,8 @@ def compile_scc_to_ir( insert_exception_handling(fn) # Insert refcount handling. insert_ref_count_opcodes(fn) + # Switch to lower abstraction level IR. + lower_ir(fn, compiler_options) # Perform optimizations. do_copy_propagation(fn, compiler_options) do_flag_elimination(fn, compiler_options) @@ -423,10 +426,11 @@ def compile_modules_to_c( ) modules = compile_modules_to_ir(result, mapper, compiler_options, errors) - ctext = compile_ir_to_c(groups, modules, result, mapper, compiler_options) + if errors.num_errors > 0: + return {}, [] - if errors.num_errors == 0: - write_cache(modules, result, group_map, ctext) + ctext = compile_ir_to_c(groups, modules, result, mapper, compiler_options) + write_cache(modules, result, group_map, ctext) return modules, [ctext[name] for _, name in groups] diff --git a/mypyc/ir/ops.py b/mypyc/ir/ops.py index 04c50d1e2841..3acfb0933e5a 100644 --- a/mypyc/ir/ops.py +++ b/mypyc/ir/ops.py @@ -576,6 +576,78 @@ def accept(self, visitor: OpVisitor[T]) -> T: return visitor.visit_method_call(self) +class PrimitiveDescription: + """Description of a primitive op. + + Primitives get lowered into lower-level ops before code generation. + + If c_function_name is provided, a primitive will be lowered into a CallC op. + Otherwise custom logic will need to be implemented to transform the + primitive into lower-level ops. + """ + + def __init__( + self, + name: str, + arg_types: list[RType], + return_type: RType, # TODO: What about generic? + var_arg_type: RType | None, + truncated_type: RType | None, + c_function_name: str | None, + error_kind: int, + steals: StealsDescription, + is_borrowed: bool, + ordering: list[int] | None, + extra_int_constants: list[tuple[int, RType]], + priority: int, + ) -> None: + # Each primitive much have a distinct name, but otherwise they are arbitrary. + self.name: Final = name + self.arg_types: Final = arg_types + self.return_type: Final = return_type + self.var_arg_type: Final = var_arg_type + self.truncated_type: Final = truncated_type + # If non-None, this will map to a call of a C helper function; if None, + # there must be a custom handler function that gets invoked during the lowering + # pass to generate low-level IR for the primitive (in the mypyc.lower package) + self.c_function_name: Final = c_function_name + self.error_kind: Final = error_kind + self.steals: Final = steals + self.is_borrowed: Final = is_borrowed + self.ordering: Final = ordering + self.extra_int_constants: Final = extra_int_constants + self.priority: Final = priority + + def __repr__(self) -> str: + return f"" + + +class PrimitiveOp(RegisterOp): + """A higher-level primitive operation. + + Some of these have special compiler support. These will be lowered + (transformed) into lower-level IR ops before code generation, and after + reference counting op insertion. Others will be transformed into CallC + ops. + + Tagged integer equality is a typical primitive op with non-trivial + lowering. It gets transformed into a tag check, followed by different + code paths for short and long representations. + """ + + def __init__(self, args: list[Value], desc: PrimitiveDescription, line: int = -1) -> None: + self.args = args + self.type = desc.return_type + self.error_kind = desc.error_kind + self.desc = desc + + def sources(self) -> list[Value]: + return self.args + + def accept(self, visitor: OpVisitor[T]) -> T: + return visitor.visit_primitive_op(self) + + class LoadErrorValue(RegisterOp): """Load an error value. @@ -1446,7 +1518,8 @@ class Unborrow(RegisterOp): error_kind = ERR_NEVER - def __init__(self, src: Value) -> None: + def __init__(self, src: Value, line: int = -1) -> None: + super().__init__(line) assert src.is_borrowed self.src = src self.type = src.type @@ -1555,6 +1628,10 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> T: def visit_call_c(self, op: CallC) -> T: raise NotImplementedError + @abstractmethod + def visit_primitive_op(self, op: PrimitiveOp) -> T: + raise NotImplementedError + @abstractmethod def visit_truncate(self, op: Truncate) -> T: raise NotImplementedError diff --git a/mypyc/ir/pprint.py b/mypyc/ir/pprint.py index 5578049256f1..8d6723917ea0 100644 --- a/mypyc/ir/pprint.py +++ b/mypyc/ir/pprint.py @@ -43,6 +43,7 @@ MethodCall, Op, OpVisitor, + PrimitiveOp, RaiseStandardError, Register, Return, @@ -217,6 +218,22 @@ def visit_call_c(self, op: CallC) -> str: else: return self.format("%r = %s(%s)", op, op.function_name, args_str) + def visit_primitive_op(self, op: PrimitiveOp) -> str: + args = [] + arg_index = 0 + type_arg_index = 0 + for arg_type in zip(op.desc.arg_types): + if arg_type: + args.append(self.format("%r", op.args[arg_index])) + arg_index += 1 + else: + assert op.type_args + args.append(self.format("%r", op.type_args[type_arg_index])) + type_arg_index += 1 + + args_str = ", ".join(args) + return self.format("%r = %s %s ", op, op.desc.name, args_str) + def visit_truncate(self, op: Truncate) -> str: return self.format("%r = truncate %r: %t to %t", op, op.src, op.src_type, op.type) diff --git a/mypyc/irbuild/ast_helpers.py b/mypyc/irbuild/ast_helpers.py index 1af1ad611a89..8490eaa03477 100644 --- a/mypyc/irbuild/ast_helpers.py +++ b/mypyc/irbuild/ast_helpers.py @@ -93,7 +93,12 @@ def maybe_process_conditional_comparison( self.add_bool_branch(reg, true, false) else: # "left op right" for two tagged integers - self.builder.compare_tagged_condition(left, right, op, true, false, e.line) + if op in ("==", "!="): + reg = self.builder.binary_op(left, right, op, e.line) + self.flush_keep_alives() + self.add_bool_branch(reg, true, false) + else: + self.builder.compare_tagged_condition(left, right, op, true, false, e.line) return True diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 81e37953809f..021b7a1dbe90 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -756,7 +756,7 @@ def transform_comparison_expr(builder: IRBuilder, e: ComparisonExpr) -> Value: set_literal = precompute_set_literal(builder, e.operands[1]) if set_literal is not None: lhs = e.operands[0] - result = builder.builder.call_c( + result = builder.builder.primitive_op( set_in_op, [builder.accept(lhs), set_literal], e.line, bool_rprimitive ) if first_op == "not in": @@ -778,7 +778,7 @@ def transform_comparison_expr(builder: IRBuilder, e: ComparisonExpr) -> Value: borrow_left = is_borrow_friendly_expr(builder, right_expr) left = builder.accept(left_expr, can_borrow=borrow_left) right = builder.accept(right_expr, can_borrow=True) - return builder.compare_tagged(left, right, first_op, e.line) + return builder.binary_op(left, right, first_op, e.line) # TODO: Don't produce an expression when used in conditional context # All of the trickiness here is due to support for chained conditionals diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index 45c06e11befd..f9bacb43bc3e 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -63,6 +63,8 @@ LoadStatic, MethodCall, Op, + PrimitiveDescription, + PrimitiveOp, RaiseStandardError, Register, SetMem, @@ -1313,7 +1315,12 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: return self.compare_strings(lreg, rreg, op, line) if is_bytes_rprimitive(ltype) and is_bytes_rprimitive(rtype) and op in ("==", "!="): return self.compare_bytes(lreg, rreg, op, line) - if is_tagged(ltype) and is_tagged(rtype) and op in int_comparison_op_mapping: + if ( + is_tagged(ltype) + and is_tagged(rtype) + and op in int_comparison_op_mapping + and op not in ("==", "!=") + ): return self.compare_tagged(lreg, rreg, op, line) if is_bool_rprimitive(ltype) and is_bool_rprimitive(rtype) and op in BOOL_BINARY_OPS: if op in ComparisonOp.signed_ops: @@ -1379,13 +1386,7 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: # Mixed int comparisons if op in ("==", "!="): - op_id = ComparisonOp.signed_ops[op] - if is_tagged(ltype) and is_subtype(rtype, ltype): - rreg = self.coerce(rreg, int_rprimitive, line) - return self.comparison_op(lreg, rreg, op_id, line) - if is_tagged(rtype) and is_subtype(ltype, rtype): - lreg = self.coerce(lreg, int_rprimitive, line) - return self.comparison_op(lreg, rreg, op_id, line) + pass # TODO: Do we need anything here? elif op in op in int_comparison_op_mapping: if is_tagged(ltype) and is_subtype(rtype, ltype): rreg = self.coerce(rreg, short_int_rprimitive, line) @@ -1412,8 +1413,8 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: if base_op in float_op_to_id: return self.float_op(lreg, rreg, base_op, line) - call_c_ops_candidates = binary_ops.get(op, []) - target = self.matching_call_c(call_c_ops_candidates, [lreg, rreg], line) + primitive_ops_candidates = binary_ops.get(op, []) + target = self.matching_primitive_op(primitive_ops_candidates, [lreg, rreg], line) assert target, "Unsupported binary operation: %s" % op return target @@ -1432,7 +1433,14 @@ def check_tagged_short_int(self, val: Value, line: int, negated: bool = False) - def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: """Compare two tagged integers using given operator (value context).""" # generate fast binary logic ops on short ints - if is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type): + if (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) and op in ( + "==", + "!=", + ): + quick = True + else: + quick = is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type) + if quick: return self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line) op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] result = Register(bool_rprimitive) @@ -1986,6 +1994,102 @@ def matching_call_c( return target return None + def primitive_op( + self, + desc: PrimitiveDescription, + args: list[Value], + line: int, + result_type: RType | None = None, + ) -> Value: + """Add a primitive op.""" + # Does this primitive map into calling a Python C API + # or an internal mypyc C API function? + if desc.c_function_name: + # TODO: Generate PrimitiOps here and transform them into CallC + # ops only later in the lowering pass + c_desc = CFunctionDescription( + desc.name, + desc.arg_types, + desc.return_type, + desc.var_arg_type, + desc.truncated_type, + desc.c_function_name, + desc.error_kind, + desc.steals, + desc.is_borrowed, + desc.ordering, + desc.extra_int_constants, + desc.priority, + ) + return self.call_c(c_desc, args, line, result_type) + + # This primitve gets transformed in a lowering pass to + # lower-level IR ops using a custom transform function. + + coerced = [] + # Coerce fixed number arguments + for i in range(min(len(args), len(desc.arg_types))): + formal_type = desc.arg_types[i] + arg = args[i] + assert formal_type is not None # TODO + arg = self.coerce(arg, formal_type, line) + coerced.append(arg) + assert desc.ordering is None + assert desc.var_arg_type is None + assert not desc.extra_int_constants + target = self.add(PrimitiveOp(coerced, desc, line=line)) + if desc.is_borrowed: + # If the result is borrowed, force the arguments to be + # kept alive afterwards, as otherwise the result might be + # immediately freed, at the risk of a dangling pointer. + for arg in coerced: + if not isinstance(arg, (Integer, LoadLiteral)): + self.keep_alives.append(arg) + if desc.error_kind == ERR_NEG_INT: + comp = ComparisonOp(target, Integer(0, desc.return_type, line), ComparisonOp.SGE, line) + comp.error_kind = ERR_FALSE + self.add(comp) + + assert desc.truncated_type is None + result = target + if result_type and not is_runtime_subtype(result.type, result_type): + if is_none_rprimitive(result_type): + # Special case None return. The actual result may actually be a bool + # and so we can't just coerce it. + result = self.none() + else: + result = self.coerce(result, result_type, line, can_borrow=desc.is_borrowed) + return result + + def matching_primitive_op( + self, + candidates: list[PrimitiveDescription], + args: list[Value], + line: int, + result_type: RType | None = None, + can_borrow: bool = False, + ) -> Value | None: + matching: PrimitiveDescription | None = None + for desc in candidates: + if len(desc.arg_types) != len(args): + continue + if all( + # formal is not None and # TODO + is_subtype(actual.type, formal) + for actual, formal in zip(args, desc.arg_types) + ) and (not desc.is_borrowed or can_borrow): + if matching: + assert matching.priority != desc.priority, "Ambiguous:\n1) {}\n2) {}".format( + matching, desc + ) + if desc.priority > matching.priority: + matching = desc + else: + matching = desc + if matching: + return self.primitive_op(matching, args, line=line) + return None + def int_op(self, type: RType, lhs: Value, rhs: Value, op: int, line: int = -1) -> Value: """Generate a native integer binary op. diff --git a/mypyc/lower/__init__.py b/mypyc/lower/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/mypyc/lower/int_ops.py b/mypyc/lower/int_ops.py new file mode 100644 index 000000000000..40fba7af4f4d --- /dev/null +++ b/mypyc/lower/int_ops.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from mypyc.ir.ops import Value +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.lower.registry import lower_binary_op + + +@lower_binary_op("int_eq") +def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "==", line) + + +@lower_binary_op("int_ne") +def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "!=", line) diff --git a/mypyc/lower/registry.py b/mypyc/lower/registry.py new file mode 100644 index 000000000000..cc53eb93f4dd --- /dev/null +++ b/mypyc/lower/registry.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +from typing import Callable, Final, List + +from mypyc.ir.ops import Value +from mypyc.irbuild.ll_builder import LowLevelIRBuilder + +LowerFunc = Callable[[LowLevelIRBuilder, List[Value], int], Value] + + +lowering_registry: Final[dict[str, LowerFunc]] = {} + + +def lower_binary_op(name: str) -> Callable[[LowerFunc], LowerFunc]: + """Register a handler that generates low-level IR for a primitive binary op.""" + + def wrapper(f: LowerFunc) -> LowerFunc: + assert name not in lowering_registry + lowering_registry[name] = f + return f + + return wrapper + + +# Import various modules that set up global state. +import mypyc.lower.int_ops # noqa: F401 diff --git a/mypyc/primitives/int_ops.py b/mypyc/primitives/int_ops.py index 95f9cc5ff43f..4103fe349a74 100644 --- a/mypyc/primitives/int_ops.py +++ b/mypyc/primitives/int_ops.py @@ -12,7 +12,14 @@ from typing import NamedTuple -from mypyc.ir.ops import ERR_ALWAYS, ERR_MAGIC, ERR_MAGIC_OVERLAPPING, ERR_NEVER, ComparisonOp +from mypyc.ir.ops import ( + ERR_ALWAYS, + ERR_MAGIC, + ERR_MAGIC_OVERLAPPING, + ERR_NEVER, + ComparisonOp, + PrimitiveDescription, +) from mypyc.ir.rtypes import ( RType, bit_rprimitive, @@ -101,6 +108,22 @@ ) +def int_binary_primitive( + op: str, primitive_name: str, return_type: RType = int_rprimitive, error_kind: int = ERR_NEVER +) -> PrimitiveDescription: + return binary_op( + name=op, + arg_types=[int_rprimitive, int_rprimitive], + return_type=return_type, + primitive_name=primitive_name, + error_kind=error_kind, + ) + + +int_eq = int_binary_primitive(op="==", primitive_name="int_eq", return_type=bit_rprimitive) +int_ne = int_binary_primitive(op="!=", primitive_name="int_ne", return_type=bit_rprimitive) + + def int_binary_op( name: str, c_function_name: str, diff --git a/mypyc/primitives/registry.py b/mypyc/primitives/registry.py index 11fca7dc2c70..d4768b4df532 100644 --- a/mypyc/primitives/registry.py +++ b/mypyc/primitives/registry.py @@ -39,7 +39,7 @@ from typing import Final, NamedTuple -from mypyc.ir.ops import StealsDescription +from mypyc.ir.ops import PrimitiveDescription, StealsDescription from mypyc.ir.rtypes import RType # Error kind for functions that return negative integer on exception. This @@ -76,7 +76,7 @@ class LoadAddressDescription(NamedTuple): function_ops: dict[str, list[CFunctionDescription]] = {} # CallC op for binary ops -binary_ops: dict[str, list[CFunctionDescription]] = {} +binary_ops: dict[str, list[PrimitiveDescription]] = {} # CallC op for unary ops unary_ops: dict[str, list[CFunctionDescription]] = {} @@ -192,8 +192,9 @@ def binary_op( name: str, arg_types: list[RType], return_type: RType, - c_function_name: str, error_kind: int, + c_function_name: str | None = None, + primitive_name: str | None = None, var_arg_type: RType | None = None, truncated_type: RType | None = None, ordering: list[int] | None = None, @@ -201,7 +202,7 @@ def binary_op( steals: StealsDescription = False, is_borrowed: bool = False, priority: int = 1, -) -> CFunctionDescription: +) -> PrimitiveDescription: """Define a c function call op for a binary operation. This will be automatically generated by matching against the AST. @@ -209,22 +210,24 @@ def binary_op( Most arguments are similar to method_op(), but exactly two argument types are expected. """ + assert c_function_name is not None or primitive_name is not None + assert not (c_function_name is not None and primitive_name is not None) if extra_int_constants is None: extra_int_constants = [] ops = binary_ops.setdefault(name, []) - desc = CFunctionDescription( - name, - arg_types, - return_type, - var_arg_type, - truncated_type, - c_function_name, - error_kind, - steals, - is_borrowed, - ordering, - extra_int_constants, - priority, + desc = PrimitiveDescription( + name=primitive_name or name, + arg_types=arg_types, + return_type=return_type, + var_arg_type=var_arg_type, + truncated_type=truncated_type, + c_function_name=c_function_name, + error_kind=error_kind, + steals=steals, + is_borrowed=is_borrowed, + ordering=ordering, + extra_int_constants=extra_int_constants, + priority=priority, ) ops.append(desc) return desc @@ -311,11 +314,10 @@ def load_address_op(name: str, type: RType, src: str) -> LoadAddressDescription: return LoadAddressDescription(name, type, src) +# Import various modules that set up global state. import mypyc.primitives.bytes_ops import mypyc.primitives.dict_ops import mypyc.primitives.float_ops - -# Import various modules that set up global state. import mypyc.primitives.int_ops import mypyc.primitives.list_ops import mypyc.primitives.misc_ops diff --git a/mypyc/test-data/analysis.test b/mypyc/test-data/analysis.test index efd219cc222a..8e067aed4d79 100644 --- a/mypyc/test-data/analysis.test +++ b/mypyc/test-data/analysis.test @@ -10,40 +10,27 @@ def f(a: int) -> None: [out] def f(a): a, x :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit y, z :: int L0: x = 2 - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq x, a + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsEq_(x, a) - if r2 goto L3 else goto L4 :: bool -L2: - r3 = x == a - if r3 goto L3 else goto L4 :: bool -L3: y = 2 - goto L5 -L4: + goto L3 +L2: z = 2 -L5: +L3: return 1 (0, 0) {a} {a, x} (0, 1) {a, x} {a, x} (0, 2) {a, x} {a, x} -(0, 3) {a, x} {a, x} -(1, 0) {a, x} {a, x} -(1, 1) {a, x} {a, x} -(2, 0) {a, x} {a, x} -(2, 1) {a, x} {a, x} -(3, 0) {a, x} {a, x, y} -(3, 1) {a, x, y} {a, x, y} -(4, 0) {a, x} {a, x, z} -(4, 1) {a, x, z} {a, x, z} -(5, 0) {a, x, y, z} {a, x, y, z} +(1, 0) {a, x} {a, x, y} +(1, 1) {a, x, y} {a, x, y} +(2, 0) {a, x} {a, x, z} +(2, 1) {a, x, z} {a, x, z} +(3, 0) {a, x, y, z} {a, x, y, z} [case testSimple_Liveness] def f(a: int) -> int: @@ -58,7 +45,7 @@ def f(a): r0 :: bit L0: x = 2 - r0 = x == 2 + r0 = int_eq x, 2 if r0 goto L1 else goto L2 :: bool L1: return a @@ -124,7 +111,7 @@ def f(a): r0 :: bit y, x :: int L0: - r0 = a == 2 + r0 = int_eq a, 2 if r0 goto L1 else goto L2 :: bool L1: y = 2 @@ -421,40 +408,27 @@ def f(a: int) -> int: [out] def f(a): a :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit x :: int L0: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq a, a + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsEq_(a, a) - if r2 goto L3 else goto L4 :: bool -L2: - r3 = a == a - if r3 goto L3 else goto L4 :: bool -L3: x = 4 a = 2 - goto L5 -L4: + goto L3 +L2: x = 2 -L5: +L3: return x (0, 0) {a} {a} (0, 1) {a} {a} -(0, 2) {a} {a} (1, 0) {a} {a} -(1, 1) {a} {a} +(1, 1) {a} {} +(1, 2) {} {} (2, 0) {a} {a} (2, 1) {a} {a} -(3, 0) {a} {a} -(3, 1) {a} {} -(3, 2) {} {} -(4, 0) {a} {a} -(4, 1) {a} {a} -(5, 0) {} {} +(3, 0) {} {} [case testLoop_BorrowedArgument] def f(a: int) -> int: diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index cd952ef2ebfd..981460dae371 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -568,7 +568,7 @@ L3: x = 2 goto L8 L4: - r4 = n == 0 + r4 = int_eq n, 0 if r4 goto L5 else goto L6 :: bool L5: x = 2 @@ -598,7 +598,7 @@ def f(n): r0 :: bit r1 :: int L0: - r0 = n == 0 + r0 = int_eq n, 0 if r0 goto L1 else goto L2 :: bool L1: r1 = 0 @@ -1462,7 +1462,7 @@ L0: r1 = load_mem r0 :: native_int* keep_alive x r2 = r1 << 1 - r3 = r2 != 0 + r3 = int_ne r2, 0 if r3 goto L1 else goto L2 :: bool L1: return 2 @@ -2052,19 +2052,12 @@ def f(): r13 :: bit r14 :: object r15, x :: int - r16 :: native_int - r17, r18 :: bit - r19 :: bool - r20, r21 :: bit - r22 :: native_int - r23, r24 :: bit - r25 :: bool - r26, r27 :: bit - r28 :: int - r29 :: object - r30 :: i32 - r31 :: bit - r32 :: short_int + r16, r17 :: bit + r18 :: int + r19 :: object + r20 :: i32 + r21 :: bit + r22 :: short_int L0: r0 = PyList_New(0) r1 = PyList_New(3) @@ -2086,52 +2079,30 @@ L1: keep_alive r1 r12 = r11 << 1 r13 = r9 < r12 :: signed - if r13 goto L2 else goto L14 :: bool + if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) r15 = unbox(int, r14) x = r15 - r16 = x & 1 - r17 = r16 == 0 - if r17 goto L3 else goto L4 :: bool + r16 = int_ne x, 4 + if r16 goto L4 else goto L3 :: bool L3: - r18 = x != 4 - r19 = r18 - goto L5 + goto L7 L4: - r20 = CPyTagged_IsEq_(x, 4) - r21 = r20 ^ 1 - r19 = r21 + r17 = int_ne x, 6 + if r17 goto L6 else goto L5 :: bool L5: - if r19 goto L7 else goto L6 :: bool + goto L7 L6: - goto L13 + r18 = CPyTagged_Multiply(x, x) + r19 = box(int, r18) + r20 = PyList_Append(r0, r19) + r21 = r20 >= 0 :: signed L7: - r22 = x & 1 - r23 = r22 == 0 - if r23 goto L8 else goto L9 :: bool -L8: - r24 = x != 6 - r25 = r24 - goto L10 -L9: - r26 = CPyTagged_IsEq_(x, 6) - r27 = r26 ^ 1 - r25 = r27 -L10: - if r25 goto L12 else goto L11 :: bool -L11: - goto L13 -L12: - r28 = CPyTagged_Multiply(x, x) - r29 = box(int, r28) - r30 = PyList_Append(r0, r29) - r31 = r30 >= 0 :: signed -L13: - r32 = r9 + 2 - r9 = r32 + r22 = r9 + 2 + r9 = r22 goto L1 -L14: +L8: return r0 [case testDictComprehension] @@ -2151,19 +2122,12 @@ def f(): r13 :: bit r14 :: object r15, x :: int - r16 :: native_int - r17, r18 :: bit - r19 :: bool - r20, r21 :: bit - r22 :: native_int - r23, r24 :: bit - r25 :: bool - r26, r27 :: bit - r28 :: int - r29, r30 :: object - r31 :: i32 - r32 :: bit - r33 :: short_int + r16, r17 :: bit + r18 :: int + r19, r20 :: object + r21 :: i32 + r22 :: bit + r23 :: short_int L0: r0 = PyDict_New() r1 = PyList_New(3) @@ -2185,53 +2149,31 @@ L1: keep_alive r1 r12 = r11 << 1 r13 = r9 < r12 :: signed - if r13 goto L2 else goto L14 :: bool + if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) r15 = unbox(int, r14) x = r15 - r16 = x & 1 - r17 = r16 == 0 - if r17 goto L3 else goto L4 :: bool + r16 = int_ne x, 4 + if r16 goto L4 else goto L3 :: bool L3: - r18 = x != 4 - r19 = r18 - goto L5 + goto L7 L4: - r20 = CPyTagged_IsEq_(x, 4) - r21 = r20 ^ 1 - r19 = r21 + r17 = int_ne x, 6 + if r17 goto L6 else goto L5 :: bool L5: - if r19 goto L7 else goto L6 :: bool + goto L7 L6: - goto L13 + r18 = CPyTagged_Multiply(x, x) + r19 = box(int, x) + r20 = box(int, r18) + r21 = CPyDict_SetItem(r0, r19, r20) + r22 = r21 >= 0 :: signed L7: - r22 = x & 1 - r23 = r22 == 0 - if r23 goto L8 else goto L9 :: bool -L8: - r24 = x != 6 - r25 = r24 - goto L10 -L9: - r26 = CPyTagged_IsEq_(x, 6) - r27 = r26 ^ 1 - r25 = r27 -L10: - if r25 goto L12 else goto L11 :: bool -L11: - goto L13 -L12: - r28 = CPyTagged_Multiply(x, x) - r29 = box(int, x) - r30 = box(int, r28) - r31 = CPyDict_SetItem(r0, r29, r30) - r32 = r31 >= 0 :: signed -L13: - r33 = r9 + 2 - r9 = r33 + r23 = r9 + 2 + r9 = r23 goto L1 -L14: +L8: return r0 [case testLoopsMultipleAssign] @@ -3011,85 +2953,57 @@ def call_any(l): r0 :: bool r1, r2 :: object r3, i :: int - r4 :: native_int - r5, r6 :: bit - r7 :: bool - r8, r9 :: bit + r4, r5 :: bit L0: r0 = 0 r1 = PyObject_GetIter(l) L1: r2 = PyIter_Next(r1) - if is_error(r2) goto L9 else goto L2 + if is_error(r2) goto L6 else goto L2 L2: r3 = unbox(int, r2) i = r3 - r4 = i & 1 - r5 = r4 == 0 - if r5 goto L3 else goto L4 :: bool + r4 = int_eq i, 0 + if r4 goto L3 else goto L4 :: bool L3: - r6 = i == 0 - r7 = r6 - goto L5 + r0 = 1 + goto L8 L4: - r8 = CPyTagged_IsEq_(i, 0) - r7 = r8 L5: - if r7 goto L6 else goto L7 :: bool + goto L1 L6: - r0 = 1 - goto L11 + r5 = CPy_NoErrOccured() L7: L8: - goto L1 -L9: - r9 = CPy_NoErrOccured() -L10: -L11: return r0 def call_all(l): l :: object r0 :: bool r1, r2 :: object r3, i :: int - r4 :: native_int - r5, r6 :: bit - r7 :: bool - r8 :: bit - r9 :: bool - r10 :: bit + r4, r5, r6 :: bit L0: r0 = 1 r1 = PyObject_GetIter(l) L1: r2 = PyIter_Next(r1) - if is_error(r2) goto L9 else goto L2 + if is_error(r2) goto L6 else goto L2 L2: r3 = unbox(int, r2) i = r3 - r4 = i & 1 - r5 = r4 == 0 + r4 = int_eq i, 0 + r5 = r4 ^ 1 if r5 goto L3 else goto L4 :: bool L3: - r6 = i == 0 - r7 = r6 - goto L5 + r0 = 0 + goto L8 L4: - r8 = CPyTagged_IsEq_(i, 0) - r7 = r8 L5: - r9 = r7 ^ 1 - if r9 goto L6 else goto L7 :: bool + goto L1 L6: - r0 = 0 - goto L11 + r6 = CPy_NoErrOccured() L7: L8: - goto L1 -L9: - r10 = CPy_NoErrOccured() -L10: -L11: return r0 [case testSum] diff --git a/mypyc/test-data/irbuild-bool.test b/mypyc/test-data/irbuild-bool.test index 731d393d69ab..f0b0b480bc0d 100644 --- a/mypyc/test-data/irbuild-bool.test +++ b/mypyc/test-data/irbuild-bool.test @@ -96,7 +96,7 @@ L0: r1 = load_mem r0 :: native_int* keep_alive l r2 = r1 << 1 - r3 = r2 != 0 + r3 = int_ne r2, 0 return r3 def always_truthy_instance_to_bool(o): o :: __main__.C @@ -222,7 +222,7 @@ def eq1(x, y): L0: r0 = y << 1 r1 = extend r0: builtins.bool to builtins.int - r2 = x == r1 + r2 = int_eq x, r1 return r2 def eq2(x, y): x :: bool @@ -233,7 +233,7 @@ def eq2(x, y): L0: r0 = x << 1 r1 = extend r0: builtins.bool to builtins.int - r2 = r1 == y + r2 = int_eq r1, y return r2 def neq1(x, y): x :: i64 diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 55e55dbf3286..8c4743c6a47f 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -1249,7 +1249,7 @@ L0: r0 = x.__getitem__(2) r1 = CPyList_GetItemShortBorrow(r0, 0) r2 = unbox(int, r1) - r3 = r2 == 4 + r3 = int_eq r2, 4 keep_alive r0 if r3 goto L1 else goto L2 :: bool L1: diff --git a/mypyc/test-data/irbuild-int.test b/mypyc/test-data/irbuild-int.test index fbe00aff4040..1489f2f470dd 100644 --- a/mypyc/test-data/irbuild-int.test +++ b/mypyc/test-data/irbuild-int.test @@ -4,24 +4,10 @@ def f(x: int, y: int) -> bool: [out] def f(x, y): x, y :: int - r0 :: native_int - r1, r2 :: bit - r3 :: bool - r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 == 0 - if r1 goto L1 else goto L2 :: bool -L1: - r2 = x != y - r3 = r2 - goto L3 -L2: - r4 = CPyTagged_IsEq_(x, y) - r5 = r4 ^ 1 - r3 = r5 -L3: - return r3 + r0 = int_ne x, y + return r0 [case testShortIntComparisons] def f(x: int) -> int: @@ -43,22 +29,22 @@ def f(x): r4 :: native_int r5, r6, r7 :: bit L0: - r0 = x == 6 + r0 = int_eq x, 6 if r0 goto L1 else goto L2 :: bool L1: return 2 L2: - r1 = x != 8 + r1 = int_ne x, 8 if r1 goto L3 else goto L4 :: bool L3: return 4 L4: - r2 = 10 == x + r2 = int_eq 10, x if r2 goto L5 else goto L6 :: bool L5: return 6 L6: - r3 = 12 != x + r3 = int_ne 12, x if r3 goto L7 else goto L8 :: bool L7: return 8 diff --git a/mypyc/test-data/irbuild-match.test b/mypyc/test-data/irbuild-match.test index a078ae0defdb..ab5a19624ba6 100644 --- a/mypyc/test-data/irbuild-match.test +++ b/mypyc/test-data/irbuild-match.test @@ -14,7 +14,7 @@ def f(): r6 :: object_ptr r7, r8 :: object L0: - r0 = 246 == 246 + r0 = int_eq 246, 246 if r0 goto L1 else goto L2 :: bool L1: r1 = 'matched' @@ -30,6 +30,7 @@ L2: L3: r8 = box(None, 1) return r8 + [case testMatchOrPattern_python3_10] def f(): match 123: @@ -46,10 +47,10 @@ def f(): r7 :: object_ptr r8, r9 :: object L0: - r0 = 246 == 246 + r0 = int_eq 246, 246 if r0 goto L3 else goto L1 :: bool L1: - r1 = 246 == 912 + r1 = int_eq 246, 912 if r1 goto L3 else goto L2 :: bool L2: goto L4 @@ -67,6 +68,7 @@ L4: L5: r9 = box(None, 1) return r9 + [case testMatchOrPatternManyPatterns_python3_10] def f(): match 1: @@ -83,16 +85,16 @@ def f(): r9 :: object_ptr r10, r11 :: object L0: - r0 = 2 == 2 + r0 = int_eq 2, 2 if r0 goto L5 else goto L1 :: bool L1: - r1 = 2 == 4 + r1 = int_eq 2, 4 if r1 goto L5 else goto L2 :: bool L2: - r2 = 2 == 6 + r2 = int_eq 2, 6 if r2 goto L5 else goto L3 :: bool L3: - r3 = 2 == 8 + r3 = int_eq 2, 8 if r3 goto L5 else goto L4 :: bool L4: goto L6 @@ -110,6 +112,7 @@ L6: L7: r11 = box(None, 1) return r11 + [case testMatchClassPattern_python3_10] def f(): match 123: @@ -200,7 +203,7 @@ def f(): r14 :: object_ptr r15, r16 :: object L0: - r0 = 246 == 246 + r0 = int_eq 246, 246 if r0 goto L1 else goto L2 :: bool L1: r1 = 'matched' @@ -213,7 +216,7 @@ L1: keep_alive r1 goto L5 L2: - r8 = 246 == 912 + r8 = int_eq 246, 912 if r8 goto L3 else goto L4 :: bool L3: r9 = 'no match' @@ -229,6 +232,7 @@ L4: L5: r16 = box(None, 1) return r16 + [case testMatchMultiBodyAndComplexOr_python3_10] def f(): match 123: @@ -265,7 +269,7 @@ def f(): r23 :: object_ptr r24, r25 :: object L0: - r0 = 246 == 2 + r0 = int_eq 246, 2 if r0 goto L1 else goto L2 :: bool L1: r1 = 'here 1' @@ -278,10 +282,10 @@ L1: keep_alive r1 goto L9 L2: - r8 = 246 == 4 + r8 = int_eq 246, 4 if r8 goto L5 else goto L3 :: bool L3: - r9 = 246 == 6 + r9 = int_eq 246, 6 if r9 goto L5 else goto L4 :: bool L4: goto L6 @@ -296,7 +300,7 @@ L5: keep_alive r10 goto L9 L6: - r17 = 246 == 246 + r17 = int_eq 246, 246 if r17 goto L7 else goto L8 :: bool L7: r18 = 'here 123' @@ -312,6 +316,7 @@ L8: L9: r25 = box(None, 1) return r25 + [case testMatchWithGuard_python3_10] def f(): match 123: @@ -328,7 +333,7 @@ def f(): r6 :: object_ptr r7, r8 :: object L0: - r0 = 246 == 246 + r0 = int_eq 246, 246 if r0 goto L1 else goto L3 :: bool L1: if 1 goto L2 else goto L3 :: bool @@ -346,6 +351,7 @@ L3: L4: r8 = box(None, 1) return r8 + [case testMatchSingleton_python3_10] def f(): match 123: @@ -449,7 +455,7 @@ def f(): r9 :: object_ptr r10, r11 :: object L0: - r0 = 2 == 2 + r0 = int_eq 2, 2 if r0 goto L3 else goto L1 :: bool L1: r1 = load_address PyLong_Type @@ -472,6 +478,7 @@ L4: L5: r11 = box(None, 1) return r11 + [case testMatchAsPattern_python3_10] def f(): match 123: @@ -487,7 +494,7 @@ def f(): r6 :: object_ptr r7, r8 :: object L0: - r0 = 246 == 246 + r0 = int_eq 246, 246 r1 = object 123 x = r1 if r0 goto L1 else goto L2 :: bool @@ -504,6 +511,7 @@ L2: L3: r8 = box(None, 1) return r8 + [case testMatchAsPatternOnOrPattern_python3_10] def f(): match 1: @@ -521,12 +529,12 @@ def f(): r8 :: object_ptr r9, r10 :: object L0: - r0 = 2 == 2 + r0 = int_eq 2, 2 r1 = object 1 x = r1 if r0 goto L3 else goto L1 :: bool L1: - r2 = 2 == 4 + r2 = int_eq 2, 4 r3 = object 2 x = r3 if r2 goto L3 else goto L2 :: bool @@ -545,6 +553,7 @@ L4: L5: r10 = box(None, 1) return r10 + [case testMatchAsPatternOnClassPattern_python3_10] def f(): match 123: diff --git a/mypyc/test-data/irbuild-nested.test b/mypyc/test-data/irbuild-nested.test index b2b884705366..62ae6eb9ee35 100644 --- a/mypyc/test-data/irbuild-nested.test +++ b/mypyc/test-data/irbuild-nested.test @@ -658,7 +658,7 @@ def baz_f_obj.__call__(__mypyc_self__, n): r6, r7 :: int L0: r0 = __mypyc_self__.__mypyc_env__ - r1 = n == 0 + r1 = int_eq n, 0 if r1 goto L1 else goto L2 :: bool L1: return 0 @@ -796,7 +796,7 @@ def baz(n): r0 :: bit r1, r2, r3 :: int L0: - r0 = n == 0 + r0 = int_eq n, 0 if r0 goto L1 else goto L2 :: bool L1: return 0 diff --git a/mypyc/test-data/irbuild-optional.test b/mypyc/test-data/irbuild-optional.test index e89018a727da..75c008586999 100644 --- a/mypyc/test-data/irbuild-optional.test +++ b/mypyc/test-data/irbuild-optional.test @@ -222,7 +222,7 @@ def f(y): L0: r0 = box(None, 1) x = r0 - r1 = y == 2 + r1 = int_eq y, 2 if r1 goto L1 else goto L2 :: bool L1: r2 = box(int, y) diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index a47f3db6a725..ab0e2fa09a9d 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -195,70 +195,30 @@ def f(i: int) -> bool: [out] def f(i): i :: int - r0 :: native_int - r1, r2 :: bit + r0 :: bit + r1 :: bool + r2 :: bit r3 :: bool r4 :: bit - r5 :: bool - r6 :: native_int - r7, r8 :: bit - r9 :: bool - r10 :: bit - r11 :: bool - r12 :: native_int - r13, r14 :: bit - r15 :: bool - r16 :: bit L0: - r0 = i & 1 - r1 = r0 == 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq i, 2 + if r0 goto L1 else goto L2 :: bool L1: - r2 = i == 2 - r3 = r2 + r1 = r0 goto L3 L2: - r4 = CPyTagged_IsEq_(i, 2) - r3 = r4 + r2 = int_eq i, 4 + r1 = r2 L3: - if r3 goto L4 else goto L5 :: bool + if r1 goto L4 else goto L5 :: bool L4: - r5 = r3 - goto L9 + r3 = r1 + goto L6 L5: - r6 = i & 1 - r7 = r6 == 0 - if r7 goto L6 else goto L7 :: bool + r4 = int_eq i, 6 + r3 = r4 L6: - r8 = i == 4 - r9 = r8 - goto L8 -L7: - r10 = CPyTagged_IsEq_(i, 4) - r9 = r10 -L8: - r5 = r9 -L9: - if r5 goto L10 else goto L11 :: bool -L10: - r11 = r5 - goto L15 -L11: - r12 = i & 1 - r13 = r12 == 0 - if r13 goto L12 else goto L13 :: bool -L12: - r14 = i == 6 - r15 = r14 - goto L14 -L13: - r16 = CPyTagged_IsEq_(i, 6) - r15 = r16 -L14: - r11 = r15 -L15: - return r11 - + return r3 [case testTupleBuiltFromList] def f(val: int) -> bool: @@ -270,24 +230,11 @@ def test() -> None: [out] def f(val): val, r0 :: int - r1 :: native_int - r2, r3 :: bit - r4 :: bool - r5 :: bit + r1 :: bit L0: r0 = CPyTagged_Remainder(val, 4) - r1 = r0 & 1 - r2 = r1 == 0 - if r2 goto L1 else goto L2 :: bool -L1: - r3 = r0 == 0 - r4 = r3 - goto L3 -L2: - r5 = CPyTagged_IsEq_(r0, 0) - r4 = r5 -L3: - return r4 + r1 = int_eq r0, 0 + return r1 def test(): r0 :: list r1, r2, r3 :: object diff --git a/mypyc/test-data/lowering-int.test b/mypyc/test-data/lowering-int.test new file mode 100644 index 000000000000..8c813563d0e6 --- /dev/null +++ b/mypyc/test-data/lowering-int.test @@ -0,0 +1,126 @@ +-- Test cases for converting high-level IR to lower-level IR (lowering). + +[case testLowerIntEq] +def f(x: int, y: int) -> int: + if x == y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1, r2, r3 :: bit +L0: + r0 = x & 1 + r1 = r0 == 0 + if r1 goto L1 else goto L2 :: bool +L1: + r2 = x == y + if r2 goto L3 else goto L4 :: bool +L2: + r3 = CPyTagged_IsEq_(x, y) + if r3 goto L3 else goto L4 :: bool +L3: + return 2 +L4: + return 4 + +[case testLowerIntNe] +def f(x: int, y: int) -> int: + if x != y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1, r2, r3, r4 :: bit +L0: + r0 = x & 1 + r1 = r0 == 0 + if r1 goto L1 else goto L2 :: bool +L1: + r2 = x != y + if r2 goto L3 else goto L4 :: bool +L2: + r3 = CPyTagged_IsEq_(x, y) + r4 = r3 ^ 1 + if r4 goto L3 else goto L4 :: bool +L3: + return 2 +L4: + return 4 + +[case testLowerIntEqWithConstant] +def f(x: int, y: int) -> int: + if x == 2: + return 1 + elif -1 == x: + return 2 + return 3 +[out] +def f(x, y): + x, y :: int + r0, r1 :: bit +L0: + r0 = x == 4 + if r0 goto L1 else goto L2 :: bool +L1: + return 2 +L2: + r1 = -2 == x + if r1 goto L3 else goto L4 :: bool +L3: + return 4 +L4: + return 6 + +[case testLowerIntNeWithConstant] +def f(x: int, y: int) -> int: + if x != 2: + return 1 + elif -1 != x: + return 2 + return 3 +[out] +def f(x, y): + x, y :: int + r0, r1 :: bit +L0: + r0 = x != 4 + if r0 goto L1 else goto L2 :: bool +L1: + return 2 +L2: + r1 = -2 != x + if r1 goto L3 else goto L4 :: bool +L3: + return 4 +L4: + return 6 + +[case testLowerIntEqValueContext] +def f(x: int, y: int) -> bool: + return x == y +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1, r2 :: bit + r3 :: bool + r4 :: bit +L0: + r0 = x & 1 + r1 = r0 == 0 + if r1 goto L1 else goto L2 :: bool +L1: + r2 = x == y + r3 = r2 + goto L3 +L2: + r4 = CPyTagged_IsEq_(x, y) + r3 = r4 +L3: + return r3 diff --git a/mypyc/test-data/opt-flag-elimination.test b/mypyc/test-data/opt-flag-elimination.test index f047a87dc3fa..337ced70a355 100644 --- a/mypyc/test-data/opt-flag-elimination.test +++ b/mypyc/test-data/opt-flag-elimination.test @@ -29,15 +29,13 @@ L0: if x goto L1 else goto L2 :: bool L1: r0 = c() - if r0 goto L4 else goto L5 :: bool + if r0 goto L3 else goto L4 :: bool L2: r1 = d() - if r1 goto L4 else goto L5 :: bool + if r1 goto L3 else goto L4 :: bool L3: - unreachable -L4: return 2 -L5: +L4: return 4 [case testFlagEliminationOneAssignment] @@ -92,20 +90,18 @@ L0: if x goto L1 else goto L2 :: bool L1: r0 = c(2) - if r0 goto L6 else goto L7 :: bool + if r0 goto L5 else goto L6 :: bool L2: if y goto L3 else goto L4 :: bool L3: r1 = c(4) - if r1 goto L6 else goto L7 :: bool + if r1 goto L5 else goto L6 :: bool L4: r2 = c(6) - if r2 goto L6 else goto L7 :: bool + if r2 goto L5 else goto L6 :: bool L5: - unreachable -L6: return 2 -L7: +L6: return 4 [case testFlagEliminationAssignmentNotLastOp] diff --git a/mypyc/test-data/refcount.test b/mypyc/test-data/refcount.test index 0f2c134ae21e..df980af8a7c7 100644 --- a/mypyc/test-data/refcount.test +++ b/mypyc/test-data/refcount.test @@ -67,7 +67,7 @@ def f(): L0: x = 2 y = 4 - r0 = x == 2 + r0 = int_eq x, 2 if r0 goto L3 else goto L4 :: bool L1: return x @@ -185,34 +185,26 @@ def f(a: int) -> int: [out] def f(a): a :: int - r0 :: native_int - r1, r2, r3 :: bit - x, r4, y :: int + r0 :: bit + x, r1, y :: int L0: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq a, a + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsEq_(a, a) - if r2 goto L3 else goto L4 :: bool -L2: - r3 = a == a - if r3 goto L3 else goto L4 :: bool -L3: a = 2 - goto L5 -L4: + goto L3 +L2: x = 4 dec_ref x :: int - goto L6 -L5: - r4 = CPyTagged_Add(a, 2) + goto L4 +L3: + r1 = CPyTagged_Add(a, 2) dec_ref a :: int - y = r4 + y = r1 return y -L6: +L4: inc_ref a :: int - goto L5 + goto L3 [case testConditionalAssignToArgument2] def f(a: int) -> int: @@ -225,33 +217,25 @@ def f(a: int) -> int: [out] def f(a): a :: int - r0 :: native_int - r1, r2, r3 :: bit - x, r4, y :: int + r0 :: bit + x, r1, y :: int L0: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq a, a + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsEq_(a, a) - if r2 goto L3 else goto L4 :: bool -L2: - r3 = a == a - if r3 goto L3 else goto L4 :: bool -L3: x = 4 dec_ref x :: int - goto L6 -L4: + goto L4 +L2: a = 2 -L5: - r4 = CPyTagged_Add(a, 2) +L3: + r1 = CPyTagged_Add(a, 2) dec_ref a :: int - y = r4 + y = r1 return y -L6: +L4: inc_ref a :: int - goto L5 + goto L3 [case testConditionalAssignToArgument3] def f(a: int) -> int: @@ -261,25 +245,17 @@ def f(a: int) -> int: [out] def f(a): a :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit L0: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq a, a + if r0 goto L1 else goto L3 :: bool L1: - r2 = CPyTagged_IsEq_(a, a) - if r2 goto L3 else goto L5 :: bool -L2: - r3 = a == a - if r3 goto L3 else goto L5 :: bool -L3: a = 2 -L4: +L2: return a -L5: +L3: inc_ref a :: int - goto L4 + goto L2 [case testAssignRegisterToItself] def f(a: int) -> int: @@ -438,40 +414,32 @@ def f() -> int: [out] def f(): x, y, z :: int - r0 :: native_int - r1, r2, r3 :: bit - a, r4, r5 :: int + r0 :: bit + a, r1, r2 :: int L0: x = 2 y = 4 z = 6 - r0 = z & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_eq z, z + if r0 goto L3 else goto L4 :: bool L1: - r2 = CPyTagged_IsEq_(z, z) - if r2 goto L5 else goto L6 :: bool -L2: - r3 = z == z - if r3 goto L5 else goto L6 :: bool -L3: return z -L4: +L2: a = 2 - r4 = CPyTagged_Add(x, y) + r1 = CPyTagged_Add(x, y) dec_ref x :: int dec_ref y :: int - r5 = CPyTagged_Subtract(r4, a) - dec_ref r4 :: int + r2 = CPyTagged_Subtract(r1, a) + dec_ref r1 :: int dec_ref a :: int - return r5 -L5: + return r2 +L3: dec_ref x :: int dec_ref y :: int - goto L3 -L6: + goto L1 +L4: dec_ref z :: int - goto L4 + goto L2 [case testLoop] def f(a: int) -> int: @@ -1371,25 +1339,12 @@ class C: def add(c): c :: __main__.C r0, r1 :: int - r2 :: native_int - r3, r4 :: bit - r5 :: bool - r6 :: bit + r2 :: bit L0: r0 = borrow c.x r1 = borrow c.y - r2 = r0 & 1 - r3 = r2 == 0 - if r3 goto L1 else goto L2 :: bool -L1: - r4 = r0 == r1 - r5 = r4 - goto L3 -L2: - r6 = CPyTagged_IsEq_(r0, r1) - r5 = r6 -L3: - return r5 + r2 = int_eq r0, r1 + return r2 [case testBorrowIntLessThan] def add(c: C) -> bool: @@ -1441,24 +1396,11 @@ class C: def add(c): c :: __main__.C r0 :: int - r1 :: native_int - r2, r3 :: bit - r4 :: bool - r5 :: bit + r1 :: bit L0: r0 = borrow c.x - r1 = r0 & 1 - r2 = r1 == 0 - if r2 goto L1 else goto L2 :: bool -L1: - r3 = r0 == 20 - r4 = r3 - goto L3 -L2: - r5 = CPyTagged_IsEq_(r0, 20) - r4 = r5 -L3: - return r4 + r1 = int_eq r0, 20 + return r1 [case testBorrowIntArithmetic] def add(c: C) -> int: @@ -1501,23 +1443,15 @@ class C: def add(c, n): c :: __main__.C n, r0, r1 :: int - r2 :: native_int - r3, r4, r5 :: bit + r2 :: bit L0: r0 = borrow c.x r1 = borrow c.y - r2 = r0 & 1 - r3 = r2 != 0 - if r3 goto L1 else goto L2 :: bool + r2 = int_eq r0, r1 + if r2 goto L1 else goto L2 :: bool L1: - r4 = CPyTagged_IsEq_(r0, r1) - if r4 goto L3 else goto L4 :: bool -L2: - r5 = r0 == r1 - if r5 goto L3 else goto L4 :: bool -L3: return 1 -L4: +L2: return 0 [case testBorrowIntInPlaceOp] diff --git a/mypyc/test/test_cheader.py b/mypyc/test/test_cheader.py index cc0fd9df2b34..f2af41c22ea9 100644 --- a/mypyc/test/test_cheader.py +++ b/mypyc/test/test_cheader.py @@ -7,6 +7,7 @@ import re import unittest +from mypyc.ir.ops import PrimitiveDescription from mypyc.primitives import registry from mypyc.primitives.registry import CFunctionDescription @@ -25,17 +26,24 @@ def check_name(name: str) -> None: rf"\b{name}\b", header ), f'"{name}" is used in mypyc.primitives but not declared in CPy.h' - for values in [ + for old_values in [ registry.method_call_ops.values(), registry.function_ops.values(), - registry.binary_ops.values(), registry.unary_ops.values(), ]: + for old_ops in old_values: + if isinstance(old_ops, CFunctionDescription): + old_ops = [old_ops] + for old_op in old_ops: + check_name(old_op.c_function_name) + + for values in [registry.binary_ops.values()]: for ops in values: - if isinstance(ops, CFunctionDescription): + if isinstance(ops, PrimitiveDescription): ops = [ops] for op in ops: - check_name(op.c_function_name) + if op.c_function_name is not None: + check_name(op.c_function_name) primitives_path = os.path.join(os.path.dirname(__file__), "..", "primitives") for fnam in glob.glob(f"{primitives_path}/*.py"): diff --git a/mypyc/test/test_emitfunc.py b/mypyc/test/test_emitfunc.py index ab1586bb22a8..b16387aa40af 100644 --- a/mypyc/test/test_emitfunc.py +++ b/mypyc/test/test_emitfunc.py @@ -859,6 +859,8 @@ def assert_emit_binary_op( args = [left, right] if desc.ordering is not None: args = [args[i] for i in desc.ordering] + # This only supports primitives that map to C calls + assert desc.c_function_name is not None self.assert_emit( CallC( desc.c_function_name, diff --git a/mypyc/test/test_lowering.py b/mypyc/test/test_lowering.py new file mode 100644 index 000000000000..e32dba2e1021 --- /dev/null +++ b/mypyc/test/test_lowering.py @@ -0,0 +1,54 @@ +"""Runner for lowering transform tests.""" + +from __future__ import annotations + +import os.path + +from mypy.errors import CompileError +from mypy.test.config import test_temp_dir +from mypy.test.data import DataDrivenTestCase +from mypyc.common import TOP_LEVEL_NAME +from mypyc.ir.pprint import format_func +from mypyc.options import CompilerOptions +from mypyc.test.testutil import ( + ICODE_GEN_BUILTINS, + MypycDataSuite, + assert_test_output, + build_ir_for_single_file, + remove_comment_lines, + use_custom_builtins, +) +from mypyc.transform.exceptions import insert_exception_handling +from mypyc.transform.flag_elimination import do_flag_elimination +from mypyc.transform.lower import lower_ir +from mypyc.transform.refcount import insert_ref_count_opcodes +from mypyc.transform.uninit import insert_uninit_checks + + +class TestLowering(MypycDataSuite): + files = ["lowering-int.test"] + base_path = test_temp_dir + + def run_case(self, testcase: DataDrivenTestCase) -> None: + with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase): + expected_output = remove_comment_lines(testcase.output) + try: + ir = build_ir_for_single_file(testcase.input) + except CompileError as e: + actual = e.messages + else: + actual = [] + for fn in ir: + if fn.name == TOP_LEVEL_NAME and not testcase.name.endswith("_toplevel"): + continue + options = CompilerOptions() + # Lowering happens after exception handling and ref count opcodes have + # been added. Any changes must maintain reference counting semantics. + insert_uninit_checks(fn) + insert_exception_handling(fn) + insert_ref_count_opcodes(fn) + lower_ir(fn, options) + do_flag_elimination(fn, options) + actual.extend(format_func(fn)) + + assert_test_output(testcase, actual, "Invalid source code output", expected_output) diff --git a/mypyc/transform/ir_transform.py b/mypyc/transform/ir_transform.py index 254fe3f7771d..a631bd7352b5 100644 --- a/mypyc/transform/ir_transform.py +++ b/mypyc/transform/ir_transform.py @@ -35,6 +35,7 @@ MethodCall, Op, OpVisitor, + PrimitiveOp, RaiseStandardError, Return, SetAttr, @@ -80,6 +81,7 @@ def transform_blocks(self, blocks: list[BasicBlock]) -> None: """ block_map: dict[BasicBlock, BasicBlock] = {} op_map = self.op_map + empties = set() for block in blocks: new_block = BasicBlock() block_map[block] = new_block @@ -89,7 +91,10 @@ def transform_blocks(self, blocks: list[BasicBlock]) -> None: new_op = op.accept(self) if new_op is not op: op_map[op] = new_op - + # A transform can produce empty blocks which can be removed. + if is_empty_block(new_block) and not is_empty_block(block): + empties.add(new_block) + self.builder.blocks = [block for block in self.builder.blocks if block not in empties] # Update all op/block references to point to the transformed ones. patcher = PatchVisitor(op_map, block_map) for block in self.builder.blocks: @@ -170,6 +175,9 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> Value | None: def visit_call_c(self, op: CallC) -> Value | None: return self.add(op) + def visit_primitive_op(self, op: PrimitiveOp) -> Value | None: + return self.add(op) + def visit_truncate(self, op: Truncate) -> Value | None: return self.add(op) @@ -302,6 +310,9 @@ def visit_raise_standard_error(self, op: RaiseStandardError) -> None: def visit_call_c(self, op: CallC) -> None: op.args = [self.fix_op(arg) for arg in op.args] + def visit_primitive_op(self, op: PrimitiveOp) -> None: + op.args = [self.fix_op(arg) for arg in op.args] + def visit_truncate(self, op: Truncate) -> None: op.src = self.fix_op(op.src) @@ -351,3 +362,7 @@ def visit_keep_alive(self, op: KeepAlive) -> None: def visit_unborrow(self, op: Unborrow) -> None: op.src = self.fix_op(op.src) + + +def is_empty_block(block: BasicBlock) -> bool: + return len(block.ops) == 1 and isinstance(block.ops[0], Unreachable) diff --git a/mypyc/transform/lower.py b/mypyc/transform/lower.py new file mode 100644 index 000000000000..b717657095f9 --- /dev/null +++ b/mypyc/transform/lower.py @@ -0,0 +1,33 @@ +"""Transform IR to lower-level ops. + +Higher-level ops are used in earlier compiler passes, as they make +various analyses, optimizations and transforms easier to implement. +Later passes use lower-level ops, as they are easier to generate code +from, and they help with lower-level optimizations. + +Lowering of various primitive ops is implemented in the mypyc.lower +package. +""" + +from mypyc.ir.func_ir import FuncIR +from mypyc.ir.ops import PrimitiveOp, Value +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.lower.registry import lowering_registry +from mypyc.options import CompilerOptions +from mypyc.transform.ir_transform import IRTransform + + +def lower_ir(ir: FuncIR, options: CompilerOptions) -> None: + builder = LowLevelIRBuilder(None, options) + visitor = LoweringVisitor(builder) + visitor.transform_blocks(ir.blocks) + ir.blocks = builder.blocks + + +class LoweringVisitor(IRTransform): + def visit_primitive_op(self, op: PrimitiveOp) -> Value: + # The lowering implementation functions of various primitive ops are stored + # in a registry, which is populated using function decorators. The name + # of op (such as "int_eq") is used as the key. + lower_fn = lowering_registry[op.desc.name] + return lower_fn(self.builder, op.args, op.line) From cf221bdc2cefc539a0b278c10ed6bde0350f370e Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 16 Mar 2024 12:40:30 +0000 Subject: [PATCH 125/172] Sync typeshed Source commit: https://github.com/python/typeshed/commit/ff7caa30e29d9c9467b1ba0007764c65c0b44a5c --- mypy/typeshed/stdlib/_codecs.pyi | 90 +- mypy/typeshed/stdlib/_collections_abc.pyi | 6 +- mypy/typeshed/stdlib/_compression.pyi | 4 +- mypy/typeshed/stdlib/_ctypes.pyi | 44 +- mypy/typeshed/stdlib/_curses.pyi | 123 +- mypy/typeshed/stdlib/_decimal.pyi | 176 +-- mypy/typeshed/stdlib/_heapq.pyi | 10 +- mypy/typeshed/stdlib/_imp.pyi | 22 +- mypy/typeshed/stdlib/_locale.pyi | 20 +- mypy/typeshed/stdlib/_msi.pyi | 6 +- mypy/typeshed/stdlib/_operator.pyi | 130 +- mypy/typeshed/stdlib/_posixsubprocess.pyi | 47 +- mypy/typeshed/stdlib/_py_abc.pyi | 2 +- mypy/typeshed/stdlib/_random.pyi | 6 +- mypy/typeshed/stdlib/_socket.pyi | 99 +- mypy/typeshed/stdlib/_thread.pyi | 6 +- mypy/typeshed/stdlib/_tkinter.pyi | 73 +- mypy/typeshed/stdlib/_tracemalloc.pyi | 4 +- mypy/typeshed/stdlib/_typeshed/__init__.pyi | 50 +- mypy/typeshed/stdlib/_typeshed/dbapi.pyi | 12 +- mypy/typeshed/stdlib/_typeshed/wsgi.pyi | 16 +- mypy/typeshed/stdlib/_typeshed/xml.pyi | 6 +- mypy/typeshed/stdlib/_weakref.pyi | 16 +- mypy/typeshed/stdlib/_winapi.pyi | 98 +- mypy/typeshed/stdlib/abc.pyi | 2 +- mypy/typeshed/stdlib/argparse.pyi | 2 +- mypy/typeshed/stdlib/array.pyi | 74 +- mypy/typeshed/stdlib/asyncio/events.pyi | 6 +- mypy/typeshed/stdlib/asyncio/futures.pyi | 8 +- mypy/typeshed/stdlib/asyncio/tasks.pyi | 176 +-- mypy/typeshed/stdlib/asyncio/threads.pyi | 2 +- mypy/typeshed/stdlib/asyncio/trsock.pyi | 12 +- mypy/typeshed/stdlib/asyncio/unix_events.pyi | 40 +- mypy/typeshed/stdlib/audioop.pyi | 67 +- mypy/typeshed/stdlib/bdb.pyi | 2 +- mypy/typeshed/stdlib/binascii.pyi | 26 +- mypy/typeshed/stdlib/builtins.pyi | 1192 +++++++++-------- mypy/typeshed/stdlib/bz2.pyi | 4 +- mypy/typeshed/stdlib/cProfile.pyi | 2 +- mypy/typeshed/stdlib/cgi.pyi | 2 +- mypy/typeshed/stdlib/cmath.pyi | 44 +- mypy/typeshed/stdlib/codecs.pyi | 16 +- mypy/typeshed/stdlib/collections/__init__.pyi | 138 +- mypy/typeshed/stdlib/compileall.pyi | 2 +- .../stdlib/concurrent/futures/_base.pyi | 16 +- mypy/typeshed/stdlib/contextlib.pyi | 14 +- mypy/typeshed/stdlib/contextvars.pyi | 18 +- mypy/typeshed/stdlib/curses/__init__.pyi | 2 +- mypy/typeshed/stdlib/curses/panel.pyi | 2 +- mypy/typeshed/stdlib/dataclasses.pyi | 14 +- mypy/typeshed/stdlib/datetime.pyi | 116 +- mypy/typeshed/stdlib/dbm/gnu.pyi | 2 +- mypy/typeshed/stdlib/dbm/ndbm.pyi | 2 +- mypy/typeshed/stdlib/distutils/core.pyi | 2 +- mypy/typeshed/stdlib/email/charset.pyi | 2 +- mypy/typeshed/stdlib/email/header.pyi | 2 +- mypy/typeshed/stdlib/email/headerregistry.pyi | 4 +- mypy/typeshed/stdlib/email/message.pyi | 12 +- mypy/typeshed/stdlib/encodings/utf_8.pyi | 8 +- mypy/typeshed/stdlib/fcntl.pyi | 16 +- mypy/typeshed/stdlib/fractions.pyi | 2 +- mypy/typeshed/stdlib/functools.pyi | 18 +- mypy/typeshed/stdlib/gc.pyi | 6 +- mypy/typeshed/stdlib/gzip.pyi | 6 +- mypy/typeshed/stdlib/hashlib.pyi | 18 +- mypy/typeshed/stdlib/heapq.pyi | 2 +- mypy/typeshed/stdlib/hmac.pyi | 4 +- mypy/typeshed/stdlib/imghdr.pyi | 4 +- mypy/typeshed/stdlib/imp.pyi | 2 +- mypy/typeshed/stdlib/importlib/abc.pyi | 14 +- mypy/typeshed/stdlib/inspect.pyi | 6 +- mypy/typeshed/stdlib/io.pyi | 64 +- mypy/typeshed/stdlib/itertools.pyi | 108 +- mypy/typeshed/stdlib/json/encoder.pyi | 2 + mypy/typeshed/stdlib/lib2to3/fixer_base.pyi | 2 +- mypy/typeshed/stdlib/logging/__init__.pyi | 9 +- mypy/typeshed/stdlib/logging/handlers.pyi | 2 +- mypy/typeshed/stdlib/lzma.pyi | 4 +- mypy/typeshed/stdlib/marshal.pyi | 8 +- mypy/typeshed/stdlib/math.pyi | 112 +- mypy/typeshed/stdlib/mmap.pyi | 16 +- mypy/typeshed/stdlib/msvcrt.pyi | 18 +- .../stdlib/multiprocessing/context.pyi | 12 +- .../stdlib/multiprocessing/dummy/__init__.pyi | 4 +- .../stdlib/multiprocessing/managers.pyi | 70 +- .../stdlib/multiprocessing/queues.pyi | 2 +- .../stdlib/multiprocessing/sharedctypes.pyi | 10 +- .../stdlib/multiprocessing/synchronize.pyi | 4 +- mypy/typeshed/stdlib/ntpath.pyi | 6 +- mypy/typeshed/stdlib/opcode.pyi | 2 +- mypy/typeshed/stdlib/optparse.pyi | 113 +- mypy/typeshed/stdlib/os/__init__.pyi | 160 +-- mypy/typeshed/stdlib/pathlib.pyi | 4 +- mypy/typeshed/stdlib/pickle.pyi | 13 +- mypy/typeshed/stdlib/posixpath.pyi | 6 +- mypy/typeshed/stdlib/profile.pyi | 2 +- mypy/typeshed/stdlib/pstats.pyi | 3 +- mypy/typeshed/stdlib/pwd.pyi | 4 +- mypy/typeshed/stdlib/pyexpat/__init__.pyi | 14 +- mypy/typeshed/stdlib/re.pyi | 22 +- mypy/typeshed/stdlib/readline.pyi | 34 +- mypy/typeshed/stdlib/resource.pyi | 10 +- mypy/typeshed/stdlib/select.pyi | 15 +- mypy/typeshed/stdlib/signal.pyi | 30 +- mypy/typeshed/stdlib/smtplib.pyi | 4 +- mypy/typeshed/stdlib/socket.pyi | 8 +- mypy/typeshed/stdlib/spwd.pyi | 2 +- mypy/typeshed/stdlib/sqlite3/dbapi2.pyi | 175 ++- mypy/typeshed/stdlib/ssl.pyi | 20 +- mypy/typeshed/stdlib/statistics.pyi | 10 +- mypy/typeshed/stdlib/string.pyi | 8 +- mypy/typeshed/stdlib/struct.pyi | 16 +- mypy/typeshed/stdlib/sys/__init__.pyi | 34 +- mypy/typeshed/stdlib/sys/_monitoring.pyi | 16 +- mypy/typeshed/stdlib/syslog.pyi | 6 +- mypy/typeshed/stdlib/tarfile.pyi | 6 +- mypy/typeshed/stdlib/tempfile.pyi | 8 +- mypy/typeshed/stdlib/termios.pyi | 16 +- mypy/typeshed/stdlib/tkinter/__init__.pyi | 152 ++- mypy/typeshed/stdlib/tkinter/dnd.pyi | 2 +- mypy/typeshed/stdlib/tkinter/font.pyi | 4 +- mypy/typeshed/stdlib/tkinter/ttk.pyi | 8 +- mypy/typeshed/stdlib/tomllib.pyi | 4 +- mypy/typeshed/stdlib/trace.pyi | 2 +- mypy/typeshed/stdlib/traceback.pyi | 14 +- mypy/typeshed/stdlib/types.pyi | 191 +-- mypy/typeshed/stdlib/typing.pyi | 109 +- mypy/typeshed/stdlib/typing_extensions.pyi | 36 +- mypy/typeshed/stdlib/unicodedata.pyi | 68 +- mypy/typeshed/stdlib/unittest/async_case.pyi | 2 +- mypy/typeshed/stdlib/unittest/case.pyi | 6 +- mypy/typeshed/stdlib/unittest/main.pyi | 2 +- mypy/typeshed/stdlib/unittest/mock.pyi | 6 +- mypy/typeshed/stdlib/urllib/request.pyi | 3 +- mypy/typeshed/stdlib/weakref.pyi | 7 +- mypy/typeshed/stdlib/winreg.pyi | 38 +- mypy/typeshed/stdlib/wsgiref/types.pyi | 16 +- .../typeshed/stdlib/xml/etree/ElementTree.pyi | 36 +- mypy/typeshed/stdlib/xmlrpc/server.pyi | 8 +- mypy/typeshed/stdlib/xxlimited.pyi | 4 +- mypy/typeshed/stdlib/zipfile/__init__.pyi | 10 +- mypy/typeshed/stdlib/zlib.pyi | 10 +- mypy/typeshed/stdlib/zoneinfo/__init__.pyi | 12 +- 143 files changed, 2703 insertions(+), 2458 deletions(-) diff --git a/mypy/typeshed/stdlib/_codecs.pyi b/mypy/typeshed/stdlib/_codecs.pyi index 6de4666e0776..ecf874d33ddd 100644 --- a/mypy/typeshed/stdlib/_codecs.pyi +++ b/mypy/typeshed/stdlib/_codecs.pyi @@ -13,13 +13,13 @@ _CharMap: TypeAlias = dict[int, int] | _EncodingMap _Handler: TypeAlias = Callable[[UnicodeError], tuple[str | bytes, int]] _SearchFunction: TypeAlias = Callable[[str], codecs.CodecInfo | None] -def register(__search_function: _SearchFunction) -> None: ... +def register(search_function: _SearchFunction, /) -> None: ... if sys.version_info >= (3, 10): - def unregister(__search_function: _SearchFunction) -> None: ... + def unregister(search_function: _SearchFunction, /) -> None: ... -def register_error(__errors: str, __handler: _Handler) -> None: ... -def lookup_error(__name: str) -> _Handler: ... +def register_error(errors: str, handler: _Handler, /) -> None: ... +def lookup_error(name: str, /) -> _Handler: ... # The type ignore on `encode` and `decode` is to avoid issues with overlapping overloads, for more details, see #300 # https://docs.python.org/3/library/codecs.html#binary-transforms @@ -68,66 +68,66 @@ def decode( def decode(obj: str, encoding: Literal["hex", "hex_codec"], errors: str = "strict") -> bytes: ... @overload def decode(obj: ReadableBuffer, encoding: str = "utf-8", errors: str = "strict") -> str: ... -def lookup(__encoding: str) -> codecs.CodecInfo: ... -def charmap_build(__map: str) -> _CharMap: ... -def ascii_decode(__data: ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... -def ascii_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def charmap_decode(__data: ReadableBuffer, __errors: str | None = None, __mapping: _CharMap | None = None) -> tuple[str, int]: ... -def charmap_encode(__str: str, __errors: str | None = None, __mapping: _CharMap | None = None) -> tuple[bytes, int]: ... -def escape_decode(__data: str | ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... -def escape_encode(__data: bytes, __errors: str | None = None) -> tuple[bytes, int]: ... -def latin_1_decode(__data: ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... -def latin_1_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... +def lookup(encoding: str, /) -> codecs.CodecInfo: ... +def charmap_build(map: str, /) -> _CharMap: ... +def ascii_decode(data: ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ... +def ascii_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def charmap_decode(data: ReadableBuffer, errors: str | None = None, mapping: _CharMap | None = None, /) -> tuple[str, int]: ... +def charmap_encode(str: str, errors: str | None = None, mapping: _CharMap | None = None, /) -> tuple[bytes, int]: ... +def escape_decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ... +def escape_encode(data: bytes, errors: str | None = None, /) -> tuple[bytes, int]: ... +def latin_1_decode(data: ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ... +def latin_1_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... if sys.version_info >= (3, 9): def raw_unicode_escape_decode( - __data: str | ReadableBuffer, __errors: str | None = None, __final: bool = True + data: str | ReadableBuffer, errors: str | None = None, final: bool = True, / ) -> tuple[str, int]: ... else: - def raw_unicode_escape_decode(__data: str | ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... + def raw_unicode_escape_decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ... -def raw_unicode_escape_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def readbuffer_encode(__data: str | ReadableBuffer, __errors: str | None = None) -> tuple[bytes, int]: ... +def raw_unicode_escape_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def readbuffer_encode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[bytes, int]: ... if sys.version_info >= (3, 9): def unicode_escape_decode( - __data: str | ReadableBuffer, __errors: str | None = None, __final: bool = True + data: str | ReadableBuffer, errors: str | None = None, final: bool = True, / ) -> tuple[str, int]: ... else: - def unicode_escape_decode(__data: str | ReadableBuffer, __errors: str | None = None) -> tuple[str, int]: ... + 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]: ... -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]: ... -def utf_16_encode(__str: str, __errors: str | None = None, __byteorder: int = 0) -> tuple[bytes, int]: ... +def unicode_escape_encode(str: str, 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]: ... +def utf_16_encode(str: str, errors: str | None = None, byteorder: int = 0, /) -> tuple[bytes, int]: ... def utf_16_ex_decode( - __data: ReadableBuffer, __errors: str | None = None, __byteorder: int = 0, __final: bool = False + data: ReadableBuffer, errors: str | None = None, byteorder: int = 0, final: bool = False, / ) -> tuple[str, int, int]: ... -def utf_16_le_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_16_le_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def utf_32_be_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_32_be_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def utf_32_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_32_encode(__str: str, __errors: str | None = None, __byteorder: int = 0) -> tuple[bytes, int]: ... +def utf_16_le_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_16_le_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def utf_32_be_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_32_be_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def utf_32_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_32_encode(str: str, errors: str | None = None, byteorder: int = 0, /) -> tuple[bytes, int]: ... def utf_32_ex_decode( - __data: ReadableBuffer, __errors: str | None = None, __byteorder: int = 0, __final: bool = False + data: ReadableBuffer, errors: str | None = None, byteorder: int = 0, final: bool = False, / ) -> tuple[str, int, int]: ... -def utf_32_le_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_32_le_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def utf_7_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_7_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... -def utf_8_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... -def utf_8_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... +def utf_32_le_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_32_le_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def utf_7_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_7_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... +def utf_8_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... +def utf_8_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... if sys.platform == "win32": - def mbcs_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... - def mbcs_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... + def mbcs_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... + def mbcs_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... def code_page_decode( - __codepage: int, __data: ReadableBuffer, __errors: str | None = None, __final: bool = False + codepage: int, data: ReadableBuffer, errors: str | None = None, final: bool = False, / ) -> tuple[str, int]: ... - def code_page_encode(__code_page: int, __str: str, __errors: str | None = None) -> tuple[bytes, int]: ... - def oem_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... - def oem_encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... + def code_page_encode(code_page: int, str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... + def oem_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... + def oem_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... diff --git a/mypy/typeshed/stdlib/_collections_abc.pyi b/mypy/typeshed/stdlib/_collections_abc.pyi index 0aa09967a895..e467d626e8a8 100644 --- a/mypy/typeshed/stdlib/_collections_abc.pyi +++ b/mypy/typeshed/stdlib/_collections_abc.pyi @@ -69,7 +69,7 @@ _VT_co = TypeVar("_VT_co", covariant=True) # Value type covariant containers. @final class dict_keys(KeysView[_KT_co], Generic[_KT_co, _VT_co]): # undocumented - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 10): @property def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... @@ -82,7 +82,7 @@ class dict_values(ValuesView[_VT_co], Generic[_KT_co, _VT_co]): # undocumented @final class dict_items(ItemsView[_KT_co, _VT_co]): # undocumented - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 10): @property def mapping(self) -> MappingProxyType[_KT_co, _VT_co]: ... @@ -91,4 +91,4 @@ if sys.version_info >= (3, 12): @runtime_checkable class Buffer(Protocol): @abstractmethod - def __buffer__(self, __flags: int) -> memoryview: ... + def __buffer__(self, flags: int, /) -> memoryview: ... diff --git a/mypy/typeshed/stdlib/_compression.pyi b/mypy/typeshed/stdlib/_compression.pyi index 24e11261140b..a41a8142cc3a 100644 --- a/mypy/typeshed/stdlib/_compression.pyi +++ b/mypy/typeshed/stdlib/_compression.pyi @@ -6,9 +6,9 @@ from typing import Any, Protocol BUFFER_SIZE = DEFAULT_BUFFER_SIZE class _Reader(Protocol): - def read(self, __n: int) -> bytes: ... + def read(self, n: int, /) -> bytes: ... def seekable(self) -> bool: ... - def seek(self, __n: int) -> Any: ... + def seek(self, n: int, /) -> Any: ... class BaseStream(BufferedIOBase): ... diff --git a/mypy/typeshed/stdlib/_ctypes.pyi b/mypy/typeshed/stdlib/_ctypes.pyi index e0cc87814609..60bbc51d9411 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -44,8 +44,8 @@ if sys.platform == "win32": def FormatError(code: int = ...) -> str: ... def get_last_error() -> int: ... def set_last_error(value: int) -> int: ... - def LoadLibrary(__name: str, __load_flags: int = 0) -> int: ... - def FreeLibrary(__handle: int) -> None: ... + def LoadLibrary(name: str, load_flags: int = 0, /) -> int: ... + def FreeLibrary(handle: int, /) -> None: ... class _CDataMeta(type): # By default mypy complains about the following two methods, because strictly speaking cls @@ -75,8 +75,8 @@ class _CData(metaclass=_CDataMeta): def from_param(cls, obj: Any) -> Self | _CArgObject: ... @classmethod def in_dll(cls, library: CDLL, name: str) -> Self: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... class _SimpleCData(_CData, Generic[_T]): value: _T @@ -95,13 +95,13 @@ class _Pointer(_PointerLike, _CData, Generic[_CT]): @overload def __init__(self, arg: _CT) -> None: ... @overload - def __getitem__(self, __key: int) -> Any: ... + def __getitem__(self, key: int, /) -> Any: ... @overload - def __getitem__(self, __key: slice) -> list[Any]: ... - def __setitem__(self, __key: int, __value: Any) -> None: ... + def __getitem__(self, key: slice, /) -> list[Any]: ... + def __setitem__(self, key: int, value: Any, /) -> None: ... def POINTER(type: type[_CT]) -> type[_Pointer[_CT]]: ... -def pointer(__arg: _CT) -> _Pointer[_CT]: ... +def pointer(arg: _CT, /) -> _Pointer[_CT]: ... class _CArgObject: ... @@ -119,15 +119,15 @@ class CFuncPtr(_PointerLike, _CData): @overload def __init__(self) -> None: ... @overload - def __init__(self, __address: int) -> None: ... + def __init__(self, address: int, /) -> None: ... @overload - def __init__(self, __callable: Callable[..., Any]) -> None: ... + def __init__(self, callable: Callable[..., Any], /) -> None: ... @overload - def __init__(self, __func_spec: tuple[str | int, CDLL], __paramflags: tuple[_PF, ...] | None = ...) -> None: ... + def __init__(self, func_spec: tuple[str | int, CDLL], paramflags: tuple[_PF, ...] | None = ..., /) -> None: ... if sys.platform == "win32": @overload def __init__( - self, __vtbl_index: int, __name: str, __paramflags: tuple[_PF, ...] | None = ..., __iid: _CData | None = ... + self, vtbl_index: int, name: str, paramflags: tuple[_PF, ...] | None = ..., iid: _CData | None = ..., / ) -> None: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... @@ -139,10 +139,10 @@ class _CField(Generic[_CT, _GetT, _SetT]): offset: int size: int @overload - def __get__(self, __instance: None, __owner: type[Any] | None) -> Self: ... + def __get__(self, instance: None, owner: type[Any] | None, /) -> Self: ... @overload - def __get__(self, __instance: Any, __owner: type[Any] | None) -> _GetT: ... - def __set__(self, __instance: Any, __value: _SetT) -> None: ... + def __get__(self, instance: Any, owner: type[Any] | None, /) -> _GetT: ... + def __set__(self, instance: Any, value: _SetT, /) -> None: ... class _StructUnionMeta(_CDataMeta): _fields_: Sequence[tuple[str, type[_CData]] | tuple[str, type[_CData], int]] @@ -169,7 +169,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 @@ -185,13 +189,13 @@ class Array(_CData, Generic[_CT]): # the array element type would belong are annotated with Any instead. def __init__(self, *args: Any) -> None: ... @overload - def __getitem__(self, __key: int) -> Any: ... + def __getitem__(self, key: int, /) -> Any: ... @overload - def __getitem__(self, __key: slice) -> list[Any]: ... + def __getitem__(self, key: slice, /) -> list[Any]: ... @overload - def __setitem__(self, __key: int, __value: Any) -> None: ... + def __setitem__(self, key: int, value: Any, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: Iterable[Any]) -> None: ... + def __setitem__(self, key: slice, value: Iterable[Any], /) -> None: ... def __iter__(self) -> Iterator[Any]: ... # Can't inherit from Sized because the metaclass conflict between # Sized and _CData prevents using _CDataMeta. diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index 20189cb285c5..929c6f8f3bc8 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -275,15 +275,15 @@ if sys.platform != "win32": def baudrate() -> int: ... def beep() -> None: ... def can_change_color() -> bool: ... - def cbreak(__flag: bool = True) -> None: ... - def color_content(__color_number: int) -> tuple[int, int, int]: ... - def color_pair(__pair_number: int) -> int: ... - def curs_set(__visibility: int) -> int: ... + def cbreak(flag: bool = True, /) -> None: ... + def color_content(color_number: int, /) -> tuple[int, int, int]: ... + def color_pair(pair_number: int, /) -> int: ... + def curs_set(visibility: int, /) -> int: ... def def_prog_mode() -> None: ... def def_shell_mode() -> None: ... - def delay_output(__ms: int) -> None: ... + def delay_output(ms: int, /) -> None: ... def doupdate() -> None: ... - def echo(__flag: bool = True) -> None: ... + def echo(flag: bool = True, /) -> None: ... def endwin() -> None: ... def erasechar() -> bytes: ... def filter() -> None: ... @@ -295,82 +295,83 @@ if sys.platform != "win32": def getmouse() -> tuple[int, int, int, int, int]: ... def getsyx() -> tuple[int, int]: ... - def getwin(__file: SupportsRead[bytes]) -> _CursesWindow: ... - def halfdelay(__tenths: int) -> None: ... + def getwin(file: SupportsRead[bytes], /) -> _CursesWindow: ... + def halfdelay(tenths: int, /) -> None: ... def has_colors() -> bool: ... if sys.version_info >= (3, 10): def has_extended_color_support() -> bool: ... def has_ic() -> bool: ... def has_il() -> bool: ... - def has_key(__key: int) -> bool: ... - def init_color(__color_number: int, __r: int, __g: int, __b: int) -> None: ... - def init_pair(__pair_number: int, __fg: int, __bg: int) -> None: ... + def has_key(key: int, /) -> bool: ... + def init_color(color_number: int, r: int, g: int, b: int, /) -> None: ... + def init_pair(pair_number: int, fg: int, bg: int, /) -> None: ... def initscr() -> _CursesWindow: ... - def intrflush(__flag: bool) -> None: ... - def is_term_resized(__nlines: int, __ncols: int) -> bool: ... + def intrflush(flag: bool, /) -> None: ... + def is_term_resized(nlines: int, ncols: int, /) -> bool: ... def isendwin() -> bool: ... - def keyname(__key: int) -> bytes: ... + def keyname(key: int, /) -> bytes: ... def killchar() -> bytes: ... def longname() -> bytes: ... - def meta(__yes: bool) -> None: ... - def mouseinterval(__interval: int) -> None: ... - def mousemask(__newmask: int) -> tuple[int, int]: ... - def napms(__ms: int) -> int: ... - def newpad(__nlines: int, __ncols: int) -> _CursesWindow: ... - def newwin(__nlines: int, __ncols: int, __begin_y: int = ..., __begin_x: int = ...) -> _CursesWindow: ... - def nl(__flag: bool = True) -> None: ... + def meta(yes: bool, /) -> None: ... + def mouseinterval(interval: int, /) -> None: ... + def mousemask(newmask: int, /) -> tuple[int, int]: ... + def napms(ms: int, /) -> int: ... + def newpad(nlines: int, ncols: int, /) -> _CursesWindow: ... + def newwin(nlines: int, ncols: int, begin_y: int = ..., begin_x: int = ..., /) -> _CursesWindow: ... + def nl(flag: bool = True, /) -> None: ... def nocbreak() -> None: ... def noecho() -> None: ... def nonl() -> None: ... def noqiflush() -> None: ... def noraw() -> None: ... - def pair_content(__pair_number: int) -> tuple[int, int]: ... - def pair_number(__attr: int) -> int: ... - def putp(__string: ReadOnlyBuffer) -> None: ... - def qiflush(__flag: bool = True) -> None: ... - def raw(__flag: bool = True) -> None: ... + def pair_content(pair_number: int, /) -> tuple[int, int]: ... + def pair_number(attr: int, /) -> int: ... + def putp(string: ReadOnlyBuffer, /) -> None: ... + def qiflush(flag: bool = True, /) -> None: ... + def raw(flag: bool = True, /) -> None: ... def reset_prog_mode() -> None: ... def reset_shell_mode() -> None: ... def resetty() -> None: ... - def resize_term(__nlines: int, __ncols: int) -> None: ... - def resizeterm(__nlines: int, __ncols: int) -> None: ... + def resize_term(nlines: int, ncols: int, /) -> None: ... + def resizeterm(nlines: int, ncols: int, /) -> None: ... def savetty() -> None: ... if sys.version_info >= (3, 9): - def set_escdelay(__ms: int) -> None: ... - def set_tabsize(__size: int) -> None: ... + def set_escdelay(ms: int, /) -> None: ... + def set_tabsize(size: int, /) -> None: ... - def setsyx(__y: int, __x: int) -> None: ... + def setsyx(y: int, x: int, /) -> None: ... def setupterm(term: str | None = None, fd: int = -1) -> None: ... def start_color() -> None: ... def termattrs() -> int: ... def termname() -> bytes: ... - def tigetflag(__capname: str) -> int: ... - def tigetnum(__capname: str) -> int: ... - def tigetstr(__capname: str) -> bytes | None: ... + def tigetflag(capname: str, /) -> int: ... + def tigetnum(capname: str, /) -> int: ... + def tigetstr(capname: str, /) -> bytes | None: ... def tparm( - __str: ReadOnlyBuffer, - __i1: int = 0, - __i2: int = 0, - __i3: int = 0, - __i4: int = 0, - __i5: int = 0, - __i6: int = 0, - __i7: int = 0, - __i8: int = 0, - __i9: int = 0, + str: ReadOnlyBuffer, + i1: int = 0, + i2: int = 0, + i3: int = 0, + i4: int = 0, + i5: int = 0, + i6: int = 0, + i7: int = 0, + i8: int = 0, + i9: int = 0, + /, ) -> bytes: ... - def typeahead(__fd: int) -> None: ... - def unctrl(__ch: _ChType) -> bytes: ... + def typeahead(fd: int, /) -> None: ... + def unctrl(ch: _ChType, /) -> bytes: ... if sys.version_info < (3, 12) or sys.platform != "darwin": # The support for macos was dropped in 3.12 - def unget_wch(__ch: int | str) -> None: ... + def unget_wch(ch: int | str, /) -> None: ... - def ungetch(__ch: _ChType) -> None: ... - def ungetmouse(__id: int, __x: int, __y: int, __z: int, __bstate: int) -> None: ... + def ungetch(ch: _ChType, /) -> None: ... + def ungetmouse(id: int, x: int, y: int, z: int, bstate: int, /) -> None: ... def update_lines_cols() -> None: ... def use_default_colors() -> None: ... - def use_env(__flag: bool) -> None: ... + def use_env(flag: bool, /) -> None: ... class error(Exception): ... @@ -389,11 +390,11 @@ if sys.platform != "win32": def addstr(self, str: str, attr: int = ...) -> None: ... @overload def addstr(self, y: int, x: int, str: str, attr: int = ...) -> None: ... - def attroff(self, __attr: int) -> None: ... - def attron(self, __attr: int) -> None: ... - def attrset(self, __attr: int) -> None: ... - def bkgd(self, __ch: _ChType, __attr: int = ...) -> None: ... - def bkgdset(self, __ch: _ChType, __attr: int = ...) -> None: ... + def attroff(self, attr: int, /) -> None: ... + def attron(self, attr: int, /) -> None: ... + def attrset(self, attr: int, /) -> None: ... + def bkgd(self, ch: _ChType, attr: int = ..., /) -> None: ... + def bkgdset(self, ch: _ChType, attr: int = ..., /) -> None: ... def border( self, ls: _ChType = ..., @@ -431,8 +432,8 @@ if sys.platform != "win32": def derwin(self, begin_y: int, begin_x: int) -> _CursesWindow: ... @overload def derwin(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... - def echochar(self, __ch: _ChType, __attr: int = ...) -> None: ... - def enclose(self, __y: int, __x: int) -> bool: ... + def echochar(self, ch: _ChType, attr: int = ..., /) -> None: ... + def enclose(self, y: int, x: int, /) -> bool: ... def erase(self) -> None: ... def getbegyx(self) -> tuple[int, int]: ... def getbkgd(self) -> tuple[int, int]: ... @@ -491,7 +492,7 @@ if sys.platform != "win32": def instr(self, n: int = ...) -> bytes: ... @overload def instr(self, y: int, x: int, n: int = ...) -> bytes: ... - def is_linetouched(self, __line: int) -> bool: ... + def is_linetouched(self, line: int, /) -> bool: ... def is_wintouched(self) -> bool: ... def keypad(self, yes: bool) -> None: ... def leaveok(self, yes: bool) -> None: ... @@ -516,8 +517,8 @@ if sys.platform != "win32": def overwrite( self, destwin: _CursesWindow, sminrow: int, smincol: int, dminrow: int, dmincol: int, dmaxrow: int, dmaxcol: int ) -> None: ... - def putwin(self, __file: IO[Any]) -> None: ... - def redrawln(self, __beg: int, __num: int) -> None: ... + def putwin(self, file: IO[Any], /) -> None: ... + def redrawln(self, beg: int, num: int, /) -> None: ... def redrawwin(self) -> None: ... @overload def refresh(self) -> None: ... @@ -526,7 +527,7 @@ if sys.platform != "win32": def resize(self, nlines: int, ncols: int) -> None: ... def scroll(self, lines: int = ...) -> None: ... def scrollok(self, flag: bool) -> None: ... - def setscrreg(self, __top: int, __bottom: int) -> None: ... + def setscrreg(self, top: int, bottom: int, /) -> None: ... def standend(self) -> None: ... def standout(self) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/_decimal.pyi b/mypy/typeshed/stdlib/_decimal.pyi index 369d04cd2d5d..90d16215c280 100644 --- a/mypy/typeshed/stdlib/_decimal.pyi +++ b/mypy/typeshed/stdlib/_decimal.pyi @@ -47,7 +47,7 @@ class Overflow(Inexact, Rounded): ... class Underflow(Inexact, Rounded, Subnormal): ... class FloatOperation(DecimalException, TypeError): ... -def setcontext(__context: Context) -> None: ... +def setcontext(context: Context, /) -> None: ... def getcontext() -> Context: ... if sys.version_info >= (3, 11): @@ -70,7 +70,7 @@ else: class Decimal: def __new__(cls, value: _DecimalNew = ..., context: Context | None = ...) -> Self: ... @classmethod - def from_float(cls, __f: float) -> Self: ... + def from_float(cls, f: float, /) -> Self: ... def __bool__(self) -> bool: ... def compare(self, other: _Decimal, context: Context | None = None) -> Decimal: ... def __hash__(self) -> int: ... @@ -78,28 +78,28 @@ class Decimal: def as_integer_ratio(self) -> tuple[int, int]: ... def to_eng_string(self, context: Context | None = None) -> str: ... def __abs__(self) -> Decimal: ... - def __add__(self, __value: _Decimal) -> Decimal: ... - def __divmod__(self, __value: _Decimal) -> tuple[Decimal, Decimal]: ... - def __eq__(self, __value: object) -> bool: ... - def __floordiv__(self, __value: _Decimal) -> Decimal: ... - def __ge__(self, __value: _ComparableNum) -> bool: ... - def __gt__(self, __value: _ComparableNum) -> bool: ... - def __le__(self, __value: _ComparableNum) -> bool: ... - def __lt__(self, __value: _ComparableNum) -> bool: ... - def __mod__(self, __value: _Decimal) -> Decimal: ... - def __mul__(self, __value: _Decimal) -> Decimal: ... + def __add__(self, value: _Decimal, /) -> Decimal: ... + def __divmod__(self, value: _Decimal, /) -> tuple[Decimal, Decimal]: ... + def __eq__(self, value: object, /) -> bool: ... + def __floordiv__(self, value: _Decimal, /) -> Decimal: ... + def __ge__(self, value: _ComparableNum, /) -> bool: ... + def __gt__(self, value: _ComparableNum, /) -> bool: ... + def __le__(self, value: _ComparableNum, /) -> bool: ... + def __lt__(self, value: _ComparableNum, /) -> bool: ... + def __mod__(self, value: _Decimal, /) -> Decimal: ... + def __mul__(self, value: _Decimal, /) -> Decimal: ... def __neg__(self) -> Decimal: ... def __pos__(self) -> Decimal: ... - def __pow__(self, __value: _Decimal, __mod: _Decimal | None = None) -> Decimal: ... - def __radd__(self, __value: _Decimal) -> Decimal: ... - def __rdivmod__(self, __value: _Decimal) -> tuple[Decimal, Decimal]: ... - def __rfloordiv__(self, __value: _Decimal) -> Decimal: ... - def __rmod__(self, __value: _Decimal) -> Decimal: ... - def __rmul__(self, __value: _Decimal) -> Decimal: ... - def __rsub__(self, __value: _Decimal) -> Decimal: ... - def __rtruediv__(self, __value: _Decimal) -> Decimal: ... - def __sub__(self, __value: _Decimal) -> Decimal: ... - def __truediv__(self, __value: _Decimal) -> Decimal: ... + def __pow__(self, value: _Decimal, mod: _Decimal | None = None, /) -> Decimal: ... + def __radd__(self, value: _Decimal, /) -> Decimal: ... + def __rdivmod__(self, value: _Decimal, /) -> tuple[Decimal, Decimal]: ... + def __rfloordiv__(self, value: _Decimal, /) -> Decimal: ... + def __rmod__(self, value: _Decimal, /) -> Decimal: ... + def __rmul__(self, value: _Decimal, /) -> Decimal: ... + def __rsub__(self, value: _Decimal, /) -> Decimal: ... + def __rtruediv__(self, value: _Decimal, /) -> Decimal: ... + def __sub__(self, value: _Decimal, /) -> Decimal: ... + def __truediv__(self, value: _Decimal, /) -> Decimal: ... def remainder_near(self, other: _Decimal, context: Context | None = None) -> Decimal: ... def __float__(self) -> float: ... def __int__(self) -> int: ... @@ -113,11 +113,11 @@ class Decimal: @overload def __round__(self) -> int: ... @overload - def __round__(self, __ndigits: int) -> Decimal: ... + def __round__(self, ndigits: int, /) -> Decimal: ... def __floor__(self) -> int: ... def __ceil__(self) -> int: ... def fma(self, other: _Decimal, third: _Decimal, context: Context | None = None) -> Decimal: ... - def __rpow__(self, __value: _Decimal, __mod: Context | None = None) -> Decimal: ... + def __rpow__(self, value: _Decimal, mod: Context | None = None, /) -> Decimal: ... def normalize(self, context: Context | None = None) -> Decimal: ... def quantize(self, exp: _Decimal, rounding: str | None = None, context: Context | None = None) -> Decimal: ... def same_quantum(self, other: _Decimal, context: Context | None = None) -> bool: ... @@ -165,8 +165,8 @@ class Decimal: def shift(self, other: _Decimal, context: Context | None = None) -> Decimal: ... def __reduce__(self) -> tuple[type[Self], tuple[str]]: ... def __copy__(self) -> Self: ... - def __deepcopy__(self, __memo: Any) -> Self: ... - def __format__(self, __specifier: str, __context: Context | None = ...) -> str: ... + def __deepcopy__(self, memo: Any, /) -> Self: ... + def __format__(self, specifier: str, context: Context | None = ..., /) -> str: ... class _ContextManager: new_context: Context @@ -182,7 +182,7 @@ class Context: # even settable attributes like `prec` and `rounding`, # but that's inexpressable in the stub. # Type checkers either ignore it or misinterpret it - # if you add a `def __delattr__(self, __name: str) -> NoReturn` method to the stub + # if you add a `def __delattr__(self, name: str, /) -> NoReturn` method to the stub prec: int rounding: str Emin: int @@ -212,69 +212,69 @@ class Context: __hash__: ClassVar[None] # type: ignore[assignment] def Etiny(self) -> int: ... def Etop(self) -> int: ... - def create_decimal(self, __num: _DecimalNew = "0") -> Decimal: ... - def create_decimal_from_float(self, __f: float) -> Decimal: ... - def abs(self, __x: _Decimal) -> Decimal: ... - def add(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def canonical(self, __x: Decimal) -> Decimal: ... - def compare(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def compare_signal(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def compare_total(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def compare_total_mag(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def copy_abs(self, __x: _Decimal) -> Decimal: ... - def copy_decimal(self, __x: _Decimal) -> Decimal: ... - def copy_negate(self, __x: _Decimal) -> Decimal: ... - def copy_sign(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def divide(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def divide_int(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def divmod(self, __x: _Decimal, __y: _Decimal) -> tuple[Decimal, Decimal]: ... - def exp(self, __x: _Decimal) -> Decimal: ... - def fma(self, __x: _Decimal, __y: _Decimal, __z: _Decimal) -> Decimal: ... - def is_canonical(self, __x: _Decimal) -> bool: ... - def is_finite(self, __x: _Decimal) -> bool: ... - def is_infinite(self, __x: _Decimal) -> bool: ... - def is_nan(self, __x: _Decimal) -> bool: ... - def is_normal(self, __x: _Decimal) -> bool: ... - def is_qnan(self, __x: _Decimal) -> bool: ... - def is_signed(self, __x: _Decimal) -> bool: ... - def is_snan(self, __x: _Decimal) -> bool: ... - def is_subnormal(self, __x: _Decimal) -> bool: ... - def is_zero(self, __x: _Decimal) -> bool: ... - def ln(self, __x: _Decimal) -> Decimal: ... - def log10(self, __x: _Decimal) -> Decimal: ... - def logb(self, __x: _Decimal) -> Decimal: ... - def logical_and(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def logical_invert(self, __x: _Decimal) -> Decimal: ... - def logical_or(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def logical_xor(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def max(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def max_mag(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def min(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def min_mag(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def minus(self, __x: _Decimal) -> Decimal: ... - def multiply(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def next_minus(self, __x: _Decimal) -> Decimal: ... - def next_plus(self, __x: _Decimal) -> Decimal: ... - def next_toward(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def normalize(self, __x: _Decimal) -> Decimal: ... - def number_class(self, __x: _Decimal) -> str: ... - def plus(self, __x: _Decimal) -> Decimal: ... + def create_decimal(self, num: _DecimalNew = "0", /) -> Decimal: ... + def create_decimal_from_float(self, f: float, /) -> Decimal: ... + def abs(self, x: _Decimal, /) -> Decimal: ... + def add(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def canonical(self, x: Decimal, /) -> Decimal: ... + def compare(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def compare_signal(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def compare_total(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def compare_total_mag(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def copy_abs(self, x: _Decimal, /) -> Decimal: ... + def copy_decimal(self, x: _Decimal, /) -> Decimal: ... + def copy_negate(self, x: _Decimal, /) -> Decimal: ... + def copy_sign(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def divide(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def divide_int(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def divmod(self, x: _Decimal, y: _Decimal, /) -> tuple[Decimal, Decimal]: ... + def exp(self, x: _Decimal, /) -> Decimal: ... + def fma(self, x: _Decimal, y: _Decimal, z: _Decimal, /) -> Decimal: ... + def is_canonical(self, x: _Decimal, /) -> bool: ... + def is_finite(self, x: _Decimal, /) -> bool: ... + def is_infinite(self, x: _Decimal, /) -> bool: ... + def is_nan(self, x: _Decimal, /) -> bool: ... + def is_normal(self, x: _Decimal, /) -> bool: ... + def is_qnan(self, x: _Decimal, /) -> bool: ... + def is_signed(self, x: _Decimal, /) -> bool: ... + def is_snan(self, x: _Decimal, /) -> bool: ... + def is_subnormal(self, x: _Decimal, /) -> bool: ... + def is_zero(self, x: _Decimal, /) -> bool: ... + def ln(self, x: _Decimal, /) -> Decimal: ... + def log10(self, x: _Decimal, /) -> Decimal: ... + def logb(self, x: _Decimal, /) -> Decimal: ... + def logical_and(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def logical_invert(self, x: _Decimal, /) -> Decimal: ... + def logical_or(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def logical_xor(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def max(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def max_mag(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def min(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def min_mag(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def minus(self, x: _Decimal, /) -> Decimal: ... + def multiply(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def next_minus(self, x: _Decimal, /) -> Decimal: ... + def next_plus(self, x: _Decimal, /) -> Decimal: ... + def next_toward(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def normalize(self, x: _Decimal, /) -> Decimal: ... + def number_class(self, x: _Decimal, /) -> str: ... + def plus(self, x: _Decimal, /) -> Decimal: ... def power(self, a: _Decimal, b: _Decimal, modulo: _Decimal | None = None) -> Decimal: ... - def quantize(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... + def quantize(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... def radix(self) -> Decimal: ... - def remainder(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def remainder_near(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def rotate(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def same_quantum(self, __x: _Decimal, __y: _Decimal) -> bool: ... - def scaleb(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def shift(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def sqrt(self, __x: _Decimal) -> Decimal: ... - def subtract(self, __x: _Decimal, __y: _Decimal) -> Decimal: ... - def to_eng_string(self, __x: _Decimal) -> str: ... - def to_sci_string(self, __x: _Decimal) -> str: ... - def to_integral_exact(self, __x: _Decimal) -> Decimal: ... - def to_integral_value(self, __x: _Decimal) -> Decimal: ... - def to_integral(self, __x: _Decimal) -> Decimal: ... + def remainder(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def remainder_near(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def rotate(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def same_quantum(self, x: _Decimal, y: _Decimal, /) -> bool: ... + def scaleb(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def shift(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def sqrt(self, x: _Decimal, /) -> Decimal: ... + def subtract(self, x: _Decimal, y: _Decimal, /) -> Decimal: ... + def to_eng_string(self, x: _Decimal, /) -> str: ... + def to_sci_string(self, x: _Decimal, /) -> str: ... + def to_integral_exact(self, x: _Decimal, /) -> Decimal: ... + def to_integral_value(self, x: _Decimal, /) -> Decimal: ... + def to_integral(self, x: _Decimal, /) -> Decimal: ... DefaultContext: Context BasicContext: Context diff --git a/mypy/typeshed/stdlib/_heapq.pyi b/mypy/typeshed/stdlib/_heapq.pyi index 28b03a75d4c7..9f731bf91eef 100644 --- a/mypy/typeshed/stdlib/_heapq.pyi +++ b/mypy/typeshed/stdlib/_heapq.pyi @@ -4,8 +4,8 @@ _T = TypeVar("_T") __about__: Final[str] -def heapify(__heap: list[Any]) -> None: ... -def heappop(__heap: list[_T]) -> _T: ... -def heappush(__heap: list[_T], __item: _T) -> None: ... -def heappushpop(__heap: list[_T], __item: _T) -> _T: ... -def heapreplace(__heap: list[_T], __item: _T) -> _T: ... +def heapify(heap: list[Any], /) -> None: ... +def heappop(heap: list[_T], /) -> _T: ... +def heappush(heap: list[_T], item: _T, /) -> None: ... +def heappushpop(heap: list[_T], item: _T, /) -> _T: ... +def heapreplace(heap: list[_T], item: _T, /) -> _T: ... diff --git a/mypy/typeshed/stdlib/_imp.pyi b/mypy/typeshed/stdlib/_imp.pyi index adab2e803efe..de3549a91da5 100644 --- a/mypy/typeshed/stdlib/_imp.pyi +++ b/mypy/typeshed/stdlib/_imp.pyi @@ -7,22 +7,22 @@ from typing import Any check_hash_based_pycs: str def source_hash(key: int, source: ReadableBuffer) -> bytes: ... -def create_builtin(__spec: ModuleSpec) -> types.ModuleType: ... -def create_dynamic(__spec: ModuleSpec, __file: Any = None) -> types.ModuleType: ... +def create_builtin(spec: ModuleSpec, /) -> types.ModuleType: ... +def create_dynamic(spec: ModuleSpec, file: Any = None, /) -> types.ModuleType: ... def acquire_lock() -> None: ... -def exec_builtin(__mod: types.ModuleType) -> int: ... -def exec_dynamic(__mod: types.ModuleType) -> int: ... +def exec_builtin(mod: types.ModuleType, /) -> int: ... +def exec_dynamic(mod: types.ModuleType, /) -> int: ... def extension_suffixes() -> list[str]: ... -def init_frozen(__name: str) -> types.ModuleType: ... -def is_builtin(__name: str) -> int: ... -def is_frozen(__name: str) -> bool: ... -def is_frozen_package(__name: str) -> bool: ... +def init_frozen(name: str, /) -> types.ModuleType: ... +def is_builtin(name: str, /) -> int: ... +def is_frozen(name: str, /) -> bool: ... +def is_frozen_package(name: str, /) -> bool: ... def lock_held() -> bool: ... def release_lock() -> None: ... if sys.version_info >= (3, 11): - def find_frozen(__name: str, *, withdata: bool = False) -> tuple[memoryview | None, bool, str | None] | None: ... - def get_frozen_object(__name: str, __data: ReadableBuffer | None = None) -> types.CodeType: ... + def find_frozen(name: str, /, *, withdata: bool = False) -> tuple[memoryview | None, bool, str | None] | None: ... + def get_frozen_object(name: str, data: ReadableBuffer | None = None, /) -> types.CodeType: ... else: - def get_frozen_object(__name: str) -> types.CodeType: ... + def get_frozen_object(name: str, /) -> types.CodeType: ... diff --git a/mypy/typeshed/stdlib/_locale.pyi b/mypy/typeshed/stdlib/_locale.pyi index d7399f15e1a3..0825e12034f4 100644 --- a/mypy/typeshed/stdlib/_locale.pyi +++ b/mypy/typeshed/stdlib/_locale.pyi @@ -10,14 +10,14 @@ LC_NUMERIC: int LC_ALL: int CHAR_MAX: int -def setlocale(__category: int, __locale: str | None = None) -> str: ... +def setlocale(category: int, locale: str | None = None, /) -> str: ... def localeconv() -> Mapping[str, int | str | list[int]]: ... if sys.version_info >= (3, 11): def getencoding() -> str: ... -def strcoll(__os1: str, __os2: str) -> int: ... -def strxfrm(__string: str) -> str: ... +def strcoll(os1: str, os2: str, /) -> int: ... +def strxfrm(string: str, /) -> str: ... # native gettext functions # https://docs.python.org/3/library/locale.html#access-to-message-catalogs @@ -87,14 +87,14 @@ if sys.platform != "win32": CRNCYSTR: int ALT_DIGITS: int - def nl_langinfo(__key: int) -> str: ... + def nl_langinfo(key: int, /) -> str: ... # This is dependent on `libintl.h` which is a part of `gettext` # system dependency. These functions might be missing. # But, we always say that they are present. - def gettext(__msg: str) -> str: ... - def dgettext(__domain: str | None, __msg: str) -> str: ... - def dcgettext(__domain: str | None, __msg: str, __category: int) -> str: ... - def textdomain(__domain: str | None) -> str: ... - def bindtextdomain(__domain: str, __dir: StrPath | None) -> str: ... - def bind_textdomain_codeset(__domain: str, __codeset: str | None) -> str | None: ... + def gettext(msg: str, /) -> str: ... + def dgettext(domain: str | None, msg: str, /) -> str: ... + def dcgettext(domain: str | None, msg: str, category: int, /) -> str: ... + def textdomain(domain: str | None, /) -> str: ... + def bindtextdomain(domain: str, dir: StrPath | None, /) -> str: ... + def bind_textdomain_codeset(domain: str, codeset: str | None, /) -> str | None: ... diff --git a/mypy/typeshed/stdlib/_msi.pyi b/mypy/typeshed/stdlib/_msi.pyi index 22239cbfff04..779fda3b67fe 100644 --- a/mypy/typeshed/stdlib/_msi.pyi +++ b/mypy/typeshed/stdlib/_msi.pyi @@ -47,9 +47,9 @@ if sys.platform == "win32": __init__: None # type: ignore[assignment] def UuidCreate() -> str: ... - def FCICreate(__cabname: str, __files: list[str]) -> None: ... - def OpenDatabase(__path: str, __persist: int) -> _Database: ... - def CreateRecord(__count: int) -> _Record: ... + def FCICreate(cabname: str, files: list[str], /) -> None: ... + def OpenDatabase(path: str, persist: int, /) -> _Database: ... + def CreateRecord(count: int, /) -> _Record: ... MSICOLINFO_NAMES: int MSICOLINFO_TYPES: int diff --git a/mypy/typeshed/stdlib/_operator.pyi b/mypy/typeshed/stdlib/_operator.pyi index 9b24e086adff..69ee563b5cf4 100644 --- a/mypy/typeshed/stdlib/_operator.pyi +++ b/mypy/typeshed/stdlib/_operator.pyi @@ -19,16 +19,16 @@ _Ts = TypeVarTuple("_Ts") # the numpy.array comparison dunders return another numpy.array. class _SupportsDunderLT(Protocol): - def __lt__(self, __other: Any) -> Any: ... + def __lt__(self, other: Any, /) -> Any: ... class _SupportsDunderGT(Protocol): - def __gt__(self, __other: Any) -> Any: ... + def __gt__(self, other: Any, /) -> Any: ... class _SupportsDunderLE(Protocol): - def __le__(self, __other: Any) -> Any: ... + def __le__(self, other: Any, /) -> Any: ... class _SupportsDunderGE(Protocol): - def __ge__(self, __other: Any) -> Any: ... + def __ge__(self, other: Any, /) -> Any: ... _SupportsComparison: TypeAlias = _SupportsDunderLE | _SupportsDunderGE | _SupportsDunderGT | _SupportsDunderLT @@ -42,56 +42,56 @@ class _SupportsPos(Protocol[_T_co]): def __pos__(self) -> _T_co: ... # All four comparison functions must have the same signature, or we get false-positive errors -def lt(__a: _SupportsComparison, __b: _SupportsComparison) -> Any: ... -def le(__a: _SupportsComparison, __b: _SupportsComparison) -> Any: ... -def eq(__a: object, __b: object) -> Any: ... -def ne(__a: object, __b: object) -> Any: ... -def ge(__a: _SupportsComparison, __b: _SupportsComparison) -> Any: ... -def gt(__a: _SupportsComparison, __b: _SupportsComparison) -> Any: ... -def not_(__a: object) -> bool: ... -def truth(__a: object) -> bool: ... -def is_(__a: object, __b: object) -> bool: ... -def is_not(__a: object, __b: object) -> bool: ... -def abs(__a: SupportsAbs[_T]) -> _T: ... -def add(__a: Any, __b: Any) -> Any: ... -def and_(__a: Any, __b: Any) -> Any: ... -def floordiv(__a: Any, __b: Any) -> Any: ... -def index(__a: SupportsIndex) -> int: ... -def inv(__a: _SupportsInversion[_T_co]) -> _T_co: ... -def invert(__a: _SupportsInversion[_T_co]) -> _T_co: ... -def lshift(__a: Any, __b: Any) -> Any: ... -def mod(__a: Any, __b: Any) -> Any: ... -def mul(__a: Any, __b: Any) -> Any: ... -def matmul(__a: Any, __b: Any) -> Any: ... -def neg(__a: _SupportsNeg[_T_co]) -> _T_co: ... -def or_(__a: Any, __b: Any) -> Any: ... -def pos(__a: _SupportsPos[_T_co]) -> _T_co: ... -def pow(__a: Any, __b: Any) -> Any: ... -def rshift(__a: Any, __b: Any) -> Any: ... -def sub(__a: Any, __b: Any) -> Any: ... -def truediv(__a: Any, __b: Any) -> Any: ... -def xor(__a: Any, __b: Any) -> Any: ... -def concat(__a: Sequence[_T], __b: Sequence[_T]) -> Sequence[_T]: ... -def contains(__a: Container[object], __b: object) -> bool: ... -def countOf(__a: Iterable[object], __b: object) -> int: ... +def lt(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... +def le(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... +def eq(a: object, b: object, /) -> Any: ... +def ne(a: object, b: object, /) -> Any: ... +def ge(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... +def gt(a: _SupportsComparison, b: _SupportsComparison, /) -> Any: ... +def not_(a: object, /) -> bool: ... +def truth(a: object, /) -> bool: ... +def is_(a: object, b: object, /) -> bool: ... +def is_not(a: object, b: object, /) -> bool: ... +def abs(a: SupportsAbs[_T], /) -> _T: ... +def add(a: Any, b: Any, /) -> Any: ... +def and_(a: Any, b: Any, /) -> Any: ... +def floordiv(a: Any, b: Any, /) -> Any: ... +def index(a: SupportsIndex, /) -> int: ... +def inv(a: _SupportsInversion[_T_co], /) -> _T_co: ... +def invert(a: _SupportsInversion[_T_co], /) -> _T_co: ... +def lshift(a: Any, b: Any, /) -> Any: ... +def mod(a: Any, b: Any, /) -> Any: ... +def mul(a: Any, b: Any, /) -> Any: ... +def matmul(a: Any, b: Any, /) -> Any: ... +def neg(a: _SupportsNeg[_T_co], /) -> _T_co: ... +def or_(a: Any, b: Any, /) -> Any: ... +def pos(a: _SupportsPos[_T_co], /) -> _T_co: ... +def pow(a: Any, b: Any, /) -> Any: ... +def rshift(a: Any, b: Any, /) -> Any: ... +def sub(a: Any, b: Any, /) -> Any: ... +def truediv(a: Any, b: Any, /) -> Any: ... +def xor(a: Any, b: Any, /) -> Any: ... +def concat(a: Sequence[_T], b: Sequence[_T], /) -> Sequence[_T]: ... +def contains(a: Container[object], b: object, /) -> bool: ... +def countOf(a: Iterable[object], b: object, /) -> int: ... @overload -def delitem(__a: MutableSequence[Any], __b: SupportsIndex) -> None: ... +def delitem(a: MutableSequence[Any], b: SupportsIndex, /) -> None: ... @overload -def delitem(__a: MutableSequence[Any], __b: slice) -> None: ... +def delitem(a: MutableSequence[Any], b: slice, /) -> None: ... @overload -def delitem(__a: MutableMapping[_K, Any], __b: _K) -> None: ... +def delitem(a: MutableMapping[_K, Any], b: _K, /) -> None: ... @overload -def getitem(__a: Sequence[_T], __b: slice) -> Sequence[_T]: ... +def getitem(a: Sequence[_T], b: slice, /) -> Sequence[_T]: ... @overload -def getitem(__a: SupportsGetItem[_K, _V], __b: _K) -> _V: ... -def indexOf(__a: Iterable[_T], __b: _T) -> int: ... +def getitem(a: SupportsGetItem[_K, _V], b: _K, /) -> _V: ... +def indexOf(a: Iterable[_T], b: _T, /) -> int: ... @overload -def setitem(__a: MutableSequence[_T], __b: SupportsIndex, __c: _T) -> None: ... +def setitem(a: MutableSequence[_T], b: SupportsIndex, c: _T, /) -> None: ... @overload -def setitem(__a: MutableSequence[_T], __b: slice, __c: Sequence[_T]) -> None: ... +def setitem(a: MutableSequence[_T], b: slice, c: Sequence[_T], /) -> None: ... @overload -def setitem(__a: MutableMapping[_K, _V], __b: _K, __c: _V) -> None: ... -def length_hint(__obj: object, __default: int = 0) -> int: ... +def setitem(a: MutableMapping[_K, _V], b: _K, c: _V, /) -> None: ... +def length_hint(obj: object, default: int = 0, /) -> int: ... @final class attrgetter(Generic[_T_co]): @overload @@ -109,9 +109,9 @@ class attrgetter(Generic[_T_co]): @final class itemgetter(Generic[_T_co]): @overload - def __new__(cls, __item: _T) -> itemgetter[_T]: ... + def __new__(cls, item: _T, /) -> itemgetter[_T]: ... @overload - def __new__(cls, __item1: _T1, __item2: _T2, *items: Unpack[_Ts]) -> itemgetter[tuple[_T1, _T2, Unpack[_Ts]]]: ... + 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" @@ -123,25 +123,25 @@ class itemgetter(Generic[_T_co]): @final class methodcaller: - def __init__(self, __name: str, *args: Any, **kwargs: Any) -> None: ... + def __init__(self, name: str, /, *args: Any, **kwargs: Any) -> None: ... def __call__(self, obj: Any) -> Any: ... -def iadd(__a: Any, __b: Any) -> Any: ... -def iand(__a: Any, __b: Any) -> Any: ... -def iconcat(__a: Any, __b: Any) -> Any: ... -def ifloordiv(__a: Any, __b: Any) -> Any: ... -def ilshift(__a: Any, __b: Any) -> Any: ... -def imod(__a: Any, __b: Any) -> Any: ... -def imul(__a: Any, __b: Any) -> Any: ... -def imatmul(__a: Any, __b: Any) -> Any: ... -def ior(__a: Any, __b: Any) -> Any: ... -def ipow(__a: Any, __b: Any) -> Any: ... -def irshift(__a: Any, __b: Any) -> Any: ... -def isub(__a: Any, __b: Any) -> Any: ... -def itruediv(__a: Any, __b: Any) -> Any: ... -def ixor(__a: Any, __b: Any) -> Any: ... +def iadd(a: Any, b: Any, /) -> Any: ... +def iand(a: Any, b: Any, /) -> Any: ... +def iconcat(a: Any, b: Any, /) -> Any: ... +def ifloordiv(a: Any, b: Any, /) -> Any: ... +def ilshift(a: Any, b: Any, /) -> Any: ... +def imod(a: Any, b: Any, /) -> Any: ... +def imul(a: Any, b: Any, /) -> Any: ... +def imatmul(a: Any, b: Any, /) -> Any: ... +def ior(a: Any, b: Any, /) -> Any: ... +def ipow(a: Any, b: Any, /) -> Any: ... +def irshift(a: Any, b: Any, /) -> Any: ... +def isub(a: Any, b: Any, /) -> Any: ... +def itruediv(a: Any, b: Any, /) -> Any: ... +def ixor(a: Any, b: Any, /) -> Any: ... if sys.version_info >= (3, 11): - def call(__obj: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... + def call(obj: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... -def _compare_digest(__a: AnyStr, __b: AnyStr) -> bool: ... +def _compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/_posixsubprocess.pyi b/mypy/typeshed/stdlib/_posixsubprocess.pyi index 6c1782433e45..3df56d9a3d03 100644 --- a/mypy/typeshed/stdlib/_posixsubprocess.pyi +++ b/mypy/typeshed/stdlib/_posixsubprocess.pyi @@ -6,27 +6,28 @@ from typing import SupportsIndex if sys.platform != "win32": def cloexec_pipe() -> tuple[int, int]: ... def fork_exec( - __args: Sequence[StrOrBytesPath] | None, - __executable_list: Sequence[bytes], - __close_fds: bool, - __pass_fds: tuple[int, ...], - __cwd: str, - __env: Sequence[bytes] | None, - __p2cread: int, - __p2cwrite: int, - __c2pread: int, - __c2pwrite: int, - __errread: int, - __errwrite: int, - __errpipe_read: int, - __errpipe_write: int, - __restore_signals: int, - __call_setsid: int, - __pgid_to_set: int, - __gid: SupportsIndex | None, - __extra_groups: list[int] | None, - __uid: SupportsIndex | None, - __child_umask: int, - __preexec_fn: Callable[[], None], - __allow_vfork: bool, + args: Sequence[StrOrBytesPath] | None, + executable_list: Sequence[bytes], + close_fds: bool, + pass_fds: tuple[int, ...], + cwd: str, + env: Sequence[bytes] | None, + p2cread: int, + p2cwrite: int, + c2pread: int, + c2pwrite: int, + errread: int, + errwrite: int, + errpipe_read: int, + errpipe_write: int, + restore_signals: int, + call_setsid: int, + pgid_to_set: int, + gid: SupportsIndex | None, + extra_groups: list[int] | None, + uid: SupportsIndex | None, + child_umask: int, + preexec_fn: Callable[[], None], + allow_vfork: bool, + /, ) -> int: ... diff --git a/mypy/typeshed/stdlib/_py_abc.pyi b/mypy/typeshed/stdlib/_py_abc.pyi index cc45c6ad3814..1260717489e4 100644 --- a/mypy/typeshed/stdlib/_py_abc.pyi +++ b/mypy/typeshed/stdlib/_py_abc.pyi @@ -9,6 +9,6 @@ def get_cache_token() -> _CacheToken: ... class ABCMeta(type): def __new__( - __mcls: type[_typeshed.Self], __name: str, __bases: tuple[type[Any], ...], __namespace: dict[str, Any] + mcls: type[_typeshed.Self], name: str, bases: tuple[type[Any], ...], namespace: dict[str, Any], / ) -> _typeshed.Self: ... def register(cls, subclass: type[_T]) -> type[_T]: ... diff --git a/mypy/typeshed/stdlib/_random.pyi b/mypy/typeshed/stdlib/_random.pyi index 7c5803ede781..4082344ade8e 100644 --- a/mypy/typeshed/stdlib/_random.pyi +++ b/mypy/typeshed/stdlib/_random.pyi @@ -5,8 +5,8 @@ _State: TypeAlias = tuple[int, ...] class Random: def __init__(self, seed: object = ...) -> None: ... - def seed(self, __n: object = None) -> None: ... + def seed(self, n: object = None, /) -> None: ... def getstate(self) -> _State: ... - def setstate(self, __state: _State) -> None: ... + def setstate(self, state: _State, /) -> None: ... def random(self) -> float: ... - def getrandbits(self, __k: int) -> int: ... + def getrandbits(self, k: int, /) -> int: ... diff --git a/mypy/typeshed/stdlib/_socket.pyi b/mypy/typeshed/stdlib/_socket.pyi index 6471cae2e72d..2a48349d4f7d 100644 --- a/mypy/typeshed/stdlib/_socket.pyi +++ b/mypy/typeshed/stdlib/_socket.pyi @@ -696,70 +696,71 @@ class socket: else: def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: SupportsIndex | None = ...) -> None: ... - def bind(self, __address: _Address) -> None: ... + def bind(self, address: _Address, /) -> None: ... def close(self) -> None: ... - def connect(self, __address: _Address) -> None: ... - def connect_ex(self, __address: _Address) -> int: ... + def connect(self, address: _Address, /) -> None: ... + def connect_ex(self, address: _Address, /) -> int: ... def detach(self) -> int: ... def fileno(self) -> int: ... def getpeername(self) -> _RetAddress: ... def getsockname(self) -> _RetAddress: ... @overload - def getsockopt(self, __level: int, __optname: int) -> int: ... + def getsockopt(self, level: int, optname: int, /) -> int: ... @overload - def getsockopt(self, __level: int, __optname: int, __buflen: int) -> bytes: ... + def getsockopt(self, level: int, optname: int, buflen: int, /) -> bytes: ... def getblocking(self) -> bool: ... def gettimeout(self) -> float | None: ... if sys.platform == "win32": - def ioctl(self, __control: int, __option: int | tuple[int, int, int] | bool) -> None: ... + def ioctl(self, control: int, option: int | tuple[int, int, int] | bool, /) -> None: ... - def listen(self, __backlog: int = ...) -> None: ... - def recv(self, __bufsize: int, __flags: int = ...) -> bytes: ... - def recvfrom(self, __bufsize: int, __flags: int = ...) -> tuple[bytes, _RetAddress]: ... + def listen(self, backlog: int = ..., /) -> None: ... + def recv(self, bufsize: int, flags: int = ..., /) -> bytes: ... + def recvfrom(self, bufsize: int, flags: int = ..., /) -> tuple[bytes, _RetAddress]: ... if sys.platform != "win32": - def recvmsg(self, __bufsize: int, __ancbufsize: int = ..., __flags: int = ...) -> tuple[bytes, list[_CMSG], int, Any]: ... + def recvmsg(self, bufsize: int, ancbufsize: int = ..., flags: int = ..., /) -> tuple[bytes, list[_CMSG], int, Any]: ... def recvmsg_into( - self, __buffers: Iterable[WriteableBuffer], __ancbufsize: int = ..., __flags: int = ... + self, buffers: Iterable[WriteableBuffer], ancbufsize: int = ..., flags: int = ..., / ) -> tuple[int, list[_CMSG], int, Any]: ... def recvfrom_into(self, buffer: WriteableBuffer, nbytes: int = ..., flags: int = ...) -> tuple[int, _RetAddress]: ... def recv_into(self, buffer: WriteableBuffer, nbytes: int = ..., flags: int = ...) -> int: ... - def send(self, __data: ReadableBuffer, __flags: int = ...) -> int: ... - def sendall(self, __data: ReadableBuffer, __flags: int = ...) -> None: ... + def send(self, data: ReadableBuffer, flags: int = ..., /) -> int: ... + def sendall(self, data: ReadableBuffer, flags: int = ..., /) -> None: ... @overload - def sendto(self, __data: ReadableBuffer, __address: _Address) -> int: ... + def sendto(self, data: ReadableBuffer, address: _Address, /) -> int: ... @overload - def sendto(self, __data: ReadableBuffer, __flags: int, __address: _Address) -> int: ... + def sendto(self, data: ReadableBuffer, flags: int, address: _Address, /) -> int: ... if sys.platform != "win32": def sendmsg( self, - __buffers: Iterable[ReadableBuffer], - __ancdata: Iterable[_CMSGArg] = ..., - __flags: int = ..., - __address: _Address | None = ..., + buffers: Iterable[ReadableBuffer], + ancdata: Iterable[_CMSGArg] = ..., + flags: int = ..., + address: _Address | None = ..., + /, ) -> int: ... if sys.platform == "linux": def sendmsg_afalg( self, msg: Iterable[ReadableBuffer] = ..., *, op: int, iv: Any = ..., assoclen: int = ..., flags: int = ... ) -> int: ... - def setblocking(self, __flag: bool) -> None: ... - def settimeout(self, __value: float | None) -> None: ... + def setblocking(self, flag: bool, /) -> None: ... + def settimeout(self, value: float | None, /) -> None: ... @overload - def setsockopt(self, __level: int, __optname: int, __value: int | ReadableBuffer) -> None: ... + def setsockopt(self, level: int, optname: int, value: int | ReadableBuffer, /) -> None: ... @overload - def setsockopt(self, __level: int, __optname: int, __value: None, __optlen: int) -> None: ... + def setsockopt(self, level: int, optname: int, value: None, optlen: int, /) -> None: ... if sys.platform == "win32": - def share(self, __process_id: int) -> bytes: ... + def share(self, process_id: int, /) -> bytes: ... - def shutdown(self, __how: int) -> None: ... + def shutdown(self, how: int, /) -> None: ... SocketType = socket # ===== Functions ===== -def close(__fd: SupportsIndex) -> None: ... -def dup(__fd: SupportsIndex) -> int: ... +def close(fd: SupportsIndex, /) -> None: ... +def dup(fd: SupportsIndex, /) -> int: ... # the 5th tuple item is an address def getaddrinfo( @@ -770,33 +771,33 @@ def getaddrinfo( proto: int = ..., flags: int = ..., ) -> list[tuple[int, int, int, str, tuple[str, int] | tuple[str, int, int, int]]]: ... -def gethostbyname(__hostname: str) -> str: ... -def gethostbyname_ex(__hostname: str) -> tuple[str, list[str], list[str]]: ... +def gethostbyname(hostname: str, /) -> str: ... +def gethostbyname_ex(hostname: str, /) -> tuple[str, list[str], list[str]]: ... def gethostname() -> str: ... -def gethostbyaddr(__ip_address: str) -> tuple[str, list[str], list[str]]: ... -def getnameinfo(__sockaddr: tuple[str, int] | tuple[str, int, int, int], __flags: int) -> tuple[str, str]: ... -def getprotobyname(__protocolname: str) -> int: ... -def getservbyname(__servicename: str, __protocolname: str = ...) -> int: ... -def getservbyport(__port: int, __protocolname: str = ...) -> str: ... -def ntohl(__x: int) -> int: ... # param & ret val are 32-bit ints -def ntohs(__x: int) -> int: ... # param & ret val are 16-bit ints -def htonl(__x: int) -> int: ... # param & ret val are 32-bit ints -def htons(__x: int) -> int: ... # param & ret val are 16-bit ints -def inet_aton(__ip_string: str) -> bytes: ... # ret val 4 bytes in length -def inet_ntoa(__packed_ip: ReadableBuffer) -> str: ... -def inet_pton(__address_family: int, __ip_string: str) -> bytes: ... -def inet_ntop(__address_family: int, __packed_ip: ReadableBuffer) -> str: ... +def gethostbyaddr(ip_address: str, /) -> tuple[str, list[str], list[str]]: ... +def getnameinfo(sockaddr: tuple[str, int] | tuple[str, int, int, int], flags: int, /) -> tuple[str, str]: ... +def getprotobyname(protocolname: str, /) -> int: ... +def getservbyname(servicename: str, protocolname: str = ..., /) -> int: ... +def getservbyport(port: int, protocolname: str = ..., /) -> str: ... +def ntohl(x: int, /) -> int: ... # param & ret val are 32-bit ints +def ntohs(x: int, /) -> int: ... # param & ret val are 16-bit ints +def htonl(x: int, /) -> int: ... # param & ret val are 32-bit ints +def htons(x: int, /) -> int: ... # param & ret val are 16-bit ints +def inet_aton(ip_string: str, /) -> bytes: ... # ret val 4 bytes in length +def inet_ntoa(packed_ip: ReadableBuffer, /) -> str: ... +def inet_pton(address_family: int, ip_string: str, /) -> bytes: ... +def inet_ntop(address_family: int, packed_ip: ReadableBuffer, /) -> str: ... def getdefaulttimeout() -> float | None: ... -def setdefaulttimeout(__timeout: float | None) -> None: ... +def setdefaulttimeout(timeout: float | None, /) -> None: ... if sys.platform != "win32": - def sethostname(__name: str) -> None: ... - def CMSG_LEN(__length: int) -> int: ... - def CMSG_SPACE(__length: int) -> int: ... - def socketpair(__family: int = ..., __type: int = ..., __proto: int = ...) -> tuple[socket, socket]: ... + def sethostname(name: str, /) -> None: ... + def CMSG_LEN(length: int, /) -> int: ... + def CMSG_SPACE(length: int, /) -> int: ... + def socketpair(family: int = ..., type: int = ..., proto: int = ..., /) -> tuple[socket, socket]: ... def if_nameindex() -> list[tuple[int, str]]: ... -def if_nametoindex(__name: str) -> int: ... -def if_indextoname(__index: int) -> str: ... +def if_nametoindex(name: str, /) -> int: ... +def if_indextoname(index: int, /) -> str: ... CAPI: object diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index e69f9d2359aa..4ea9aa0609e5 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -54,6 +54,6 @@ 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: ... + 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/_tkinter.pyi b/mypy/typeshed/stdlib/_tkinter.pyi index 67e7e3f696e2..3340df424163 100644 --- a/mypy/typeshed/stdlib/_tkinter.pyi +++ b/mypy/typeshed/stdlib/_tkinter.pyi @@ -21,12 +21,12 @@ class Tcl_Obj: @property def typename(self) -> str: ... __hash__: ClassVar[None] # type: ignore[assignment] - def __eq__(self, __value): ... - def __ge__(self, __value): ... - def __gt__(self, __value): ... - def __le__(self, __value): ... - def __lt__(self, __value): ... - def __ne__(self, __value): ... + def __eq__(self, value, /): ... + def __ge__(self, value, /): ... + def __gt__(self, value, /): ... + def __le__(self, value, /): ... + def __lt__(self, value, /): ... + def __ne__(self, value, /): ... class TclError(Exception): ... @@ -50,39 +50,39 @@ class TclError(Exception): ... @final class TkappType: # Please keep in sync with tkinter.Tk - def adderrorinfo(self, __msg): ... - def call(self, __command: Any, *args: Any) -> Any: ... - def createcommand(self, __name, __func): ... + def adderrorinfo(self, msg, /): ... + def call(self, command: Any, /, *args: Any) -> Any: ... + def createcommand(self, name, func, /): ... if sys.platform != "win32": - def createfilehandler(self, __file, __mask, __func): ... - def deletefilehandler(self, __file): ... + def createfilehandler(self, file, mask, func, /): ... + def deletefilehandler(self, file, /): ... - def createtimerhandler(self, __milliseconds, __func): ... - def deletecommand(self, __name): ... - def dooneevent(self, __flags: int = 0): ... - def eval(self, __script: str) -> str: ... - def evalfile(self, __fileName): ... - def exprboolean(self, __s): ... - def exprdouble(self, __s): ... - def exprlong(self, __s): ... - def exprstring(self, __s): ... - def getboolean(self, __arg): ... - def getdouble(self, __arg): ... - def getint(self, __arg): ... + def createtimerhandler(self, milliseconds, func, /): ... + def deletecommand(self, name, /): ... + def dooneevent(self, flags: int = 0, /): ... + def eval(self, script: str, /) -> str: ... + def evalfile(self, fileName, /): ... + def exprboolean(self, s, /): ... + def exprdouble(self, s, /): ... + def exprlong(self, s, /): ... + def exprstring(self, s, /): ... + def getboolean(self, arg, /): ... + def getdouble(self, arg, /): ... + def getint(self, arg, /): ... def getvar(self, *args, **kwargs): ... def globalgetvar(self, *args, **kwargs): ... def globalsetvar(self, *args, **kwargs): ... def globalunsetvar(self, *args, **kwargs): ... def interpaddr(self): ... def loadtk(self) -> None: ... - def mainloop(self, __threshold: int = 0): ... + def mainloop(self, threshold: int = 0, /): ... def quit(self): ... - def record(self, __script): ... + def record(self, script, /): ... def setvar(self, *ags, **kwargs): ... if sys.version_info < (3, 11): - def split(self, __arg): ... + def split(self, arg, /): ... - def splitlist(self, __arg): ... + def splitlist(self, arg, /): ... def unsetvar(self, *args, **kwargs): ... def wantobjects(self, *args, **kwargs): ... def willdispatch(self): ... @@ -107,14 +107,15 @@ class TkttType: def deletetimerhandler(self): ... 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, + 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): ... +def setbusywaitinterval(new_val, /): ... diff --git a/mypy/typeshed/stdlib/_tracemalloc.pyi b/mypy/typeshed/stdlib/_tracemalloc.pyi index 1b79d9dc5785..b1aeb710233e 100644 --- a/mypy/typeshed/stdlib/_tracemalloc.pyi +++ b/mypy/typeshed/stdlib/_tracemalloc.pyi @@ -2,7 +2,7 @@ import sys from collections.abc import Sequence from tracemalloc import _FrameTuple, _TraceTuple -def _get_object_traceback(__obj: object) -> Sequence[_FrameTuple] | None: ... +def _get_object_traceback(obj: object, /) -> Sequence[_FrameTuple] | None: ... def _get_traces() -> Sequence[_TraceTuple]: ... def clear_traces() -> None: ... def get_traceback_limit() -> int: ... @@ -13,5 +13,5 @@ def is_tracing() -> bool: ... if sys.version_info >= (3, 9): def reset_peak() -> None: ... -def start(__nframe: int = 1) -> None: ... +def start(nframe: int = 1, /) -> None: ... def stop() -> None: ... diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index e9a24bab28a9..9469081ae5d6 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -67,7 +67,7 @@ sentinel: Any # stable class IdentityFunction(Protocol): - def __call__(self, __x: _T) -> _T: ... + def __call__(self, x: _T, /) -> _T: ... # stable class SupportsNext(Protocol[_T_co]): @@ -80,16 +80,16 @@ class SupportsAnext(Protocol[_T_co]): # Comparison protocols class SupportsDunderLT(Protocol[_T_contra]): - def __lt__(self, __other: _T_contra) -> bool: ... + def __lt__(self, other: _T_contra, /) -> bool: ... class SupportsDunderGT(Protocol[_T_contra]): - def __gt__(self, __other: _T_contra) -> bool: ... + def __gt__(self, other: _T_contra, /) -> bool: ... class SupportsDunderLE(Protocol[_T_contra]): - def __le__(self, __other: _T_contra) -> bool: ... + def __le__(self, other: _T_contra, /) -> bool: ... class SupportsDunderGE(Protocol[_T_contra]): - def __ge__(self, __other: _T_contra) -> bool: ... + def __ge__(self, other: _T_contra, /) -> bool: ... class SupportsAllComparisons( SupportsDunderLT[Any], SupportsDunderGT[Any], SupportsDunderLE[Any], SupportsDunderGE[Any], Protocol @@ -101,22 +101,22 @@ SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichC # Dunder protocols class SupportsAdd(Protocol[_T_contra, _T_co]): - def __add__(self, __x: _T_contra) -> _T_co: ... + def __add__(self, x: _T_contra, /) -> _T_co: ... class SupportsRAdd(Protocol[_T_contra, _T_co]): - def __radd__(self, __x: _T_contra) -> _T_co: ... + def __radd__(self, x: _T_contra, /) -> _T_co: ... class SupportsSub(Protocol[_T_contra, _T_co]): - def __sub__(self, __x: _T_contra) -> _T_co: ... + def __sub__(self, x: _T_contra, /) -> _T_co: ... class SupportsRSub(Protocol[_T_contra, _T_co]): - def __rsub__(self, __x: _T_contra) -> _T_co: ... + def __rsub__(self, x: _T_contra, /) -> _T_co: ... class SupportsDivMod(Protocol[_T_contra, _T_co]): - def __divmod__(self, __other: _T_contra) -> _T_co: ... + def __divmod__(self, other: _T_contra, /) -> _T_co: ... class SupportsRDivMod(Protocol[_T_contra, _T_co]): - def __rdivmod__(self, __other: _T_contra) -> _T_co: ... + def __rdivmod__(self, other: _T_contra, /) -> _T_co: ... # This protocol is generic over the iterator type, while Iterable is # generic over the type that is iterated over. @@ -130,7 +130,7 @@ class SupportsAiter(Protocol[_T_co]): class SupportsLenAndGetItem(Protocol[_T_co]): def __len__(self) -> int: ... - def __getitem__(self, __k: int) -> _T_co: ... + def __getitem__(self, k: int, /) -> _T_co: ... class SupportsTrunc(Protocol): def __trunc__(self) -> int: ... @@ -144,17 +144,17 @@ class SupportsItems(Protocol[_KT_co, _VT_co]): # stable class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]): def keys(self) -> Iterable[_KT]: ... - def __getitem__(self, __key: _KT) -> _VT_co: ... + def __getitem__(self, key: _KT, /) -> _VT_co: ... # stable class SupportsGetItem(Protocol[_KT_contra, _VT_co]): - def __contains__(self, __x: Any) -> bool: ... - def __getitem__(self, __key: _KT_contra) -> _VT_co: ... + def __contains__(self, x: Any, /) -> bool: ... + def __getitem__(self, key: _KT_contra, /) -> _VT_co: ... # stable class SupportsItemAccess(SupportsGetItem[_KT_contra, _VT], Protocol[_KT_contra, _VT]): - def __setitem__(self, __key: _KT_contra, __value: _VT) -> None: ... - def __delitem__(self, __key: _KT_contra) -> None: ... + def __setitem__(self, key: _KT_contra, value: _VT, /) -> None: ... + def __delitem__(self, key: _KT_contra, /) -> None: ... StrPath: TypeAlias = str | PathLike[str] # stable BytesPath: TypeAlias = bytes | PathLike[bytes] # stable @@ -238,11 +238,11 @@ FileDescriptorOrPath: TypeAlias = int | StrOrBytesPath # stable class SupportsRead(Protocol[_T_co]): - def read(self, __length: int = ...) -> _T_co: ... + def read(self, length: int = ..., /) -> _T_co: ... # stable class SupportsReadline(Protocol[_T_co]): - def readline(self, __length: int = ...) -> _T_co: ... + def readline(self, length: int = ..., /) -> _T_co: ... # stable class SupportsNoArgReadline(Protocol[_T_co]): @@ -250,7 +250,7 @@ class SupportsNoArgReadline(Protocol[_T_co]): # stable class SupportsWrite(Protocol[_T_contra]): - def write(self, __s: _T_contra) -> object: ... + def write(self, s: _T_contra, /) -> object: ... # stable class SupportsFlush(Protocol): @@ -267,17 +267,17 @@ WriteableBuffer: TypeAlias = Buffer ReadableBuffer: TypeAlias = Buffer # stable class SliceableBuffer(Buffer, Protocol): - def __getitem__(self, __slice: slice) -> Sequence[int]: ... + def __getitem__(self, slice: slice, /) -> Sequence[int]: ... class IndexableBuffer(Buffer, Protocol): - def __getitem__(self, __i: int) -> int: ... + def __getitem__(self, i: int, /) -> int: ... class SupportsGetItemBuffer(SliceableBuffer, IndexableBuffer, Protocol): - def __contains__(self, __x: Any) -> bool: ... + def __contains__(self, x: Any, /) -> bool: ... @overload - def __getitem__(self, __slice: slice) -> Sequence[int]: ... + def __getitem__(self, slice: slice, /) -> Sequence[int]: ... @overload - def __getitem__(self, __i: int) -> int: ... + def __getitem__(self, i: int, /) -> int: ... class SizedBuffer(Sized, Buffer, Protocol): ... diff --git a/mypy/typeshed/stdlib/_typeshed/dbapi.pyi b/mypy/typeshed/stdlib/_typeshed/dbapi.pyi index 022e95996bb3..d54fbee57042 100644 --- a/mypy/typeshed/stdlib/_typeshed/dbapi.pyi +++ b/mypy/typeshed/stdlib/_typeshed/dbapi.pyi @@ -23,15 +23,15 @@ class DBAPICursor(Protocol): @property def rowcount(self) -> int: ... # optional: - # def callproc(self, __procname: str, __parameters: Sequence[Any] = ...) -> Sequence[Any]: ... + # def callproc(self, procname: str, parameters: Sequence[Any] = ..., /) -> Sequence[Any]: ... def close(self) -> object: ... - def execute(self, __operation: str, __parameters: Sequence[Any] | Mapping[str, Any] = ...) -> object: ... - def executemany(self, __operation: str, __seq_of_parameters: Sequence[Sequence[Any]]) -> object: ... + def execute(self, operation: str, parameters: Sequence[Any] | Mapping[str, Any] = ..., /) -> object: ... + def executemany(self, operation: str, seq_of_parameters: Sequence[Sequence[Any]], /) -> object: ... def fetchone(self) -> Sequence[Any] | None: ... - def fetchmany(self, __size: int = ...) -> Sequence[Sequence[Any]]: ... + def fetchmany(self, size: int = ..., /) -> Sequence[Sequence[Any]]: ... def fetchall(self) -> Sequence[Sequence[Any]]: ... # optional: # def nextset(self) -> None | Literal[True]: ... arraysize: int - def setinputsizes(self, __sizes: Sequence[DBAPITypeCode | int | None]) -> object: ... - def setoutputsize(self, __size: int, __column: int = ...) -> object: ... + def setinputsizes(self, sizes: Sequence[DBAPITypeCode | int | None], /) -> object: ... + def setoutputsize(self, size: int, column: int = ..., /) -> object: ... diff --git a/mypy/typeshed/stdlib/_typeshed/wsgi.pyi b/mypy/typeshed/stdlib/_typeshed/wsgi.pyi index e8ebf6409e7f..63f204eb889b 100644 --- a/mypy/typeshed/stdlib/_typeshed/wsgi.pyi +++ b/mypy/typeshed/stdlib/_typeshed/wsgi.pyi @@ -11,7 +11,7 @@ from typing import Any, Protocol from typing_extensions import TypeAlias class _Readable(Protocol): - def read(self, __size: int = ...) -> bytes: ... + def read(self, size: int = ..., /) -> bytes: ... # Optional: def close(self) -> object: ... if sys.version_info >= (3, 11): @@ -20,7 +20,7 @@ else: # stable class StartResponse(Protocol): def __call__( - self, __status: str, __headers: list[tuple[str, str]], __exc_info: OptExcInfo | None = ... + self, status: str, headers: list[tuple[str, str]], exc_info: OptExcInfo | None = ..., / ) -> Callable[[bytes], object]: ... WSGIEnvironment: TypeAlias = dict[str, Any] # stable @@ -28,17 +28,17 @@ else: # WSGI input streams per PEP 3333, stable class InputStream(Protocol): - def read(self, __size: int = ...) -> bytes: ... - def readline(self, __size: int = ...) -> bytes: ... - def readlines(self, __hint: int = ...) -> list[bytes]: ... + def read(self, size: int = ..., /) -> bytes: ... + def readline(self, size: int = ..., /) -> bytes: ... + def readlines(self, hint: int = ..., /) -> list[bytes]: ... def __iter__(self) -> Iterator[bytes]: ... # WSGI error streams per PEP 3333, stable class ErrorStream(Protocol): def flush(self) -> object: ... - def write(self, __s: str) -> object: ... - def writelines(self, __seq: list[str]) -> object: ... + def write(self, s: str, /) -> object: ... + def writelines(self, seq: list[str], /) -> object: ... # Optional file wrapper in wsgi.file_wrapper class FileWrapper(Protocol): - def __call__(self, __file: _Readable, __block_size: int = ...) -> Iterable[bytes]: ... + def __call__(self, file: _Readable, block_size: int = ..., /) -> Iterable[bytes]: ... diff --git a/mypy/typeshed/stdlib/_typeshed/xml.pyi b/mypy/typeshed/stdlib/_typeshed/xml.pyi index 46c5fab097c4..6cd1b39af628 100644 --- a/mypy/typeshed/stdlib/_typeshed/xml.pyi +++ b/mypy/typeshed/stdlib/_typeshed/xml.pyi @@ -4,6 +4,6 @@ from typing import Any, Protocol # As defined https://docs.python.org/3/library/xml.dom.html#domimplementation-objects class DOMImplementation(Protocol): - def hasFeature(self, __feature: str, __version: str | None) -> bool: ... - def createDocument(self, __namespaceUri: str, __qualifiedName: str, __doctype: Any | None) -> Any: ... - def createDocumentType(self, __qualifiedName: str, __publicId: str, __systemId: str) -> Any: ... + def hasFeature(self, feature: str, version: str | None, /) -> bool: ... + def createDocument(self, namespaceUri: str, qualifiedName: str, doctype: Any | None, /) -> Any: ... + def createDocumentType(self, qualifiedName: str, publicId: str, systemId: str, /) -> Any: ... diff --git a/mypy/typeshed/stdlib/_weakref.pyi b/mypy/typeshed/stdlib/_weakref.pyi index f939aa815bd2..e395143cc027 100644 --- a/mypy/typeshed/stdlib/_weakref.pyi +++ b/mypy/typeshed/stdlib/_weakref.pyi @@ -11,31 +11,31 @@ _T = TypeVar("_T") @final class CallableProxyType(Generic[_C]): # "weakcallableproxy" - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __getattr__(self, attr: str) -> Any: ... __call__: _C @final class ProxyType(Generic[_T]): # "weakproxy" - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __getattr__(self, attr: str) -> Any: ... class ReferenceType(Generic[_T]): __callback__: Callable[[ReferenceType[_T]], Any] - def __new__(cls, __o: _T, __callback: Callable[[ReferenceType[_T]], Any] | None = ...) -> Self: ... + def __new__(cls, o: _T, callback: Callable[[ReferenceType[_T]], Any] | None = ..., /) -> Self: ... def __call__(self) -> _T | None: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... ref = ReferenceType -def getweakrefcount(__object: Any) -> int: ... -def getweakrefs(__object: Any) -> list[Any]: ... +def getweakrefcount(object: Any, /) -> int: ... +def getweakrefs(object: Any, /) -> list[Any]: ... # Return CallableProxyType if object is callable, ProxyType otherwise @overload -def proxy(__object: _C, __callback: Callable[[_C], Any] | None = None) -> CallableProxyType[_C]: ... +def proxy(object: _C, callback: Callable[[_C], Any] | None = None, /) -> CallableProxyType[_C]: ... @overload -def proxy(__object: _T, __callback: Callable[[_T], Any] | None = None) -> Any: ... +def proxy(object: _T, callback: Callable[[_T], Any] | None = None, /) -> Any: ... diff --git a/mypy/typeshed/stdlib/_winapi.pyi b/mypy/typeshed/stdlib/_winapi.pyi index 21ae149e186e..c6fb0484df8e 100644 --- a/mypy/typeshed/stdlib/_winapi.pyi +++ b/mypy/typeshed/stdlib/_winapi.pyi @@ -158,7 +158,7 @@ if sys.platform == "win32": ERROR_ACCESS_DENIED: Literal[5] ERROR_PRIVILEGE_NOT_HELD: Literal[1314] - def CloseHandle(__handle: int) -> None: ... + def CloseHandle(handle: int, /) -> None: ... @overload def ConnectNamedPipe(handle: int, overlapped: Literal[True]) -> Overlapped: ... @overload @@ -166,59 +166,63 @@ if sys.platform == "win32": @overload def ConnectNamedPipe(handle: int, overlapped: bool) -> Overlapped | None: ... def CreateFile( - __file_name: str, - __desired_access: int, - __share_mode: int, - __security_attributes: int, - __creation_disposition: int, - __flags_and_attributes: int, - __template_file: int, + file_name: str, + desired_access: int, + share_mode: int, + security_attributes: int, + creation_disposition: int, + flags_and_attributes: int, + template_file: int, + /, ) -> int: ... - def CreateJunction(__src_path: str, __dst_path: str) -> None: ... + def CreateJunction(src_path: str, dst_path: str, /) -> None: ... def CreateNamedPipe( - __name: str, - __open_mode: int, - __pipe_mode: int, - __max_instances: int, - __out_buffer_size: int, - __in_buffer_size: int, - __default_timeout: int, - __security_attributes: int, + name: str, + open_mode: int, + pipe_mode: int, + max_instances: int, + out_buffer_size: int, + in_buffer_size: int, + default_timeout: int, + security_attributes: int, + /, ) -> int: ... - def CreatePipe(__pipe_attrs: Any, __size: int) -> tuple[int, int]: ... + def CreatePipe(pipe_attrs: Any, size: int, /) -> tuple[int, int]: ... def CreateProcess( - __application_name: str | None, - __command_line: str | None, - __proc_attrs: Any, - __thread_attrs: Any, - __inherit_handles: bool, - __creation_flags: int, - __env_mapping: dict[str, str], - __current_directory: str | None, - __startup_info: Any, + application_name: str | None, + command_line: str | None, + proc_attrs: Any, + thread_attrs: Any, + inherit_handles: bool, + creation_flags: int, + env_mapping: dict[str, str], + current_directory: str | None, + startup_info: Any, + /, ) -> tuple[int, int, int, int]: ... def DuplicateHandle( - __source_process_handle: int, - __source_handle: int, - __target_process_handle: int, - __desired_access: int, - __inherit_handle: bool, - __options: int = 0, + source_process_handle: int, + source_handle: int, + target_process_handle: int, + desired_access: int, + inherit_handle: bool, + options: int = 0, + /, ) -> int: ... - def ExitProcess(__ExitCode: int) -> NoReturn: ... + def ExitProcess(ExitCode: int, /) -> NoReturn: ... def GetACP() -> int: ... def GetFileType(handle: int) -> int: ... def GetCurrentProcess() -> int: ... - def GetExitCodeProcess(__process: int) -> int: ... + def GetExitCodeProcess(process: int, /) -> int: ... def GetLastError() -> int: ... - def GetModuleFileName(__module_handle: int) -> str: ... - def GetStdHandle(__std_handle: int) -> int: ... + def GetModuleFileName(module_handle: int, /) -> str: ... + def GetStdHandle(std_handle: int, /) -> int: ... def GetVersion() -> int: ... - def OpenProcess(__desired_access: int, __inherit_handle: bool, __process_id: int) -> int: ... - def PeekNamedPipe(__handle: int, __size: int = 0) -> tuple[int, int] | tuple[bytes, int, int]: ... + def OpenProcess(desired_access: int, inherit_handle: bool, process_id: int, /) -> int: ... + def PeekNamedPipe(handle: int, size: int = 0, /) -> tuple[int, int] | tuple[bytes, int, int]: ... if sys.version_info >= (3, 10): def LCMapStringEx(locale: str, flags: int, src: str) -> str: ... - def UnmapViewOfFile(__address: int) -> None: ... + def UnmapViewOfFile(address: int, /) -> None: ... @overload def ReadFile(handle: int, size: int, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... @@ -227,12 +231,12 @@ if sys.platform == "win32": @overload def ReadFile(handle: int, size: int, overlapped: int | bool) -> tuple[Any, int]: ... def SetNamedPipeHandleState( - __named_pipe: int, __mode: int | None, __max_collection_count: int | None, __collect_data_timeout: int | None + named_pipe: int, mode: int | None, max_collection_count: int | None, collect_data_timeout: int | None, / ) -> None: ... - def TerminateProcess(__handle: int, __exit_code: int) -> None: ... - def WaitForMultipleObjects(__handle_seq: Sequence[int], __wait_flag: bool, __milliseconds: int = 0xFFFFFFFF) -> int: ... - def WaitForSingleObject(__handle: int, __milliseconds: int) -> int: ... - def WaitNamedPipe(__name: str, __timeout: int) -> None: ... + def TerminateProcess(handle: int, exit_code: int, /) -> None: ... + def WaitForMultipleObjects(handle_seq: Sequence[int], wait_flag: bool, milliseconds: int = 0xFFFFFFFF, /) -> int: ... + def WaitForSingleObject(handle: int, milliseconds: int, /) -> int: ... + def WaitNamedPipe(name: str, timeout: int, /) -> None: ... @overload def WriteFile(handle: int, buffer: ReadableBuffer, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... @overload @@ -242,10 +246,10 @@ if sys.platform == "win32": @final class Overlapped: event: int - def GetOverlappedResult(self, __wait: bool) -> tuple[int, int]: ... + def GetOverlappedResult(self, wait: bool, /) -> tuple[int, int]: ... def cancel(self) -> None: ... def getbuffer(self) -> bytes | None: ... if sys.version_info >= (3, 12): def CopyFile2(existing_file_name: str, new_file_name: str, flags: int, progress_routine: int | None = None) -> int: ... - def NeedCurrentDirectoryForExePath(__exe_name: str) -> bool: ... + def NeedCurrentDirectoryForExePath(exe_name: str, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/abc.pyi b/mypy/typeshed/stdlib/abc.pyi index e4e7f59b58ca..6bf7821f1c1b 100644 --- a/mypy/typeshed/stdlib/abc.pyi +++ b/mypy/typeshed/stdlib/abc.pyi @@ -15,7 +15,7 @@ class ABCMeta(type): __abstractmethods__: frozenset[str] if sys.version_info >= (3, 11): def __new__( - __mcls: type[_typeshed.Self], __name: str, __bases: tuple[type, ...], __namespace: dict[str, Any], **kwargs: Any + mcls: type[_typeshed.Self], name: str, bases: tuple[type, ...], namespace: dict[str, Any], /, **kwargs: Any ) -> _typeshed.Self: ... else: def __new__( diff --git a/mypy/typeshed/stdlib/argparse.pyi b/mypy/typeshed/stdlib/argparse.pyi index c34aca1f8c20..0701654734a4 100644 --- a/mypy/typeshed/stdlib/argparse.pyi +++ b/mypy/typeshed/stdlib/argparse.pyi @@ -392,7 +392,7 @@ elif sys.version_info >= (3, 9): class Namespace(_AttributeHolder): def __init__(self, **kwargs: Any) -> None: ... def __getattr__(self, name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... def __contains__(self, key: str) -> bool: ... def __eq__(self, other: object) -> bool: ... diff --git a/mypy/typeshed/stdlib/array.pyi b/mypy/typeshed/stdlib/array.pyi index 4b5675d2a76e..1b7de1c7882d 100644 --- a/mypy/typeshed/stdlib/array.pyi +++ b/mypy/typeshed/stdlib/array.pyi @@ -24,68 +24,68 @@ class array(MutableSequence[_T]): @property def itemsize(self) -> int: ... @overload - def __init__(self: array[int], __typecode: _IntTypeCode, __initializer: bytes | bytearray | Iterable[int] = ...) -> None: ... + def __init__(self: array[int], typecode: _IntTypeCode, initializer: bytes | bytearray | Iterable[int] = ..., /) -> None: ... @overload def __init__( - self: array[float], __typecode: _FloatTypeCode, __initializer: bytes | bytearray | Iterable[float] = ... + self: array[float], typecode: _FloatTypeCode, initializer: bytes | bytearray | Iterable[float] = ..., / ) -> None: ... @overload def __init__( - self: array[str], __typecode: _UnicodeTypeCode, __initializer: bytes | bytearray | Iterable[str] = ... + self: array[str], typecode: _UnicodeTypeCode, initializer: bytes | bytearray | Iterable[str] = ..., / ) -> None: ... @overload - def __init__(self, __typecode: str, __initializer: Iterable[_T]) -> None: ... + def __init__(self, typecode: str, initializer: Iterable[_T], /) -> None: ... @overload - def __init__(self, __typecode: str, __initializer: bytes | bytearray = ...) -> None: ... - def append(self, __v: _T) -> None: ... + def __init__(self, typecode: str, initializer: bytes | bytearray = ..., /) -> None: ... + def append(self, v: _T, /) -> None: ... def buffer_info(self) -> tuple[int, int]: ... def byteswap(self) -> None: ... - def count(self, __v: _T) -> int: ... - def extend(self, __bb: Iterable[_T]) -> None: ... - def frombytes(self, __buffer: ReadableBuffer) -> None: ... - def fromfile(self, __f: SupportsRead[bytes], __n: int) -> None: ... - def fromlist(self, __list: list[_T]) -> None: ... - def fromunicode(self, __ustr: str) -> None: ... + def count(self, v: _T, /) -> int: ... + def extend(self, bb: Iterable[_T], /) -> None: ... + def frombytes(self, buffer: ReadableBuffer, /) -> None: ... + def fromfile(self, f: SupportsRead[bytes], n: int, /) -> None: ... + def fromlist(self, list: list[_T], /) -> None: ... + def fromunicode(self, ustr: str, /) -> None: ... if sys.version_info >= (3, 10): - def index(self, __v: _T, __start: int = 0, __stop: int = sys.maxsize) -> int: ... + def index(self, v: _T, start: int = 0, stop: int = sys.maxsize, /) -> int: ... else: - def index(self, __v: _T) -> int: ... # type: ignore[override] + def index(self, v: _T, /) -> int: ... # type: ignore[override] - def insert(self, __i: int, __v: _T) -> None: ... - def pop(self, __i: int = -1) -> _T: ... - def remove(self, __v: _T) -> None: ... + def insert(self, i: int, v: _T, /) -> None: ... + def pop(self, i: int = -1, /) -> _T: ... + def remove(self, v: _T, /) -> None: ... def tobytes(self) -> bytes: ... - def tofile(self, __f: SupportsWrite[bytes]) -> None: ... + def tofile(self, f: SupportsWrite[bytes], /) -> None: ... def tolist(self) -> list[_T]: ... def tounicode(self) -> str: ... if sys.version_info < (3, 9): - def fromstring(self, __buffer: str | ReadableBuffer) -> None: ... + def fromstring(self, buffer: str | ReadableBuffer, /) -> None: ... def tostring(self) -> bytes: ... def __len__(self) -> int: ... @overload - def __getitem__(self, __key: SupportsIndex) -> _T: ... + def __getitem__(self, key: SupportsIndex, /) -> _T: ... @overload - def __getitem__(self, __key: slice) -> array[_T]: ... + def __getitem__(self, key: slice, /) -> array[_T]: ... @overload # type: ignore[override] - def __setitem__(self, __key: SupportsIndex, __value: _T) -> None: ... + def __setitem__(self, key: SupportsIndex, value: _T, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: array[_T]) -> None: ... - def __delitem__(self, __key: SupportsIndex | slice) -> None: ... - def __add__(self, __value: array[_T]) -> array[_T]: ... - def __eq__(self, __value: object) -> bool: ... - def __ge__(self, __value: array[_T]) -> bool: ... - def __gt__(self, __value: array[_T]) -> bool: ... - def __iadd__(self, __value: array[_T]) -> Self: ... # type: ignore[override] - def __imul__(self, __value: int) -> Self: ... - def __le__(self, __value: array[_T]) -> bool: ... - def __lt__(self, __value: array[_T]) -> bool: ... - def __mul__(self, __value: int) -> array[_T]: ... - def __rmul__(self, __value: int) -> array[_T]: ... + def __setitem__(self, key: slice, value: array[_T], /) -> None: ... + def __delitem__(self, key: SupportsIndex | slice, /) -> None: ... + def __add__(self, value: array[_T], /) -> array[_T]: ... + def __eq__(self, value: object, /) -> bool: ... + def __ge__(self, value: array[_T], /) -> bool: ... + def __gt__(self, value: array[_T], /) -> bool: ... + def __iadd__(self, value: array[_T], /) -> Self: ... # type: ignore[override] + def __imul__(self, value: int, /) -> Self: ... + def __le__(self, value: array[_T], /) -> bool: ... + def __lt__(self, value: array[_T], /) -> bool: ... + def __mul__(self, value: int, /) -> array[_T]: ... + def __rmul__(self, value: int, /) -> array[_T]: ... def __copy__(self) -> array[_T]: ... - def __deepcopy__(self, __unused: Any) -> array[_T]: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... + def __deepcopy__(self, unused: Any, /) -> array[_T]: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... if sys.version_info >= (3, 12): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 16f5296e2125..95de28c5021e 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -43,9 +43,7 @@ _ProtocolFactory: TypeAlias = Callable[[], BaseProtocol] _SSLContext: TypeAlias = bool | None | ssl.SSLContext class _TaskFactory(Protocol): - def __call__( - self, __loop: AbstractEventLoop, __factory: Coroutine[Any, Any, _T] | Generator[Any, None, _T] - ) -> Future[_T]: ... + def __call__(self, loop: AbstractEventLoop, factory: Coroutine[Any, Any, _T] | Generator[Any, None, _T], /) -> Future[_T]: ... class Handle: _cancelled: bool @@ -577,6 +575,6 @@ else: def get_child_watcher() -> AbstractChildWatcher: ... def set_child_watcher(watcher: AbstractChildWatcher) -> None: ... -def _set_running_loop(__loop: AbstractEventLoop | None) -> None: ... +def _set_running_loop(loop: AbstractEventLoop | None, /) -> None: ... def _get_running_loop() -> AbstractEventLoop: ... def get_running_loop() -> AbstractEventLoop: ... diff --git a/mypy/typeshed/stdlib/asyncio/futures.pyi b/mypy/typeshed/stdlib/asyncio/futures.pyi index 44b9528705a5..560dcc1d5712 100644 --- a/mypy/typeshed/stdlib/asyncio/futures.pyi +++ b/mypy/typeshed/stdlib/asyncio/futures.pyi @@ -34,7 +34,7 @@ class Future(Awaitable[_T], Iterable[_T]): def get_loop(self) -> AbstractEventLoop: ... @property def _callbacks(self) -> list[tuple[Callable[[Self], Any], Context]]: ... - def add_done_callback(self, __fn: Callable[[Self], object], *, context: Context | None = None) -> None: ... + def add_done_callback(self, fn: Callable[[Self], object], /, *, context: Context | None = None) -> None: ... if sys.version_info >= (3, 9): def cancel(self, msg: Any | None = None) -> bool: ... else: @@ -44,9 +44,9 @@ class Future(Awaitable[_T], Iterable[_T]): def done(self) -> bool: ... def result(self) -> _T: ... def exception(self) -> BaseException | None: ... - def remove_done_callback(self, __fn: Callable[[Self], object]) -> int: ... - def set_result(self, __result: _T) -> None: ... - def set_exception(self, __exception: type | BaseException) -> None: ... + def remove_done_callback(self, fn: Callable[[Self], object], /) -> int: ... + def set_result(self, result: _T, /) -> None: ... + def set_exception(self, exception: type | BaseException, /) -> None: ... def __iter__(self) -> Generator[Any, None, _T]: ... def __await__(self) -> Generator[Any, None, _T]: ... @property diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index 028a7571bb79..67291071d512 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -98,81 +98,88 @@ def ensure_future(coro_or_future: Awaitable[_T], *, loop: AbstractEventLoop | No # N.B. Having overlapping overloads is the only way to get acceptable type inference in all edge cases. if sys.version_info >= (3, 10): @overload - def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: Literal[False] = False) -> Future[tuple[_T1]]: ... # type: ignore[overload-overlap] + def gather(coro_or_future1: _FutureLike[_T1], /, *, return_exceptions: Literal[False] = False) -> Future[tuple[_T1]]: ... # type: ignore[overload-overlap] @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, return_exceptions: Literal[False] = False + coro_or_future1: _FutureLike[_T1], coro_or_future2: _FutureLike[_T2], /, *, return_exceptions: Literal[False] = False ) -> Future[tuple[_T1, _T2]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + /, *, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + /, *, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + /, *, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], - __coro_or_future6: _FutureLike[_T6], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + coro_or_future6: _FutureLike[_T6], + /, *, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... @overload def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: Literal[False] = False) -> Future[list[_T]]: ... # type: ignore[overload-overlap] @overload - def gather(__coro_or_future1: _FutureLike[_T1], *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ... # type: ignore[overload-overlap] + def gather(coro_or_future1: _FutureLike[_T1], /, *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ... # type: ignore[overload-overlap] @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], __coro_or_future2: _FutureLike[_T2], *, return_exceptions: bool + coro_or_future1: _FutureLike[_T1], coro_or_future2: _FutureLike[_T2], /, *, return_exceptions: bool ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + /, *, return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + /, *, return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + /, *, return_exceptions: bool, ) -> Future[ @@ -180,12 +187,13 @@ if sys.version_info >= (3, 10): ]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], - __coro_or_future6: _FutureLike[_T6], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + coro_or_future6: _FutureLike[_T6], + /, *, return_exceptions: bool, ) -> Future[ @@ -204,54 +212,59 @@ if sys.version_info >= (3, 10): else: @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False + coro_or_future1: _FutureLike[_T1], /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False ) -> Future[tuple[_T1]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False, ) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], - __coro_or_future6: _FutureLike[_T6], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + coro_or_future6: _FutureLike[_T6], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False, @@ -262,43 +275,47 @@ else: ) -> Future[list[_T]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], *, loop: AbstractEventLoop | None = None, return_exceptions: bool + coro_or_future1: _FutureLike[_T1], /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool ) -> Future[tuple[_T1 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool, ) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ... @overload def gather( # type: ignore[overload-overlap] - __coro_or_future1: _FutureLike[_T1], - __coro_or_future2: _FutureLike[_T2], - __coro_or_future3: _FutureLike[_T3], - __coro_or_future4: _FutureLike[_T4], - __coro_or_future5: _FutureLike[_T5], - __coro_or_future6: _FutureLike[_T6], + coro_or_future1: _FutureLike[_T1], + coro_or_future2: _FutureLike[_T2], + coro_or_future3: _FutureLike[_T3], + coro_or_future4: _FutureLike[_T4], + coro_or_future5: _FutureLike[_T5], + coro_or_future6: _FutureLike[_T6], + /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool, @@ -411,7 +428,7 @@ class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportIn def get_coro(self) -> _TaskCompatibleCoro[_T_co]: ... def get_name(self) -> str: ... - def set_name(self, __value: object) -> None: ... + def set_name(self, value: object, /) -> None: ... if sys.version_info >= (3, 12): def get_context(self) -> Context: ... @@ -446,7 +463,8 @@ if sys.version_info >= (3, 12): class _CustomTaskConstructor(Protocol[_TaskT_co]): def __call__( self, - __coro: _TaskCompatibleCoro[Any], + coro: _TaskCompatibleCoro[Any], + /, *, loop: AbstractEventLoop, name: str | None, diff --git a/mypy/typeshed/stdlib/asyncio/threads.pyi b/mypy/typeshed/stdlib/asyncio/threads.pyi index 88c4fddcaa3f..799efd25fea4 100644 --- a/mypy/typeshed/stdlib/asyncio/threads.pyi +++ b/mypy/typeshed/stdlib/asyncio/threads.pyi @@ -6,4 +6,4 @@ __all__ = ("to_thread",) _P = ParamSpec("_P") _R = TypeVar("_R") -async def to_thread(__func: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... +async def to_thread(func: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ... diff --git a/mypy/typeshed/stdlib/asyncio/trsock.pyi b/mypy/typeshed/stdlib/asyncio/trsock.pyi index 742216a84ccd..e74cf6fd4e05 100644 --- a/mypy/typeshed/stdlib/asyncio/trsock.pyi +++ b/mypy/typeshed/stdlib/asyncio/trsock.pyi @@ -51,7 +51,7 @@ class TransportSocket: else: def ioctl(self, control: int, option: int | tuple[int, int, int] | bool) -> NoReturn: ... - def listen(self, __backlog: int = ...) -> None: ... + def listen(self, backlog: int = ..., /) -> None: ... def makefile(self) -> BinaryIO: ... def sendfile(self, file: BinaryIO, offset: int = ..., count: int | None = ...) -> int: ... def close(self) -> None: ... @@ -66,11 +66,7 @@ class TransportSocket: ) -> NoReturn: ... def sendmsg( - self, - __buffers: Iterable[ReadableBuffer], - __ancdata: Iterable[_CMSG] = ..., - __flags: int = ..., - __address: _Address = ..., + self, buffers: Iterable[ReadableBuffer], ancdata: Iterable[_CMSG] = ..., flags: int = ..., address: _Address = ..., / ) -> int: ... @overload def sendto(self, data: ReadableBuffer, address: _Address) -> int: ... @@ -87,9 +83,9 @@ class TransportSocket: def recv_into(self, buffer: _WriteBuffer, nbytes: int = ..., flags: int = ...) -> int: ... def recvfrom_into(self, buffer: _WriteBuffer, nbytes: int = ..., flags: int = ...) -> tuple[int, _RetAddress]: ... def recvmsg_into( - self, __buffers: Iterable[_WriteBuffer], __ancbufsize: int = ..., __flags: int = ... + self, buffers: Iterable[_WriteBuffer], ancbufsize: int = ..., flags: int = ..., / ) -> tuple[int, list[_CMSG], int, Any]: ... - def recvmsg(self, __bufsize: int, __ancbufsize: int = ..., __flags: int = ...) -> tuple[bytes, list[_CMSG], int, Any]: ... + def recvmsg(self, bufsize: int, ancbufsize: int = ..., flags: int = ..., /) -> tuple[bytes, list[_CMSG], int, Any]: ... def recvfrom(self, bufsize: int, flags: int = ...) -> tuple[bytes, _RetAddress]: ... def recv(self, bufsize: int, flags: int = ...) -> bytes: ... def __enter__(self) -> socket.socket: ... diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index 2fbc0a4e6049..e9274b853290 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -17,7 +17,9 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... @abstractmethod def remove_child_handler(self, pid: int) -> bool: ... @abstractmethod @@ -36,7 +38,9 @@ if sys.version_info >= (3, 12): else: class AbstractChildWatcher: @abstractmethod - def add_child_handler(self, pid: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... @abstractmethod def remove_child_handler(self, pid: int) -> bool: ... @abstractmethod @@ -87,27 +91,35 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... class _UnixSelectorEventLoop(BaseSelectorEventLoop): ... @@ -135,7 +147,9 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... @@ -147,7 +161,9 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... @@ -159,7 +175,9 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... def attach_loop(self, loop: AbstractEventLoop | None) -> None: ... @@ -172,5 +190,7 @@ 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[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ... + def add_child_handler( + self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts] + ) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... diff --git a/mypy/typeshed/stdlib/audioop.pyi b/mypy/typeshed/stdlib/audioop.pyi index b5934516e40f..830d6f83a273 100644 --- a/mypy/typeshed/stdlib/audioop.pyi +++ b/mypy/typeshed/stdlib/audioop.pyi @@ -5,38 +5,39 @@ _RatecvState: TypeAlias = tuple[int, tuple[tuple[int, int], ...]] class error(Exception): ... -def add(__fragment1: bytes, __fragment2: bytes, __width: int) -> bytes: ... -def adpcm2lin(__fragment: bytes, __width: int, __state: _AdpcmState | None) -> tuple[bytes, _AdpcmState]: ... -def alaw2lin(__fragment: bytes, __width: int) -> bytes: ... -def avg(__fragment: bytes, __width: int) -> int: ... -def avgpp(__fragment: bytes, __width: int) -> int: ... -def bias(__fragment: bytes, __width: int, __bias: int) -> bytes: ... -def byteswap(__fragment: bytes, __width: int) -> bytes: ... -def cross(__fragment: bytes, __width: int) -> int: ... -def findfactor(__fragment: bytes, __reference: bytes) -> float: ... -def findfit(__fragment: bytes, __reference: bytes) -> tuple[int, float]: ... -def findmax(__fragment: bytes, __length: int) -> int: ... -def getsample(__fragment: bytes, __width: int, __index: int) -> int: ... -def lin2adpcm(__fragment: bytes, __width: int, __state: _AdpcmState | None) -> tuple[bytes, _AdpcmState]: ... -def lin2alaw(__fragment: bytes, __width: int) -> bytes: ... -def lin2lin(__fragment: bytes, __width: int, __newwidth: int) -> bytes: ... -def lin2ulaw(__fragment: bytes, __width: int) -> bytes: ... -def max(__fragment: bytes, __width: int) -> int: ... -def maxpp(__fragment: bytes, __width: int) -> int: ... -def minmax(__fragment: bytes, __width: int) -> tuple[int, int]: ... -def mul(__fragment: bytes, __width: int, __factor: float) -> bytes: ... +def add(fragment1: bytes, fragment2: bytes, width: int, /) -> bytes: ... +def adpcm2lin(fragment: bytes, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... +def alaw2lin(fragment: bytes, width: int, /) -> bytes: ... +def avg(fragment: bytes, width: int, /) -> int: ... +def avgpp(fragment: bytes, width: int, /) -> int: ... +def bias(fragment: bytes, width: int, bias: int, /) -> bytes: ... +def byteswap(fragment: bytes, width: int, /) -> bytes: ... +def cross(fragment: bytes, width: int, /) -> int: ... +def findfactor(fragment: bytes, reference: bytes, /) -> float: ... +def findfit(fragment: bytes, reference: bytes, /) -> tuple[int, float]: ... +def findmax(fragment: bytes, length: int, /) -> int: ... +def getsample(fragment: bytes, width: int, index: int, /) -> int: ... +def lin2adpcm(fragment: bytes, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... +def lin2alaw(fragment: bytes, width: int, /) -> bytes: ... +def lin2lin(fragment: bytes, width: int, newwidth: int, /) -> bytes: ... +def lin2ulaw(fragment: bytes, width: int, /) -> bytes: ... +def max(fragment: bytes, width: int, /) -> int: ... +def maxpp(fragment: bytes, width: int, /) -> int: ... +def minmax(fragment: bytes, width: int, /) -> tuple[int, int]: ... +def mul(fragment: bytes, width: int, factor: float, /) -> bytes: ... def ratecv( - __fragment: bytes, - __width: int, - __nchannels: int, - __inrate: int, - __outrate: int, - __state: _RatecvState | None, - __weightA: int = 1, - __weightB: int = 0, + fragment: bytes, + width: int, + nchannels: int, + inrate: int, + outrate: int, + state: _RatecvState | None, + weightA: int = 1, + weightB: int = 0, + /, ) -> tuple[bytes, _RatecvState]: ... -def reverse(__fragment: bytes, __width: int) -> bytes: ... -def rms(__fragment: bytes, __width: int) -> int: ... -def tomono(__fragment: bytes, __width: int, __lfactor: float, __rfactor: float) -> bytes: ... -def tostereo(__fragment: bytes, __width: int, __lfactor: float, __rfactor: float) -> bytes: ... -def ulaw2lin(__fragment: bytes, __width: int) -> bytes: ... +def reverse(fragment: bytes, width: int, /) -> bytes: ... +def rms(fragment: bytes, width: int, /) -> int: ... +def tomono(fragment: bytes, width: int, lfactor: float, rfactor: float, /) -> bytes: ... +def tostereo(fragment: bytes, width: int, lfactor: float, rfactor: float, /) -> bytes: ... +def ulaw2lin(fragment: bytes, width: int, /) -> bytes: ... diff --git a/mypy/typeshed/stdlib/bdb.pyi b/mypy/typeshed/stdlib/bdb.pyi index 43012a253164..a72e986728a7 100644 --- a/mypy/typeshed/stdlib/bdb.pyi +++ b/mypy/typeshed/stdlib/bdb.pyi @@ -67,7 +67,7 @@ class Bdb: ) -> None: ... def runeval(self, expr: str, globals: dict[str, Any] | None = None, locals: Mapping[str, Any] | None = None) -> None: ... def runctx(self, cmd: str | CodeType, globals: dict[str, Any] | None, locals: Mapping[str, Any] | None) -> None: ... - def runcall(self, __func: Callable[_P, _T], *args: _P.args, **kwds: _P.kwargs) -> _T | None: ... + def runcall(self, func: Callable[_P, _T], /, *args: _P.args, **kwds: _P.kwargs) -> _T | None: ... class Breakpoint: next: int diff --git a/mypy/typeshed/stdlib/binascii.pyi b/mypy/typeshed/stdlib/binascii.pyi index d48507b90694..32e018c653cb 100644 --- a/mypy/typeshed/stdlib/binascii.pyi +++ b/mypy/typeshed/stdlib/binascii.pyi @@ -6,31 +6,31 @@ from typing_extensions import TypeAlias # or ASCII-only strings. _AsciiBuffer: TypeAlias = str | ReadableBuffer -def a2b_uu(__data: _AsciiBuffer) -> bytes: ... -def b2a_uu(__data: ReadableBuffer, *, backtick: bool = False) -> bytes: ... +def a2b_uu(data: _AsciiBuffer, /) -> bytes: ... +def b2a_uu(data: ReadableBuffer, /, *, backtick: bool = False) -> bytes: ... if sys.version_info >= (3, 11): - def a2b_base64(__data: _AsciiBuffer, *, strict_mode: bool = False) -> bytes: ... + def a2b_base64(data: _AsciiBuffer, /, *, strict_mode: bool = False) -> bytes: ... else: - def a2b_base64(__data: _AsciiBuffer) -> bytes: ... + def a2b_base64(data: _AsciiBuffer, /) -> bytes: ... -def b2a_base64(__data: ReadableBuffer, *, newline: bool = True) -> bytes: ... +def b2a_base64(data: ReadableBuffer, /, *, newline: bool = True) -> bytes: ... def a2b_qp(data: _AsciiBuffer, header: bool = False) -> bytes: ... def b2a_qp(data: ReadableBuffer, quotetabs: bool = False, istext: bool = True, header: bool = False) -> bytes: ... if sys.version_info < (3, 11): - def a2b_hqx(__data: _AsciiBuffer) -> bytes: ... - def rledecode_hqx(__data: ReadableBuffer) -> bytes: ... - def rlecode_hqx(__data: ReadableBuffer) -> bytes: ... - def b2a_hqx(__data: ReadableBuffer) -> bytes: ... + def a2b_hqx(data: _AsciiBuffer, /) -> bytes: ... + def rledecode_hqx(data: ReadableBuffer, /) -> bytes: ... + def rlecode_hqx(data: ReadableBuffer, /) -> bytes: ... + def b2a_hqx(data: ReadableBuffer, /) -> bytes: ... -def crc_hqx(__data: ReadableBuffer, __crc: int) -> int: ... -def crc32(__data: ReadableBuffer, __crc: int = 0) -> int: ... +def crc_hqx(data: ReadableBuffer, crc: int, /) -> int: ... +def crc32(data: ReadableBuffer, crc: int = 0, /) -> int: ... 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: ... +def a2b_hex(hexstr: _AsciiBuffer, /) -> bytes: ... +def unhexlify(hexstr: _AsciiBuffer, /) -> bytes: ... class Error(ValueError): ... class Incomplete(Exception): ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 02e128234dc1..b4765b26c8e5 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, @@ -97,45 +98,44 @@ class object: __annotations__: dict[str, Any] @property def __class__(self) -> type[Self]: ... - # Ignore errors about type mismatch between property getter and setter @__class__.setter - def __class__(self, __type: type[object]) -> None: ... # noqa: F811 + def __class__(self, type: type[object], /) -> None: ... def __init__(self) -> None: ... def __new__(cls) -> Self: ... # N.B. `object.__setattr__` and `object.__delattr__` are heavily special-cased by type checkers. # Overriding them in subclasses has different semantics, even if the override has an identical signature. - def __setattr__(self, __name: str, __value: Any) -> None: ... - def __delattr__(self, __name: str) -> None: ... - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... + def __delattr__(self, name: str, /) -> None: ... + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... def __str__(self) -> str: ... # noqa: Y029 def __repr__(self) -> str: ... # noqa: Y029 def __hash__(self) -> int: ... - def __format__(self, __format_spec: str) -> str: ... - def __getattribute__(self, __name: str) -> Any: ... + def __format__(self, format_spec: str, /) -> str: ... + def __getattribute__(self, name: str, /) -> Any: ... def __sizeof__(self) -> int: ... # 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, ...]: ... - def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ... + def __reduce_ex__(self, protocol: SupportsIndex, /) -> str | tuple[Any, ...]: ... if sys.version_info >= (3, 11): def __getstate__(self) -> object: ... def __dir__(self) -> Iterable[str]: ... def __init_subclass__(cls) -> None: ... @classmethod - def __subclasshook__(cls, __subclass: type) -> bool: ... + def __subclasshook__(cls, subclass: type, /) -> bool: ... class staticmethod(Generic[_P, _R_co]): @property def __func__(self) -> Callable[_P, _R_co]: ... @property def __isabstractmethod__(self) -> bool: ... - def __init__(self, __f: Callable[_P, _R_co]) -> None: ... + def __init__(self, f: Callable[_P, _R_co], /) -> None: ... @overload - def __get__(self, __instance: None, __owner: type) -> Callable[_P, _R_co]: ... + def __get__(self, instance: None, owner: type, /) -> Callable[_P, _R_co]: ... @overload - def __get__(self, __instance: _T, __owner: type[_T] | None = None) -> Callable[_P, _R_co]: ... + def __get__(self, instance: _T, owner: type[_T] | None = None, /) -> Callable[_P, _R_co]: ... if sys.version_info >= (3, 10): __name__: str __qualname__: str @@ -148,11 +148,11 @@ class classmethod(Generic[_T, _P, _R_co]): def __func__(self) -> Callable[Concatenate[type[_T], _P], _R_co]: ... @property def __isabstractmethod__(self) -> bool: ... - def __init__(self, __f: Callable[Concatenate[type[_T], _P], _R_co]) -> None: ... + def __init__(self, f: Callable[Concatenate[type[_T], _P], _R_co], /) -> None: ... @overload - def __get__(self, __instance: _T, __owner: type[_T] | None = None) -> Callable[_P, _R_co]: ... + def __get__(self, instance: _T, owner: type[_T] | None = None, /) -> Callable[_P, _R_co]: ... @overload - def __get__(self, __instance: None, __owner: type[_T]) -> Callable[_P, _R_co]: ... + def __get__(self, instance: None, owner: type[_T], /) -> Callable[_P, _R_co]: ... if sys.version_info >= (3, 10): __name__: str __qualname__: str @@ -184,35 +184,35 @@ class type: @property def __weakrefoffset__(self) -> int: ... @overload - def __init__(self, __o: object) -> None: ... + def __init__(self, o: object, /) -> None: ... @overload - def __init__(self, __name: str, __bases: tuple[type, ...], __dict: dict[str, Any], **kwds: Any) -> None: ... + def __init__(self, name: str, bases: tuple[type, ...], dict: dict[str, Any], /, **kwds: Any) -> None: ... @overload - def __new__(cls, __o: object) -> type: ... + def __new__(cls, o: object, /) -> type: ... @overload def __new__( - cls: type[_typeshed.Self], __name: str, __bases: tuple[type, ...], __namespace: dict[str, Any], **kwds: Any + cls: type[_typeshed.Self], name: str, bases: tuple[type, ...], namespace: dict[str, Any], /, **kwds: Any ) -> _typeshed.Self: ... def __call__(self, *args: Any, **kwds: Any) -> Any: ... def __subclasses__(self: _typeshed.Self) -> list[_typeshed.Self]: ... # Note: the documentation doesn't specify what the return type is, the standard # implementation seems to be returning a list. def mro(self) -> list[type]: ... - def __instancecheck__(self, __instance: Any) -> bool: ... - def __subclasscheck__(self, __subclass: type) -> bool: ... + def __instancecheck__(self, instance: Any, /) -> bool: ... + def __subclasscheck__(self, subclass: type, /) -> bool: ... @classmethod - def __prepare__(metacls, __name: str, __bases: tuple[type, ...], **kwds: Any) -> MutableMapping[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: ... + def __or__(self, value: Any, /) -> types.UnionType: ... + def __ror__(self, value: Any, /) -> types.UnionType: ... if sys.version_info >= (3, 12): __type_params__: tuple[TypeVar | ParamSpec | TypeVarTuple, ...] class super: @overload - def __init__(self, __t: Any, __obj: Any) -> None: ... + def __init__(self, t: Any, obj: Any, /) -> None: ... @overload - def __init__(self, __t: Any) -> None: ... + def __init__(self, t: Any, /) -> None: ... @overload def __init__(self) -> None: ... @@ -222,9 +222,9 @@ _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 class int: @overload - def __new__(cls, __x: ConvertibleToInt = ...) -> Self: ... + def __new__(cls, x: ConvertibleToInt = ..., /) -> Self: ... @overload - def __new__(cls, __x: str | bytes | bytearray, base: SupportsIndex) -> Self: ... + def __new__(cls, x: str | bytes | bytearray, /, base: SupportsIndex) -> Self: ... def as_integer_ratio(self) -> tuple[int, Literal[1]]: ... @property def real(self) -> int: ... @@ -265,59 +265,59 @@ class int: if sys.version_info >= (3, 12): def is_integer(self) -> Literal[True]: ... - def __add__(self, __value: int) -> int: ... - def __sub__(self, __value: int) -> int: ... - def __mul__(self, __value: int) -> int: ... - def __floordiv__(self, __value: int) -> int: ... - def __truediv__(self, __value: int) -> float: ... - def __mod__(self, __value: int) -> int: ... - def __divmod__(self, __value: int) -> tuple[int, int]: ... - def __radd__(self, __value: int) -> int: ... - def __rsub__(self, __value: int) -> int: ... - def __rmul__(self, __value: int) -> int: ... - def __rfloordiv__(self, __value: int) -> int: ... - def __rtruediv__(self, __value: int) -> float: ... - def __rmod__(self, __value: int) -> int: ... - def __rdivmod__(self, __value: int) -> tuple[int, int]: ... + def __add__(self, value: int, /) -> int: ... + def __sub__(self, value: int, /) -> int: ... + def __mul__(self, value: int, /) -> int: ... + def __floordiv__(self, value: int, /) -> int: ... + def __truediv__(self, value: int, /) -> float: ... + def __mod__(self, value: int, /) -> int: ... + def __divmod__(self, value: int, /) -> tuple[int, int]: ... + def __radd__(self, value: int, /) -> int: ... + def __rsub__(self, value: int, /) -> int: ... + def __rmul__(self, value: int, /) -> int: ... + def __rfloordiv__(self, value: int, /) -> int: ... + def __rtruediv__(self, value: int, /) -> float: ... + def __rmod__(self, value: int, /) -> int: ... + def __rdivmod__(self, value: int, /) -> tuple[int, int]: ... @overload - def __pow__(self, __x: Literal[0]) -> Literal[1]: ... + def __pow__(self, x: Literal[0], /) -> Literal[1]: ... @overload - def __pow__(self, __value: Literal[0], __mod: None) -> Literal[1]: ... + def __pow__(self, value: Literal[0], mod: None, /) -> Literal[1]: ... @overload - def __pow__(self, __value: _PositiveInteger, __mod: None = None) -> int: ... + def __pow__(self, value: _PositiveInteger, mod: None = None, /) -> int: ... @overload - def __pow__(self, __value: _NegativeInteger, __mod: None = None) -> float: ... + def __pow__(self, value: _NegativeInteger, mod: None = None, /) -> float: ... # positive __value -> int; negative __value -> float # return type must be Any as `int | float` causes too many false-positive errors @overload - def __pow__(self, __value: int, __mod: None = None) -> Any: ... - @overload - def __pow__(self, __value: int, __mod: int) -> int: ... - def __rpow__(self, __value: int, __mod: int | None = None) -> Any: ... - def __and__(self, __value: int) -> int: ... - def __or__(self, __value: int) -> int: ... - def __xor__(self, __value: int) -> int: ... - def __lshift__(self, __value: int) -> int: ... - def __rshift__(self, __value: int) -> int: ... - def __rand__(self, __value: int) -> int: ... - def __ror__(self, __value: int) -> int: ... - def __rxor__(self, __value: int) -> int: ... - def __rlshift__(self, __value: int) -> int: ... - def __rrshift__(self, __value: int) -> int: ... + def __pow__(self, value: int, mod: None = None, /) -> Any: ... + @overload + def __pow__(self, value: int, mod: int, /) -> int: ... + def __rpow__(self, value: int, mod: int | None = None, /) -> Any: ... + def __and__(self, value: int, /) -> int: ... + def __or__(self, value: int, /) -> int: ... + def __xor__(self, value: int, /) -> int: ... + def __lshift__(self, value: int, /) -> int: ... + def __rshift__(self, value: int, /) -> int: ... + def __rand__(self, value: int, /) -> int: ... + def __ror__(self, value: int, /) -> int: ... + def __rxor__(self, value: int, /) -> int: ... + def __rlshift__(self, value: int, /) -> int: ... + def __rrshift__(self, value: int, /) -> int: ... def __neg__(self) -> int: ... def __pos__(self) -> int: ... def __invert__(self) -> int: ... def __trunc__(self) -> int: ... def __ceil__(self) -> int: ... def __floor__(self) -> int: ... - def __round__(self, __ndigits: SupportsIndex = ...) -> int: ... + def __round__(self, ndigits: SupportsIndex = ..., /) -> int: ... def __getnewargs__(self) -> tuple[int]: ... - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... - def __lt__(self, __value: int) -> bool: ... - def __le__(self, __value: int) -> bool: ... - def __gt__(self, __value: int) -> bool: ... - def __ge__(self, __value: int) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... + def __lt__(self, value: int, /) -> bool: ... + def __le__(self, value: int, /) -> bool: ... + def __gt__(self, value: int, /) -> bool: ... + def __ge__(self, value: int, /) -> bool: ... def __float__(self) -> float: ... def __int__(self) -> int: ... def __abs__(self) -> int: ... @@ -326,44 +326,44 @@ class int: def __index__(self) -> int: ... class float: - def __new__(cls, __x: ConvertibleToFloat = ...) -> Self: ... + def __new__(cls, x: ConvertibleToFloat = ..., /) -> Self: ... def as_integer_ratio(self) -> tuple[int, int]: ... def hex(self) -> str: ... def is_integer(self) -> bool: ... @classmethod - def fromhex(cls, __string: str) -> Self: ... + def fromhex(cls, string: str, /) -> Self: ... @property def real(self) -> float: ... @property def imag(self) -> float: ... def conjugate(self) -> float: ... - def __add__(self, __value: float) -> float: ... - def __sub__(self, __value: float) -> float: ... - def __mul__(self, __value: float) -> float: ... - def __floordiv__(self, __value: float) -> float: ... - def __truediv__(self, __value: float) -> float: ... - def __mod__(self, __value: float) -> float: ... - def __divmod__(self, __value: float) -> tuple[float, float]: ... - @overload - def __pow__(self, __value: int, __mod: None = None) -> float: ... + def __add__(self, value: float, /) -> float: ... + def __sub__(self, value: float, /) -> float: ... + def __mul__(self, value: float, /) -> float: ... + def __floordiv__(self, value: float, /) -> float: ... + def __truediv__(self, value: float, /) -> float: ... + def __mod__(self, value: float, /) -> float: ... + def __divmod__(self, value: float, /) -> tuple[float, float]: ... + @overload + def __pow__(self, value: int, mod: None = None, /) -> float: ... # positive __value -> float; negative __value -> complex # return type must be Any as `float | complex` causes too many false-positive errors @overload - def __pow__(self, __value: float, __mod: None = None) -> Any: ... - def __radd__(self, __value: float) -> float: ... - def __rsub__(self, __value: float) -> float: ... - def __rmul__(self, __value: float) -> float: ... - def __rfloordiv__(self, __value: float) -> float: ... - def __rtruediv__(self, __value: float) -> float: ... - def __rmod__(self, __value: float) -> float: ... - def __rdivmod__(self, __value: float) -> tuple[float, float]: ... + def __pow__(self, value: float, mod: None = None, /) -> Any: ... + def __radd__(self, value: float, /) -> float: ... + def __rsub__(self, value: float, /) -> float: ... + def __rmul__(self, value: float, /) -> float: ... + def __rfloordiv__(self, value: float, /) -> float: ... + def __rtruediv__(self, value: float, /) -> float: ... + def __rmod__(self, value: float, /) -> float: ... + def __rdivmod__(self, value: float, /) -> tuple[float, float]: ... @overload - def __rpow__(self, __value: _PositiveInteger, __mod: None = None) -> float: ... + def __rpow__(self, value: _PositiveInteger, mod: None = None, /) -> float: ... @overload - def __rpow__(self, __value: _NegativeInteger, __mod: None = None) -> complex: ... + def __rpow__(self, value: _NegativeInteger, mod: None = None, /) -> complex: ... # Returning `complex` for the general case gives too many false-positive errors. @overload - def __rpow__(self, __value: float, __mod: None = None) -> Any: ... + def __rpow__(self, value: float, mod: None = None, /) -> Any: ... def __getnewargs__(self) -> tuple[float]: ... def __trunc__(self) -> int: ... if sys.version_info >= (3, 9): @@ -371,15 +371,15 @@ class float: def __floor__(self) -> int: ... @overload - def __round__(self, __ndigits: None = None) -> int: ... + def __round__(self, ndigits: None = None, /) -> int: ... @overload - def __round__(self, __ndigits: SupportsIndex) -> float: ... - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... - def __lt__(self, __value: float) -> bool: ... - def __le__(self, __value: float) -> bool: ... - def __gt__(self, __value: float) -> bool: ... - def __ge__(self, __value: float) -> bool: ... + def __round__(self, ndigits: SupportsIndex, /) -> float: ... + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... + def __lt__(self, value: float, /) -> bool: ... + def __le__(self, value: float, /) -> bool: ... + def __gt__(self, value: float, /) -> bool: ... + def __ge__(self, value: float, /) -> bool: ... def __neg__(self) -> float: ... def __pos__(self) -> float: ... def __int__(self) -> int: ... @@ -403,18 +403,18 @@ class complex: @property def imag(self) -> float: ... def conjugate(self) -> complex: ... - def __add__(self, __value: complex) -> complex: ... - def __sub__(self, __value: complex) -> complex: ... - def __mul__(self, __value: complex) -> complex: ... - def __pow__(self, __value: complex, __mod: None = None) -> complex: ... - def __truediv__(self, __value: complex) -> complex: ... - def __radd__(self, __value: complex) -> complex: ... - def __rsub__(self, __value: complex) -> complex: ... - def __rmul__(self, __value: complex) -> complex: ... - def __rpow__(self, __value: complex, __mod: None = None) -> complex: ... - def __rtruediv__(self, __value: complex) -> complex: ... - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __add__(self, value: complex, /) -> complex: ... + def __sub__(self, value: complex, /) -> complex: ... + def __mul__(self, value: complex, /) -> complex: ... + def __pow__(self, value: complex, mod: None = None, /) -> complex: ... + def __truediv__(self, value: complex, /) -> complex: ... + def __radd__(self, value: complex, /) -> complex: ... + def __rsub__(self, value: complex, /) -> complex: ... + def __rmul__(self, value: complex, /) -> complex: ... + def __rpow__(self, value: complex, mod: None = None, /) -> complex: ... + def __rtruediv__(self, value: complex, /) -> complex: ... + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... def __neg__(self) -> complex: ... def __pos__(self) -> complex: ... def __abs__(self) -> float: ... @@ -424,29 +424,44 @@ class complex: def __complex__(self) -> complex: ... class _FormatMapMapping(Protocol): - def __getitem__(self, __key: str) -> Any: ... + def __getitem__(self, key: str, /) -> Any: ... class _TranslateTable(Protocol): - def __getitem__(self, __key: int) -> str | int | None: ... + def __getitem__(self, key: int, /) -> str | int | None: ... class str(Sequence[str]): @overload 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] - def center(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] - def count(self, __sub: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... + @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, sub: 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 = ... + 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: ... + 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: ... + def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ... def isalnum(self) -> bool: ... def isalpha(self) -> bool: ... def isascii(self) -> bool: ... @@ -459,86 +474,159 @@ class str(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - def join(self, __iterable: Iterable[str]) -> str: ... # type: ignore[misc] - def ljust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] + @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] - def lstrip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] - def partition(self, __sep: str) -> tuple[str, str, str]: ... # type: ignore[misc] - def replace(self, __old: str, __new: str, __count: SupportsIndex = -1) -> 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): - def removeprefix(self, __prefix: str) -> str: ... # type: ignore[misc] - def removesuffix(self, __suffix: str) -> str: ... # type: ignore[misc] + @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: ... - def rjust(self, __width: SupportsIndex, __fillchar: str = " ") -> str: ... # type: ignore[misc] - def rpartition(self, __sep: str) -> tuple[str, 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] - def rstrip(self, __chars: str | None = None) -> 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 = ... + self, prefix: str | tuple[str, ...], start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> bool: ... - def strip(self, __chars: str | None = None) -> str: ... # type: ignore[misc] + @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: ... + def translate(self, table: _TranslateTable, /) -> str: ... + @overload + def upper(self: LiteralString) -> LiteralString: ... + @overload def upper(self) -> str: ... # type: ignore[misc] - def zfill(self, __width: SupportsIndex) -> str: ... # type: ignore[misc] + @overload + def zfill(self: LiteralString, width: SupportsIndex, /) -> LiteralString: ... + @overload + def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc] @staticmethod @overload - def maketrans(__x: dict[int, _T] | dict[str, _T] | dict[str | int, _T]) -> dict[int, _T]: ... + def maketrans(x: dict[int, _T] | dict[str, _T] | dict[str | int, _T], /) -> dict[int, _T]: ... @staticmethod @overload - def maketrans(__x: str, __y: str) -> dict[int, int]: ... + def maketrans(x: str, y: str, /) -> dict[int, int]: ... @staticmethod @overload - def maketrans(__x: str, __y: str, __z: str) -> dict[int, int | None]: ... - def __add__(self, __value: str) -> str: ... # type: ignore[misc] + 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] - def __eq__(self, __value: object) -> bool: ... - def __ge__(self, __value: str) -> bool: ... - def __getitem__(self, __key: SupportsIndex | slice) -> str: ... - def __gt__(self, __value: str) -> bool: ... + def __contains__(self, key: str, /) -> bool: ... # type: ignore[override] + def __eq__(self, value: object, /) -> bool: ... + def __ge__(self, value: str, /) -> bool: ... + 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 __le__(self, value: str, /) -> bool: ... def __len__(self) -> int: ... - def __lt__(self, __value: str) -> bool: ... - def __mod__(self, __value: Any) -> str: ... - def __mul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] - def __ne__(self, __value: object) -> bool: ... - def __rmul__(self, __value: SupportsIndex) -> str: ... # type: ignore[misc] + 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]: ... class bytes(Sequence[int]): @overload - def __new__(cls, __o: Iterable[SupportsIndex] | SupportsIndex | SupportsBytes | ReadableBuffer) -> Self: ... + def __new__(cls, o: Iterable[SupportsIndex] | SupportsIndex | SupportsBytes | ReadableBuffer, /) -> Self: ... @overload - def __new__(cls, __string: str, encoding: str, errors: str = ...) -> Self: ... + def __new__(cls, string: str, /, encoding: str, errors: str = ...) -> Self: ... @overload def __new__(cls) -> Self: ... def capitalize(self) -> bytes: ... - def center(self, __width: SupportsIndex, __fillchar: bytes = b" ") -> bytes: ... + def center(self, width: SupportsIndex, fillchar: bytes = b" ", /) -> bytes: ... def count( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def decode(self, encoding: str = "utf-8", errors: str = "strict") -> str: ... def endswith( self, - __suffix: ReadableBuffer | tuple[ReadableBuffer, ...], - __start: SupportsIndex | None = ..., - __end: SupportsIndex | None = ..., + suffix: ReadableBuffer | tuple[ReadableBuffer, ...], + start: SupportsIndex | None = ..., + end: SupportsIndex | None = ..., + /, ) -> bool: ... def expandtabs(self, tabsize: SupportsIndex = 8) -> bytes: ... def find( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... def index( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def isalnum(self) -> bool: ... def isalpha(self) -> bool: ... @@ -548,100 +636,102 @@ class bytes(Sequence[int]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - def join(self, __iterable_of_bytes: Iterable[ReadableBuffer]) -> bytes: ... - def ljust(self, __width: SupportsIndex, __fillchar: bytes | bytearray = b" ") -> bytes: ... + def join(self, iterable_of_bytes: Iterable[ReadableBuffer], /) -> bytes: ... + def ljust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytes: ... def lower(self) -> bytes: ... - def lstrip(self, __bytes: ReadableBuffer | None = None) -> bytes: ... - def partition(self, __sep: ReadableBuffer) -> tuple[bytes, bytes, bytes]: ... - def replace(self, __old: ReadableBuffer, __new: ReadableBuffer, __count: SupportsIndex = -1) -> bytes: ... + def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ... + def partition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ... + def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytes: ... if sys.version_info >= (3, 9): - def removeprefix(self, __prefix: ReadableBuffer) -> bytes: ... - def removesuffix(self, __suffix: ReadableBuffer) -> bytes: ... + def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ... + def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ... def rfind( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def rindex( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... - def rjust(self, __width: SupportsIndex, __fillchar: bytes | bytearray = b" ") -> bytes: ... - def rpartition(self, __sep: ReadableBuffer) -> tuple[bytes, bytes, bytes]: ... + def rjust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytes: ... + def rpartition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ... def rsplit(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytes]: ... - def rstrip(self, __bytes: ReadableBuffer | None = None) -> bytes: ... + def rstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ... def split(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytes]: ... def splitlines(self, keepends: bool = False) -> list[bytes]: ... def startswith( self, - __prefix: ReadableBuffer | tuple[ReadableBuffer, ...], - __start: SupportsIndex | None = ..., - __end: SupportsIndex | None = ..., + prefix: ReadableBuffer | tuple[ReadableBuffer, ...], + start: SupportsIndex | None = ..., + end: SupportsIndex | None = ..., + /, ) -> bool: ... - def strip(self, __bytes: ReadableBuffer | None = None) -> bytes: ... + def strip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ... def swapcase(self) -> bytes: ... def title(self) -> bytes: ... - def translate(self, __table: ReadableBuffer | None, delete: bytes = b"") -> bytes: ... + def translate(self, table: ReadableBuffer | None, /, delete: bytes = b"") -> bytes: ... def upper(self) -> bytes: ... - def zfill(self, __width: SupportsIndex) -> bytes: ... + def zfill(self, width: SupportsIndex, /) -> bytes: ... @classmethod - def fromhex(cls, __string: str) -> Self: ... + def fromhex(cls, string: str, /) -> Self: ... @staticmethod - def maketrans(__frm: ReadableBuffer, __to: ReadableBuffer) -> bytes: ... + def maketrans(frm: ReadableBuffer, to: ReadableBuffer, /) -> bytes: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[int]: ... def __hash__(self) -> int: ... @overload - def __getitem__(self, __key: SupportsIndex) -> int: ... + def __getitem__(self, key: SupportsIndex, /) -> int: ... @overload - def __getitem__(self, __key: slice) -> bytes: ... - def __add__(self, __value: ReadableBuffer) -> bytes: ... - def __mul__(self, __value: SupportsIndex) -> bytes: ... - def __rmul__(self, __value: SupportsIndex) -> bytes: ... - def __mod__(self, __value: Any) -> bytes: ... + def __getitem__(self, key: slice, /) -> bytes: ... + def __add__(self, value: ReadableBuffer, /) -> bytes: ... + def __mul__(self, value: SupportsIndex, /) -> bytes: ... + def __rmul__(self, value: SupportsIndex, /) -> bytes: ... + def __mod__(self, value: Any, /) -> bytes: ... # Incompatible with Sequence.__contains__ - def __contains__(self, __key: SupportsIndex | ReadableBuffer) -> bool: ... # type: ignore[override] - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... - def __lt__(self, __value: bytes) -> bool: ... - def __le__(self, __value: bytes) -> bool: ... - def __gt__(self, __value: bytes) -> bool: ... - def __ge__(self, __value: bytes) -> bool: ... + def __contains__(self, key: SupportsIndex | ReadableBuffer, /) -> bool: ... # type: ignore[override] + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... + def __lt__(self, value: bytes, /) -> bool: ... + def __le__(self, value: bytes, /) -> bool: ... + def __gt__(self, value: bytes, /) -> bool: ... + def __ge__(self, value: bytes, /) -> bool: ... def __getnewargs__(self) -> tuple[bytes]: ... if sys.version_info >= (3, 11): def __bytes__(self) -> bytes: ... - def __buffer__(self, __flags: int) -> memoryview: ... + def __buffer__(self, flags: int, /) -> memoryview: ... class bytearray(MutableSequence[int]): @overload def __init__(self) -> None: ... @overload - def __init__(self, __ints: Iterable[SupportsIndex] | SupportsIndex | ReadableBuffer) -> None: ... + def __init__(self, ints: Iterable[SupportsIndex] | SupportsIndex | ReadableBuffer, /) -> None: ... @overload - def __init__(self, __string: str, encoding: str, errors: str = ...) -> None: ... - def append(self, __item: SupportsIndex) -> None: ... + def __init__(self, string: str, /, encoding: str, errors: str = ...) -> None: ... + def append(self, item: SupportsIndex, /) -> None: ... def capitalize(self) -> bytearray: ... - def center(self, __width: SupportsIndex, __fillchar: bytes = b" ") -> bytearray: ... + def center(self, width: SupportsIndex, fillchar: bytes = b" ", /) -> bytearray: ... def count( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def copy(self) -> bytearray: ... def decode(self, encoding: str = "utf-8", errors: str = "strict") -> str: ... def endswith( self, - __suffix: ReadableBuffer | tuple[ReadableBuffer, ...], - __start: SupportsIndex | None = ..., - __end: SupportsIndex | None = ..., + suffix: ReadableBuffer | tuple[ReadableBuffer, ...], + start: SupportsIndex | None = ..., + end: SupportsIndex | None = ..., + /, ) -> bool: ... def expandtabs(self, tabsize: SupportsIndex = 8) -> bytearray: ... - def extend(self, __iterable_of_ints: Iterable[SupportsIndex]) -> None: ... + def extend(self, iterable_of_ints: Iterable[SupportsIndex], /) -> None: ... def find( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... def index( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... - def insert(self, __index: SupportsIndex, __item: SupportsIndex) -> None: ... + def insert(self, index: SupportsIndex, item: SupportsIndex, /) -> None: ... def isalnum(self) -> bool: ... def isalpha(self) -> bool: ... def isascii(self) -> bool: ... @@ -650,76 +740,77 @@ class bytearray(MutableSequence[int]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... - def join(self, __iterable_of_bytes: Iterable[ReadableBuffer]) -> bytearray: ... - def ljust(self, __width: SupportsIndex, __fillchar: bytes | bytearray = b" ") -> bytearray: ... + def join(self, iterable_of_bytes: Iterable[ReadableBuffer], /) -> bytearray: ... + def ljust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytearray: ... def lower(self) -> bytearray: ... - def lstrip(self, __bytes: ReadableBuffer | None = None) -> bytearray: ... - def partition(self, __sep: ReadableBuffer) -> tuple[bytearray, bytearray, bytearray]: ... - def pop(self, __index: int = -1) -> int: ... - def remove(self, __value: int) -> None: ... + def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytearray: ... + def partition(self, sep: ReadableBuffer, /) -> tuple[bytearray, bytearray, bytearray]: ... + def pop(self, index: int = -1, /) -> int: ... + def remove(self, value: int, /) -> None: ... if sys.version_info >= (3, 9): - def removeprefix(self, __prefix: ReadableBuffer) -> bytearray: ... - def removesuffix(self, __suffix: ReadableBuffer) -> bytearray: ... + def removeprefix(self, prefix: ReadableBuffer, /) -> bytearray: ... + def removesuffix(self, suffix: ReadableBuffer, /) -> bytearray: ... - def replace(self, __old: ReadableBuffer, __new: ReadableBuffer, __count: SupportsIndex = -1) -> bytearray: ... + def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytearray: ... def rfind( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... def rindex( - self, __sub: ReadableBuffer | SupportsIndex, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., / ) -> int: ... - def rjust(self, __width: SupportsIndex, __fillchar: bytes | bytearray = b" ") -> bytearray: ... - def rpartition(self, __sep: ReadableBuffer) -> tuple[bytearray, bytearray, bytearray]: ... + def rjust(self, width: SupportsIndex, fillchar: bytes | bytearray = b" ", /) -> bytearray: ... + def rpartition(self, sep: ReadableBuffer, /) -> tuple[bytearray, bytearray, bytearray]: ... def rsplit(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytearray]: ... - def rstrip(self, __bytes: ReadableBuffer | None = None) -> bytearray: ... + def rstrip(self, bytes: ReadableBuffer | None = None, /) -> bytearray: ... def split(self, sep: ReadableBuffer | None = None, maxsplit: SupportsIndex = -1) -> list[bytearray]: ... def splitlines(self, keepends: bool = False) -> list[bytearray]: ... def startswith( self, - __prefix: ReadableBuffer | tuple[ReadableBuffer, ...], - __start: SupportsIndex | None = ..., - __end: SupportsIndex | None = ..., + prefix: ReadableBuffer | tuple[ReadableBuffer, ...], + start: SupportsIndex | None = ..., + end: SupportsIndex | None = ..., + /, ) -> bool: ... - def strip(self, __bytes: ReadableBuffer | None = None) -> bytearray: ... + def strip(self, bytes: ReadableBuffer | None = None, /) -> bytearray: ... def swapcase(self) -> bytearray: ... def title(self) -> bytearray: ... - def translate(self, __table: ReadableBuffer | None, delete: bytes = b"") -> bytearray: ... + def translate(self, table: ReadableBuffer | None, /, delete: bytes = b"") -> bytearray: ... def upper(self) -> bytearray: ... - def zfill(self, __width: SupportsIndex) -> bytearray: ... + def zfill(self, width: SupportsIndex, /) -> bytearray: ... @classmethod - def fromhex(cls, __string: str) -> Self: ... + def fromhex(cls, string: str, /) -> Self: ... @staticmethod - def maketrans(__frm: ReadableBuffer, __to: ReadableBuffer) -> bytes: ... + def maketrans(frm: ReadableBuffer, to: ReadableBuffer, /) -> bytes: ... def __len__(self) -> int: ... def __iter__(self) -> Iterator[int]: ... __hash__: ClassVar[None] # type: ignore[assignment] @overload - def __getitem__(self, __key: SupportsIndex) -> int: ... + def __getitem__(self, key: SupportsIndex, /) -> int: ... @overload - def __getitem__(self, __key: slice) -> bytearray: ... + def __getitem__(self, key: slice, /) -> bytearray: ... @overload - def __setitem__(self, __key: SupportsIndex, __value: SupportsIndex) -> None: ... + def __setitem__(self, key: SupportsIndex, value: SupportsIndex, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: Iterable[SupportsIndex] | bytes) -> None: ... - def __delitem__(self, __key: SupportsIndex | slice) -> None: ... - def __add__(self, __value: ReadableBuffer) -> bytearray: ... + def __setitem__(self, key: slice, value: Iterable[SupportsIndex] | bytes, /) -> None: ... + def __delitem__(self, key: SupportsIndex | slice, /) -> None: ... + def __add__(self, value: ReadableBuffer, /) -> bytearray: ... # The superclass wants us to accept Iterable[int], but that fails at runtime. - def __iadd__(self, __value: ReadableBuffer) -> Self: ... # type: ignore[override] - def __mul__(self, __value: SupportsIndex) -> bytearray: ... - def __rmul__(self, __value: SupportsIndex) -> bytearray: ... - def __imul__(self, __value: SupportsIndex) -> Self: ... - def __mod__(self, __value: Any) -> bytes: ... + def __iadd__(self, value: ReadableBuffer, /) -> Self: ... # type: ignore[override] + def __mul__(self, value: SupportsIndex, /) -> bytearray: ... + def __rmul__(self, value: SupportsIndex, /) -> bytearray: ... + def __imul__(self, value: SupportsIndex, /) -> Self: ... + def __mod__(self, value: Any, /) -> bytes: ... # Incompatible with Sequence.__contains__ - def __contains__(self, __key: SupportsIndex | ReadableBuffer) -> bool: ... # type: ignore[override] - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... - def __lt__(self, __value: ReadableBuffer) -> bool: ... - def __le__(self, __value: ReadableBuffer) -> bool: ... - def __gt__(self, __value: ReadableBuffer) -> bool: ... - def __ge__(self, __value: ReadableBuffer) -> bool: ... + def __contains__(self, key: SupportsIndex | ReadableBuffer, /) -> bool: ... # type: ignore[override] + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... + def __lt__(self, value: ReadableBuffer, /) -> bool: ... + def __le__(self, value: ReadableBuffer, /) -> bool: ... + def __gt__(self, value: ReadableBuffer, /) -> bool: ... + def __ge__(self, value: ReadableBuffer, /) -> bool: ... def __alloc__(self) -> int: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... @final class memoryview(Sequence[int]): @@ -750,22 +841,22 @@ class memoryview(Sequence[int]): def __new__(cls, obj: ReadableBuffer) -> Self: ... def __enter__(self) -> Self: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, / ) -> None: ... def cast(self, format: str, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload - def __getitem__(self, __key: SupportsIndex | tuple[SupportsIndex, ...]) -> int: ... + def __getitem__(self, key: SupportsIndex | tuple[SupportsIndex, ...], /) -> int: ... @overload - def __getitem__(self, __key: slice) -> memoryview: ... - def __contains__(self, __x: object) -> bool: ... + def __getitem__(self, key: slice, /) -> memoryview: ... + def __contains__(self, x: object, /) -> bool: ... def __iter__(self) -> Iterator[int]: ... def __len__(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @overload - def __setitem__(self, __key: slice, __value: ReadableBuffer) -> None: ... + def __setitem__(self, key: slice, value: ReadableBuffer, /) -> None: ... @overload - def __setitem__(self, __key: SupportsIndex | tuple[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: ... else: @@ -775,38 +866,38 @@ class memoryview(Sequence[int]): def toreadonly(self) -> memoryview: ... def release(self) -> None: ... def hex(self, sep: str | bytes = ..., bytes_per_sep: SupportsIndex = ...) -> str: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... @final class bool(int): - def __new__(cls, __o: object = ...) -> Self: ... + def __new__(cls, o: object = ..., /) -> Self: ... # The following overloads could be represented more elegantly with a TypeVar("_B", bool, int), # however mypy has a bug regarding TypeVar constraints (https://github.com/python/mypy/issues/11880). @overload - def __and__(self, __value: bool) -> bool: ... + def __and__(self, value: bool, /) -> bool: ... @overload - def __and__(self, __value: int) -> int: ... + def __and__(self, value: int, /) -> int: ... @overload - def __or__(self, __value: bool) -> bool: ... + def __or__(self, value: bool, /) -> bool: ... @overload - def __or__(self, __value: int) -> int: ... + def __or__(self, value: int, /) -> int: ... @overload - def __xor__(self, __value: bool) -> bool: ... + def __xor__(self, value: bool, /) -> bool: ... @overload - def __xor__(self, __value: int) -> int: ... + def __xor__(self, value: int, /) -> int: ... @overload - def __rand__(self, __value: bool) -> bool: ... + def __rand__(self, value: bool, /) -> bool: ... @overload - def __rand__(self, __value: int) -> int: ... + def __rand__(self, value: int, /) -> int: ... @overload - def __ror__(self, __value: bool) -> bool: ... + def __ror__(self, value: bool, /) -> bool: ... @overload - def __ror__(self, __value: int) -> int: ... + def __ror__(self, value: int, /) -> int: ... @overload - def __rxor__(self, __value: bool) -> bool: ... + def __rxor__(self, value: bool, /) -> bool: ... @overload - def __rxor__(self, __value: int) -> int: ... + def __rxor__(self, value: int, /) -> int: ... def __getnewargs__(self) -> tuple[int]: ... @deprecated("Will throw an error in Python 3.14. Use `not` for logical negation of bools instead.") def __invert__(self) -> int: ... @@ -820,38 +911,38 @@ class slice: @property def stop(self) -> Any: ... @overload - def __new__(cls, __stop: Any) -> Self: ... + def __new__(cls, stop: Any, /) -> Self: ... @overload - def __new__(cls, __start: Any, __stop: Any, __step: Any = ...) -> Self: ... - def __eq__(self, __value: object) -> bool: ... + def __new__(cls, start: Any, stop: Any, step: Any = ..., /) -> Self: ... + def __eq__(self, value: object, /) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] - def indices(self, __len: SupportsIndex) -> tuple[int, int, int]: ... + def indices(self, len: SupportsIndex, /) -> tuple[int, int, int]: ... class tuple(Sequence[_T_co]): - def __new__(cls, __iterable: Iterable[_T_co] = ...) -> Self: ... + def __new__(cls, iterable: Iterable[_T_co] = ..., /) -> Self: ... def __len__(self) -> int: ... - def __contains__(self, __key: object) -> bool: ... + def __contains__(self, key: object, /) -> bool: ... @overload - def __getitem__(self, __key: SupportsIndex) -> _T_co: ... + def __getitem__(self, key: SupportsIndex, /) -> _T_co: ... @overload - def __getitem__(self, __key: slice) -> tuple[_T_co, ...]: ... + def __getitem__(self, key: slice, /) -> tuple[_T_co, ...]: ... def __iter__(self) -> Iterator[_T_co]: ... - def __lt__(self, __value: tuple[_T_co, ...]) -> bool: ... - def __le__(self, __value: tuple[_T_co, ...]) -> bool: ... - def __gt__(self, __value: tuple[_T_co, ...]) -> bool: ... - def __ge__(self, __value: tuple[_T_co, ...]) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __lt__(self, value: tuple[_T_co, ...], /) -> bool: ... + def __le__(self, value: tuple[_T_co, ...], /) -> bool: ... + def __gt__(self, value: tuple[_T_co, ...], /) -> bool: ... + def __ge__(self, value: tuple[_T_co, ...], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @overload - def __add__(self, __value: tuple[_T_co, ...]) -> tuple[_T_co, ...]: ... + def __add__(self, value: tuple[_T_co, ...], /) -> tuple[_T_co, ...]: ... @overload - def __add__(self, __value: tuple[_T, ...]) -> tuple[_T_co | _T, ...]: ... - def __mul__(self, __value: SupportsIndex) -> tuple[_T_co, ...]: ... - def __rmul__(self, __value: SupportsIndex) -> tuple[_T_co, ...]: ... - def count(self, __value: Any) -> int: ... - def index(self, __value: Any, __start: SupportsIndex = 0, __stop: SupportsIndex = sys.maxsize) -> int: ... + def __add__(self, value: tuple[_T, ...], /) -> tuple[_T_co | _T, ...]: ... + def __mul__(self, value: SupportsIndex, /) -> tuple[_T_co, ...]: ... + def __rmul__(self, value: SupportsIndex, /) -> tuple[_T_co, ...]: ... + def count(self, value: Any, /) -> int: ... + def index(self, value: Any, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... # Doesn't exist at runtime, but deleting this breaks mypy. See #2999 @final @@ -877,23 +968,23 @@ class function: __module__: str # mypy uses `builtins.function.__get__` to represent methods, properties, and getset_descriptors so we type the return as Any. - def __get__(self, __instance: object, __owner: type | None = None) -> Any: ... + def __get__(self, instance: object, owner: type | None = None, /) -> Any: ... class list(MutableSequence[_T]): @overload def __init__(self) -> None: ... @overload - def __init__(self, __iterable: Iterable[_T]) -> None: ... + def __init__(self, iterable: Iterable[_T], /) -> None: ... def copy(self) -> list[_T]: ... - def append(self, __object: _T) -> None: ... - def extend(self, __iterable: Iterable[_T]) -> None: ... - def pop(self, __index: SupportsIndex = -1) -> _T: ... + def append(self, object: _T, /) -> None: ... + def extend(self, iterable: Iterable[_T], /) -> None: ... + def pop(self, index: SupportsIndex = -1, /) -> _T: ... # Signature of `list.index` should be kept in line with `collections.UserList.index()` # and multiprocessing.managers.ListProxy.index() - def index(self, __value: _T, __start: SupportsIndex = 0, __stop: SupportsIndex = sys.maxsize) -> int: ... - def count(self, __value: _T) -> int: ... - def insert(self, __index: SupportsIndex, __object: _T) -> None: ... - def remove(self, __value: _T) -> None: ... + def index(self, value: _T, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int: ... + def count(self, value: _T, /) -> int: ... + def insert(self, index: SupportsIndex, object: _T, /) -> None: ... + def remove(self, value: _T, /) -> None: ... # Signature of `list.sort` should be kept inline with `collections.UserList.sort()` # and multiprocessing.managers.ListProxy.sort() # @@ -907,32 +998,32 @@ class list(MutableSequence[_T]): def __iter__(self) -> Iterator[_T]: ... __hash__: ClassVar[None] # type: ignore[assignment] @overload - def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __getitem__(self, i: SupportsIndex, /) -> _T: ... @overload - def __getitem__(self, __s: slice) -> list[_T]: ... + def __getitem__(self, s: slice, /) -> list[_T]: ... @overload - def __setitem__(self, __key: SupportsIndex, __value: _T) -> None: ... + def __setitem__(self, key: SupportsIndex, value: _T, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: Iterable[_T]) -> None: ... - def __delitem__(self, __key: SupportsIndex | slice) -> None: ... + def __setitem__(self, key: slice, value: Iterable[_T], /) -> None: ... + def __delitem__(self, key: SupportsIndex | slice, /) -> None: ... # Overloading looks unnecessary, but is needed to work around complex mypy problems @overload - def __add__(self, __value: list[_T]) -> list[_T]: ... + def __add__(self, value: list[_T], /) -> list[_T]: ... @overload - def __add__(self, __value: list[_S]) -> list[_S | _T]: ... - def __iadd__(self, __value: Iterable[_T]) -> Self: ... # type: ignore[misc] - def __mul__(self, __value: SupportsIndex) -> list[_T]: ... - def __rmul__(self, __value: SupportsIndex) -> list[_T]: ... - def __imul__(self, __value: SupportsIndex) -> Self: ... - def __contains__(self, __key: object) -> bool: ... + def __add__(self, value: list[_S], /) -> list[_S | _T]: ... + def __iadd__(self, value: Iterable[_T], /) -> Self: ... # type: ignore[misc] + def __mul__(self, value: SupportsIndex, /) -> list[_T]: ... + def __rmul__(self, value: SupportsIndex, /) -> list[_T]: ... + def __imul__(self, value: SupportsIndex, /) -> Self: ... + def __contains__(self, key: object, /) -> bool: ... def __reversed__(self) -> Iterator[_T]: ... - def __gt__(self, __value: list[_T]) -> bool: ... - def __ge__(self, __value: list[_T]) -> bool: ... - def __lt__(self, __value: list[_T]) -> bool: ... - def __le__(self, __value: list[_T]) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __gt__(self, value: list[_T], /) -> bool: ... + def __ge__(self, value: list[_T], /) -> bool: ... + def __lt__(self, value: list[_T], /) -> bool: ... + def __le__(self, value: list[_T], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class dict(MutableMapping[_KT, _VT]): # __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics @@ -942,19 +1033,19 @@ class dict(MutableMapping[_KT, _VT]): @overload def __init__(self: dict[str, _VT], **kwargs: _VT) -> None: ... @overload - def __init__(self, __map: SupportsKeysAndGetItem[_KT, _VT]) -> None: ... + def __init__(self, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload - def __init__(self: dict[str, _VT], __map: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> None: ... + def __init__(self: dict[str, _VT], map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... @overload - def __init__(self, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ... + def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload - def __init__(self: dict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ... + def __init__(self: dict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... # Next two overloads are for dict(string.split(sep) for string in iterable) # Cannot be Iterable[Sequence[_T]] or otherwise dict(["foo", "bar", "baz"]) is not an error @overload - def __init__(self: dict[str, str], __iterable: Iterable[list[str]]) -> None: ... + def __init__(self: dict[str, str], iterable: Iterable[list[str]], /) -> None: ... @overload - def __init__(self: dict[bytes, bytes], __iterable: Iterable[list[bytes]]) -> None: ... + def __init__(self: dict[bytes, bytes], iterable: Iterable[list[bytes]], /) -> None: ... def __new__(cls, *args: Any, **kwargs: Any) -> Self: ... def copy(self) -> dict[_KT, _VT]: ... def keys(self) -> dict_keys[_KT, _VT]: ... @@ -965,122 +1056,122 @@ class dict(MutableMapping[_KT, _VT]): # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. @classmethod @overload - def fromkeys(cls, __iterable: Iterable[_T], __value: None = None) -> dict[_T, Any | None]: ... + def fromkeys(cls, iterable: Iterable[_T], value: None = None, /) -> dict[_T, Any | None]: ... @classmethod @overload - def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> dict[_T, _S]: ... + def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> dict[_T, _S]: ... # Positional-only in dict, but not in MutableMapping @overload # type: ignore[override] - def get(self, __key: _KT) -> _VT | None: ... + def get(self, key: _KT, /) -> _VT | None: ... @overload - def get(self, __key: _KT, __default: _VT) -> _VT: ... + def get(self, key: _KT, default: _VT, /) -> _VT: ... @overload - def get(self, __key: _KT, __default: _T) -> _VT | _T: ... + def get(self, key: _KT, default: _T, /) -> _VT | _T: ... @overload - def pop(self, __key: _KT) -> _VT: ... + def pop(self, key: _KT, /) -> _VT: ... @overload - def pop(self, __key: _KT, __default: _VT) -> _VT: ... + def pop(self, key: _KT, default: _VT, /) -> _VT: ... @overload - def pop(self, __key: _KT, __default: _T) -> _VT | _T: ... + def pop(self, key: _KT, default: _T, /) -> _VT | _T: ... def __len__(self) -> int: ... - def __getitem__(self, __key: _KT) -> _VT: ... - def __setitem__(self, __key: _KT, __value: _VT) -> None: ... - def __delitem__(self, __key: _KT) -> None: ... + def __getitem__(self, key: _KT, /) -> _VT: ... + def __setitem__(self, key: _KT, value: _VT, /) -> None: ... + def __delitem__(self, key: _KT, /) -> None: ... def __iter__(self) -> Iterator[_KT]: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __reversed__(self) -> Iterator[_KT]: ... __hash__: ClassVar[None] # type: ignore[assignment] if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @overload - def __or__(self, __value: dict[_KT, _VT]) -> dict[_KT, _VT]: ... + def __or__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ... @overload - def __or__(self, __value: dict[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ... + def __or__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... @overload - def __ror__(self, __value: dict[_KT, _VT]) -> dict[_KT, _VT]: ... + def __ror__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ... @overload - def __ror__(self, __value: dict[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]: ... + def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... # dict.__ior__ should be kept roughly in line with MutableMapping.update() @overload # type: ignore[misc] - def __ior__(self, __value: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ... + def __ior__(self, value: SupportsKeysAndGetItem[_KT, _VT], /) -> Self: ... @overload - def __ior__(self, __value: Iterable[tuple[_KT, _VT]]) -> Self: ... + def __ior__(self, value: Iterable[tuple[_KT, _VT]], /) -> Self: ... class set(MutableSet[_T]): @overload def __init__(self) -> None: ... @overload - def __init__(self, __iterable: Iterable[_T]) -> None: ... - def add(self, __element: _T) -> None: ... + def __init__(self, iterable: Iterable[_T], /) -> None: ... + def add(self, element: _T, /) -> None: ... def copy(self) -> set[_T]: ... def difference(self, *s: Iterable[Any]) -> set[_T]: ... def difference_update(self, *s: Iterable[Any]) -> None: ... - def discard(self, __element: _T) -> None: ... + def discard(self, element: _T, /) -> None: ... def intersection(self, *s: Iterable[Any]) -> set[_T]: ... def intersection_update(self, *s: Iterable[Any]) -> None: ... - def isdisjoint(self, __s: Iterable[Any]) -> bool: ... - def issubset(self, __s: Iterable[Any]) -> bool: ... - def issuperset(self, __s: Iterable[Any]) -> bool: ... - def remove(self, __element: _T) -> None: ... - def symmetric_difference(self, __s: Iterable[_T]) -> set[_T]: ... - def symmetric_difference_update(self, __s: Iterable[_T]) -> None: ... + def isdisjoint(self, s: Iterable[Any], /) -> bool: ... + def issubset(self, s: Iterable[Any], /) -> bool: ... + def issuperset(self, s: Iterable[Any], /) -> bool: ... + def remove(self, element: _T, /) -> None: ... + def symmetric_difference(self, s: Iterable[_T], /) -> set[_T]: ... + def symmetric_difference_update(self, s: Iterable[_T], /) -> None: ... def union(self, *s: Iterable[_S]) -> set[_T | _S]: ... def update(self, *s: Iterable[_T]) -> None: ... def __len__(self) -> int: ... - def __contains__(self, __o: object) -> bool: ... + def __contains__(self, o: object, /) -> bool: ... def __iter__(self) -> Iterator[_T]: ... - def __and__(self, __value: AbstractSet[object]) -> set[_T]: ... - def __iand__(self, __value: AbstractSet[object]) -> Self: ... - def __or__(self, __value: AbstractSet[_S]) -> set[_T | _S]: ... - def __ior__(self, __value: AbstractSet[_T]) -> Self: ... # type: ignore[override,misc] - def __sub__(self, __value: AbstractSet[_T | None]) -> set[_T]: ... - def __isub__(self, __value: AbstractSet[object]) -> Self: ... - def __xor__(self, __value: AbstractSet[_S]) -> set[_T | _S]: ... - def __ixor__(self, __value: AbstractSet[_T]) -> Self: ... # type: ignore[override,misc] - def __le__(self, __value: AbstractSet[object]) -> bool: ... - def __lt__(self, __value: AbstractSet[object]) -> bool: ... - def __ge__(self, __value: AbstractSet[object]) -> bool: ... - def __gt__(self, __value: AbstractSet[object]) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __and__(self, value: AbstractSet[object], /) -> set[_T]: ... + def __iand__(self, value: AbstractSet[object], /) -> Self: ... + def __or__(self, value: AbstractSet[_S], /) -> set[_T | _S]: ... + def __ior__(self, value: AbstractSet[_T], /) -> Self: ... # type: ignore[override,misc] + def __sub__(self, value: AbstractSet[_T | None], /) -> set[_T]: ... + def __isub__(self, value: AbstractSet[object], /) -> Self: ... + def __xor__(self, value: AbstractSet[_S], /) -> set[_T | _S]: ... + def __ixor__(self, value: AbstractSet[_T], /) -> Self: ... # type: ignore[override,misc] + def __le__(self, value: AbstractSet[object], /) -> bool: ... + def __lt__(self, value: AbstractSet[object], /) -> bool: ... + def __ge__(self, value: AbstractSet[object], /) -> bool: ... + def __gt__(self, value: AbstractSet[object], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class frozenset(AbstractSet[_T_co]): @overload def __new__(cls) -> Self: ... @overload - def __new__(cls, __iterable: Iterable[_T_co]) -> Self: ... + def __new__(cls, iterable: Iterable[_T_co], /) -> Self: ... def copy(self) -> frozenset[_T_co]: ... def difference(self, *s: Iterable[object]) -> frozenset[_T_co]: ... def intersection(self, *s: Iterable[object]) -> frozenset[_T_co]: ... - def isdisjoint(self, __s: Iterable[_T_co]) -> bool: ... - def issubset(self, __s: Iterable[object]) -> bool: ... - def issuperset(self, __s: Iterable[object]) -> bool: ... - def symmetric_difference(self, __s: Iterable[_T_co]) -> frozenset[_T_co]: ... + def isdisjoint(self, s: Iterable[_T_co], /) -> bool: ... + def issubset(self, s: Iterable[object], /) -> bool: ... + def issuperset(self, s: Iterable[object], /) -> bool: ... + def symmetric_difference(self, s: Iterable[_T_co], /) -> frozenset[_T_co]: ... def union(self, *s: Iterable[_S]) -> frozenset[_T_co | _S]: ... def __len__(self) -> int: ... - def __contains__(self, __o: object) -> bool: ... + def __contains__(self, o: object, /) -> bool: ... def __iter__(self) -> Iterator[_T_co]: ... - def __and__(self, __value: AbstractSet[_T_co]) -> frozenset[_T_co]: ... - def __or__(self, __value: AbstractSet[_S]) -> frozenset[_T_co | _S]: ... - def __sub__(self, __value: AbstractSet[_T_co]) -> frozenset[_T_co]: ... - def __xor__(self, __value: AbstractSet[_S]) -> frozenset[_T_co | _S]: ... - def __le__(self, __value: AbstractSet[object]) -> bool: ... - def __lt__(self, __value: AbstractSet[object]) -> bool: ... - def __ge__(self, __value: AbstractSet[object]) -> bool: ... - def __gt__(self, __value: AbstractSet[object]) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __and__(self, value: AbstractSet[_T_co], /) -> frozenset[_T_co]: ... + def __or__(self, value: AbstractSet[_S], /) -> frozenset[_T_co | _S]: ... + def __sub__(self, value: AbstractSet[_T_co], /) -> frozenset[_T_co]: ... + def __xor__(self, value: AbstractSet[_S], /) -> frozenset[_T_co | _S]: ... + def __le__(self, value: AbstractSet[object], /) -> bool: ... + def __lt__(self, value: AbstractSet[object], /) -> bool: ... + def __ge__(self, value: AbstractSet[object], /) -> bool: ... + def __gt__(self, value: AbstractSet[object], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class enumerate(Iterator[tuple[int, _T]]): def __new__(cls, iterable: Iterable[_T], start: int = ...) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> tuple[int, _T]: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @final class range(Sequence[int]): @@ -1091,20 +1182,20 @@ class range(Sequence[int]): @property def step(self) -> int: ... @overload - def __new__(cls, __stop: SupportsIndex) -> Self: ... + def __new__(cls, stop: SupportsIndex, /) -> Self: ... @overload - def __new__(cls, __start: SupportsIndex, __stop: SupportsIndex, __step: SupportsIndex = ...) -> Self: ... - def count(self, __value: int) -> int: ... - def index(self, __value: int) -> int: ... # type: ignore[override] + def __new__(cls, start: SupportsIndex, stop: SupportsIndex, step: SupportsIndex = ..., /) -> Self: ... + def count(self, value: int, /) -> int: ... + def index(self, value: int, /) -> int: ... # type: ignore[override] def __len__(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... - def __contains__(self, __key: object) -> bool: ... + def __contains__(self, key: object, /) -> bool: ... def __iter__(self) -> Iterator[int]: ... @overload - def __getitem__(self, __key: SupportsIndex) -> int: ... + def __getitem__(self, key: SupportsIndex, /) -> int: ... @overload - def __getitem__(self, __key: slice) -> range: ... + def __getitem__(self, key: slice, /) -> range: ... def __reversed__(self) -> Iterator[int]: ... class property: @@ -1119,12 +1210,12 @@ class property: fdel: Callable[[Any], None] | None = ..., doc: str | None = ..., ) -> None: ... - def getter(self, __fget: Callable[[Any], Any]) -> property: ... - def setter(self, __fset: Callable[[Any, Any], None]) -> property: ... - def deleter(self, __fdel: Callable[[Any], None]) -> property: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... - def __set__(self, __instance: Any, __value: Any) -> None: ... - def __delete__(self, __instance: Any) -> None: ... + def getter(self, fget: Callable[[Any], Any], /) -> property: ... + def setter(self, fset: Callable[[Any, Any], None], /) -> property: ... + def deleter(self, fdel: Callable[[Any], None], /) -> property: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... + def __set__(self, instance: Any, value: Any, /) -> None: ... + def __delete__(self, instance: Any, /) -> None: ... @final class _NotImplementedType(Any): @@ -1134,14 +1225,14 @@ class _NotImplementedType(Any): NotImplemented: _NotImplementedType -def abs(__x: SupportsAbs[_T]) -> _T: ... -def all(__iterable: Iterable[object]) -> bool: ... -def any(__iterable: Iterable[object]) -> bool: ... -def ascii(__obj: object) -> str: ... -def bin(__number: int | SupportsIndex) -> str: ... +def abs(x: SupportsAbs[_T], /) -> _T: ... +def all(iterable: Iterable[object], /) -> bool: ... +def any(iterable: Iterable[object], /) -> bool: ... +def ascii(obj: object, /) -> str: ... +def bin(number: int | SupportsIndex, /) -> str: ... def breakpoint(*args: Any, **kws: Any) -> None: ... -def callable(__obj: object) -> TypeGuard[Callable[..., object]]: ... -def chr(__i: int) -> str: ... +def callable(obj: object, /) -> TypeGuard[Callable[..., object]]: ... +def chr(i: int, /) -> str: ... # We define this here instead of using os.PathLike to avoid import cycle issues. # See https://github.com/python/typeshed/pull/991#issuecomment-288160993 @@ -1149,7 +1240,7 @@ class _PathLike(Protocol[AnyStr_co]): def __fspath__(self) -> AnyStr_co: ... if sys.version_info >= (3, 10): - def aiter(__async_iterable: SupportsAiter[_SupportsAnextT]) -> _SupportsAnextT: ... + def aiter(async_iterable: SupportsAiter[_SupportsAnextT], /) -> _SupportsAnextT: ... class _SupportsSynchronousAnext(Protocol[_AwaitableT_co]): def __anext__(self) -> _AwaitableT_co: ... @@ -1158,9 +1249,9 @@ if sys.version_info >= (3, 10): # `anext` is not, in fact, an async function. When default is not provided # `anext` is just a passthrough for `obj.__anext__` # See discussion in #7491 and pure-Python implementation of `anext` at https://github.com/python/cpython/blob/ea786a882b9ed4261eafabad6011bc7ef3b5bf94/Lib/test/test_asyncgen.py#L52-L80 - def anext(__i: _SupportsSynchronousAnext[_AwaitableT]) -> _AwaitableT: ... + def anext(i: _SupportsSynchronousAnext[_AwaitableT], /) -> _AwaitableT: ... @overload - async def anext(__i: SupportsAnext[_T], __default: _VT) -> _T | _VT: ... + async def anext(i: SupportsAnext[_T], default: _VT, /) -> _T | _VT: ... # 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 @@ -1210,86 +1301,86 @@ def compile( ) -> Any: ... def copyright() -> None: ... def credits() -> None: ... -def delattr(__obj: object, __name: str) -> None: ... -def dir(__o: object = ...) -> list[str]: ... +def delattr(obj: object, name: str, /) -> None: ... +def dir(o: object = ..., /) -> list[str]: ... @overload -def divmod(__x: SupportsDivMod[_T_contra, _T_co], __y: _T_contra) -> _T_co: ... +def divmod(x: SupportsDivMod[_T_contra, _T_co], y: _T_contra, /) -> _T_co: ... @overload -def divmod(__x: _T_contra, __y: SupportsRDivMod[_T_contra, _T_co]) -> _T_co: ... +def divmod(x: _T_contra, y: SupportsRDivMod[_T_contra, _T_co], /) -> _T_co: ... # The `globals` argument to `eval` has to be `dict[str, Any]` rather than `dict[str, object]` due to invariance. # (The `globals` argument has to be a "real dict", rather than any old mapping, unlike the `locals` argument.) def eval( - __source: str | ReadableBuffer | CodeType, - __globals: dict[str, Any] | None = None, - __locals: Mapping[str, object] | None = None, + source: str | ReadableBuffer | CodeType, globals: dict[str, Any] | None = None, locals: Mapping[str, object] | None = None, / ) -> Any: ... # Comment above regarding `eval` applies to `exec` as well if sys.version_info >= (3, 11): def exec( - __source: str | ReadableBuffer | CodeType, - __globals: dict[str, Any] | None = None, - __locals: Mapping[str, object] | None = None, + source: str | ReadableBuffer | CodeType, + globals: dict[str, Any] | None = None, + locals: Mapping[str, object] | None = None, + /, *, closure: tuple[_Cell, ...] | None = None, ) -> None: ... else: def exec( - __source: str | ReadableBuffer | CodeType, - __globals: dict[str, Any] | None = None, - __locals: Mapping[str, object] | None = None, + source: str | ReadableBuffer | CodeType, + globals: dict[str, Any] | None = None, + locals: Mapping[str, object] | None = None, + /, ) -> None: ... def exit(code: sys._ExitCode = None) -> NoReturn: ... class filter(Iterator[_T]): @overload - def __new__(cls, __function: None, __iterable: Iterable[_T | None]) -> Self: ... + def __new__(cls, function: None, iterable: Iterable[_T | None], /) -> Self: ... @overload - def __new__(cls, __function: Callable[[_S], TypeGuard[_T]], __iterable: Iterable[_S]) -> Self: ... + def __new__(cls, function: Callable[[_S], TypeGuard[_T]], iterable: Iterable[_S], /) -> Self: ... @overload - def __new__(cls, __function: Callable[[_T], Any], __iterable: Iterable[_T]) -> Self: ... + def __new__(cls, function: Callable[[_T], Any], iterable: Iterable[_T], /) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -def format(__value: object, __format_spec: str = "") -> str: ... +def format(value: object, format_spec: str = "", /) -> str: ... @overload -def getattr(__o: object, __name: str) -> Any: ... +def getattr(o: object, name: str, /) -> Any: ... # While technically covered by the last overload, spelling out the types for None, bool # and basic containers help mypy out in some tricky situations involving type context # (aka bidirectional inference) @overload -def getattr(__o: object, __name: str, __default: None) -> Any | None: ... +def getattr(o: object, name: str, default: None, /) -> Any | None: ... @overload -def getattr(__o: object, __name: str, __default: bool) -> Any | bool: ... +def getattr(o: object, name: str, default: bool, /) -> Any | bool: ... @overload -def getattr(__o: object, __name: str, __default: list[Any]) -> Any | list[Any]: ... +def getattr(o: object, name: str, default: list[Any], /) -> Any | list[Any]: ... @overload -def getattr(__o: object, __name: str, __default: dict[Any, Any]) -> Any | dict[Any, Any]: ... +def getattr(o: object, name: str, default: dict[Any, Any], /) -> Any | dict[Any, Any]: ... @overload -def getattr(__o: object, __name: str, __default: _T) -> Any | _T: ... +def getattr(o: object, name: str, default: _T, /) -> Any | _T: ... def globals() -> dict[str, Any]: ... -def hasattr(__obj: object, __name: str) -> bool: ... -def hash(__obj: object) -> int: ... +def hasattr(obj: object, name: str, /) -> bool: ... +def hash(obj: object, /) -> int: ... def help(request: object = ...) -> None: ... -def hex(__number: int | SupportsIndex) -> str: ... -def id(__obj: object) -> int: ... -def input(__prompt: object = "") -> str: ... +def hex(number: int | SupportsIndex, /) -> str: ... +def id(obj: object, /) -> int: ... +def input(prompt: object = "", /) -> str: ... class _GetItemIterable(Protocol[_T_co]): - def __getitem__(self, __i: int) -> _T_co: ... + def __getitem__(self, i: int, /) -> _T_co: ... @overload -def iter(__object: SupportsIter[_SupportsNextT]) -> _SupportsNextT: ... +def iter(object: SupportsIter[_SupportsNextT], /) -> _SupportsNextT: ... @overload -def iter(__object: _GetItemIterable[_T]) -> Iterator[_T]: ... +def iter(object: _GetItemIterable[_T], /) -> Iterator[_T]: ... @overload -def iter(__object: Callable[[], _T | None], __sentinel: None) -> Iterator[_T]: ... +def iter(object: Callable[[], _T | None], sentinel: None, /) -> Iterator[_T]: ... @overload -def iter(__object: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... +def iter(object: Callable[[], _T], sentinel: object, /) -> Iterator[_T]: ... # Keep this alias in sync with unittest.case._ClassInfo if sys.version_info >= (3, 10): @@ -1297,50 +1388,53 @@ if sys.version_info >= (3, 10): else: _ClassInfo: TypeAlias = type | tuple[_ClassInfo, ...] -def isinstance(__obj: object, __class_or_tuple: _ClassInfo) -> bool: ... -def issubclass(__cls: type, __class_or_tuple: _ClassInfo) -> bool: ... -def len(__obj: Sized) -> int: ... +def isinstance(obj: object, class_or_tuple: _ClassInfo, /) -> bool: ... +def issubclass(cls: type, class_or_tuple: _ClassInfo, /) -> bool: ... +def len(obj: Sized, /) -> int: ... def license() -> None: ... def locals() -> dict[str, Any]: ... class map(Iterator[_S]): @overload - def __new__(cls, __func: Callable[[_T1], _S], __iter1: Iterable[_T1]) -> Self: ... + def __new__(cls, func: Callable[[_T1], _S], iter1: Iterable[_T1], /) -> Self: ... @overload - def __new__(cls, __func: Callable[[_T1, _T2], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> Self: ... + def __new__(cls, func: Callable[[_T1, _T2], _S], iter1: Iterable[_T1], iter2: Iterable[_T2], /) -> Self: ... @overload def __new__( - cls, __func: Callable[[_T1, _T2, _T3], _S], __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3] + cls, func: Callable[[_T1, _T2, _T3], _S], iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], / ) -> Self: ... @overload def __new__( cls, - __func: Callable[[_T1, _T2, _T3, _T4], _S], - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], + func: Callable[[_T1, _T2, _T3, _T4], _S], + iter1: Iterable[_T1], + iter2: Iterable[_T2], + iter3: Iterable[_T3], + iter4: Iterable[_T4], + /, ) -> Self: ... @overload def __new__( cls, - __func: Callable[[_T1, _T2, _T3, _T4, _T5], _S], - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + func: Callable[[_T1, _T2, _T3, _T4, _T5], _S], + iter1: Iterable[_T1], + iter2: Iterable[_T2], + iter3: Iterable[_T3], + iter4: Iterable[_T4], + iter5: Iterable[_T5], + /, ) -> Self: ... @overload def __new__( cls, - __func: Callable[..., _S], - __iter1: Iterable[Any], - __iter2: Iterable[Any], - __iter3: Iterable[Any], - __iter4: Iterable[Any], - __iter5: Iterable[Any], - __iter6: Iterable[Any], + func: Callable[..., _S], + iter1: Iterable[Any], + iter2: Iterable[Any], + iter3: Iterable[Any], + iter4: Iterable[Any], + iter5: Iterable[Any], + iter6: Iterable[Any], + /, *iterables: Iterable[Any], ) -> Self: ... def __iter__(self) -> Self: ... @@ -1348,37 +1442,37 @@ class map(Iterator[_S]): @overload def max( - __arg1: SupportsRichComparisonT, __arg2: SupportsRichComparisonT, *_args: SupportsRichComparisonT, key: None = None + arg1: SupportsRichComparisonT, arg2: SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = None ) -> SupportsRichComparisonT: ... @overload -def max(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... +def max(arg1: _T, arg2: _T, /, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def max(__iterable: Iterable[SupportsRichComparisonT], *, key: None = None) -> SupportsRichComparisonT: ... +def max(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None) -> SupportsRichComparisonT: ... @overload -def max(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... +def max(iterable: Iterable[_T], /, *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def max(__iterable: Iterable[SupportsRichComparisonT], *, key: None = None, default: _T) -> SupportsRichComparisonT | _T: ... +def max(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None, default: _T) -> SupportsRichComparisonT | _T: ... @overload -def max(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... +def max(iterable: Iterable[_T1], /, *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... @overload def min( - __arg1: SupportsRichComparisonT, __arg2: SupportsRichComparisonT, *_args: SupportsRichComparisonT, key: None = None + arg1: SupportsRichComparisonT, arg2: SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = None ) -> SupportsRichComparisonT: ... @overload -def min(__arg1: _T, __arg2: _T, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... +def min(arg1: _T, arg2: _T, /, *_args: _T, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def min(__iterable: Iterable[SupportsRichComparisonT], *, key: None = None) -> SupportsRichComparisonT: ... +def min(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None) -> SupportsRichComparisonT: ... @overload -def min(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... +def min(iterable: Iterable[_T], /, *, key: Callable[[_T], SupportsRichComparison]) -> _T: ... @overload -def min(__iterable: Iterable[SupportsRichComparisonT], *, key: None = None, default: _T) -> SupportsRichComparisonT | _T: ... +def min(iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None, default: _T) -> SupportsRichComparisonT | _T: ... @overload -def min(__iterable: Iterable[_T1], *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... +def min(iterable: Iterable[_T1], /, *, key: Callable[[_T1], SupportsRichComparison], default: _T2) -> _T1 | _T2: ... @overload -def next(__i: SupportsNext[_T]) -> _T: ... +def next(i: SupportsNext[_T], /) -> _T: ... @overload -def next(__i: SupportsNext[_T], __default: _VT) -> _T | _VT: ... -def oct(__number: int | SupportsIndex) -> str: ... +def next(i: SupportsNext[_T], default: _VT, /) -> _T | _VT: ... +def oct(number: int | SupportsIndex, /) -> str: ... _Opener: TypeAlias = Callable[[str, int], int] @@ -1468,7 +1562,7 @@ def open( closefd: bool = True, opener: _Opener | None = None, ) -> IO[Any]: ... -def ord(__c: str | bytes | bytearray) -> int: ... +def ord(c: str | bytes | bytearray, /) -> int: ... class _SupportsWriteAndFlush(SupportsWrite[_T_contra], SupportsFlush, Protocol[_T_contra]): ... @@ -1489,13 +1583,13 @@ _E = TypeVar("_E", contravariant=True) _M = TypeVar("_M", contravariant=True) class _SupportsPow2(Protocol[_E, _T_co]): - def __pow__(self, __other: _E) -> _T_co: ... + def __pow__(self, other: _E, /) -> _T_co: ... class _SupportsPow3NoneOnly(Protocol[_E, _T_co]): - def __pow__(self, __other: _E, __modulo: None = None) -> _T_co: ... + def __pow__(self, other: _E, modulo: None = None, /) -> _T_co: ... class _SupportsPow3(Protocol[_E, _M, _T_co]): - def __pow__(self, __other: _E, __modulo: _M) -> _T_co: ... + def __pow__(self, other: _E, modulo: _M, /) -> _T_co: ... _SupportsSomeKindOfPow = ( # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed _SupportsPow2[Any, Any] | _SupportsPow3NoneOnly[Any, Any] | _SupportsPow3[Any, Any, Any] @@ -1544,14 +1638,14 @@ def quit(code: sys._ExitCode = None) -> NoReturn: ... class reversed(Iterator[_T]): @overload - def __new__(cls, __sequence: Reversible[_T]) -> Iterator[_T]: ... # type: ignore[misc] + def __new__(cls, sequence: Reversible[_T], /) -> Iterator[_T]: ... # type: ignore[misc] @overload - def __new__(cls, __sequence: SupportsLenAndGetItem[_T]) -> Iterator[_T]: ... # type: ignore[misc] + def __new__(cls, sequence: SupportsLenAndGetItem[_T], /) -> Iterator[_T]: ... # type: ignore[misc] def __iter__(self) -> Self: ... def __next__(self) -> _T: ... def __length_hint__(self) -> int: ... -def repr(__obj: object) -> str: ... +def repr(obj: object, /) -> str: ... # See https://github.com/python/typeshed/pull/9141 # and https://github.com/python/typeshed/pull/9151 @@ -1561,7 +1655,7 @@ class _SupportsRound1(Protocol[_T_co]): def __round__(self) -> _T_co: ... class _SupportsRound2(Protocol[_T_co]): - def __round__(self, __ndigits: int) -> _T_co: ... + def __round__(self, ndigits: int, /) -> _T_co: ... @overload def round(number: _SupportsRound1[_T], ndigits: None = None) -> _T: ... @@ -1570,13 +1664,13 @@ def round(number: _SupportsRound2[_T], ndigits: SupportsIndex) -> _T: ... # See https://github.com/python/typeshed/pull/6292#discussion_r748875189 # for why arg 3 of `setattr` should be annotated with `Any` and not `object` -def setattr(__obj: object, __name: str, __value: Any) -> None: ... +def setattr(obj: object, name: str, value: Any, /) -> None: ... @overload def sorted( - __iterable: Iterable[SupportsRichComparisonT], *, key: None = None, reverse: bool = False + iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None, reverse: bool = False ) -> list[SupportsRichComparisonT]: ... @overload -def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison], reverse: bool = False) -> list[_T]: ... +def sorted(iterable: Iterable[_T], /, *, key: Callable[[_T], SupportsRichComparison], reverse: bool = False) -> list[_T]: ... _AddableT1 = TypeVar("_AddableT1", bound=SupportsAdd[Any, Any]) _AddableT2 = TypeVar("_AddableT2", bound=SupportsAdd[Any, Any]) @@ -1590,62 +1684,58 @@ _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]: ... +def sum(iterable: Iterable[_SupportsSumNoDefaultT], /) -> _SupportsSumNoDefaultT | Literal[0]: ... @overload -def sum(__iterable: Iterable[_AddableT1], start: _AddableT2) -> _AddableT1 | _AddableT2: ... +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) # Use a type: ignore to make complaints about overlapping overloads go away @overload -def vars(__object: type) -> types.MappingProxyType[str, Any]: ... # type: ignore[overload-overlap] +def vars(object: type, /) -> types.MappingProxyType[str, Any]: ... # type: ignore[overload-overlap] @overload -def vars(__object: Any = ...) -> dict[str, Any]: ... +def vars(object: Any = ..., /) -> dict[str, Any]: ... class zip(Iterator[_T_co]): if sys.version_info >= (3, 10): @overload def __new__(cls, *, strict: bool = ...) -> zip[Any]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], *, strict: bool = ...) -> zip[tuple[_T1]]: ... + def __new__(cls, iter1: Iterable[_T1], /, *, strict: bool = ...) -> zip[tuple[_T1]]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], *, strict: bool = ...) -> zip[tuple[_T1, _T2]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /, *, strict: bool = ...) -> zip[tuple[_T1, _T2]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], *, strict: bool = ... + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], /, *, strict: bool = ... ) -> zip[tuple[_T1, _T2, _T3]]: ... @overload def __new__( - cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - *, - strict: bool = ..., + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], /, *, strict: bool = ... ) -> zip[tuple[_T1, _T2, _T3, _T4]]: ... @overload def __new__( cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + iter1: Iterable[_T1], + iter2: Iterable[_T2], + iter3: Iterable[_T3], + iter4: Iterable[_T4], + iter5: Iterable[_T5], + /, *, strict: bool = ..., ) -> zip[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload def __new__( cls, - __iter1: Iterable[Any], - __iter2: Iterable[Any], - __iter3: Iterable[Any], - __iter4: Iterable[Any], - __iter5: Iterable[Any], - __iter6: Iterable[Any], + iter1: Iterable[Any], + iter2: Iterable[Any], + iter3: Iterable[Any], + iter4: Iterable[Any], + iter5: Iterable[Any], + iter6: Iterable[Any], + /, *iterables: Iterable[Any], strict: bool = ..., ) -> zip[tuple[Any, ...]]: ... @@ -1653,33 +1743,29 @@ class zip(Iterator[_T_co]): @overload def __new__(cls) -> zip[Any]: ... @overload - def __new__(cls, __iter1: Iterable[_T1]) -> zip[tuple[_T1]]: ... + def __new__(cls, iter1: Iterable[_T1], /) -> zip[tuple[_T1]]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> zip[tuple[_T1, _T2]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /) -> zip[tuple[_T1, _T2]]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3]) -> zip[tuple[_T1, _T2, _T3]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], /) -> zip[tuple[_T1, _T2, _T3]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4] + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], / ) -> zip[tuple[_T1, _T2, _T3, _T4]]: ... @overload def __new__( - cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], iter5: Iterable[_T5], / ) -> zip[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload def __new__( cls, - __iter1: Iterable[Any], - __iter2: Iterable[Any], - __iter3: Iterable[Any], - __iter4: Iterable[Any], - __iter5: Iterable[Any], - __iter6: Iterable[Any], + iter1: Iterable[Any], + iter2: Iterable[Any], + iter3: Iterable[Any], + iter4: Iterable[Any], + iter5: Iterable[Any], + iter6: Iterable[Any], + /, *iterables: Iterable[Any], ) -> zip[tuple[Any, ...]]: ... @@ -1695,7 +1781,7 @@ def __import__( fromlist: Sequence[str] = (), level: int = 0, ) -> types.ModuleType: ... -def __build_class__(__func: Callable[[], _Cell | Any], __name: str, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... +def __build_class__(func: Callable[[], _Cell | Any], name: str, /, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... if sys.version_info >= (3, 10): from types import EllipsisType @@ -1722,12 +1808,12 @@ class BaseException: __suppress_context__: bool __traceback__: TracebackType | None def __init__(self, *args: object) -> None: ... - def __setstate__(self, __state: dict[str, Any] | None) -> None: ... - def with_traceback(self, __tb: TracebackType | None) -> Self: ... + def __setstate__(self, state: dict[str, Any] | None, /) -> None: ... + def with_traceback(self, tb: TracebackType | None, /) -> Self: ... if sys.version_info >= (3, 11): # only present after add_note() is called __notes__: list[str] - def add_note(self, __note: str) -> None: ... + def add_note(self, note: str, /) -> None: ... class GeneratorExit(BaseException): ... class KeyboardInterrupt(BaseException): ... @@ -1837,7 +1923,7 @@ class UnicodeDecodeError(UnicodeError): start: int end: int reason: str - def __init__(self, __encoding: str, __object: ReadableBuffer, __start: int, __end: int, __reason: str) -> None: ... + def __init__(self, encoding: str, object: ReadableBuffer, start: int, end: int, reason: str, /) -> None: ... class UnicodeEncodeError(UnicodeError): encoding: str @@ -1845,7 +1931,7 @@ class UnicodeEncodeError(UnicodeError): start: int end: int reason: str - def __init__(self, __encoding: str, __object: str, __start: int, __end: int, __reason: str) -> None: ... + def __init__(self, encoding: str, object: str, start: int, end: int, reason: str, /) -> None: ... class UnicodeTranslateError(UnicodeError): encoding: None @@ -1853,7 +1939,7 @@ class UnicodeTranslateError(UnicodeError): start: int end: int reason: str - def __init__(self, __object: str, __start: int, __end: int, __reason: str) -> None: ... + def __init__(self, object: str, start: int, end: int, reason: str, /) -> None: ... class Warning(Exception): ... class UserWarning(Warning): ... @@ -1878,60 +1964,60 @@ if sys.version_info >= (3, 11): # See `check_exception_group.py` for use-cases and comments. class BaseExceptionGroup(BaseException, Generic[_BaseExceptionT_co]): - def __new__(cls, __message: str, __exceptions: Sequence[_BaseExceptionT_co]) -> Self: ... - def __init__(self, __message: str, __exceptions: Sequence[_BaseExceptionT_co]) -> None: ... + def __new__(cls, message: str, exceptions: Sequence[_BaseExceptionT_co], /) -> Self: ... + def __init__(self, message: str, exceptions: Sequence[_BaseExceptionT_co], /) -> None: ... @property def message(self) -> str: ... @property def exceptions(self) -> tuple[_BaseExceptionT_co | BaseExceptionGroup[_BaseExceptionT_co], ...]: ... @overload def subgroup( - self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + self, condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...], / ) -> ExceptionGroup[_ExceptionT] | None: ... @overload def subgroup( - self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] + self, condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...], / ) -> BaseExceptionGroup[_BaseExceptionT] | None: ... @overload def subgroup( - self, __condition: Callable[[_BaseExceptionT_co | Self], bool] + self, condition: Callable[[_BaseExceptionT_co | Self], bool], / ) -> BaseExceptionGroup[_BaseExceptionT_co] | None: ... @overload def split( - self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + self, condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...], / ) -> tuple[ExceptionGroup[_ExceptionT] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... @overload def split( - self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] + self, condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...], / ) -> tuple[BaseExceptionGroup[_BaseExceptionT] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... @overload def split( - self, __condition: Callable[[_BaseExceptionT_co | Self], bool] + self, condition: Callable[[_BaseExceptionT_co | Self], bool], / ) -> tuple[BaseExceptionGroup[_BaseExceptionT_co] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... # In reality it is `NonEmptySequence`: @overload - def derive(self, __excs: Sequence[_ExceptionT]) -> ExceptionGroup[_ExceptionT]: ... + def derive(self, excs: Sequence[_ExceptionT], /) -> ExceptionGroup[_ExceptionT]: ... @overload - def derive(self, __excs: Sequence[_BaseExceptionT]) -> BaseExceptionGroup[_BaseExceptionT]: ... - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def derive(self, excs: Sequence[_BaseExceptionT], /) -> BaseExceptionGroup[_BaseExceptionT]: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class ExceptionGroup(BaseExceptionGroup[_ExceptionT_co], Exception): - def __new__(cls, __message: str, __exceptions: Sequence[_ExceptionT_co]) -> Self: ... - def __init__(self, __message: str, __exceptions: Sequence[_ExceptionT_co]) -> None: ... + def __new__(cls, message: str, exceptions: Sequence[_ExceptionT_co], /) -> Self: ... + def __init__(self, message: str, exceptions: Sequence[_ExceptionT_co], /) -> None: ... @property def exceptions(self) -> tuple[_ExceptionT_co | ExceptionGroup[_ExceptionT_co], ...]: ... # We accept a narrower type, but that's OK. @overload # type: ignore[override] def subgroup( - self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + self, condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...], / ) -> ExceptionGroup[_ExceptionT] | None: ... @overload - def subgroup(self, __condition: Callable[[_ExceptionT_co | Self], bool]) -> ExceptionGroup[_ExceptionT_co] | None: ... + def subgroup(self, condition: Callable[[_ExceptionT_co | Self], bool], /) -> ExceptionGroup[_ExceptionT_co] | None: ... @overload # type: ignore[override] def split( - self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + self, condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...], / ) -> tuple[ExceptionGroup[_ExceptionT] | None, ExceptionGroup[_ExceptionT_co] | None]: ... @overload def split( - self, __condition: Callable[[_ExceptionT_co | Self], bool] + self, condition: Callable[[_ExceptionT_co | Self], bool], / ) -> tuple[ExceptionGroup[_ExceptionT_co] | None, ExceptionGroup[_ExceptionT_co] | None]: ... diff --git a/mypy/typeshed/stdlib/bz2.pyi b/mypy/typeshed/stdlib/bz2.pyi index 620d59a6010c..a7837e1b9ff8 100644 --- a/mypy/typeshed/stdlib/bz2.pyi +++ b/mypy/typeshed/stdlib/bz2.pyi @@ -14,7 +14,7 @@ __all__ = ["BZ2File", "BZ2Compressor", "BZ2Decompressor", "open", "compress", "d class _ReadableFileobj(_compression._Reader, Protocol): ... class _WritableFileobj(Protocol): - def write(self, __b: bytes) -> object: ... + def write(self, b: bytes, /) -> object: ... # The following attributes and methods are optional: # def fileno(self) -> int: ... # def close(self) -> object: ... @@ -132,7 +132,7 @@ class BZ2File(BaseStream, IO[bytes]): @final class BZ2Compressor: def __init__(self, compresslevel: int = ...) -> None: ... - def compress(self, __data: ReadableBuffer) -> bytes: ... + def compress(self, data: ReadableBuffer, /) -> bytes: ... def flush(self) -> bytes: ... @final diff --git a/mypy/typeshed/stdlib/cProfile.pyi b/mypy/typeshed/stdlib/cProfile.pyi index c212f0383eaf..0cf6e34ec99e 100644 --- a/mypy/typeshed/stdlib/cProfile.pyi +++ b/mypy/typeshed/stdlib/cProfile.pyi @@ -24,7 +24,7 @@ class Profile(_lsprof.Profiler): def snapshot_stats(self) -> None: ... 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: ... + def runcall(self, func: Callable[_P, _T], /, *args: _P.args, **kw: _P.kwargs) -> _T: ... def __enter__(self) -> Self: ... def __exit__(self, *exc_info: Unused) -> None: ... diff --git a/mypy/typeshed/stdlib/cgi.pyi b/mypy/typeshed/stdlib/cgi.pyi index 91179c2ed8d5..d20be33e3d76 100644 --- a/mypy/typeshed/stdlib/cgi.pyi +++ b/mypy/typeshed/stdlib/cgi.pyi @@ -33,7 +33,7 @@ def parse_multipart( ) -> dict[str, list[Any]]: ... class _Environ(Protocol): - def __getitem__(self, __k: str) -> str: ... + def __getitem__(self, k: str, /) -> str: ... def keys(self) -> Iterable[str]: ... def parse_header(line: str) -> tuple[str, dict[str, str]]: ... diff --git a/mypy/typeshed/stdlib/cmath.pyi b/mypy/typeshed/stdlib/cmath.pyi index 8aad19dafcfb..fab9d10230f8 100644 --- a/mypy/typeshed/stdlib/cmath.pyi +++ b/mypy/typeshed/stdlib/cmath.pyi @@ -11,26 +11,26 @@ tau: float _C: TypeAlias = SupportsFloat | SupportsComplex | SupportsIndex | complex -def acos(__z: _C) -> complex: ... -def acosh(__z: _C) -> complex: ... -def asin(__z: _C) -> complex: ... -def asinh(__z: _C) -> complex: ... -def atan(__z: _C) -> complex: ... -def atanh(__z: _C) -> complex: ... -def cos(__z: _C) -> complex: ... -def cosh(__z: _C) -> complex: ... -def exp(__z: _C) -> complex: ... +def acos(z: _C, /) -> complex: ... +def acosh(z: _C, /) -> complex: ... +def asin(z: _C, /) -> complex: ... +def asinh(z: _C, /) -> complex: ... +def atan(z: _C, /) -> complex: ... +def atanh(z: _C, /) -> complex: ... +def cos(z: _C, /) -> complex: ... +def cosh(z: _C, /) -> complex: ... +def exp(z: _C, /) -> complex: ... def isclose(a: _C, b: _C, *, rel_tol: SupportsFloat = 1e-09, abs_tol: SupportsFloat = 0.0) -> bool: ... -def isinf(__z: _C) -> bool: ... -def isnan(__z: _C) -> bool: ... -def log(__x: _C, __base: _C = ...) -> complex: ... -def log10(__z: _C) -> complex: ... -def phase(__z: _C) -> float: ... -def polar(__z: _C) -> tuple[float, float]: ... -def rect(__r: float, __phi: float) -> complex: ... -def sin(__z: _C) -> complex: ... -def sinh(__z: _C) -> complex: ... -def sqrt(__z: _C) -> complex: ... -def tan(__z: _C) -> complex: ... -def tanh(__z: _C) -> complex: ... -def isfinite(__z: _C) -> bool: ... +def isinf(z: _C, /) -> bool: ... +def isnan(z: _C, /) -> bool: ... +def log(x: _C, base: _C = ..., /) -> complex: ... +def log10(z: _C, /) -> complex: ... +def phase(z: _C, /) -> float: ... +def polar(z: _C, /) -> tuple[float, float]: ... +def rect(r: float, phi: float, /) -> complex: ... +def sin(z: _C, /) -> complex: ... +def sinh(z: _C, /) -> complex: ... +def sqrt(z: _C, /) -> complex: ... +def tan(z: _C, /) -> complex: ... +def tanh(z: _C, /) -> complex: ... +def isfinite(z: _C, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/codecs.pyi b/mypy/typeshed/stdlib/codecs.pyi index 7e192d91ddc5..6e53b780c473 100644 --- a/mypy/typeshed/stdlib/codecs.pyi +++ b/mypy/typeshed/stdlib/codecs.pyi @@ -59,13 +59,13 @@ BOM64_BE: Literal[b"\x00\x00\xfe\xff"] BOM64_LE: Literal[b"\xff\xfe\x00\x00"] class _WritableStream(Protocol): - def write(self, __data: bytes) -> object: ... - def seek(self, __offset: int, __whence: int) -> object: ... + def write(self, data: bytes, /) -> object: ... + def seek(self, offset: int, whence: int, /) -> object: ... def close(self) -> object: ... class _ReadableStream(Protocol): - def read(self, __size: int = ...) -> bytes: ... - def seek(self, __offset: int, __whence: int) -> object: ... + def read(self, size: int = ..., /) -> bytes: ... + def seek(self, offset: int, whence: int, /) -> object: ... def close(self) -> object: ... class _Stream(_WritableStream, _ReadableStream, Protocol): ... @@ -77,16 +77,16 @@ class _Stream(_WritableStream, _ReadableStream, Protocol): ... # They were much more common in Python 2 than in Python 3. class _Encoder(Protocol): - def __call__(self, __input: str, __errors: str = ...) -> tuple[bytes, int]: ... # signature of Codec().encode + def __call__(self, input: str, errors: str = ..., /) -> tuple[bytes, int]: ... # signature of Codec().encode class _Decoder(Protocol): - def __call__(self, __input: bytes, __errors: str = ...) -> tuple[str, int]: ... # signature of Codec().decode + def __call__(self, input: bytes, errors: str = ..., /) -> tuple[str, int]: ... # signature of Codec().decode class _StreamReader(Protocol): - def __call__(self, __stream: _ReadableStream, __errors: str = ...) -> StreamReader: ... + def __call__(self, stream: _ReadableStream, errors: str = ..., /) -> StreamReader: ... class _StreamWriter(Protocol): - def __call__(self, __stream: _WritableStream, __errors: str = ...) -> StreamWriter: ... + def __call__(self, stream: _WritableStream, errors: str = ..., /) -> StreamWriter: ... class _IncrementalEncoder(Protocol): def __call__(self, errors: str = ...) -> IncrementalEncoder: ... diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index 0df800a4a3be..1d23ecd66a8d 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -49,21 +49,21 @@ class UserDict(MutableMapping[_KT, _VT]): data: dict[_KT, _VT] # __init__ should be kept roughly in line with `dict.__init__`, which has the same semantics @overload - def __init__(self, __dict: None = None) -> None: ... + def __init__(self, dict: None = None, /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], __dict: None = None, **kwargs: _VT) -> None: ... + def __init__(self: UserDict[str, _VT], dict: None = None, /, **kwargs: _VT) -> None: ... @overload - def __init__(self, __dict: SupportsKeysAndGetItem[_KT, _VT]) -> None: ... + def __init__(self, dict: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], __dict: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> None: ... + def __init__(self: UserDict[str, _VT], dict: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... @overload - def __init__(self, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ... + def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> None: ... + def __init__(self: UserDict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... @overload - def __init__(self: UserDict[str, str], __iterable: Iterable[list[str]]) -> None: ... + def __init__(self: UserDict[str, str], iterable: Iterable[list[str]], /) -> None: ... @overload - def __init__(self: UserDict[bytes, bytes], __iterable: Iterable[list[bytes]]) -> None: ... + def __init__(self: UserDict[bytes, bytes], iterable: Iterable[list[bytes]], /) -> None: ... def __len__(self) -> int: ... def __getitem__(self, key: _KT) -> _VT: ... def __setitem__(self, key: _KT, item: _VT) -> None: ... @@ -137,8 +137,10 @@ class UserList(MutableSequence[_T]): def copy(self) -> Self: ... def __copy__(self) -> Self: ... def count(self, item: _T) -> int: ... - # All arguments are passed to `list.index` at runtime, so the signature should be kept in line with `list.index`. - def index(self, item: _T, __start: SupportsIndex = 0, __stop: SupportsIndex = sys.maxsize) -> int: ... + # The runtime signature is "item, *args", and the arguments are then passed + # to `list.index`. In order to give more precise types, we pretend that the + # `item` argument is positional-only. + def index(self, item: _T, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int: ... # All arguments are passed to `list.sort` at runtime, so the signature should be kept in line with `list.sort`. @overload def sort(self: UserList[SupportsRichComparisonT], *, key: None = None, reverse: bool = False) -> None: ... @@ -200,8 +202,8 @@ class UserString(Sequence[UserString]): maketrans = str.maketrans def partition(self, sep: str) -> tuple[str, str, str]: ... if sys.version_info >= (3, 9): - def removeprefix(self, __prefix: str | UserString) -> Self: ... - def removesuffix(self, __suffix: str | UserString) -> Self: ... + def removeprefix(self, prefix: str | UserString, /) -> Self: ... + def removesuffix(self, suffix: str | UserString, /) -> Self: ... def replace(self, old: str | UserString, new: str | UserString, maxsplit: int = -1) -> Self: ... def rfind(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ... @@ -227,58 +229,58 @@ class deque(MutableSequence[_T]): def __init__(self, *, maxlen: int | None = None) -> None: ... @overload def __init__(self, iterable: Iterable[_T], maxlen: int | None = None) -> None: ... - def append(self, __x: _T) -> None: ... - def appendleft(self, __x: _T) -> None: ... + def append(self, x: _T, /) -> None: ... + def appendleft(self, x: _T, /) -> None: ... def copy(self) -> Self: ... - def count(self, __x: _T) -> int: ... - def extend(self, __iterable: Iterable[_T]) -> None: ... - def extendleft(self, __iterable: Iterable[_T]) -> None: ... - def insert(self, __i: int, __x: _T) -> None: ... - def index(self, __x: _T, __start: int = 0, __stop: int = ...) -> int: ... + def count(self, x: _T, /) -> int: ... + def extend(self, iterable: Iterable[_T], /) -> None: ... + def extendleft(self, iterable: Iterable[_T], /) -> None: ... + def insert(self, i: int, x: _T, /) -> None: ... + def index(self, x: _T, start: int = 0, stop: int = ..., /) -> int: ... def pop(self) -> _T: ... # type: ignore[override] def popleft(self) -> _T: ... - def remove(self, __value: _T) -> None: ... - def rotate(self, __n: int = 1) -> None: ... + def remove(self, value: _T, /) -> None: ... + def rotate(self, n: int = 1, /) -> None: ... def __copy__(self) -> Self: ... def __len__(self) -> int: ... # These methods of deque don't take slices, unlike MutableSequence, hence the type: ignores - def __getitem__(self, __key: SupportsIndex) -> _T: ... # type: ignore[override] - def __setitem__(self, __key: SupportsIndex, __value: _T) -> None: ... # type: ignore[override] - def __delitem__(self, __key: SupportsIndex) -> None: ... # type: ignore[override] - def __contains__(self, __key: object) -> bool: ... + def __getitem__(self, key: SupportsIndex, /) -> _T: ... # type: ignore[override] + def __setitem__(self, key: SupportsIndex, value: _T, /) -> None: ... # type: ignore[override] + def __delitem__(self, key: SupportsIndex, /) -> None: ... # type: ignore[override] + def __contains__(self, key: object, /) -> bool: ... def __reduce__(self) -> tuple[type[Self], tuple[()], None, Iterator[_T]]: ... - def __iadd__(self, __value: Iterable[_T]) -> Self: ... - def __add__(self, __value: Self) -> Self: ... - def __mul__(self, __value: int) -> Self: ... - def __imul__(self, __value: int) -> Self: ... - def __lt__(self, __value: deque[_T]) -> bool: ... - def __le__(self, __value: deque[_T]) -> bool: ... - def __gt__(self, __value: deque[_T]) -> bool: ... - def __ge__(self, __value: deque[_T]) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __iadd__(self, value: Iterable[_T], /) -> Self: ... + def __add__(self, value: Self, /) -> Self: ... + def __mul__(self, value: int, /) -> Self: ... + def __imul__(self, value: int, /) -> Self: ... + def __lt__(self, value: deque[_T], /) -> bool: ... + def __le__(self, value: deque[_T], /) -> bool: ... + def __gt__(self, value: deque[_T], /) -> bool: ... + def __ge__(self, value: deque[_T], /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class Counter(dict[_T, int], Generic[_T]): @overload - def __init__(self, __iterable: None = None) -> None: ... + def __init__(self, iterable: None = None, /) -> None: ... @overload - def __init__(self: Counter[str], __iterable: None = None, **kwargs: int) -> None: ... + def __init__(self: Counter[str], iterable: None = None, /, **kwargs: int) -> None: ... @overload - def __init__(self, __mapping: SupportsKeysAndGetItem[_T, int]) -> None: ... + def __init__(self, mapping: SupportsKeysAndGetItem[_T, int], /) -> None: ... @overload - def __init__(self, __iterable: Iterable[_T]) -> None: ... + def __init__(self, iterable: Iterable[_T], /) -> None: ... def copy(self) -> Self: ... def elements(self) -> Iterator[_T]: ... def most_common(self, n: int | None = None) -> list[tuple[_T, int]]: ... @classmethod def fromkeys(cls, iterable: Any, v: int | None = None) -> NoReturn: ... # type: ignore[override] @overload - def subtract(self, __iterable: None = None) -> None: ... + def subtract(self, iterable: None = None, /) -> None: ... @overload - def subtract(self, __mapping: Mapping[_T, int]) -> None: ... + def subtract(self, mapping: Mapping[_T, int], /) -> None: ... @overload - def subtract(self, __iterable: Iterable[_T]) -> None: ... + def subtract(self, iterable: Iterable[_T], /) -> None: ... # Unlike dict.update(), use Mapping instead of SupportsKeysAndGetItem for the first overload # (source code does an `isinstance(other, Mapping)` check) # @@ -286,11 +288,11 @@ class Counter(dict[_T, int], Generic[_T]): # (if it were `Iterable[_T] | Iterable[tuple[_T, int]]`, # the tuples would be added as keys, breaking type safety) @overload # type: ignore[override] - def update(self, __m: Mapping[_T, int], **kwargs: int) -> None: ... + def update(self, m: Mapping[_T, int], /, **kwargs: int) -> None: ... @overload - def update(self, __iterable: Iterable[_T], **kwargs: int) -> None: ... + def update(self, iterable: Iterable[_T], /, **kwargs: int) -> None: ... @overload - def update(self, __iterable: None = None, **kwargs: int) -> None: ... + def update(self, iterable: None = None, /, **kwargs: int) -> None: ... def __missing__(self, key: _T) -> int: ... def __delitem__(self, elem: object) -> None: ... if sys.version_info >= (3, 10): @@ -371,16 +373,16 @@ class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): def pop(self, key: _KT, default: _VT) -> _VT: ... @overload def pop(self, key: _KT, default: _T) -> _VT | _T: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 9): @overload - def __or__(self, __value: dict[_KT, _VT]) -> Self: ... + def __or__(self, value: dict[_KT, _VT], /) -> Self: ... @overload - def __or__(self, __value: dict[_T1, _T2]) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... @overload - def __ror__(self, __value: dict[_KT, _VT]) -> Self: ... + def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... @overload - def __ror__(self, __value: dict[_T1, _T2]) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] + def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] class defaultdict(dict[_KT, _VT]): default_factory: Callable[[], _VT] | None @@ -389,39 +391,41 @@ class defaultdict(dict[_KT, _VT]): @overload def __init__(self: defaultdict[str, _VT], **kwargs: _VT) -> None: ... @overload - def __init__(self, __default_factory: Callable[[], _VT] | None) -> None: ... + def __init__(self, default_factory: Callable[[], _VT] | None, /) -> None: ... @overload - def __init__(self: defaultdict[str, _VT], __default_factory: Callable[[], _VT] | None, **kwargs: _VT) -> None: ... + def __init__(self: defaultdict[str, _VT], default_factory: Callable[[], _VT] | None, /, **kwargs: _VT) -> None: ... @overload - def __init__(self, __default_factory: Callable[[], _VT] | None, __map: SupportsKeysAndGetItem[_KT, _VT]) -> None: ... + def __init__(self, default_factory: Callable[[], _VT] | None, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload def __init__( self: defaultdict[str, _VT], - __default_factory: Callable[[], _VT] | None, - __map: SupportsKeysAndGetItem[str, _VT], + default_factory: Callable[[], _VT] | None, + map: SupportsKeysAndGetItem[str, _VT], + /, **kwargs: _VT, ) -> None: ... @overload - def __init__(self, __default_factory: Callable[[], _VT] | None, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ... + def __init__(self, default_factory: Callable[[], _VT] | None, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload def __init__( self: defaultdict[str, _VT], - __default_factory: Callable[[], _VT] | None, - __iterable: Iterable[tuple[str, _VT]], + default_factory: Callable[[], _VT] | None, + iterable: Iterable[tuple[str, _VT]], + /, **kwargs: _VT, ) -> None: ... - def __missing__(self, __key: _KT) -> _VT: ... + def __missing__(self, key: _KT, /) -> _VT: ... def __copy__(self) -> Self: ... def copy(self) -> Self: ... if sys.version_info >= (3, 9): @overload - def __or__(self, __value: dict[_KT, _VT]) -> Self: ... + def __or__(self, value: dict[_KT, _VT], /) -> Self: ... @overload - def __or__(self, __value: dict[_T1, _T2]) -> defaultdict[_KT | _T1, _VT | _T2]: ... + def __or__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... @overload - def __ror__(self, __value: dict[_KT, _VT]) -> Self: ... + def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... @overload - def __ror__(self, __value: dict[_T1, _T2]) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] + def __ror__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] class ChainMap(MutableMapping[_KT, _VT]): maps: list[MutableMapping[_KT, _VT]] @@ -457,10 +461,14 @@ class ChainMap(MutableMapping[_KT, _VT]): # All arguments to `fromkeys` are passed to `dict.fromkeys` at runtime, so the signature should be kept in line with `dict.fromkeys`. @classmethod @overload - def fromkeys(cls, iterable: Iterable[_T], __value: None = None) -> ChainMap[_T, Any | None]: ... + def fromkeys(cls, iterable: Iterable[_T]) -> ChainMap[_T, Any | None]: ... @classmethod @overload - def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> ChainMap[_T, _S]: ... + # Special-case None: the user probably wants to add non-None values later. + def fromkeys(cls, iterable: Iterable[_T], value: None, /) -> ChainMap[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> ChainMap[_T, _S]: ... if sys.version_info >= (3, 9): @overload def __or__(self, other: Mapping[_KT, _VT]) -> Self: ... diff --git a/mypy/typeshed/stdlib/compileall.pyi b/mypy/typeshed/stdlib/compileall.pyi index 7f101bf79f6d..9fb3608f2979 100644 --- a/mypy/typeshed/stdlib/compileall.pyi +++ b/mypy/typeshed/stdlib/compileall.pyi @@ -6,7 +6,7 @@ from typing import Any, Protocol __all__ = ["compile_dir", "compile_file", "compile_path"] class _SupportsSearch(Protocol): - def search(self, __string: str) -> Any: ... + def search(self, string: str, /) -> Any: ... if sys.version_info >= (3, 10): def compile_dir( diff --git a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi index 9ea4d5dff6fb..7dfdda224013 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi @@ -1,7 +1,7 @@ import sys import threading from _typeshed import Unused -from collections.abc import Callable, Iterable, Iterator +from collections.abc import Callable, Collection, Iterable, Iterator from logging import Logger from types import TracebackType from typing import Any, Generic, Literal, NamedTuple, Protocol, TypeVar @@ -58,7 +58,7 @@ class Future(Generic[_T]): class Executor: if sys.version_info >= (3, 9): - def submit(self, __fn: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ... + def submit(self, fn: Callable[_P, _T], /, *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ... else: def submit(self, fn: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ... @@ -91,9 +91,15 @@ class DoneAndNotDoneFutures(NamedTuple, Generic[_T]): done: set[Future[_T]] not_done: set[Future[_T]] -def wait( - fs: Iterable[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED" -) -> DoneAndNotDoneFutures[_T]: ... +if sys.version_info >= (3, 9): + def wait( + fs: Iterable[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> DoneAndNotDoneFutures[_T]: ... + +else: + def wait( + fs: Collection[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED" + ) -> DoneAndNotDoneFutures[_T]: ... class _Waiter: event: threading.Event diff --git a/mypy/typeshed/stdlib/contextlib.pyi b/mypy/typeshed/stdlib/contextlib.pyi index eb4e95b33509..f82bb4b7b6ad 100644 --- a/mypy/typeshed/stdlib/contextlib.pyi +++ b/mypy/typeshed/stdlib/contextlib.pyi @@ -42,7 +42,7 @@ class AbstractContextManager(Protocol[_T_co]): def __enter__(self) -> _T_co: ... @abstractmethod def __exit__( - self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / ) -> bool | None: ... @runtime_checkable @@ -50,7 +50,7 @@ class AbstractAsyncContextManager(Protocol[_T_co]): async def __aenter__(self) -> _T_co: ... @abstractmethod async def __aexit__( - self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / ) -> bool | None: ... class ContextDecorator: @@ -145,12 +145,12 @@ class redirect_stderr(_RedirectStream[_T_io]): ... class ExitStack(metaclass=abc.ABCMeta): def enter_context(self, cm: AbstractContextManager[_T]) -> _T: ... def push(self, exit: _CM_EF) -> _CM_EF: ... - def callback(self, __callback: Callable[_P, _T], *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... + def callback(self, callback: Callable[_P, _T], /, *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... def pop_all(self) -> Self: ... def close(self) -> None: ... def __enter__(self) -> Self: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / ) -> bool: ... _ExitCoroFunc: TypeAlias = Callable[ @@ -165,15 +165,15 @@ class AsyncExitStack(metaclass=abc.ABCMeta): async def enter_async_context(self, cm: AbstractAsyncContextManager[_T]) -> _T: ... def push(self, exit: _CM_EF) -> _CM_EF: ... def push_async_exit(self, exit: _ACM_EF) -> _ACM_EF: ... - def callback(self, __callback: Callable[_P, _T], *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... + def callback(self, callback: Callable[_P, _T], /, *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... def push_async_callback( - self, __callback: Callable[_P, Awaitable[_T]], *args: _P.args, **kwds: _P.kwargs + self, callback: Callable[_P, Awaitable[_T]], /, *args: _P.args, **kwds: _P.kwargs ) -> Callable[_P, Awaitable[_T]]: ... def pop_all(self) -> Self: ... async def aclose(self) -> None: ... async def __aenter__(self) -> Self: ... async def __aexit__( - self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / ) -> bool: ... if sys.version_info >= (3, 10): diff --git a/mypy/typeshed/stdlib/contextvars.pyi b/mypy/typeshed/stdlib/contextvars.pyi index 3245cdd5dad2..ceb9085fa187 100644 --- a/mypy/typeshed/stdlib/contextvars.pyi +++ b/mypy/typeshed/stdlib/contextvars.pyi @@ -24,11 +24,11 @@ class ContextVar(Generic[_T]): @overload def get(self) -> _T: ... @overload - def get(self, __default: _T) -> _T: ... + def get(self, default: _T, /) -> _T: ... @overload - def get(self, __default: _D) -> _D | _T: ... - def set(self, __value: _T) -> Token[_T]: ... - def reset(self, __token: Token[_T]) -> None: ... + def get(self, default: _D, /) -> _D | _T: ... + def set(self, value: _T, /) -> Token[_T]: ... + def reset(self, token: Token[_T], /) -> None: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... @@ -50,14 +50,14 @@ def copy_context() -> Context: ... class Context(Mapping[ContextVar[Any], Any]): def __init__(self) -> None: ... @overload - def get(self, __key: ContextVar[_T], __default: None = None) -> _T | None: ... + def get(self, key: ContextVar[_T], default: None = None, /) -> _T | None: ... @overload - def get(self, __key: ContextVar[_T], __default: _T) -> _T: ... + def get(self, key: ContextVar[_T], default: _T, /) -> _T: ... @overload - def get(self, __key: ContextVar[_T], __default: _D) -> _T | _D: ... + def get(self, key: ContextVar[_T], default: _D, /) -> _T | _D: ... def run(self, callable: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> _T: ... def copy(self) -> Context: ... - def __getitem__(self, __key: ContextVar[_T]) -> _T: ... + def __getitem__(self, key: ContextVar[_T], /) -> _T: ... def __iter__(self) -> Iterator[ContextVar[Any]]: ... def __len__(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/curses/__init__.pyi b/mypy/typeshed/stdlib/curses/__init__.pyi index db44fa6a6be7..2a82ae9bda22 100644 --- a/mypy/typeshed/stdlib/curses/__init__.pyi +++ b/mypy/typeshed/stdlib/curses/__init__.pyi @@ -18,4 +18,4 @@ if sys.platform != "win32": COLORS: int COLOR_PAIRS: int - def wrapper(__func: Callable[Concatenate[_CursesWindow, _P], _T], *arg: _P.args, **kwds: _P.kwargs) -> _T: ... + def wrapper(func: Callable[Concatenate[_CursesWindow, _P], _T], /, *arg: _P.args, **kwds: _P.kwargs) -> _T: ... diff --git a/mypy/typeshed/stdlib/curses/panel.pyi b/mypy/typeshed/stdlib/curses/panel.pyi index 30803791f039..403ae9b50019 100644 --- a/mypy/typeshed/stdlib/curses/panel.pyi +++ b/mypy/typeshed/stdlib/curses/panel.pyi @@ -20,6 +20,6 @@ if sys.platform != "win32": def window(self) -> _CursesWindow: ... def bottom_panel() -> _Curses_Panel: ... - def new_panel(__win: _CursesWindow) -> _Curses_Panel: ... + def new_panel(win: _CursesWindow, /) -> _Curses_Panel: ... def top_panel() -> _Curses_Panel: ... def update_panels() -> _Curses_Panel: ... diff --git a/mypy/typeshed/stdlib/dataclasses.pyi b/mypy/typeshed/stdlib/dataclasses.pyi index 389a159a915f..00e0d31d092a 100644 --- a/mypy/typeshed/stdlib/dataclasses.pyi +++ b/mypy/typeshed/stdlib/dataclasses.pyi @@ -55,9 +55,9 @@ def astuple(obj: DataclassInstance) -> tuple[Any, ...]: ... @overload def astuple(obj: DataclassInstance, *, tuple_factory: Callable[[list[Any]], _T]) -> _T: ... @overload -def dataclass(__cls: None) -> Callable[[type[_T]], type[_T]]: ... +def dataclass(cls: None, /) -> Callable[[type[_T]], type[_T]]: ... @overload -def dataclass(__cls: type[_T]) -> type[_T]: ... +def dataclass(cls: type[_T], /) -> type[_T]: ... if sys.version_info >= (3, 11): @overload @@ -227,16 +227,18 @@ if sys.version_info >= (3, 9): else: class _InitVarMeta(type): # Not used, instead `InitVar.__class_getitem__` is called. - def __getitem__(self, params: Any) -> InitVar[Any]: ... + # pyright ignore is needed because pyright (not unreasonably) thinks this + # is an invalid use of InitVar. + def __getitem__(self, params: Any) -> InitVar[Any]: ... # pyright: ignore class InitVar(Generic[_T], metaclass=_InitVarMeta): type: Type[_T] def __init__(self, type: Type[_T]) -> None: ... if sys.version_info >= (3, 9): @overload - def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... + def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... # pyright: ignore @overload - def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... + def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... # pyright: ignore if sys.version_info >= (3, 12): def make_dataclass( @@ -310,4 +312,4 @@ else: frozen: bool = False, ) -> type: ... -def replace(__obj: _DataclassT, **changes: Any) -> _DataclassT: ... +def replace(obj: _DataclassT, /, **changes: Any) -> _DataclassT: ... diff --git a/mypy/typeshed/stdlib/datetime.pyi b/mypy/typeshed/stdlib/datetime.pyi index 852208cd83a1..7b890ca010dc 100644 --- a/mypy/typeshed/stdlib/datetime.pyi +++ b/mypy/typeshed/stdlib/datetime.pyi @@ -14,12 +14,12 @@ MAXYEAR: Literal[9999] class tzinfo: @abstractmethod - def tzname(self, __dt: datetime | None) -> str | None: ... + def tzname(self, dt: datetime | None, /) -> str | None: ... @abstractmethod - def utcoffset(self, __dt: datetime | None) -> timedelta | None: ... + def utcoffset(self, dt: datetime | None, /) -> timedelta | None: ... @abstractmethod - def dst(self, __dt: datetime | None) -> timedelta | None: ... - def fromutc(self, __dt: datetime) -> datetime: ... + def dst(self, dt: datetime | None, /) -> timedelta | None: ... + def fromutc(self, dt: datetime, /) -> datetime: ... # Alias required to avoid name conflicts with date(time).tzinfo. _TzInfo: TypeAlias = tzinfo @@ -30,11 +30,11 @@ class timezone(tzinfo): min: ClassVar[timezone] max: ClassVar[timezone] def __init__(self, offset: timedelta, name: str = ...) -> None: ... - def tzname(self, __dt: datetime | None) -> str: ... - def utcoffset(self, __dt: datetime | None) -> timedelta: ... - def dst(self, __dt: datetime | None) -> None: ... + def tzname(self, dt: datetime | None, /) -> str: ... + def utcoffset(self, dt: datetime | None, /) -> timedelta: ... + def dst(self, dt: datetime | None, /) -> None: ... def __hash__(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... if sys.version_info >= (3, 11): UTC: timezone @@ -51,13 +51,13 @@ class date: resolution: ClassVar[timedelta] def __new__(cls, year: SupportsIndex, month: SupportsIndex, day: SupportsIndex) -> Self: ... @classmethod - def fromtimestamp(cls, __timestamp: float) -> Self: ... + def fromtimestamp(cls, timestamp: float, /) -> Self: ... @classmethod def today(cls) -> Self: ... @classmethod - def fromordinal(cls, __n: int) -> Self: ... + def fromordinal(cls, n: int, /) -> Self: ... @classmethod - def fromisoformat(cls, __date_string: str) -> Self: ... + def fromisoformat(cls, date_string: str, /) -> Self: ... @classmethod def fromisocalendar(cls, year: int, week: int, day: int) -> Self: ... @property @@ -73,26 +73,26 @@ class date: if sys.version_info >= (3, 12): def strftime(self, format: str) -> str: ... else: - def strftime(self, __format: str) -> str: ... + def strftime(self, format: str, /) -> str: ... - def __format__(self, __fmt: str) -> str: ... + def __format__(self, fmt: str, /) -> str: ... def isoformat(self) -> str: ... def timetuple(self) -> struct_time: ... def toordinal(self) -> int: ... def replace(self, year: SupportsIndex = ..., month: SupportsIndex = ..., day: SupportsIndex = ...) -> Self: ... - def __le__(self, __value: date) -> bool: ... - def __lt__(self, __value: date) -> bool: ... - def __ge__(self, __value: date) -> bool: ... - def __gt__(self, __value: date) -> bool: ... - def __eq__(self, __value: object) -> bool: ... - def __add__(self, __value: timedelta) -> Self: ... - def __radd__(self, __value: timedelta) -> Self: ... + def __le__(self, value: date, /) -> bool: ... + def __lt__(self, value: date, /) -> bool: ... + def __ge__(self, value: date, /) -> bool: ... + def __gt__(self, value: date, /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... + def __add__(self, value: timedelta, /) -> Self: ... + def __radd__(self, value: timedelta, /) -> Self: ... @overload - def __sub__(self, __value: datetime) -> NoReturn: ... + def __sub__(self, value: datetime, /) -> NoReturn: ... @overload - def __sub__(self, __value: Self) -> timedelta: ... + def __sub__(self, value: Self, /) -> timedelta: ... @overload - def __sub__(self, __value: timedelta) -> Self: ... + def __sub__(self, value: timedelta, /) -> Self: ... def __hash__(self) -> int: ... def weekday(self) -> int: ... def isoweekday(self) -> int: ... @@ -127,24 +127,24 @@ class time: def tzinfo(self) -> _TzInfo | None: ... @property def fold(self) -> int: ... - def __le__(self, __value: time) -> bool: ... - def __lt__(self, __value: time) -> bool: ... - def __ge__(self, __value: time) -> bool: ... - def __gt__(self, __value: time) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __le__(self, value: time, /) -> bool: ... + def __lt__(self, value: time, /) -> bool: ... + def __ge__(self, value: time, /) -> bool: ... + def __gt__(self, value: time, /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... def isoformat(self, timespec: str = ...) -> str: ... @classmethod - def fromisoformat(cls, __time_string: str) -> Self: ... + def fromisoformat(cls, time_string: str, /) -> Self: ... # On <3.12, the name of the parameter in the pure-Python implementation # didn't match the name in the C implementation, # meaning it is only *safe* to pass it as a keyword argument on 3.12+ if sys.version_info >= (3, 12): def strftime(self, format: str) -> str: ... else: - def strftime(self, __format: str) -> str: ... + def strftime(self, format: str, /) -> str: ... - def __format__(self, __fmt: str) -> str: ... + def __format__(self, fmt: str, /) -> str: ... def utcoffset(self) -> timedelta | None: ... def tzname(self) -> str | None: ... def dst(self) -> timedelta | None: ... @@ -183,30 +183,30 @@ class timedelta: @property def microseconds(self) -> int: ... def total_seconds(self) -> float: ... - def __add__(self, __value: timedelta) -> timedelta: ... - def __radd__(self, __value: timedelta) -> timedelta: ... - def __sub__(self, __value: timedelta) -> timedelta: ... - def __rsub__(self, __value: timedelta) -> timedelta: ... + def __add__(self, value: timedelta, /) -> timedelta: ... + def __radd__(self, value: timedelta, /) -> timedelta: ... + def __sub__(self, value: timedelta, /) -> timedelta: ... + def __rsub__(self, value: timedelta, /) -> timedelta: ... def __neg__(self) -> timedelta: ... def __pos__(self) -> timedelta: ... def __abs__(self) -> timedelta: ... - def __mul__(self, __value: float) -> timedelta: ... - def __rmul__(self, __value: float) -> timedelta: ... + def __mul__(self, value: float, /) -> timedelta: ... + def __rmul__(self, value: float, /) -> timedelta: ... @overload - def __floordiv__(self, __value: timedelta) -> int: ... + def __floordiv__(self, value: timedelta, /) -> int: ... @overload - def __floordiv__(self, __value: int) -> timedelta: ... + def __floordiv__(self, value: int, /) -> timedelta: ... @overload - def __truediv__(self, __value: timedelta) -> float: ... + def __truediv__(self, value: timedelta, /) -> float: ... @overload - def __truediv__(self, __value: float) -> timedelta: ... - def __mod__(self, __value: timedelta) -> timedelta: ... - def __divmod__(self, __value: timedelta) -> tuple[int, timedelta]: ... - def __le__(self, __value: timedelta) -> bool: ... - def __lt__(self, __value: timedelta) -> bool: ... - def __ge__(self, __value: timedelta) -> bool: ... - def __gt__(self, __value: timedelta) -> bool: ... - def __eq__(self, __value: object) -> bool: ... + def __truediv__(self, value: float, /) -> timedelta: ... + def __mod__(self, value: timedelta, /) -> timedelta: ... + def __divmod__(self, value: timedelta, /) -> tuple[int, timedelta]: ... + def __le__(self, value: timedelta, /) -> bool: ... + def __lt__(self, value: timedelta, /) -> bool: ... + def __ge__(self, value: timedelta, /) -> bool: ... + def __gt__(self, value: timedelta, /) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __bool__(self) -> bool: ... def __hash__(self) -> int: ... @@ -246,11 +246,11 @@ class datetime(date): def fromtimestamp(cls, timestamp: float, tz: _TzInfo | None = ...) -> Self: ... else: @classmethod - def fromtimestamp(cls, __timestamp: float, tz: _TzInfo | None = ...) -> Self: ... + def fromtimestamp(cls, timestamp: float, /, tz: _TzInfo | None = ...) -> Self: ... @classmethod @deprecated("Use timezone-aware objects to represent datetimes in UTC; e.g. by calling .fromtimestamp(datetime.UTC)") - def utcfromtimestamp(cls, __t: float) -> Self: ... + def utcfromtimestamp(cls, t: float, /) -> Self: ... @classmethod def now(cls, tz: _TzInfo | None = None) -> Self: ... @classmethod @@ -279,17 +279,17 @@ class datetime(date): 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: ... + def strptime(cls, date_string: str, format: str, /) -> Self: ... def utcoffset(self) -> timedelta | None: ... def tzname(self) -> str | None: ... def dst(self) -> timedelta | None: ... - def __le__(self, __value: datetime) -> bool: ... # type: ignore[override] - def __lt__(self, __value: datetime) -> bool: ... # type: ignore[override] - def __ge__(self, __value: datetime) -> bool: ... # type: ignore[override] - def __gt__(self, __value: datetime) -> bool: ... # type: ignore[override] - def __eq__(self, __value: object) -> bool: ... + def __le__(self, value: datetime, /) -> bool: ... # type: ignore[override] + def __lt__(self, value: datetime, /) -> bool: ... # type: ignore[override] + def __ge__(self, value: datetime, /) -> bool: ... # type: ignore[override] + def __gt__(self, value: datetime, /) -> bool: ... # type: ignore[override] + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @overload # type: ignore[override] - def __sub__(self, __value: Self) -> timedelta: ... + def __sub__(self, value: Self, /) -> timedelta: ... @overload - def __sub__(self, __value: timedelta) -> Self: ... + def __sub__(self, value: timedelta, /) -> Self: ... diff --git a/mypy/typeshed/stdlib/dbm/gnu.pyi b/mypy/typeshed/stdlib/dbm/gnu.pyi index 0f818ed5e7f5..8b562019fcfb 100644 --- a/mypy/typeshed/stdlib/dbm/gnu.pyi +++ b/mypy/typeshed/stdlib/dbm/gnu.pyi @@ -38,4 +38,4 @@ if sys.platform != "win32": __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] - def open(__filename: str, __flags: str = "r", __mode: int = 0o666) -> _gdbm: ... + def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _gdbm: ... diff --git a/mypy/typeshed/stdlib/dbm/ndbm.pyi b/mypy/typeshed/stdlib/dbm/ndbm.pyi index a7a6d52d8f19..5eb84e6949fc 100644 --- a/mypy/typeshed/stdlib/dbm/ndbm.pyi +++ b/mypy/typeshed/stdlib/dbm/ndbm.pyi @@ -34,4 +34,4 @@ if sys.platform != "win32": __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] - def open(__filename: str, __flags: str = "r", __mode: int = 0o666) -> _dbm: ... + def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _dbm: ... diff --git a/mypy/typeshed/stdlib/distutils/core.pyi b/mypy/typeshed/stdlib/distutils/core.pyi index 7b0bdd1b35bd..c41c8ba19a8b 100644 --- a/mypy/typeshed/stdlib/distutils/core.pyi +++ b/mypy/typeshed/stdlib/distutils/core.pyi @@ -53,5 +53,5 @@ def setup( password: str = ..., fullname: str = ..., **attrs: Any, -) -> None: ... +) -> Distribution: ... def run_setup(script_name: str, script_args: list[str] | None = None, stop_after: str = "run") -> Distribution: ... diff --git a/mypy/typeshed/stdlib/email/charset.pyi b/mypy/typeshed/stdlib/email/charset.pyi index f8de016ab8bf..2d12df337207 100644 --- a/mypy/typeshed/stdlib/email/charset.pyi +++ b/mypy/typeshed/stdlib/email/charset.pyi @@ -25,7 +25,7 @@ class Charset: @overload def body_encode(self, string: str | bytes) -> str: ... def __eq__(self, other: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... def add_charset( charset: str, header_enc: int | None = None, body_enc: int | None = None, output_charset: str | None = None diff --git a/mypy/typeshed/stdlib/email/header.pyi b/mypy/typeshed/stdlib/email/header.pyi index fc9d73331bae..212132c6be18 100644 --- a/mypy/typeshed/stdlib/email/header.pyi +++ b/mypy/typeshed/stdlib/email/header.pyi @@ -17,7 +17,7 @@ class Header: def append(self, s: bytes | bytearray | str, charset: Charset | str | None = None, errors: str = "strict") -> None: ... def encode(self, splitchars: str = ";, \t", maxlinelen: int | None = None, linesep: str = "\n") -> str: ... def __eq__(self, other: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... # decode_header() either returns list[tuple[str, None]] if the header # contains no encoded parts, or list[tuple[bytes, str | None]] if the header diff --git a/mypy/typeshed/stdlib/email/headerregistry.pyi b/mypy/typeshed/stdlib/email/headerregistry.pyi index 93a2b3ee72b5..2ffdca9b2f22 100644 --- a/mypy/typeshed/stdlib/email/headerregistry.pyi +++ b/mypy/typeshed/stdlib/email/headerregistry.pyi @@ -140,9 +140,9 @@ class MessageIDHeader: class _HeaderParser(Protocol): max_count: ClassVar[Literal[1] | None] @staticmethod - def value_parser(__value: str) -> TokenList: ... + def value_parser(value: str, /) -> TokenList: ... @classmethod - def parse(cls, __value: str, __kwds: dict[str, Any]) -> None: ... + def parse(cls, value: str, kwds: dict[str, Any], /) -> None: ... class HeaderRegistry: registry: dict[str, type[_HeaderParser]] diff --git a/mypy/typeshed/stdlib/email/message.pyi b/mypy/typeshed/stdlib/email/message.pyi index 7384f3146a8e..d7d7e8c8e908 100644 --- a/mypy/typeshed/stdlib/email/message.pyi +++ b/mypy/typeshed/stdlib/email/message.pyi @@ -15,16 +15,20 @@ _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] +# Type returned by Policy.header_fetch_parse, often str or Header. _HeaderType: TypeAlias = Any -_HeaderTypeParam: TypeAlias = str | Header +# Type accepted by Policy.header_store_parse. +_HeaderTypeParam: TypeAlias = str | Header | Any class _SupportsEncodeToPayload(Protocol): - def encode(self, __encoding: str) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload: ... + def encode(self, encoding: str, /) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload: ... class _SupportsDecodeToPayload(Protocol): - def decode(self, __encoding: str, __errors: str) -> _PayloadType | _MultipartPayloadType: ... + def decode(self, encoding: str, errors: str, /) -> _PayloadType | _MultipartPayloadType: ... +# TODO: This class should be generic over the header policy and/or the header +# value types allowed by the policy. This depends on PEP 696 support +# (https://github.com/python/typeshed/issues/11422). class Message: policy: Policy # undocumented preamble: str | None diff --git a/mypy/typeshed/stdlib/encodings/utf_8.pyi b/mypy/typeshed/stdlib/encodings/utf_8.pyi index 0de51026f9f5..bb745399eb8c 100644 --- a/mypy/typeshed/stdlib/encodings/utf_8.pyi +++ b/mypy/typeshed/stdlib/encodings/utf_8.pyi @@ -6,16 +6,16 @@ class IncrementalEncoder(codecs.IncrementalEncoder): class IncrementalDecoder(codecs.BufferedIncrementalDecoder): @staticmethod - def _buffer_decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... + def _buffer_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... class StreamWriter(codecs.StreamWriter): @staticmethod - def encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... + def encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... class StreamReader(codecs.StreamReader): @staticmethod - def decode(__data: ReadableBuffer, __errors: str | None = None, __final: bool = False) -> tuple[str, int]: ... + def decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ... def getregentry() -> codecs.CodecInfo: ... -def encode(__str: str, __errors: str | None = None) -> tuple[bytes, int]: ... +def encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ... def decode(input: ReadableBuffer, errors: str | None = "strict") -> tuple[str, int]: ... diff --git a/mypy/typeshed/stdlib/fcntl.pyi b/mypy/typeshed/stdlib/fcntl.pyi index 7e5af76c2aae..ccf638205bbe 100644 --- a/mypy/typeshed/stdlib/fcntl.pyi +++ b/mypy/typeshed/stdlib/fcntl.pyi @@ -106,22 +106,22 @@ if sys.platform != "win32": FICLONERANGE: int @overload - def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: int = 0) -> int: ... + def fcntl(fd: FileDescriptorLike, cmd: int, arg: int = 0, /) -> int: ... @overload - def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: str | ReadOnlyBuffer) -> bytes: ... + def fcntl(fd: FileDescriptorLike, cmd: int, arg: str | ReadOnlyBuffer, /) -> bytes: ... # If arg is an int, return int @overload - def ioctl(__fd: FileDescriptorLike, __request: int, __arg: int = 0, __mutate_flag: bool = True) -> int: ... + def ioctl(fd: FileDescriptorLike, request: int, arg: int = 0, mutate_flag: bool = True, /) -> int: ... # The return type works as follows: # - If arg is a read-write buffer, return int if mutate_flag is True, otherwise bytes # - If arg is a read-only buffer, return bytes (and ignore the value of mutate_flag) # We can't represent that precisely as we can't distinguish between read-write and read-only # buffers, so we add overloads for a few unambiguous cases and use Any for the rest. @overload - def ioctl(__fd: FileDescriptorLike, __request: int, __arg: bytes, __mutate_flag: bool = True) -> bytes: ... + def ioctl(fd: FileDescriptorLike, request: int, arg: bytes, mutate_flag: bool = True, /) -> bytes: ... @overload - def ioctl(__fd: FileDescriptorLike, __request: int, __arg: WriteableBuffer, __mutate_flag: Literal[False]) -> bytes: ... + def ioctl(fd: FileDescriptorLike, request: int, arg: WriteableBuffer, mutate_flag: Literal[False], /) -> bytes: ... @overload - def ioctl(__fd: FileDescriptorLike, __request: int, __arg: Buffer, __mutate_flag: bool = True) -> Any: ... - def flock(__fd: FileDescriptorLike, __operation: int) -> None: ... - def lockf(__fd: FileDescriptorLike, __cmd: int, __len: int = 0, __start: int = 0, __whence: int = 0) -> Any: ... + def ioctl(fd: FileDescriptorLike, request: int, arg: Buffer, mutate_flag: bool = True, /) -> Any: ... + def flock(fd: FileDescriptorLike, operation: int, /) -> None: ... + def lockf(fd: FileDescriptorLike, cmd: int, len: int = 0, start: int = 0, whence: int = 0, /) -> Any: ... diff --git a/mypy/typeshed/stdlib/fractions.pyi b/mypy/typeshed/stdlib/fractions.pyi index 43eaa21bd039..086aff50344c 100644 --- a/mypy/typeshed/stdlib/fractions.pyi +++ b/mypy/typeshed/stdlib/fractions.pyi @@ -24,7 +24,7 @@ class Fraction(Rational): @overload def __new__(cls, numerator: int | Rational = 0, denominator: int | Rational | None = None) -> Self: ... @overload - def __new__(cls, __value: float | Decimal | str) -> Self: ... + def __new__(cls, value: float | Decimal | str, /) -> Self: ... @classmethod def from_float(cls, f: float) -> Self: ... @classmethod diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index d3f702bcef4f..27550cfe08e6 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -36,9 +36,9 @@ _PWrapper = ParamSpec("_PWrapper") _RWrapper = TypeVar("_RWrapper") @overload -def reduce(__function: Callable[[_T, _S], _T], __sequence: Iterable[_S], __initial: _T) -> _T: ... +def reduce(function: Callable[[_T, _S], _T], sequence: Iterable[_S], initial: _T, /) -> _T: ... @overload -def reduce(__function: Callable[[_T, _T], _T], __sequence: Iterable[_T]) -> _T: ... +def reduce(function: Callable[[_T, _T], _T], sequence: Iterable[_T], /) -> _T: ... class _CacheInfo(NamedTuple): hits: int @@ -61,7 +61,7 @@ class _lru_cache_wrapper(Generic[_T]): def cache_parameters(self) -> _CacheParameters: ... def __copy__(self) -> _lru_cache_wrapper[_T]: ... - def __deepcopy__(self, __memo: Any) -> _lru_cache_wrapper[_T]: ... + def __deepcopy__(self, memo: Any, /) -> _lru_cache_wrapper[_T]: ... @overload def lru_cache(maxsize: int | None = 128, typed: bool = False) -> Callable[[Callable[..., _T]], _lru_cache_wrapper[_T]]: ... @@ -129,8 +129,8 @@ class partial(Generic[_T]): def args(self) -> tuple[Any, ...]: ... @property def keywords(self) -> dict[str, Any]: ... - def __new__(cls, __func: Callable[..., _T], *args: Any, **kwargs: Any) -> Self: ... - def __call__(__self, *args: Any, **kwargs: Any) -> _T: ... + def __new__(cls, func: Callable[..., _T], /, *args: Any, **kwargs: Any) -> Self: ... + def __call__(self, /, *args: Any, **kwargs: Any) -> _T: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... @@ -142,9 +142,9 @@ class partialmethod(Generic[_T]): args: tuple[Any, ...] keywords: dict[str, Any] @overload - def __init__(self, __func: Callable[..., _T], *args: Any, **keywords: Any) -> None: ... + def __init__(self, func: Callable[..., _T], /, *args: Any, **keywords: Any) -> None: ... @overload - def __init__(self, __func: _Descriptor, *args: Any, **keywords: Any) -> None: ... + def __init__(self, func: _Descriptor, /, *args: Any, **keywords: Any) -> None: ... def __get__(self, obj: Any, cls: type[Any] | None = None) -> Callable[..., _T]: ... @property def __isabstractmethod__(self) -> bool: ... @@ -166,7 +166,7 @@ class _SingleDispatchCallable(Generic[_T]): @overload def register(self, cls: type[Any], func: Callable[..., _T]) -> Callable[..., _T]: ... def _clear_cache(self) -> None: ... - def __call__(__self, *args: Any, **kwargs: Any) -> _T: ... + def __call__(self, /, *args: Any, **kwargs: Any) -> _T: ... def singledispatch(func: Callable[..., _T]) -> _SingleDispatchCallable[_T]: ... @@ -199,7 +199,7 @@ class cached_property(Generic[_T_co]): def __class_getitem__(cls, item: Any) -> GenericAlias: ... if sys.version_info >= (3, 9): - def cache(__user_function: Callable[..., _T]) -> _lru_cache_wrapper[_T]: ... + def cache(user_function: Callable[..., _T], /) -> _lru_cache_wrapper[_T]: ... def _make_key( args: tuple[Hashable, ...], diff --git a/mypy/typeshed/stdlib/gc.pyi b/mypy/typeshed/stdlib/gc.pyi index 914c41434791..31179add314c 100644 --- a/mypy/typeshed/stdlib/gc.pyi +++ b/mypy/typeshed/stdlib/gc.pyi @@ -27,11 +27,11 @@ def get_referents(*objs: Any) -> list[Any]: ... def get_referrers(*objs: Any) -> list[Any]: ... def get_stats() -> list[dict[str, Any]]: ... def get_threshold() -> tuple[int, int, int]: ... -def is_tracked(__obj: Any) -> bool: ... +def is_tracked(obj: Any, /) -> bool: ... if sys.version_info >= (3, 9): - def is_finalized(__obj: Any) -> bool: ... + def is_finalized(obj: Any, /) -> bool: ... def isenabled() -> bool: ... -def set_debug(__flags: int) -> None: ... +def set_debug(flags: int, /) -> None: ... def set_threshold(threshold0: int, threshold1: int = ..., threshold2: int = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/gzip.pyi b/mypy/typeshed/stdlib/gzip.pyi index 2c33d7cf5810..7f43795dd01f 100644 --- a/mypy/typeshed/stdlib/gzip.pyi +++ b/mypy/typeshed/stdlib/gzip.pyi @@ -22,15 +22,15 @@ FNAME: int # actually Literal[8] # undocumented FCOMMENT: int # actually Literal[16] # undocumented class _ReadableFileobj(Protocol): - def read(self, __n: int) -> bytes: ... - def seek(self, __n: int) -> object: ... + def read(self, n: int, /) -> bytes: ... + def seek(self, n: int, /) -> object: ... # The following attributes and methods are optional: # name: str # mode: str # def fileno() -> int: ... class _WritableFileobj(Protocol): - def write(self, __b: bytes) -> object: ... + def write(self, b: bytes, /) -> object: ... def flush(self) -> object: ... # The following attributes and methods are optional: # name: str diff --git a/mypy/typeshed/stdlib/hashlib.pyi b/mypy/typeshed/stdlib/hashlib.pyi index 38e846ab7eb3..93bd986c9d31 100644 --- a/mypy/typeshed/stdlib/hashlib.pyi +++ b/mypy/typeshed/stdlib/hashlib.pyi @@ -59,7 +59,7 @@ class _Hash: def copy(self) -> Self: ... def digest(self) -> bytes: ... def hexdigest(self) -> str: ... - def update(self, __data: ReadableBuffer) -> None: ... + def update(self, data: ReadableBuffer, /) -> None: ... if sys.version_info >= (3, 9): def new(name: str, data: ReadableBuffer = b"", *, usedforsecurity: bool = ...) -> _Hash: ... @@ -92,9 +92,9 @@ class _VarLenHash: name: str def __init__(self, data: ReadableBuffer = ...) -> None: ... def copy(self) -> _VarLenHash: ... - def digest(self, __length: int) -> bytes: ... - def hexdigest(self, __length: int) -> str: ... - def update(self, __data: ReadableBuffer) -> None: ... + def digest(self, length: int, /) -> bytes: ... + def hexdigest(self, length: int, /) -> str: ... + def update(self, data: ReadableBuffer, /) -> None: ... sha3_224 = _Hash sha3_256 = _Hash @@ -116,7 +116,8 @@ class _BlakeHash(_Hash): if sys.version_info >= (3, 9): def __init__( self, - __data: ReadableBuffer = ..., + data: ReadableBuffer = ..., + /, *, digest_size: int = ..., key: ReadableBuffer = ..., @@ -134,7 +135,8 @@ class _BlakeHash(_Hash): else: def __init__( self, - __data: ReadableBuffer = ..., + data: ReadableBuffer = ..., + /, *, digest_size: int = ..., key: ReadableBuffer = ..., @@ -157,9 +159,9 @@ if sys.version_info >= (3, 11): def getbuffer(self) -> ReadableBuffer: ... class _FileDigestFileObj(Protocol): - def readinto(self, __buf: bytearray) -> int: ... + def readinto(self, buf: bytearray, /) -> int: ... def readable(self) -> bool: ... def file_digest( - __fileobj: _BytesIOLike | _FileDigestFileObj, __digest: str | Callable[[], _Hash], *, _bufsize: int = 262144 + fileobj: _BytesIOLike | _FileDigestFileObj, digest: str | Callable[[], _Hash], /, *, _bufsize: int = 262144 ) -> _Hash: ... diff --git a/mypy/typeshed/stdlib/heapq.pyi b/mypy/typeshed/stdlib/heapq.pyi index 9198febd3cfa..7a3aa8b442a5 100644 --- a/mypy/typeshed/stdlib/heapq.pyi +++ b/mypy/typeshed/stdlib/heapq.pyi @@ -14,4 +14,4 @@ def merge( ) -> Iterable[_S]: ... def nlargest(n: int, iterable: Iterable[_S], key: Callable[[_S], SupportsRichComparison] | None = None) -> list[_S]: ... def nsmallest(n: int, iterable: Iterable[_S], key: Callable[[_S], SupportsRichComparison] | None = None) -> list[_S]: ... -def _heapify_max(__heap: list[Any]) -> None: ... # undocumented +def _heapify_max(heap: list[Any], /) -> None: ... # undocumented diff --git a/mypy/typeshed/stdlib/hmac.pyi b/mypy/typeshed/stdlib/hmac.pyi index 614121529416..ac1372dd1e9c 100644 --- a/mypy/typeshed/stdlib/hmac.pyi +++ b/mypy/typeshed/stdlib/hmac.pyi @@ -32,7 +32,7 @@ class HMAC: def copy(self) -> HMAC: ... @overload -def compare_digest(__a: ReadableBuffer, __b: ReadableBuffer) -> bool: ... +def compare_digest(a: ReadableBuffer, b: ReadableBuffer, /) -> bool: ... @overload -def compare_digest(__a: AnyStr, __b: AnyStr) -> bool: ... +def compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ... def digest(key: SizedBuffer, msg: ReadableBuffer, digest: _DigestMod) -> bytes: ... diff --git a/mypy/typeshed/stdlib/imghdr.pyi b/mypy/typeshed/stdlib/imghdr.pyi index d0960a5a1c5c..6e1b858b8f32 100644 --- a/mypy/typeshed/stdlib/imghdr.pyi +++ b/mypy/typeshed/stdlib/imghdr.pyi @@ -6,8 +6,8 @@ __all__ = ["what"] class _ReadableBinary(Protocol): def tell(self) -> int: ... - def read(self, __size: int) -> bytes: ... - def seek(self, __offset: int) -> Any: ... + def read(self, size: int, /) -> bytes: ... + def seek(self, offset: int, /) -> Any: ... @overload def what(file: StrPath | _ReadableBinary, h: None = None) -> str | None: ... diff --git a/mypy/typeshed/stdlib/imp.pyi b/mypy/typeshed/stdlib/imp.pyi index b532f480fa13..ee5a0cd7bc72 100644 --- a/mypy/typeshed/stdlib/imp.pyi +++ b/mypy/typeshed/stdlib/imp.pyi @@ -45,7 +45,7 @@ class _FileLike(Protocol): def read(self) -> str | bytes: ... def close(self) -> Any: ... def __enter__(self) -> Any: ... - def __exit__(self, __typ: type[BaseException] | None, __exc: BaseException | None, __tb: TracebackType | None) -> Any: ... + def __exit__(self, typ: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None, /) -> Any: ... # PathLike doesn't work for the pathname argument here def load_source(name: str, pathname: str, file: _FileLike | None = None) -> types.ModuleType: ... diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index 825eab7ffde2..75e78ed59172 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -72,7 +72,7 @@ if sys.version_info >= (3, 10): def invalidate_caches(self) -> None: ... # Not defined on the actual class, but expected to exist. def find_spec( - self, __fullname: str, __path: Sequence[str] | None, __target: types.ModuleType | None = ... + self, fullname: str, path: Sequence[str] | None, target: types.ModuleType | None = ..., / ) -> ModuleSpec | None: ... class PathEntryFinder(metaclass=ABCMeta): @@ -91,7 +91,7 @@ else: def invalidate_caches(self) -> None: ... # Not defined on the actual class, but expected to exist. def find_spec( - self, __fullname: str, __path: Sequence[str] | None, __target: types.ModuleType | None = ... + self, fullname: str, path: Sequence[str] | None, target: types.ModuleType | None = ..., / ) -> ModuleSpec | None: ... class PathEntryFinder(Finder): @@ -138,25 +138,25 @@ if sys.version_info >= (3, 9): def joinpath(self, *descendants: str) -> Traversable: ... else: @abstractmethod - def joinpath(self, __child: str) -> Traversable: ... + def joinpath(self, child: str, /) -> Traversable: ... # The documentation and runtime protocol allows *args, **kwargs arguments, # but this would mean that all implementers would have to support them, # which is not the case. @overload @abstractmethod - def open(self, __mode: Literal["r"] = "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"]) -> IO[bytes]: ... + def open(self, mode: Literal["rb"], /) -> IO[bytes]: ... @property @abstractmethod def name(self) -> str: ... if sys.version_info >= (3, 10): - def __truediv__(self, __child: str) -> Traversable: ... + def __truediv__(self, child: str, /) -> Traversable: ... else: @abstractmethod - def __truediv__(self, __child: str) -> Traversable: ... + def __truediv__(self, child: str, /) -> Traversable: ... @abstractmethod def read_bytes(self) -> bytes: ... diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index 06a8ff6a3462..bb5ddc37c603 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -225,10 +225,10 @@ def isasyncgenfunction(obj: Callable[_P, Any]) -> TypeGuard[Callable[_P, AsyncGe 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: ... + def __set__(self, instance: _T_cont, value: _V_cont, /) -> None: ... class _SupportsDelete(Protocol[_T_cont]): - def __delete__(self, __instance: _T_cont) -> None: ... + def __delete__(self, instance: _T_cont, /) -> None: ... def isasyncgen(object: object) -> TypeGuard[AsyncGeneratorType[Any, Any]]: ... def istraceback(object: object) -> TypeGuard[TracebackType]: ... @@ -482,7 +482,7 @@ def formatargvalues( formatvalue: Callable[[Any], str] | None = ..., ) -> str: ... def getmro(cls: type) -> tuple[type, ...]: ... -def getcallargs(__func: Callable[_P, Any], *args: _P.args, **kwds: _P.kwargs) -> dict[str, Any]: ... +def getcallargs(func: Callable[_P, Any], /, *args: _P.args, **kwds: _P.kwargs) -> dict[str, Any]: ... class ClosureVars(NamedTuple): nonlocals: Mapping[str, Any] diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index 659b216c43dc..e7ed1b0b5ee5 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -63,15 +63,15 @@ class IOBase(metaclass=abc.ABCMeta): def isatty(self) -> bool: ... def readable(self) -> bool: ... read: Callable[..., Any] - def readlines(self, __hint: int = -1) -> list[bytes]: ... - def seek(self, __offset: int, __whence: int = ...) -> int: ... + def readlines(self, hint: int = -1, /) -> 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 truncate(self, size: int | None = ..., /) -> int: ... def writable(self) -> bool: ... write: Callable[..., Any] - def writelines(self, __lines: Iterable[ReadableBuffer]) -> None: ... - def readline(self, __size: int | None = -1) -> bytes: ... + def writelines(self, lines: Iterable[ReadableBuffer], /) -> None: ... + def readline(self, size: int | None = -1, /) -> bytes: ... def __del__(self) -> None: ... @property def closed(self) -> bool: ... @@ -79,18 +79,18 @@ class IOBase(metaclass=abc.ABCMeta): class RawIOBase(IOBase): def readall(self) -> bytes: ... - def readinto(self, __buffer: WriteableBuffer) -> int | None: ... - def write(self, __b: ReadableBuffer) -> int | None: ... - def read(self, __size: int = -1) -> bytes | None: ... + def readinto(self, buffer: WriteableBuffer, /) -> int | None: ... + def write(self, b: ReadableBuffer, /) -> int | None: ... + def read(self, size: int = -1, /) -> bytes | None: ... class BufferedIOBase(IOBase): raw: RawIOBase # This is not part of the BufferedIOBase API and may not exist on some implementations. def detach(self) -> RawIOBase: ... - def readinto(self, __buffer: WriteableBuffer) -> int: ... - def write(self, __buffer: ReadableBuffer) -> int: ... - def readinto1(self, __buffer: WriteableBuffer) -> int: ... - def read(self, __size: int | None = ...) -> bytes: ... - def read1(self, __size: int = ...) -> bytes: ... + def readinto(self, buffer: WriteableBuffer, /) -> int: ... + def write(self, buffer: ReadableBuffer, /) -> int: ... + def readinto1(self, buffer: WriteableBuffer, /) -> int: ... + def read(self, size: int | None = ..., /) -> bytes: ... + def read1(self, size: int = ..., /) -> bytes: ... class FileIO(RawIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of writelines in the base classes mode: str @@ -103,8 +103,8 @@ class FileIO(RawIOBase, BinaryIO): # type: ignore[misc] # incompatible definit ) -> None: ... @property def closefd(self) -> bool: ... - def write(self, __b: ReadableBuffer) -> int: ... - def read(self, __size: int = -1) -> bytes: ... + def write(self, b: ReadableBuffer, /) -> int: ... + def read(self, size: int = -1, /) -> bytes: ... def __enter__(self) -> Self: ... class BytesIO(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of methods in the base classes @@ -116,25 +116,25 @@ class BytesIO(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible d def __enter__(self) -> Self: ... def getvalue(self) -> bytes: ... def getbuffer(self) -> memoryview: ... - def read1(self, __size: int | None = -1) -> bytes: ... + def read1(self, size: int | None = -1, /) -> bytes: ... class BufferedReader(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of methods in the base classes def __enter__(self) -> Self: ... def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... - def peek(self, __size: int = 0) -> bytes: ... + def peek(self, size: int = 0, /) -> bytes: ... class BufferedWriter(BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible definitions of writelines in the base classes def __enter__(self) -> Self: ... def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... - def write(self, __buffer: ReadableBuffer) -> int: ... + def write(self, buffer: ReadableBuffer, /) -> int: ... class BufferedRandom(BufferedReader, BufferedWriter): # type: ignore[misc] # incompatible definitions of methods in the base classes def __enter__(self) -> Self: ... - def seek(self, __target: int, __whence: int = 0) -> int: ... # stubtest needs this + def seek(self, target: int, whence: int = 0, /) -> int: ... # stubtest needs this class BufferedRWPair(BufferedIOBase): def __init__(self, reader: RawIOBase, writer: RawIOBase, buffer_size: int = ...) -> None: ... - def peek(self, __size: int = ...) -> bytes: ... + def peek(self, size: int = ..., /) -> bytes: ... class TextIOBase(IOBase): encoding: str @@ -143,11 +143,11 @@ class TextIOBase(IOBase): def __iter__(self) -> Iterator[str]: ... # type: ignore[override] def __next__(self) -> str: ... # type: ignore[override] def detach(self) -> BinaryIO: ... - def write(self, __s: str) -> int: ... - def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] - def readline(self, __size: int = ...) -> str: ... # type: ignore[override] - def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] - def read(self, __size: int | None = ...) -> str: ... + def write(self, s: str, /) -> int: ... + def writelines(self, lines: Iterable[str], /) -> None: ... # type: ignore[override] + def readline(self, size: int = ..., /) -> str: ... # type: ignore[override] + def readlines(self, hint: int = -1, /) -> list[str]: ... # type: ignore[override] + def read(self, size: int | None = ..., /) -> str: ... @type_check_only class _WrappedBuffer(Protocol): @@ -207,14 +207,14 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def __enter__(self) -> Self: ... def __iter__(self) -> Iterator[str]: ... # type: ignore[override] def __next__(self) -> str: ... # type: ignore[override] - def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] - def readline(self, __size: int = -1) -> str: ... # type: ignore[override] - def readlines(self, __hint: int = -1) -> list[str]: ... # type: ignore[override] + def writelines(self, lines: Iterable[str], /) -> None: ... # type: ignore[override] + def readline(self, size: int = -1, /) -> str: ... # type: ignore[override] + def readlines(self, hint: int = -1, /) -> list[str]: ... # type: ignore[override] # Equals the "buffer" argument passed in to the constructor. def detach(self) -> BinaryIO: ... # TextIOWrapper's version of seek only supports a limited subset of # operations. - def seek(self, __cookie: int, __whence: int = 0) -> int: ... + def seek(self, cookie: int, whence: int = 0, /) -> int: ... class StringIO(TextIOWrapper): def __init__(self, initial_value: str | None = ..., newline: str | None = ...) -> None: ... @@ -229,10 +229,10 @@ class IncrementalNewlineDecoder(codecs.IncrementalDecoder): def decode(self, input: ReadableBuffer | str, final: bool = False) -> str: ... @property def newlines(self) -> str | tuple[str, ...] | None: ... - def setstate(self, __state: tuple[bytes, int]) -> None: ... + def setstate(self, state: tuple[bytes, int], /) -> None: ... if sys.version_info >= (3, 10): @overload - def text_encoding(__encoding: None, __stacklevel: int = 2) -> Literal["locale", "utf-8"]: ... + def text_encoding(encoding: None, stacklevel: int = 2, /) -> Literal["locale", "utf-8"]: ... @overload - def text_encoding(__encoding: _T, __stacklevel: int = 2) -> _T: ... + def text_encoding(encoding: _T, stacklevel: int = 2, /) -> _T: ... diff --git a/mypy/typeshed/stdlib/itertools.pyi b/mypy/typeshed/stdlib/itertools.pyi index 0e501e1ade4d..264064dcd682 100644 --- a/mypy/typeshed/stdlib/itertools.pyi +++ b/mypy/typeshed/stdlib/itertools.pyi @@ -35,7 +35,7 @@ class count(Iterator[_N]): def __iter__(self) -> Self: ... class cycle(Iterator[_T]): - def __init__(self, __iterable: Iterable[_T]) -> None: ... + def __init__(self, iterable: Iterable[_T], /) -> None: ... def __next__(self) -> _T: ... def __iter__(self) -> Self: ... @@ -62,9 +62,9 @@ class chain(Iterator[_T]): def __iter__(self) -> Self: ... @classmethod # We use type[Any] and not type[_S] to not lose the type inference from __iterable - def from_iterable(cls: type[Any], __iterable: Iterable[Iterable[_S]]) -> chain[_S]: ... + def from_iterable(cls: type[Any], iterable: Iterable[Iterable[_S]], /) -> chain[_S]: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class compress(Iterator[_T]): def __init__(self, data: Iterable[_T], selectors: Iterable[Any]) -> None: ... @@ -72,12 +72,12 @@ class compress(Iterator[_T]): def __next__(self) -> _T: ... class dropwhile(Iterator[_T]): - def __init__(self, __predicate: _Predicate[_T], __iterable: Iterable[_T]) -> None: ... + def __init__(self, predicate: _Predicate[_T], iterable: Iterable[_T], /) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... class filterfalse(Iterator[_T]): - def __init__(self, __predicate: _Predicate[_T] | None, __iterable: Iterable[_T]) -> None: ... + def __init__(self, predicate: _Predicate[_T] | None, iterable: Iterable[_T], /) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... @@ -91,74 +91,70 @@ class groupby(Iterator[tuple[_T_co, Iterator[_S_co]]], Generic[_T_co, _S_co]): class islice(Iterator[_T]): @overload - def __init__(self, __iterable: Iterable[_T], __stop: int | None) -> None: ... + def __init__(self, iterable: Iterable[_T], stop: int | None, /) -> None: ... @overload - def __init__(self, __iterable: Iterable[_T], __start: int | None, __stop: int | None, __step: int | None = ...) -> None: ... + def __init__(self, iterable: Iterable[_T], start: int | None, stop: int | None, step: int | None = ..., /) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... class starmap(Iterator[_T_co]): - def __new__(cls, __function: Callable[..., _T], __iterable: Iterable[Iterable[Any]]) -> starmap[_T]: ... + def __new__(cls, function: Callable[..., _T], iterable: Iterable[Iterable[Any]], /) -> starmap[_T]: ... def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... class takewhile(Iterator[_T]): - def __init__(self, __predicate: _Predicate[_T], __iterable: Iterable[_T]) -> None: ... + def __init__(self, predicate: _Predicate[_T], iterable: Iterable[_T], /) -> None: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... -def tee(__iterable: Iterable[_T], __n: int = 2) -> tuple[Iterator[_T], ...]: ... +def tee(iterable: Iterable[_T], n: int = 2, /) -> tuple[Iterator[_T], ...]: ... class zip_longest(Iterator[_T_co]): # one iterable (fillvalue doesn't matter) @overload - def __new__(cls, __iter1: Iterable[_T1], *, fillvalue: object = ...) -> zip_longest[tuple[_T1]]: ... + def __new__(cls, iter1: Iterable[_T1], /, *, fillvalue: object = ...) -> zip_longest[tuple[_T1]]: ... # two iterables @overload # In the overloads without fillvalue, all of the tuple members could theoretically be None, # but we return Any instead to avoid false positives for code where we know one of the iterables # is longer. - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> zip_longest[tuple[_T1 | Any, _T2 | Any]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /) -> zip_longest[tuple[_T1 | Any, _T2 | Any]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], *, fillvalue: _T + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /, *, fillvalue: _T ) -> zip_longest[tuple[_T1 | _T, _T2 | _T]]: ... # three iterables @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3] + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], / ) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], *, fillvalue: _T + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], /, *, fillvalue: _T ) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T]]: ... # four iterables @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4] + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], / ) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any, _T4 | Any]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4], *, fillvalue: _T + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], /, *, fillvalue: _T ) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T, _T4 | _T]]: ... # five iterables @overload def __new__( - cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], iter5: Iterable[_T5], / ) -> zip_longest[tuple[_T1 | Any, _T2 | Any, _T3 | Any, _T4 | Any, _T5 | Any]]: ... @overload def __new__( cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + iter1: Iterable[_T1], + iter2: Iterable[_T2], + iter3: Iterable[_T3], + iter4: Iterable[_T4], + iter5: Iterable[_T5], + /, *, fillvalue: _T, ) -> zip_longest[tuple[_T1 | _T, _T2 | _T, _T3 | _T, _T4 | _T, _T5 | _T]]: ... @@ -166,23 +162,25 @@ class zip_longest(Iterator[_T_co]): @overload def __new__( cls, - __iter1: Iterable[_T], - __iter2: Iterable[_T], - __iter3: Iterable[_T], - __iter4: Iterable[_T], - __iter5: Iterable[_T], - __iter6: Iterable[_T], + iter1: Iterable[_T], + iter2: Iterable[_T], + iter3: Iterable[_T], + iter4: Iterable[_T], + iter5: Iterable[_T], + iter6: Iterable[_T], + /, *iterables: Iterable[_T], ) -> zip_longest[tuple[_T | Any, ...]]: ... @overload def __new__( cls, - __iter1: Iterable[_T], - __iter2: Iterable[_T], - __iter3: Iterable[_T], - __iter4: Iterable[_T], - __iter5: Iterable[_T], - __iter6: Iterable[_T], + iter1: Iterable[_T], + iter2: Iterable[_T], + iter3: Iterable[_T], + iter4: Iterable[_T], + iter5: Iterable[_T], + iter6: Iterable[_T], + /, *iterables: Iterable[_T], fillvalue: _T, ) -> zip_longest[tuple[_T, ...]]: ... @@ -191,33 +189,29 @@ class zip_longest(Iterator[_T_co]): class product(Iterator[_T_co]): @overload - def __new__(cls, __iter1: Iterable[_T1]) -> product[tuple[_T1]]: ... + def __new__(cls, iter1: Iterable[_T1], /) -> product[tuple[_T1]]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2]) -> product[tuple[_T1, _T2]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], /) -> product[tuple[_T1, _T2]]: ... @overload - def __new__(cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3]) -> product[tuple[_T1, _T2, _T3]]: ... + def __new__(cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], /) -> product[tuple[_T1, _T2, _T3]]: ... @overload def __new__( - cls, __iter1: Iterable[_T1], __iter2: Iterable[_T2], __iter3: Iterable[_T3], __iter4: Iterable[_T4] + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], / ) -> product[tuple[_T1, _T2, _T3, _T4]]: ... @overload def __new__( - cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], + cls, iter1: Iterable[_T1], iter2: Iterable[_T2], iter3: Iterable[_T3], iter4: Iterable[_T4], iter5: Iterable[_T5], / ) -> product[tuple[_T1, _T2, _T3, _T4, _T5]]: ... @overload def __new__( cls, - __iter1: Iterable[_T1], - __iter2: Iterable[_T2], - __iter3: Iterable[_T3], - __iter4: Iterable[_T4], - __iter5: Iterable[_T5], - __iter6: Iterable[_T6], + iter1: Iterable[_T1], + iter2: Iterable[_T2], + iter3: Iterable[_T3], + iter4: Iterable[_T4], + iter5: Iterable[_T5], + iter6: Iterable[_T6], + /, ) -> product[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ... @overload def __new__(cls, *iterables: Iterable[_T1], repeat: int = 1) -> product[tuple[_T1, ...]]: ... @@ -268,7 +262,7 @@ class combinations_with_replacement(Iterator[_T_co]): if sys.version_info >= (3, 10): class pairwise(Iterator[_T_co]): - def __new__(cls, __iterable: Iterable[_T]) -> pairwise[tuple[_T, _T]]: ... + def __new__(cls, iterable: Iterable[_T], /) -> pairwise[tuple[_T, _T]]: ... def __iter__(self) -> Self: ... def __next__(self) -> _T_co: ... diff --git a/mypy/typeshed/stdlib/json/encoder.pyi b/mypy/typeshed/stdlib/json/encoder.pyi index 0c0d366eb7a2..c1062688bd93 100644 --- a/mypy/typeshed/stdlib/json/encoder.pyi +++ b/mypy/typeshed/stdlib/json/encoder.pyi @@ -10,6 +10,8 @@ INFINITY: float def py_encode_basestring(s: str) -> str: ... # undocumented def py_encode_basestring_ascii(s: str) -> str: ... # undocumented +def encode_basestring(s: str) -> str: ... # undocumented +def encode_basestring_ascii(s: str) -> str: ... # undocumented class JSONEncoder: item_separator: str diff --git a/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi b/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi index 5468ab1db5c3..06813c94308a 100644 --- a/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi +++ b/mypy/typeshed/stdlib/lib2to3/fixer_base.pyi @@ -38,5 +38,5 @@ class BaseFix: class ConditionalFix(BaseFix, metaclass=ABCMeta): skip_on: ClassVar[str | None] - def start_tree(self, __tree: Node, __filename: StrPath) -> None: ... + def start_tree(self, tree: Node, filename: StrPath, /) -> None: ... def should_skip(self, node: Base) -> bool: ... diff --git a/mypy/typeshed/stdlib/logging/__init__.pyi b/mypy/typeshed/stdlib/logging/__init__.pyi index eae2bcd3e96c..a62d0674df4c 100644 --- a/mypy/typeshed/stdlib/logging/__init__.pyi +++ b/mypy/typeshed/stdlib/logging/__init__.pyi @@ -71,12 +71,12 @@ _FormatStyle: TypeAlias = Literal["%", "{", "$"] if sys.version_info >= (3, 12): class _SupportsFilter(Protocol): - def filter(self, __record: LogRecord) -> bool | LogRecord: ... + def filter(self, record: LogRecord, /) -> bool | LogRecord: ... _FilterType: TypeAlias = Filter | Callable[[LogRecord], bool | LogRecord] | _SupportsFilter else: class _SupportsFilter(Protocol): - def filter(self, __record: LogRecord) -> bool: ... + def filter(self, record: LogRecord, /) -> bool: ... _FilterType: TypeAlias = Filter | Callable[[LogRecord], bool] | _SupportsFilter @@ -341,6 +341,9 @@ class LogRecord: stack_info: str | None thread: int | None threadName: str | None + if sys.version_info >= (3, 12): + taskName: str | None + def __init__( self, name: str, @@ -355,7 +358,7 @@ class LogRecord: ) -> None: ... def getMessage(self) -> str: ... # Allows setting contextual information on LogRecord objects as per the docs, see #7833 - def __setattr__(self, __name: str, __value: Any) -> None: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... _L = TypeVar("_L", bound=Logger | LoggerAdapter[Any]) diff --git a/mypy/typeshed/stdlib/logging/handlers.pyi b/mypy/typeshed/stdlib/logging/handlers.pyi index 2280dbad4c5d..4c3dc913308c 100644 --- a/mypy/typeshed/stdlib/logging/handlers.pyi +++ b/mypy/typeshed/stdlib/logging/handlers.pyi @@ -253,7 +253,7 @@ class HTTPHandler(Handler): class _QueueLike(Protocol[_T]): def get(self) -> _T: ... - def put_nowait(self, __item: _T) -> None: ... + def put_nowait(self, item: _T, /) -> None: ... class QueueHandler(Handler): queue: _QueueLike[Any] diff --git a/mypy/typeshed/stdlib/lzma.pyi b/mypy/typeshed/stdlib/lzma.pyi index 05248ee0e710..c05e46a02aeb 100644 --- a/mypy/typeshed/stdlib/lzma.pyi +++ b/mypy/typeshed/stdlib/lzma.pyi @@ -99,7 +99,7 @@ class LZMACompressor: def __init__( self, format: int | None = ..., check: int = ..., preset: int | None = ..., filters: _FilterChain | None = ... ) -> None: ... - def compress(self, __data: ReadableBuffer) -> bytes: ... + def compress(self, data: ReadableBuffer, /) -> bytes: ... def flush(self) -> bytes: ... class LZMAError(Exception): ... @@ -194,4 +194,4 @@ def compress( def decompress( data: ReadableBuffer, format: int = 0, memlimit: int | None = None, filters: _FilterChain | None = None ) -> bytes: ... -def is_check_supported(__check_id: int) -> bool: ... +def is_check_supported(check_id: int, /) -> bool: ... diff --git a/mypy/typeshed/stdlib/marshal.pyi b/mypy/typeshed/stdlib/marshal.pyi index 21f05c908479..69546344f5bf 100644 --- a/mypy/typeshed/stdlib/marshal.pyi +++ b/mypy/typeshed/stdlib/marshal.pyi @@ -27,7 +27,7 @@ _Marshallable: TypeAlias = ( | ReadableBuffer ) -def dump(__value: _Marshallable, __file: SupportsWrite[bytes], __version: int = 4) -> None: ... -def load(__file: SupportsRead[bytes]) -> Any: ... -def dumps(__value: _Marshallable, __version: int = 4) -> bytes: ... -def loads(__bytes: ReadableBuffer) -> Any: ... +def dump(value: _Marshallable, file: SupportsWrite[bytes], version: int = 4, /) -> None: ... +def load(file: SupportsRead[bytes], /) -> Any: ... +def dumps(value: _Marshallable, version: int = 4, /) -> bytes: ... +def loads(bytes: ReadableBuffer, /) -> Any: ... diff --git a/mypy/typeshed/stdlib/math.pyi b/mypy/typeshed/stdlib/math.pyi index ee0693912a8b..0c2fd4aba719 100644 --- a/mypy/typeshed/stdlib/math.pyi +++ b/mypy/typeshed/stdlib/math.pyi @@ -14,58 +14,58 @@ inf: float nan: float tau: float -def acos(__x: _SupportsFloatOrIndex) -> float: ... -def acosh(__x: _SupportsFloatOrIndex) -> float: ... -def asin(__x: _SupportsFloatOrIndex) -> float: ... -def asinh(__x: _SupportsFloatOrIndex) -> float: ... -def atan(__x: _SupportsFloatOrIndex) -> float: ... -def atan2(__y: _SupportsFloatOrIndex, __x: _SupportsFloatOrIndex) -> float: ... -def atanh(__x: _SupportsFloatOrIndex) -> float: ... +def acos(x: _SupportsFloatOrIndex, /) -> float: ... +def acosh(x: _SupportsFloatOrIndex, /) -> float: ... +def asin(x: _SupportsFloatOrIndex, /) -> float: ... +def asinh(x: _SupportsFloatOrIndex, /) -> float: ... +def atan(x: _SupportsFloatOrIndex, /) -> float: ... +def atan2(y: _SupportsFloatOrIndex, x: _SupportsFloatOrIndex, /) -> float: ... +def atanh(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 11): - def cbrt(__x: _SupportsFloatOrIndex) -> float: ... + def cbrt(x: _SupportsFloatOrIndex, /) -> float: ... class _SupportsCeil(Protocol[_T_co]): def __ceil__(self) -> _T_co: ... @overload -def ceil(__x: _SupportsCeil[_T]) -> _T: ... +def ceil(x: _SupportsCeil[_T], /) -> _T: ... @overload -def ceil(__x: _SupportsFloatOrIndex) -> 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: ... -def dist(__p: Iterable[_SupportsFloatOrIndex], __q: Iterable[_SupportsFloatOrIndex]) -> float: ... -def erf(__x: _SupportsFloatOrIndex) -> float: ... -def erfc(__x: _SupportsFloatOrIndex) -> float: ... -def exp(__x: _SupportsFloatOrIndex) -> float: ... +def ceil(x: _SupportsFloatOrIndex, /) -> 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: ... +def dist(p: Iterable[_SupportsFloatOrIndex], q: Iterable[_SupportsFloatOrIndex], /) -> float: ... +def erf(x: _SupportsFloatOrIndex, /) -> float: ... +def erfc(x: _SupportsFloatOrIndex, /) -> float: ... +def exp(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 11): - def exp2(__x: _SupportsFloatOrIndex) -> float: ... + def exp2(x: _SupportsFloatOrIndex, /) -> float: ... -def expm1(__x: _SupportsFloatOrIndex) -> float: ... -def fabs(__x: _SupportsFloatOrIndex) -> float: ... -def factorial(__x: SupportsIndex) -> int: ... +def expm1(x: _SupportsFloatOrIndex, /) -> float: ... +def fabs(x: _SupportsFloatOrIndex, /) -> float: ... +def factorial(x: SupportsIndex, /) -> int: ... class _SupportsFloor(Protocol[_T_co]): def __floor__(self) -> _T_co: ... @overload -def floor(__x: _SupportsFloor[_T]) -> _T: ... +def floor(x: _SupportsFloor[_T], /) -> _T: ... @overload -def floor(__x: _SupportsFloatOrIndex) -> int: ... -def fmod(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... -def frexp(__x: _SupportsFloatOrIndex) -> tuple[float, int]: ... -def fsum(__seq: Iterable[_SupportsFloatOrIndex]) -> float: ... -def gamma(__x: _SupportsFloatOrIndex) -> float: ... +def floor(x: _SupportsFloatOrIndex, /) -> int: ... +def fmod(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... +def frexp(x: _SupportsFloatOrIndex, /) -> tuple[float, int]: ... +def fsum(seq: Iterable[_SupportsFloatOrIndex], /) -> float: ... +def gamma(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 9): def gcd(*integers: SupportsIndex) -> int: ... else: - def gcd(__x: SupportsIndex, __y: SupportsIndex) -> int: ... + def gcd(x: SupportsIndex, y: SupportsIndex, /) -> int: ... def hypot(*coordinates: _SupportsFloatOrIndex) -> float: ... def isclose( @@ -75,51 +75,51 @@ def isclose( rel_tol: _SupportsFloatOrIndex = 1e-09, abs_tol: _SupportsFloatOrIndex = 0.0, ) -> bool: ... -def isinf(__x: _SupportsFloatOrIndex) -> bool: ... -def isfinite(__x: _SupportsFloatOrIndex) -> bool: ... -def isnan(__x: _SupportsFloatOrIndex) -> bool: ... -def isqrt(__n: SupportsIndex) -> int: ... +def isinf(x: _SupportsFloatOrIndex, /) -> bool: ... +def isfinite(x: _SupportsFloatOrIndex, /) -> bool: ... +def isnan(x: _SupportsFloatOrIndex, /) -> bool: ... +def isqrt(n: SupportsIndex, /) -> int: ... if sys.version_info >= (3, 9): def lcm(*integers: SupportsIndex) -> int: ... -def ldexp(__x: _SupportsFloatOrIndex, __i: int) -> float: ... -def lgamma(__x: _SupportsFloatOrIndex) -> float: ... +def ldexp(x: _SupportsFloatOrIndex, i: int, /) -> float: ... +def lgamma(x: _SupportsFloatOrIndex, /) -> float: ... def log(x: _SupportsFloatOrIndex, base: _SupportsFloatOrIndex = ...) -> float: ... -def log10(__x: _SupportsFloatOrIndex) -> float: ... -def log1p(__x: _SupportsFloatOrIndex) -> float: ... -def log2(__x: _SupportsFloatOrIndex) -> float: ... -def modf(__x: _SupportsFloatOrIndex) -> tuple[float, float]: ... +def log10(x: _SupportsFloatOrIndex, /) -> float: ... +def log1p(x: _SupportsFloatOrIndex, /) -> float: ... +def log2(x: _SupportsFloatOrIndex, /) -> float: ... +def modf(x: _SupportsFloatOrIndex, /) -> tuple[float, float]: ... if sys.version_info >= (3, 12): - def nextafter(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex, *, steps: SupportsIndex | None = None) -> float: ... + def nextafter(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /, *, steps: SupportsIndex | None = None) -> float: ... elif sys.version_info >= (3, 9): - def nextafter(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... + def nextafter(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... -def perm(__n: SupportsIndex, __k: SupportsIndex | None = None) -> int: ... -def pow(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... +def perm(n: SupportsIndex, k: SupportsIndex | None = None, /) -> int: ... +def pow(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... @overload -def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = 1) -> int: ... # type: ignore[overload-overlap] +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: ... -def sinh(__x: _SupportsFloatOrIndex) -> float: ... +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: ... +def sinh(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 12): - def sumprod(__p: Iterable[float], __q: Iterable[float]) -> float: ... + def sumprod(p: Iterable[float], q: Iterable[float], /) -> float: ... -def sqrt(__x: _SupportsFloatOrIndex) -> float: ... -def tan(__x: _SupportsFloatOrIndex) -> float: ... -def tanh(__x: _SupportsFloatOrIndex) -> float: ... +def sqrt(x: _SupportsFloatOrIndex, /) -> float: ... +def tan(x: _SupportsFloatOrIndex, /) -> float: ... +def tanh(x: _SupportsFloatOrIndex, /) -> float: ... # Is different from `_typeshed.SupportsTrunc`, which is not generic class _SupportsTrunc(Protocol[_T_co]): def __trunc__(self) -> _T_co: ... -def trunc(__x: _SupportsTrunc[_T]) -> _T: ... +def trunc(x: _SupportsTrunc[_T], /) -> _T: ... if sys.version_info >= (3, 9): - def ulp(__x: _SupportsFloatOrIndex) -> float: ... + def ulp(x: _SupportsFloatOrIndex, /) -> float: ... diff --git a/mypy/typeshed/stdlib/mmap.pyi b/mypy/typeshed/stdlib/mmap.pyi index 6bbb797f054d..93c4f408e5b6 100644 --- a/mypy/typeshed/stdlib/mmap.pyi +++ b/mypy/typeshed/stdlib/mmap.pyi @@ -58,24 +58,24 @@ class mmap(Iterable[int], Sized): def read(self, n: int | None = ...) -> bytes: ... def write(self, bytes: ReadableBuffer) -> int: ... @overload - def __getitem__(self, __key: int) -> int: ... + def __getitem__(self, key: int, /) -> int: ... @overload - def __getitem__(self, __key: slice) -> bytes: ... - def __delitem__(self, __key: int | slice) -> NoReturn: ... + def __getitem__(self, key: slice, /) -> bytes: ... + def __delitem__(self, key: int | slice, /) -> NoReturn: ... @overload - def __setitem__(self, __key: int, __value: int) -> None: ... + def __setitem__(self, key: int, value: int, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: ReadableBuffer) -> None: ... + def __setitem__(self, key: slice, value: ReadableBuffer, /) -> None: ... # Doesn't actually exist, but the object actually supports "in" because it has __getitem__, # so we claim that there is also a __contains__ to help type checkers. - def __contains__(self, __o: object) -> bool: ... + def __contains__(self, o: object, /) -> bool: ... # Doesn't actually exist, but the object is actually iterable because it has __getitem__ and __len__, # so we claim that there is also an __iter__ to help type checkers. def __iter__(self) -> Iterator[int]: ... def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... - def __buffer__(self, __flags: int) -> memoryview: ... - def __release_buffer__(self, __buffer: memoryview) -> None: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... if sys.platform != "win32": MADV_NORMAL: int diff --git a/mypy/typeshed/stdlib/msvcrt.pyi b/mypy/typeshed/stdlib/msvcrt.pyi index bfd7ec62a9be..54b3674a3a46 100644 --- a/mypy/typeshed/stdlib/msvcrt.pyi +++ b/mypy/typeshed/stdlib/msvcrt.pyi @@ -13,20 +13,20 @@ if sys.platform == "win32": SEM_NOALIGNMENTFAULTEXCEPT: int SEM_NOGPFAULTERRORBOX: int SEM_NOOPENFILEERRORBOX: int - def locking(__fd: int, __mode: int, __nbytes: int) -> None: ... - def setmode(__fd: int, __mode: int) -> int: ... - def open_osfhandle(__handle: int, __flags: int) -> int: ... - def get_osfhandle(__fd: int) -> int: ... + def locking(fd: int, mode: int, nbytes: int, /) -> None: ... + def setmode(fd: int, mode: int, /) -> int: ... + def open_osfhandle(handle: int, flags: int, /) -> int: ... + def get_osfhandle(fd: int, /) -> int: ... def kbhit() -> bool: ... def getch() -> bytes: ... def getwch() -> str: ... def getche() -> bytes: ... def getwche() -> str: ... - def putch(__char: bytes | bytearray) -> None: ... - def putwch(__unicode_char: str) -> None: ... - def ungetch(__char: bytes | bytearray) -> None: ... - def ungetwch(__unicode_char: str) -> None: ... + def putch(char: bytes | bytearray, /) -> None: ... + def putwch(unicode_char: str, /) -> None: ... + def ungetch(char: bytes | bytearray, /) -> None: ... + def ungetwch(unicode_char: str, /) -> None: ... def heapmin() -> None: ... - def SetErrorMode(__mode: int) -> int: ... + def SetErrorMode(mode: int, /) -> int: ... if sys.version_info >= (3, 10): def GetErrorMode() -> int: ... # undocumented diff --git a/mypy/typeshed/stdlib/multiprocessing/context.pyi b/mypy/typeshed/stdlib/multiprocessing/context.pyi index 1cc8d03ea436..a3edaa463818 100644 --- a/mypy/typeshed/stdlib/multiprocessing/context.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/context.pyi @@ -7,7 +7,7 @@ from multiprocessing import popen_fork, popen_forkserver, popen_spawn_posix, pop from multiprocessing.managers import SyncManager from multiprocessing.pool import Pool as _Pool from multiprocessing.process import BaseProcess -from multiprocessing.sharedctypes import SynchronizedArray, SynchronizedBase +from multiprocessing.sharedctypes import Synchronized, SynchronizedArray from typing import Any, ClassVar, Literal, TypeVar, overload from typing_extensions import TypeAlias @@ -79,15 +79,17 @@ class BaseContext: @overload def RawArray(self, typecode_or_type: str, size_or_initializer: int | Sequence[Any]) -> Any: ... @overload - def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[False]) -> _CT: ... + def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[False]) -> Synchronized[_CT]: ... @overload - def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[True] | _LockLike = True) -> SynchronizedBase[_CT]: ... + def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[True] | _LockLike = True) -> Synchronized[_CT]: ... @overload - def Value(self, typecode_or_type: str, *args: Any, lock: Literal[True] | _LockLike = True) -> SynchronizedBase[Any]: ... + def Value(self, typecode_or_type: str, *args: Any, lock: Literal[True] | _LockLike = True) -> Synchronized[Any]: ... @overload def Value(self, typecode_or_type: str | type[_CData], *args: Any, lock: bool | _LockLike = True) -> Any: ... @overload - def Array(self, typecode_or_type: type[_CT], size_or_initializer: int | Sequence[Any], *, lock: Literal[False]) -> _CT: ... + def Array( + self, typecode_or_type: type[_CT], size_or_initializer: int | Sequence[Any], *, lock: Literal[False] + ) -> SynchronizedArray[_CT]: ... @overload def Array( self, typecode_or_type: type[_CT], size_or_initializer: int | Sequence[Any], *, lock: Literal[True] | _LockLike = True diff --git a/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi b/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi index 804a56e9cbcf..3cbeeb057791 100644 --- a/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/dummy/__init__.pyi @@ -57,8 +57,8 @@ Process = DummyProcess class Namespace: def __init__(self, **kwds: Any) -> None: ... - def __getattr__(self, __name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... + def __getattr__(self, name: str, /) -> Any: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... class Value: _typecode: Any diff --git a/mypy/typeshed/stdlib/multiprocessing/managers.pyi b/mypy/typeshed/stdlib/multiprocessing/managers.pyi index eb3ac29b1449..02b5c4bc8c67 100644 --- a/mypy/typeshed/stdlib/multiprocessing/managers.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/managers.pyi @@ -22,8 +22,8 @@ _VT = TypeVar("_VT") class Namespace: def __init__(self, **kwds: Any) -> None: ... - def __getattr__(self, __name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... + def __getattr__(self, name: str, /) -> Any: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... _Namespace: TypeAlias = Namespace @@ -63,23 +63,23 @@ class ValueProxy(BaseProxy, Generic[_T]): class DictProxy(BaseProxy, MutableMapping[_KT, _VT]): __builtins__: ClassVar[dict[str, Any]] def __len__(self) -> int: ... - def __getitem__(self, __key: _KT) -> _VT: ... - def __setitem__(self, __key: _KT, __value: _VT) -> None: ... - def __delitem__(self, __key: _KT) -> None: ... + def __getitem__(self, key: _KT, /) -> _VT: ... + def __setitem__(self, key: _KT, value: _VT, /) -> None: ... + def __delitem__(self, key: _KT, /) -> None: ... def __iter__(self) -> Iterator[_KT]: ... def copy(self) -> dict[_KT, _VT]: ... @overload # type: ignore[override] - def get(self, __key: _KT) -> _VT | None: ... + def get(self, key: _KT, /) -> _VT | None: ... @overload - def get(self, __key: _KT, __default: _VT) -> _VT: ... + def get(self, key: _KT, default: _VT, /) -> _VT: ... @overload - def get(self, __key: _KT, __default: _T) -> _VT | _T: ... + def get(self, key: _KT, default: _T, /) -> _VT | _T: ... @overload - def pop(self, __key: _KT) -> _VT: ... + def pop(self, key: _KT, /) -> _VT: ... @overload - def pop(self, __key: _KT, __default: _VT) -> _VT: ... + def pop(self, key: _KT, default: _VT, /) -> _VT: ... @overload - def pop(self, __key: _KT, __default: _T) -> _VT | _T: ... + def pop(self, key: _KT, default: _T, /) -> _VT | _T: ... def keys(self) -> list[_KT]: ... # type: ignore[override] def items(self) -> list[tuple[_KT, _VT]]: ... # type: ignore[override] def values(self) -> list[_VT]: ... # type: ignore[override] @@ -87,26 +87,26 @@ class DictProxy(BaseProxy, MutableMapping[_KT, _VT]): class BaseListProxy(BaseProxy, MutableSequence[_T]): __builtins__: ClassVar[dict[str, Any]] def __len__(self) -> int: ... - def __add__(self, __x: list[_T]) -> list[_T]: ... - def __delitem__(self, __i: SupportsIndex | slice) -> None: ... + def __add__(self, x: list[_T], /) -> list[_T]: ... + def __delitem__(self, i: SupportsIndex | slice, /) -> None: ... @overload - def __getitem__(self, __i: SupportsIndex) -> _T: ... + def __getitem__(self, i: SupportsIndex, /) -> _T: ... @overload - def __getitem__(self, __s: slice) -> list[_T]: ... + def __getitem__(self, s: slice, /) -> list[_T]: ... @overload - def __setitem__(self, __i: SupportsIndex, __o: _T) -> None: ... + def __setitem__(self, i: SupportsIndex, o: _T, /) -> None: ... @overload - def __setitem__(self, __s: slice, __o: Iterable[_T]) -> None: ... - def __mul__(self, __n: SupportsIndex) -> list[_T]: ... - def __rmul__(self, __n: SupportsIndex) -> list[_T]: ... + def __setitem__(self, s: slice, o: Iterable[_T], /) -> None: ... + def __mul__(self, n: SupportsIndex, /) -> list[_T]: ... + def __rmul__(self, n: SupportsIndex, /) -> list[_T]: ... def __reversed__(self) -> Iterator[_T]: ... - def append(self, __object: _T) -> None: ... - def extend(self, __iterable: Iterable[_T]) -> None: ... - def pop(self, __index: SupportsIndex = ...) -> _T: ... - def index(self, __value: _T, __start: SupportsIndex = ..., __stop: SupportsIndex = ...) -> int: ... - def count(self, __value: _T) -> int: ... - def insert(self, __index: SupportsIndex, __object: _T) -> None: ... - def remove(self, __value: _T) -> None: ... + def append(self, object: _T, /) -> None: ... + def extend(self, iterable: Iterable[_T], /) -> None: ... + def pop(self, index: SupportsIndex = ..., /) -> _T: ... + def index(self, value: _T, start: SupportsIndex = ..., stop: SupportsIndex = ..., /) -> int: ... + def count(self, value: _T, /) -> int: ... + def insert(self, index: SupportsIndex, object: _T, /) -> None: ... + def remove(self, value: _T, /) -> None: ... # Use BaseListProxy[SupportsRichComparisonT] for the first overload rather than [SupportsRichComparison] # to work around invariance @overload @@ -115,8 +115,8 @@ class BaseListProxy(BaseProxy, MutableSequence[_T]): def sort(self, *, key: Callable[[_T], SupportsRichComparison], reverse: bool = ...) -> None: ... class ListProxy(BaseListProxy[_T]): - def __iadd__(self, __value: Iterable[_T]) -> Self: ... # type: ignore[override] - def __imul__(self, __value: SupportsIndex) -> Self: ... # type: ignore[override] + def __iadd__(self, value: Iterable[_T], /) -> Self: ... # type: ignore[override] + def __imul__(self, value: SupportsIndex, /) -> Self: ... # type: ignore[override] # Returned by BaseManager.get_server() class Server: @@ -186,19 +186,19 @@ class SyncManager(BaseManager): @overload def dict(self, **kwargs: _VT) -> DictProxy[str, _VT]: ... @overload - def dict(self, __map: SupportsKeysAndGetItem[_KT, _VT]) -> DictProxy[_KT, _VT]: ... + def dict(self, map: SupportsKeysAndGetItem[_KT, _VT], /) -> DictProxy[_KT, _VT]: ... @overload - def dict(self, __map: SupportsKeysAndGetItem[str, _VT], **kwargs: _VT) -> DictProxy[str, _VT]: ... + def dict(self, map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> DictProxy[str, _VT]: ... @overload - def dict(self, __iterable: Iterable[tuple[_KT, _VT]]) -> DictProxy[_KT, _VT]: ... + def dict(self, iterable: Iterable[tuple[_KT, _VT]], /) -> DictProxy[_KT, _VT]: ... @overload - def dict(self, __iterable: Iterable[tuple[str, _VT]], **kwargs: _VT) -> DictProxy[str, _VT]: ... + def dict(self, iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> DictProxy[str, _VT]: ... @overload - def dict(self, __iterable: Iterable[list[str]]) -> DictProxy[str, str]: ... + def dict(self, iterable: Iterable[list[str]], /) -> DictProxy[str, str]: ... @overload - def dict(self, __iterable: Iterable[list[bytes]]) -> DictProxy[bytes, bytes]: ... + def dict(self, iterable: Iterable[list[bytes]], /) -> DictProxy[bytes, bytes]: ... @overload - def list(self, __sequence: Sequence[_T]) -> ListProxy[_T]: ... + def list(self, sequence: Sequence[_T], /) -> ListProxy[_T]: ... @overload def list(self) -> ListProxy[Any]: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/queues.pyi b/mypy/typeshed/stdlib/multiprocessing/queues.pyi index 8e72d15f25f6..4cedd665552a 100644 --- a/mypy/typeshed/stdlib/multiprocessing/queues.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/queues.pyi @@ -23,7 +23,7 @@ class Queue(Generic[_T]): def join_thread(self) -> None: ... def cancel_join_thread(self) -> None: ... if sys.version_info >= (3, 12): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... class JoinableQueue(Queue[_T]): def task_done(self) -> None: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi b/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi index 3979f14cf636..4093a97e6ca3 100644 --- a/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/sharedctypes.pyi @@ -72,7 +72,7 @@ def synchronized(obj: ctypes.Array[_CT], lock: _LockLike | None = None, ctx: Any def synchronized(obj: _CT, lock: _LockLike | None = None, ctx: Any | None = None) -> SynchronizedBase[_CT]: ... class _AcquireFunc(Protocol): - def __call__(self, __block: bool = ..., __timeout: float | None = ...) -> bool: ... + def __call__(self, block: bool = ..., timeout: float | None = ..., /) -> bool: ... class SynchronizedBase(Generic[_CT]): acquire: _AcquireFunc @@ -83,7 +83,7 @@ class SynchronizedBase(Generic[_CT]): def get_lock(self) -> _LockLike: ... def __enter__(self) -> bool: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, / ) -> None: ... class Synchronized(SynchronizedBase[_SimpleCData[_T]], Generic[_T]): @@ -91,7 +91,13 @@ class Synchronized(SynchronizedBase[_SimpleCData[_T]], Generic[_T]): class SynchronizedArray(SynchronizedBase[ctypes.Array[_CT]], Generic[_CT]): def __len__(self) -> int: ... + @overload + def __getitem__(self, i: slice) -> list[_CT]: ... + @overload def __getitem__(self, i: int) -> _CT: ... + @overload + def __setitem__(self, i: slice, value: Iterable[_CT]) -> None: ... + @overload def __setitem__(self, i: int, value: _CT) -> None: ... def __getslice__(self, start: int, stop: int) -> list[_CT]: ... def __setslice__(self, start: int, stop: int, values: Iterable[_CT]) -> None: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi index a4e36cfa0b6e..048c6fe8d891 100644 --- a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi @@ -23,7 +23,7 @@ class Condition(AbstractContextManager[bool]): def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... def release(self) -> None: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, / ) -> None: ... class Event: @@ -38,7 +38,7 @@ class SemLock(AbstractContextManager[bool]): def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... def release(self) -> None: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None + self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, / ) -> None: ... class Lock(SemLock): diff --git a/mypy/typeshed/stdlib/ntpath.pyi b/mypy/typeshed/stdlib/ntpath.pyi index bfa880ee03a8..079366018bf5 100644 --- a/mypy/typeshed/stdlib/ntpath.pyi +++ b/mypy/typeshed/stdlib/ntpath.pyi @@ -97,11 +97,11 @@ altsep: LiteralString # but must be defined as pos-only in the stub or cross-platform code doesn't type-check, # as the parameter name is different in posixpath.join() @overload -def join(__path: LiteralString, *paths: LiteralString) -> LiteralString: ... +def join(path: LiteralString, /, *paths: LiteralString) -> LiteralString: ... @overload -def join(__path: StrPath, *paths: StrPath) -> str: ... +def join(path: StrPath, /, *paths: StrPath) -> str: ... @overload -def join(__path: BytesPath, *paths: BytesPath) -> bytes: ... +def join(path: BytesPath, /, *paths: BytesPath) -> bytes: ... if sys.platform == "win32": if sys.version_info >= (3, 10): diff --git a/mypy/typeshed/stdlib/opcode.pyi b/mypy/typeshed/stdlib/opcode.pyi index 02da0c9f954a..14bdb7622142 100644 --- a/mypy/typeshed/stdlib/opcode.pyi +++ b/mypy/typeshed/stdlib/opcode.pyi @@ -56,4 +56,4 @@ opmap: dict[str, int] HAVE_ARGUMENT: Literal[90] EXTENDED_ARG: Literal[144] -def stack_effect(__opcode: int, __oparg: int | None = None, *, jump: bool | None = None) -> int: ... +def stack_effect(opcode: int, oparg: int | None = None, /, *, jump: bool | None = None) -> int: ... diff --git a/mypy/typeshed/stdlib/optparse.pyi b/mypy/typeshed/stdlib/optparse.pyi index a8c1c4cfb93e..3474648617c2 100644 --- a/mypy/typeshed/stdlib/optparse.pyi +++ b/mypy/typeshed/stdlib/optparse.pyi @@ -1,6 +1,7 @@ +from _typeshed import Incomplete from abc import abstractmethod from collections.abc import Callable, Iterable, Mapping, Sequence -from typing import IO, Any, AnyStr, overload +from typing import IO, Any, AnyStr, Literal, overload __all__ = [ "Option", @@ -26,8 +27,8 @@ NO_DEFAULT: tuple[str, ...] SUPPRESS_HELP: str SUPPRESS_USAGE: str -def check_builtin(option: Option, opt: Any, value: str) -> Any: ... -def check_choice(option: Option, opt: Any, value: str) -> str: ... +def check_builtin(option: Option, opt, value: str): ... +def check_choice(option: Option, opt, value: str) -> str: ... class OptParseError(Exception): msg: str @@ -54,26 +55,26 @@ class HelpFormatter: _short_opt_fmt: str current_indent: int default_tag: str - help_position: Any - help_width: Any + help_position: int + help_width: int | Any # initialized as None and computed later as int when storing option strings indent_increment: int level: int max_help_position: int option_strings: dict[Option, str] parser: OptionParser - short_first: Any + short_first: Incomplete width: int def __init__(self, indent_increment: int, max_help_position: int, width: int | None, short_first: int) -> None: ... def dedent(self) -> None: ... def expand_default(self, option: Option) -> str: ... - def format_description(self, description: str) -> str: ... - def format_epilog(self, epilog: str) -> str: ... + def format_description(self, description: str | None) -> str: ... + def format_epilog(self, epilog: str | None) -> str: ... @abstractmethod - def format_heading(self, heading: Any) -> str: ... + def format_heading(self, heading: str) -> str: ... def format_option(self, option: Option) -> str: ... def format_option_strings(self, option: Option) -> str: ... @abstractmethod - def format_usage(self, usage: Any) -> str: ... + def format_usage(self, usage: str) -> str: ... def indent(self) -> None: ... def set_long_opt_delimiter(self, delim: str) -> None: ... def set_parser(self, parser: OptionParser) -> None: ... @@ -98,25 +99,25 @@ class Option: ACTIONS: tuple[str, ...] ALWAYS_TYPED_ACTIONS: tuple[str, ...] ATTRS: list[str] - CHECK_METHODS: list[Callable[..., Any]] | None + CHECK_METHODS: list[Callable[..., Incomplete]] | None CONST_ACTIONS: tuple[str, ...] STORE_ACTIONS: tuple[str, ...] TYPED_ACTIONS: tuple[str, ...] TYPES: tuple[str, ...] - TYPE_CHECKER: dict[str, Callable[..., Any]] + TYPE_CHECKER: dict[str, Callable[[Option, str, Incomplete], Any]] _long_opts: list[str] _short_opts: list[str] action: str dest: str | None - default: Any + default: Incomplete nargs: int - type: Any - callback: Callable[..., Any] | None - callback_args: tuple[Any, ...] | None - callback_kwargs: dict[str, Any] | None + type: Incomplete + callback: Callable[..., Incomplete] | None + callback_args: tuple[Incomplete, ...] | None + callback_kwargs: dict[str, Incomplete] | None help: str | None metavar: str | None - def __init__(self, *opts: str | None, **attrs: Any) -> None: ... + def __init__(self, *opts: str | None, **attrs) -> None: ... def _check_action(self) -> None: ... def _check_callback(self) -> None: ... def _check_choice(self) -> None: ... @@ -125,13 +126,13 @@ class Option: def _check_nargs(self) -> None: ... def _check_opt_strings(self, opts: Iterable[str | None]) -> list[str]: ... def _check_type(self) -> None: ... - def _set_attrs(self, attrs: dict[str, Any]) -> None: ... + def _set_attrs(self, attrs: dict[str, Incomplete]) -> None: ... def _set_opt_strings(self, opts: Iterable[str]) -> None: ... - def check_value(self, opt: str, value: Any) -> Any: ... - def convert_value(self, opt: str, value: Any) -> Any: ... + def check_value(self, opt: str, value): ... + def convert_value(self, opt: str, value): ... def get_opt_string(self) -> str: ... - def process(self, opt: Any, value: Any, values: Any, parser: OptionParser) -> int: ... - def take_action(self, action: str, dest: str, opt: Any, value: Any, values: Any, parser: OptionParser) -> int: ... + def process(self, opt, value, values, parser: OptionParser) -> int: ... + def take_action(self, action: str, dest: str, opt, value, values, parser: OptionParser) -> int: ... def takes_value(self) -> bool: ... make_option = Option @@ -140,28 +141,30 @@ class OptionContainer: _long_opt: dict[str, Option] _short_opt: dict[str, Option] conflict_handler: str - defaults: dict[str, Any] - description: Any + defaults: dict[str, Incomplete] + description: str | None option_class: type[Option] - def __init__(self, option_class: type[Option], conflict_handler: Any, description: Any) -> None: ... - def _check_conflict(self, option: Any) -> None: ... + def __init__( + self, option_class: type[Option], conflict_handler: Literal["error", "resolve"], description: str | None + ) -> None: ... + def _check_conflict(self, option: Option) -> None: ... def _create_option_mappings(self) -> None: ... def _share_option_mappings(self, parser: OptionParser) -> None: ... @overload def add_option(self, opt: Option) -> Option: ... @overload - def add_option(self, *args: str | None, **kwargs: Any) -> Any: ... + def add_option(self, arg: str, /, *args: str | None, **kwargs) -> Option: ... def add_options(self, option_list: Iterable[Option]) -> None: ... def destroy(self) -> None: ... - def format_description(self, formatter: HelpFormatter | None) -> Any: ... - def format_help(self, formatter: HelpFormatter | None) -> str: ... - def format_option_help(self, formatter: HelpFormatter | None) -> str: ... - def get_description(self) -> Any: ... + def format_option_help(self, formatter: HelpFormatter) -> str: ... + def format_description(self, formatter: HelpFormatter) -> str: ... + def format_help(self, formatter: HelpFormatter) -> str: ... + def get_description(self) -> str | None: ... def get_option(self, opt_str: str) -> Option | None: ... def has_option(self, opt_str: str) -> bool: ... def remove_option(self, opt_str: str) -> None: ... - def set_conflict_handler(self, handler: Any) -> None: ... - def set_description(self, description: Any) -> None: ... + def set_conflict_handler(self, handler: Literal["error", "resolve"]) -> None: ... + def set_description(self, description: str | None) -> None: ... class OptionGroup(OptionContainer): option_list: list[Option] @@ -172,15 +175,15 @@ class OptionGroup(OptionContainer): def set_title(self, title: str) -> None: ... class Values: - def __init__(self, defaults: Mapping[str, Any] | None = None) -> None: ... - def _update(self, dict: Mapping[str, Any], mode: Any) -> None: ... - def _update_careful(self, dict: Mapping[str, Any]) -> None: ... - def _update_loose(self, dict: Mapping[str, Any]) -> None: ... - def ensure_value(self, attr: str, value: Any) -> Any: ... + def __init__(self, defaults: Mapping[str, Incomplete] | None = None) -> None: ... + def _update(self, dict: Mapping[str, Incomplete], mode) -> None: ... + def _update_careful(self, dict: Mapping[str, Incomplete]) -> None: ... + def _update_loose(self, dict: Mapping[str, Incomplete]) -> None: ... + def ensure_value(self, attr: str, value): ... def read_file(self, filename: str, mode: str = "careful") -> None: ... def read_module(self, modname: str, mode: str = "careful") -> None: ... - def __getattr__(self, name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... + def __getattr__(self, name: str): ... + def __setattr__(self, name: str, value, /) -> None: ... def __eq__(self, other: object) -> bool: ... class OptionParser(OptionContainer): @@ -190,9 +193,9 @@ class OptionParser(OptionContainer): largs: list[str] | None option_groups: list[OptionGroup] option_list: list[Option] - process_default_values: Any + process_default_values: bool prog: str | None - rargs: list[Any] | None + rargs: list[str] | None standard_option_list: list[Option] usage: str | None values: Values | None @@ -214,28 +217,28 @@ class OptionParser(OptionContainer): def _add_version_option(self) -> None: ... def _create_option_list(self) -> None: ... def _get_all_options(self) -> list[Option]: ... - def _get_args(self, args: Iterable[Any]) -> list[Any]: ... + def _get_args(self, args: Iterable[Incomplete]) -> list[Incomplete]: ... def _init_parsing_state(self) -> None: ... def _match_long_opt(self, opt: str) -> str: ... def _populate_option_list(self, option_list: Iterable[Option], add_help: bool = True) -> None: ... - def _process_args(self, largs: list[Any], rargs: list[Any], values: Values) -> None: ... - def _process_long_opt(self, rargs: list[Any], values: Any) -> None: ... - def _process_short_opts(self, rargs: list[Any], values: Any) -> None: ... + def _process_args(self, largs: list[Incomplete], rargs: list[Incomplete], values: Values) -> None: ... + def _process_long_opt(self, rargs: list[Incomplete], values) -> None: ... + def _process_short_opts(self, rargs: list[Incomplete], values) -> None: ... @overload - def add_option_group(self, __opt_group: OptionGroup) -> OptionGroup: ... + def add_option_group(self, opt_group: OptionGroup, /) -> OptionGroup: ... @overload - def add_option_group(self, *args: Any, **kwargs: Any) -> OptionGroup: ... + def add_option_group(self, *args, **kwargs) -> OptionGroup: ... def check_values(self, values: Values, args: list[str]) -> tuple[Values, list[str]]: ... def disable_interspersed_args(self) -> None: ... def enable_interspersed_args(self) -> None: ... def error(self, msg: str) -> None: ... def exit(self, status: int = 0, msg: str | None = None) -> None: ... - def expand_prog_name(self, s: str | None) -> Any: ... - def format_epilog(self, formatter: HelpFormatter) -> Any: ... + def expand_prog_name(self, s: str) -> str: ... + def format_epilog(self, formatter: HelpFormatter) -> str: ... def format_help(self, formatter: HelpFormatter | None = None) -> str: ... def format_option_help(self, formatter: HelpFormatter | None = None) -> str: ... def get_default_values(self) -> Values: ... - def get_option_group(self, opt_str: str) -> Any: ... + def get_option_group(self, opt_str: str) -> OptionGroup | None: ... def get_prog_name(self) -> str: ... def get_usage(self) -> str: ... def get_version(self) -> str: ... @@ -246,7 +249,7 @@ class OptionParser(OptionContainer): def print_usage(self, file: IO[str] | None = None) -> None: ... def print_help(self, file: IO[str] | None = None) -> None: ... def print_version(self, file: IO[str] | None = None) -> None: ... - def set_default(self, dest: Any, value: Any) -> None: ... - def set_defaults(self, **kwargs: Any) -> None: ... - def set_process_default_values(self, process: Any) -> None: ... + def set_default(self, dest, value) -> None: ... + def set_defaults(self, **kwargs) -> None: ... + def set_process_default_values(self, process) -> None: ... def set_usage(self, usage: str) -> None: ... diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index eef52e7a8b3b..89d906d4edfc 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -493,8 +493,8 @@ def get_exec_path(env: Mapping[str, str] | None = None) -> list[str]: ... def getlogin() -> str: ... def getpid() -> int: ... def getppid() -> int: ... -def strerror(__code: int) -> str: ... -def umask(__mask: int) -> int: ... +def strerror(code: int, /) -> str: ... +def umask(mask: int, /) -> int: ... @final class uname_result(structseq[str], tuple[str, str, str, str, str]): if sys.version_info >= (3, 10): @@ -516,9 +516,9 @@ if sys.platform != "win32": def getegid() -> int: ... def geteuid() -> int: ... def getgid() -> int: ... - def getgrouplist(__user: str, __group: int) -> list[int]: ... + def getgrouplist(user: str, group: int, /) -> list[int]: ... def getgroups() -> list[int]: ... # Unix only, behaves differently on Mac - def initgroups(__username: str, __gid: int) -> None: ... + def initgroups(username: str, gid: int, /) -> None: ... def getpgid(pid: int) -> int: ... def getpgrp() -> int: ... def getpriority(which: int, who: int) -> int: ... @@ -528,21 +528,21 @@ if sys.platform != "win32": def getresgid() -> tuple[int, int, int]: ... def getuid() -> int: ... - def setegid(__egid: int) -> None: ... - def seteuid(__euid: int) -> None: ... - def setgid(__gid: int) -> None: ... - def setgroups(__groups: Sequence[int]) -> None: ... + def setegid(egid: int, /) -> None: ... + def seteuid(euid: int, /) -> None: ... + def setgid(gid: int, /) -> None: ... + def setgroups(groups: Sequence[int], /) -> None: ... def setpgrp() -> None: ... - def setpgid(__pid: int, __pgrp: int) -> None: ... - def setregid(__rgid: int, __egid: int) -> None: ... + def setpgid(pid: int, pgrp: int, /) -> None: ... + def setregid(rgid: int, egid: int, /) -> None: ... if sys.platform != "darwin": - def setresgid(__rgid: int, __egid: int, __sgid: int) -> None: ... - def setresuid(__ruid: int, __euid: int, __suid: int) -> None: ... + def setresgid(rgid: int, egid: int, sgid: int, /) -> None: ... + def setresuid(ruid: int, euid: int, suid: int, /) -> None: ... - def setreuid(__ruid: int, __euid: int) -> None: ... - def getsid(__pid: int) -> int: ... + def setreuid(ruid: int, euid: int, /) -> None: ... + def getsid(pid: int, /) -> int: ... def setsid() -> None: ... - def setuid(__uid: int) -> None: ... + def setuid(uid: int, /) -> None: ... def uname() -> uname_result: ... @overload @@ -555,14 +555,14 @@ if sys.platform != "win32": def getenvb(key: bytes) -> bytes | None: ... @overload def getenvb(key: bytes, default: _T) -> bytes | _T: ... - def putenv(__name: StrOrBytesPath, __value: StrOrBytesPath) -> None: ... - def unsetenv(__name: StrOrBytesPath) -> None: ... + def putenv(name: StrOrBytesPath, value: StrOrBytesPath, /) -> None: ... + def unsetenv(name: StrOrBytesPath, /) -> None: ... else: - def putenv(__name: str, __value: str) -> None: ... + def putenv(name: str, value: str, /) -> None: ... if sys.version_info >= (3, 9): - def unsetenv(__name: str) -> None: ... + def unsetenv(name: str, /) -> None: ... _Opener: TypeAlias = Callable[[str, int], int] @@ -644,50 +644,50 @@ def fdopen( opener: _Opener | None = ..., ) -> IO[Any]: ... def close(fd: int) -> None: ... -def closerange(__fd_low: int, __fd_high: int) -> None: ... +def closerange(fd_low: int, fd_high: int, /) -> None: ... def device_encoding(fd: int) -> str | None: ... -def dup(__fd: int) -> int: ... +def dup(fd: int, /) -> int: ... def dup2(fd: int, fd2: int, inheritable: bool = True) -> int: ... def fstat(fd: int) -> stat_result: ... -def ftruncate(__fd: int, __length: int) -> None: ... +def ftruncate(fd: int, length: int, /) -> None: ... def fsync(fd: FileDescriptorLike) -> None: ... -def isatty(__fd: int) -> bool: ... +def isatty(fd: int, /) -> bool: ... if sys.platform != "win32" and sys.version_info >= (3, 11): - def login_tty(__fd: int) -> None: ... + def login_tty(fd: int, /) -> None: ... if sys.version_info >= (3, 11): - def lseek(__fd: int, __position: int, __whence: int) -> int: ... + def lseek(fd: int, position: int, whence: int, /) -> int: ... else: - def lseek(__fd: int, __position: int, __how: int) -> int: ... + def lseek(fd: int, position: int, how: int, /) -> int: ... def open(path: StrOrBytesPath, flags: int, mode: int = 0o777, *, dir_fd: int | None = None) -> int: ... def pipe() -> tuple[int, int]: ... -def read(__fd: int, __length: int) -> bytes: ... +def read(fd: int, length: int, /) -> bytes: ... if sys.version_info >= (3, 12) or sys.platform != "win32": - def get_blocking(__fd: int) -> bool: ... - def set_blocking(__fd: int, __blocking: bool) -> None: ... + def get_blocking(fd: int, /) -> bool: ... + def set_blocking(fd: int, blocking: bool, /) -> None: ... if sys.platform != "win32": def fchmod(fd: int, mode: int) -> None: ... def fchown(fd: int, uid: int, gid: int) -> None: ... - def fpathconf(__fd: int, __name: str | int) -> int: ... - def fstatvfs(__fd: int) -> statvfs_result: ... - def lockf(__fd: int, __command: int, __length: int) -> None: ... + def fpathconf(fd: int, name: str | int, /) -> int: ... + def fstatvfs(fd: int, /) -> statvfs_result: ... + def lockf(fd: int, command: int, length: int, /) -> None: ... def openpty() -> tuple[int, int]: ... # some flavors of Unix if sys.platform != "darwin": def fdatasync(fd: FileDescriptorLike) -> None: ... - def pipe2(__flags: int) -> tuple[int, int]: ... # some flavors of Unix - def posix_fallocate(__fd: int, __offset: int, __length: int) -> None: ... - def posix_fadvise(__fd: int, __offset: int, __length: int, __advice: int) -> None: ... + def pipe2(flags: int, /) -> tuple[int, int]: ... # some flavors of Unix + def posix_fallocate(fd: int, offset: int, length: int, /) -> None: ... + def posix_fadvise(fd: int, offset: int, length: int, advice: int, /) -> None: ... - def pread(__fd: int, __length: int, __offset: int) -> bytes: ... - def pwrite(__fd: int, __buffer: ReadableBuffer, __offset: int) -> int: ... + def pread(fd: int, length: int, offset: int, /) -> bytes: ... + def pwrite(fd: int, buffer: ReadableBuffer, offset: int, /) -> int: ... # In CI, stubtest sometimes reports that these are available on MacOS, sometimes not - def preadv(__fd: int, __buffers: SupportsLenAndGetItem[WriteableBuffer], __offset: int, __flags: int = 0) -> int: ... - def pwritev(__fd: int, __buffers: SupportsLenAndGetItem[ReadableBuffer], __offset: int, __flags: int = 0) -> int: ... + def preadv(fd: int, buffers: SupportsLenAndGetItem[WriteableBuffer], offset: int, flags: int = 0, /) -> int: ... + def pwritev(fd: int, buffers: SupportsLenAndGetItem[ReadableBuffer], offset: int, flags: int = 0, /) -> int: ... if sys.platform != "darwin": if sys.version_info >= (3, 10): RWF_APPEND: int # docs say available on 3.7+, stubtest says otherwise @@ -709,8 +709,8 @@ if sys.platform != "win32": flags: int = 0, ) -> int: ... # FreeBSD and Mac OS X only - def readv(__fd: int, __buffers: SupportsLenAndGetItem[WriteableBuffer]) -> int: ... - def writev(__fd: int, __buffers: SupportsLenAndGetItem[ReadableBuffer]) -> int: ... + def readv(fd: int, buffers: SupportsLenAndGetItem[WriteableBuffer], /) -> int: ... + def writev(fd: int, buffers: SupportsLenAndGetItem[ReadableBuffer], /) -> int: ... @final class terminal_size(structseq[int], tuple[int, int]): @@ -722,21 +722,21 @@ class terminal_size(structseq[int], tuple[int, int]): @property def lines(self) -> int: ... -def get_terminal_size(__fd: int = ...) -> terminal_size: ... -def get_inheritable(__fd: int) -> bool: ... -def set_inheritable(__fd: int, __inheritable: bool) -> None: ... +def get_terminal_size(fd: int = ..., /) -> terminal_size: ... +def get_inheritable(fd: int, /) -> bool: ... +def set_inheritable(fd: int, inheritable: bool, /) -> None: ... if sys.platform == "win32": - def get_handle_inheritable(__handle: int) -> bool: ... - def set_handle_inheritable(__handle: int, __inheritable: bool) -> None: ... + def get_handle_inheritable(handle: int, /) -> bool: ... + def set_handle_inheritable(handle: int, inheritable: bool, /) -> None: ... if sys.platform != "win32": # Unix only - def tcgetpgrp(__fd: int) -> int: ... - def tcsetpgrp(__fd: int, __pgid: int) -> None: ... - def ttyname(__fd: int) -> str: ... + def tcgetpgrp(fd: int, /) -> int: ... + def tcsetpgrp(fd: int, pgid: int, /) -> None: ... + def ttyname(fd: int, /) -> str: ... -def write(__fd: int, __data: ReadableBuffer) -> int: ... +def write(fd: int, data: ReadableBuffer, /) -> int: ... def access( path: FileDescriptorOrPath, mode: int, *, dir_fd: int | None = None, effective_ids: bool = False, follow_symlinks: bool = True ) -> bool: ... @@ -779,9 +779,9 @@ def makedirs(name: StrOrBytesPath, mode: int = 0o777, exist_ok: bool = False) -> if sys.platform != "win32": def mknod(path: StrOrBytesPath, mode: int = 0o600, device: int = 0, *, dir_fd: int | None = None) -> None: ... - def major(__device: int) -> int: ... - def minor(__device: int) -> int: ... - def makedev(__major: int, __minor: int) -> int: ... + def major(device: int, /) -> int: ... + def minor(device: int, /) -> int: ... + def makedev(major: int, minor: int, /) -> int: ... def pathconf(path: FileDescriptorOrPath, name: str | int) -> int: ... # Unix only def readlink(path: GenericPath[AnyStr], *, dir_fd: int | None = None) -> AnyStr: ... @@ -901,21 +901,21 @@ _ExecVArgs: TypeAlias = ( # we limit to str | bytes. _ExecEnv: TypeAlias = Mapping[bytes, bytes | str] | Mapping[str, bytes | str] -def execv(__path: StrOrBytesPath, __argv: _ExecVArgs) -> NoReturn: ... +def execv(path: StrOrBytesPath, argv: _ExecVArgs, /) -> NoReturn: ... def execve(path: FileDescriptorOrPath, argv: _ExecVArgs, env: _ExecEnv) -> NoReturn: ... def execvp(file: StrOrBytesPath, args: _ExecVArgs) -> NoReturn: ... def execvpe(file: StrOrBytesPath, args: _ExecVArgs, env: _ExecEnv) -> NoReturn: ... def _exit(status: int) -> NoReturn: ... -def kill(__pid: int, __signal: int) -> None: ... +def kill(pid: int, signal: int, /) -> None: ... if sys.platform != "win32": # Unix only def fork() -> int: ... def forkpty() -> tuple[int, int]: ... # some flavors of Unix - def killpg(__pgid: int, __signal: int) -> None: ... - def nice(__increment: int) -> int: ... + def killpg(pgid: int, signal: int, /) -> None: ... + def nice(increment: int, /) -> int: ... if sys.platform != "darwin": - def plock(__op: int) -> None: ... # ???op is int? + def plock(op: int, /) -> None: ... # ???op is int? class _wrap_close(_TextIOWrapper): def __init__(self, stream: _TextIOWrapper, proc: Popen[str]) -> None: ... @@ -930,8 +930,8 @@ if sys.platform != "win32": def spawnve(mode: int, file: StrOrBytesPath, args: _ExecVArgs, env: _ExecEnv) -> int: ... else: - def spawnv(__mode: int, __path: StrOrBytesPath, __argv: _ExecVArgs) -> int: ... - def spawnve(__mode: int, __path: StrOrBytesPath, __argv: _ExecVArgs, __env: _ExecEnv) -> int: ... + def spawnv(mode: int, path: StrOrBytesPath, argv: _ExecVArgs, /) -> int: ... + def spawnve(mode: int, path: StrOrBytesPath, argv: _ExecVArgs, env: _ExecEnv, /) -> int: ... def system(command: StrOrBytesPath) -> int: ... @final @@ -951,7 +951,7 @@ class times_result(structseq[float], tuple[float, float, float, float, float]): def elapsed(self) -> float: ... def times() -> times_result: ... -def waitpid(__pid: int, __options: int) -> tuple[int, int]: ... +def waitpid(pid: int, options: int, /) -> tuple[int, int]: ... if sys.platform == "win32": if sys.version_info >= (3, 10): @@ -988,13 +988,13 @@ else: @property def si_code(self) -> int: ... - def waitid(__idtype: int, __ident: int, __options: int) -> waitid_result | None: ... + 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: ... + def WCOREDUMP(status: int, /) -> bool: ... def WIFCONTINUED(status: int) -> bool: ... def WIFSTOPPED(status: int) -> bool: ... def WIFSIGNALED(status: int) -> bool: ... @@ -1003,9 +1003,10 @@ else: def WSTOPSIG(status: int) -> int: ... def WTERMSIG(status: int) -> int: ... def posix_spawn( - __path: StrOrBytesPath, - __argv: _ExecVArgs, - __env: _ExecEnv, + path: StrOrBytesPath, + argv: _ExecVArgs, + env: _ExecEnv, + /, *, file_actions: Sequence[tuple[Any, ...]] | None = ..., setpgroup: int | None = ..., @@ -1016,9 +1017,10 @@ else: scheduler: tuple[Any, sched_param] | None = ..., ) -> int: ... def posix_spawnp( - __path: StrOrBytesPath, - __argv: _ExecVArgs, - __env: _ExecEnv, + path: StrOrBytesPath, + argv: _ExecVArgs, + env: _ExecEnv, + /, *, file_actions: Sequence[tuple[Any, ...]] | None = ..., setpgroup: int | None = ..., @@ -1046,26 +1048,26 @@ if sys.platform != "win32": def sched_get_priority_max(policy: int) -> int: ... # some flavors of Unix def sched_yield() -> None: ... # some flavors of Unix if sys.platform != "darwin": - def sched_setscheduler(__pid: int, __policy: int, __param: sched_param) -> None: ... # some flavors of Unix - def sched_getscheduler(__pid: int) -> int: ... # some flavors of Unix - def sched_rr_get_interval(__pid: int) -> float: ... # some flavors of Unix - def sched_setparam(__pid: int, __param: sched_param) -> None: ... # some flavors of Unix - def sched_getparam(__pid: int) -> sched_param: ... # some flavors of Unix - def sched_setaffinity(__pid: int, __mask: Iterable[int]) -> None: ... # some flavors of Unix - def sched_getaffinity(__pid: int) -> set[int]: ... # some flavors of Unix + def sched_setscheduler(pid: int, policy: int, param: sched_param, /) -> None: ... # some flavors of Unix + def sched_getscheduler(pid: int, /) -> int: ... # some flavors of Unix + def sched_rr_get_interval(pid: int, /) -> float: ... # some flavors of Unix + def sched_setparam(pid: int, param: sched_param, /) -> None: ... # some flavors of Unix + def sched_getparam(pid: int, /) -> sched_param: ... # some flavors of Unix + def sched_setaffinity(pid: int, mask: Iterable[int], /) -> None: ... # some flavors of Unix + def sched_getaffinity(pid: int, /) -> set[int]: ... # some flavors of Unix def cpu_count() -> int | None: ... if sys.platform != "win32": # Unix only - def confstr(__name: str | int) -> str | None: ... + def confstr(name: str | int, /) -> str | None: ... def getloadavg() -> tuple[float, float, float]: ... - def sysconf(__name: str | int) -> int: ... + def sysconf(name: str | int, /) -> int: ... if sys.platform == "linux": def getrandom(size: int, flags: int = 0) -> bytes: ... -def urandom(__size: int) -> bytes: ... +def urandom(size: int, /) -> bytes: ... if sys.platform != "win32": def register_at_fork( diff --git a/mypy/typeshed/stdlib/pathlib.pyi b/mypy/typeshed/stdlib/pathlib.pyi index c3b0b7ad6337..5ea025095f68 100644 --- a/mypy/typeshed/stdlib/pathlib.pyi +++ b/mypy/typeshed/stdlib/pathlib.pyi @@ -59,7 +59,7 @@ class PurePath(PathLike[str]): def is_absolute(self) -> bool: ... def is_reserved(self) -> bool: ... if sys.version_info >= (3, 12): - def is_relative_to(self, __other: StrPath, *_deprecated: StrPath) -> bool: ... + def is_relative_to(self, other: StrPath, /, *_deprecated: StrPath) -> bool: ... elif sys.version_info >= (3, 9): def is_relative_to(self, *other: StrPath) -> bool: ... @@ -69,7 +69,7 @@ class PurePath(PathLike[str]): def match(self, path_pattern: str) -> bool: ... if sys.version_info >= (3, 12): - def relative_to(self, __other: StrPath, *_deprecated: StrPath, walk_up: bool = False) -> Self: ... + def relative_to(self, other: StrPath, /, *_deprecated: StrPath, walk_up: bool = False) -> Self: ... else: def relative_to(self, *other: StrPath) -> Self: ... diff --git a/mypy/typeshed/stdlib/pickle.pyi b/mypy/typeshed/stdlib/pickle.pyi index 0a4d439976ff..98ec80b0f14e 100644 --- a/mypy/typeshed/stdlib/pickle.pyi +++ b/mypy/typeshed/stdlib/pickle.pyi @@ -94,7 +94,7 @@ DEFAULT_PROTOCOL: int bytes_types: tuple[type[Any], ...] # undocumented class _ReadableFileobj(Protocol): - def read(self, __n: int) -> bytes: ... + def read(self, n: int, /) -> bytes: ... def readline(self) -> bytes: ... @final @@ -102,8 +102,8 @@ 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: ... + def __buffer__(self, flags: int, /) -> memoryview: ... + def __release_buffer__(self, buffer: memoryview, /) -> None: ... _BufferCallback: TypeAlias = Callable[[PickleBuffer], Any] | None @@ -127,7 +127,8 @@ def load( buffers: Iterable[Any] | None = (), ) -> Any: ... def loads( - __data: ReadableBuffer, + data: ReadableBuffer, + /, *, fix_imports: bool = True, encoding: str = "ASCII", @@ -162,7 +163,7 @@ class Pickler: buffer_callback: _BufferCallback = ..., ) -> None: ... def reducer_override(self, obj: Any) -> Any: ... - def dump(self, __obj: Any) -> None: ... + def dump(self, obj: Any, /) -> None: ... def clear_memo(self) -> None: ... def persistent_id(self, obj: Any) -> Any: ... @@ -179,7 +180,7 @@ class Unpickler: buffers: Iterable[Any] | None = ..., ) -> None: ... def load(self) -> Any: ... - def find_class(self, __module_name: str, __global_name: str) -> Any: ... + def find_class(self, module_name: str, global_name: str, /) -> Any: ... def persistent_load(self, pid: Any) -> Any: ... MARK: bytes diff --git a/mypy/typeshed/stdlib/posixpath.pyi b/mypy/typeshed/stdlib/posixpath.pyi index 29e7c0f01017..1fc471ac7d0b 100644 --- a/mypy/typeshed/stdlib/posixpath.pyi +++ b/mypy/typeshed/stdlib/posixpath.pyi @@ -112,11 +112,11 @@ def commonpath(paths: Iterable[BytesPath]) -> bytes: ... # but must be defined as pos-only in the stub or cross-platform code doesn't type-check, # as the parameter name is different in ntpath.join() @overload -def join(__a: LiteralString, *paths: LiteralString) -> LiteralString: ... +def join(a: LiteralString, /, *paths: LiteralString) -> LiteralString: ... @overload -def join(__a: StrPath, *paths: StrPath) -> str: ... +def join(a: StrPath, /, *paths: StrPath) -> str: ... @overload -def join(__a: BytesPath, *paths: BytesPath) -> bytes: ... +def join(a: BytesPath, /, *paths: BytesPath) -> bytes: ... if sys.version_info >= (3, 10): @overload diff --git a/mypy/typeshed/stdlib/profile.pyi b/mypy/typeshed/stdlib/profile.pyi index 6ae375004158..73eba36344fe 100644 --- a/mypy/typeshed/stdlib/profile.pyi +++ b/mypy/typeshed/stdlib/profile.pyi @@ -27,5 +27,5 @@ class Profile: def snapshot_stats(self) -> None: ... 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: ... + def runcall(self, func: Callable[_P, _T], /, *args: _P.args, **kw: _P.kwargs) -> _T: ... def calibrate(self, m: int, verbose: int = 0) -> float: ... diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index 86f88da9e712..d1571fd94be5 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -48,7 +48,8 @@ class Stats: sort_arg_dict_default: _SortArgDict def __init__( self, - __arg: None | str | Profile | _cProfile = ..., + arg: None | str | Profile | _cProfile = ..., + /, *args: None | str | Profile | _cProfile | Self, stream: IO[Any] | None = None, ) -> None: ... diff --git a/mypy/typeshed/stdlib/pwd.pyi b/mypy/typeshed/stdlib/pwd.pyi index 9a8e1036e550..a84ba324718a 100644 --- a/mypy/typeshed/stdlib/pwd.pyi +++ b/mypy/typeshed/stdlib/pwd.pyi @@ -24,5 +24,5 @@ if sys.platform != "win32": def pw_shell(self) -> str: ... def getpwall() -> list[struct_passwd]: ... - def getpwuid(__uid: int) -> struct_passwd: ... - def getpwnam(__name: str) -> struct_passwd: ... + def getpwuid(uid: int, /) -> struct_passwd: ... + def getpwnam(name: str, /) -> struct_passwd: ... diff --git a/mypy/typeshed/stdlib/pyexpat/__init__.pyi b/mypy/typeshed/stdlib/pyexpat/__init__.pyi index 2188e458474c..10011b437b6a 100644 --- a/mypy/typeshed/stdlib/pyexpat/__init__.pyi +++ b/mypy/typeshed/stdlib/pyexpat/__init__.pyi @@ -24,14 +24,14 @@ _Model: TypeAlias = tuple[int, int, str | None, tuple[Any, ...]] @final class XMLParserType: - def Parse(self, __data: str | ReadableBuffer, __isfinal: bool = False) -> int: ... - def ParseFile(self, __file: SupportsRead[bytes]) -> int: ... - def SetBase(self, __base: str) -> None: ... + def Parse(self, data: str | ReadableBuffer, isfinal: bool = False, /) -> int: ... + def ParseFile(self, file: SupportsRead[bytes], /) -> int: ... + def SetBase(self, base: str, /) -> None: ... def GetBase(self) -> str | None: ... def GetInputContext(self) -> bytes | None: ... - def ExternalEntityParserCreate(self, __context: str | None, __encoding: str = ...) -> XMLParserType: ... - def SetParamEntityParsing(self, __flag: int) -> int: ... - def UseForeignDTD(self, __flag: bool = True) -> None: ... + def ExternalEntityParserCreate(self, context: str | None, encoding: str = ..., /) -> XMLParserType: ... + def SetParamEntityParsing(self, flag: int, /) -> int: ... + def UseForeignDTD(self, flag: bool = True, /) -> None: ... @property def intern(self) -> dict[str, str]: ... buffer_size: int @@ -75,7 +75,7 @@ class XMLParserType: ExternalEntityRefHandler: Callable[[str, str | None, str | None, str | None], int] | None SkippedEntityHandler: Callable[[str, bool], Any] | None -def ErrorString(__code: int) -> str: ... +def ErrorString(code: int, /) -> str: ... # intern is undocumented def ParserCreate( diff --git a/mypy/typeshed/stdlib/re.pyi b/mypy/typeshed/stdlib/re.pyi index 84c6cfceb1de..7945c5f46cdc 100644 --- a/mypy/typeshed/stdlib/re.pyi +++ b/mypy/typeshed/stdlib/re.pyi @@ -72,11 +72,11 @@ class Match(Generic[AnyStr]): def expand(self, template: AnyStr) -> AnyStr: ... # group() returns "AnyStr" or "AnyStr | None", depending on the pattern. @overload - def group(self, __group: Literal[0] = 0) -> AnyStr: ... + def group(self, group: Literal[0] = 0, /) -> AnyStr: ... @overload - def group(self, __group: str | int) -> AnyStr | Any: ... + def group(self, group: str | int, /) -> AnyStr | Any: ... @overload - def group(self, __group1: str | int, __group2: str | int, *groups: str | int) -> tuple[AnyStr | Any, ...]: ... + def group(self, group1: str | int, group2: str | int, /, *groups: str | int) -> tuple[AnyStr | Any, ...]: ... # Each item of groups()'s return tuple is either "AnyStr" or # "AnyStr | None", depending on the pattern. @overload @@ -89,18 +89,18 @@ class Match(Generic[AnyStr]): def groupdict(self) -> dict[str, AnyStr | Any]: ... @overload def groupdict(self, default: _T) -> dict[str, AnyStr | _T]: ... - def start(self, __group: int | str = 0) -> int: ... - def end(self, __group: int | str = 0) -> int: ... - def span(self, __group: int | str = 0) -> tuple[int, int]: ... + def start(self, group: int | str = 0, /) -> int: ... + def end(self, group: int | str = 0, /) -> int: ... + def span(self, group: int | str = 0, /) -> tuple[int, int]: ... @property def regs(self) -> tuple[tuple[int, int], ...]: ... # undocumented # __getitem__() returns "AnyStr" or "AnyStr | None", depending on the pattern. @overload - def __getitem__(self, __key: Literal[0]) -> AnyStr: ... + def __getitem__(self, key: Literal[0], /) -> AnyStr: ... @overload - def __getitem__(self, __key: int | str) -> AnyStr | Any: ... + def __getitem__(self, key: int | str, /) -> AnyStr | Any: ... def __copy__(self) -> Match[AnyStr]: ... - def __deepcopy__(self, __memo: Any) -> Match[AnyStr]: ... + def __deepcopy__(self, memo: Any, /) -> Match[AnyStr]: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... @@ -174,8 +174,8 @@ class Pattern(Generic[AnyStr]): @overload def subn(self, repl: AnyStr | Callable[[Match[AnyStr]], AnyStr], string: AnyStr, count: int = 0) -> tuple[AnyStr, int]: ... def __copy__(self) -> Pattern[AnyStr]: ... - def __deepcopy__(self, __memo: Any) -> Pattern[AnyStr]: ... - def __eq__(self, __value: object) -> bool: ... + def __deepcopy__(self, memo: Any, /) -> Pattern[AnyStr]: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/mypy/typeshed/stdlib/readline.pyi b/mypy/typeshed/stdlib/readline.pyi index 14c01a986351..688ae48d9f92 100644 --- a/mypy/typeshed/stdlib/readline.pyi +++ b/mypy/typeshed/stdlib/readline.pyi @@ -7,30 +7,30 @@ if sys.platform != "win32": _Completer: TypeAlias = Callable[[str, int], str | None] _CompDisp: TypeAlias = Callable[[str, Sequence[str], int], None] - def parse_and_bind(__string: str) -> None: ... - def read_init_file(__filename: StrOrBytesPath | None = None) -> None: ... + def parse_and_bind(string: str, /) -> None: ... + def read_init_file(filename: StrOrBytesPath | None = None, /) -> None: ... def get_line_buffer() -> str: ... - def insert_text(__string: str) -> None: ... + def insert_text(string: str, /) -> None: ... def redisplay() -> None: ... - def read_history_file(__filename: StrOrBytesPath | None = None) -> None: ... - def write_history_file(__filename: StrOrBytesPath | None = None) -> None: ... - def append_history_file(__nelements: int, __filename: StrOrBytesPath | None = None) -> None: ... + def read_history_file(filename: StrOrBytesPath | None = None, /) -> None: ... + def write_history_file(filename: StrOrBytesPath | None = None, /) -> None: ... + def append_history_file(nelements: int, filename: StrOrBytesPath | None = None, /) -> None: ... def get_history_length() -> int: ... - def set_history_length(__length: int) -> None: ... + def set_history_length(length: int, /) -> None: ... def clear_history() -> None: ... def get_current_history_length() -> int: ... - def get_history_item(__index: int) -> str: ... - def remove_history_item(__pos: int) -> None: ... - def replace_history_item(__pos: int, __line: str) -> None: ... - def add_history(__string: str) -> None: ... - def set_auto_history(__enabled: bool) -> None: ... - def set_startup_hook(__function: Callable[[], object] | None = None) -> None: ... - def set_pre_input_hook(__function: Callable[[], object] | None = None) -> None: ... - def set_completer(__function: _Completer | None = None) -> None: ... + def get_history_item(index: int, /) -> str: ... + def remove_history_item(pos: int, /) -> None: ... + def replace_history_item(pos: int, line: str, /) -> None: ... + def add_history(string: str, /) -> None: ... + def set_auto_history(enabled: bool, /) -> None: ... + def set_startup_hook(function: Callable[[], object] | None = None, /) -> None: ... + def set_pre_input_hook(function: Callable[[], object] | None = None, /) -> None: ... + def set_completer(function: _Completer | None = None, /) -> None: ... def get_completer() -> _Completer | None: ... def get_completion_type() -> int: ... def get_begidx() -> int: ... def get_endidx() -> int: ... - def set_completer_delims(__string: str) -> None: ... + def set_completer_delims(string: str, /) -> None: ... def get_completer_delims() -> str: ... - def set_completion_display_matches_hook(__function: _CompDisp | None = None) -> None: ... + def set_completion_display_matches_hook(function: _CompDisp | None = None, /) -> None: ... diff --git a/mypy/typeshed/stdlib/resource.pyi b/mypy/typeshed/stdlib/resource.pyi index f40e5ec1ea55..5e468c2cead5 100644 --- a/mypy/typeshed/stdlib/resource.pyi +++ b/mypy/typeshed/stdlib/resource.pyi @@ -83,12 +83,12 @@ if sys.platform != "win32": def ru_nivcsw(self) -> int: ... def getpagesize() -> int: ... - def getrlimit(__resource: int) -> tuple[int, int]: ... - def getrusage(__who: int) -> struct_rusage: ... - def setrlimit(__resource: int, __limits: tuple[int, int]) -> None: ... + def getrlimit(resource: int, /) -> tuple[int, int]: ... + def getrusage(who: int, /) -> struct_rusage: ... + def setrlimit(resource: int, limits: tuple[int, int], /) -> None: ... if sys.platform == "linux": if sys.version_info >= (3, 12): - def prlimit(__pid: int, __resource: int, __limits: tuple[int, int] | None = None) -> tuple[int, int]: ... + def prlimit(pid: int, resource: int, limits: tuple[int, int] | None = None, /) -> tuple[int, int]: ... else: - def prlimit(__pid: int, __resource: int, __limits: tuple[int, int] = ...) -> tuple[int, int]: ... + def prlimit(pid: int, resource: int, limits: tuple[int, int] = ..., /) -> tuple[int, int]: ... error = OSError diff --git a/mypy/typeshed/stdlib/select.pyi b/mypy/typeshed/stdlib/select.pyi index afab88e18453..6d4c8d8f4c15 100644 --- a/mypy/typeshed/stdlib/select.pyi +++ b/mypy/typeshed/stdlib/select.pyi @@ -28,7 +28,7 @@ class poll: def poll(self, timeout: float | None = ...) -> list[tuple[int, int]]: ... def select( - __rlist: Iterable[Any], __wlist: Iterable[Any], __xlist: Iterable[Any], __timeout: float | None = None + rlist: Iterable[Any], wlist: Iterable[Any], xlist: Iterable[Any], timeout: float | None = None, / ) -> tuple[list[Any], list[Any], list[Any]]: ... error = OSError @@ -60,11 +60,11 @@ if sys.platform != "linux" and sys.platform != "win32": def __init__(self) -> None: ... def close(self) -> None: ... def control( - self, __changelist: Iterable[kevent] | None, __maxevents: int, __timeout: float | None = None + self, changelist: Iterable[kevent] | None, maxevents: int, timeout: float | None = None, / ) -> list[kevent]: ... def fileno(self) -> int: ... @classmethod - def fromfd(cls, __fd: FileDescriptorLike) -> kqueue: ... + def fromfd(cls, fd: FileDescriptorLike, /) -> kqueue: ... KQ_EV_ADD: int KQ_EV_CLEAR: int @@ -112,9 +112,10 @@ if sys.platform == "linux": def __enter__(self) -> Self: ... def __exit__( self, - __exc_type: type[BaseException] | None = None, - __exc_value: BaseException | None = ..., - __exc_tb: TracebackType | None = None, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = ..., + exc_tb: TracebackType | None = None, + /, ) -> None: ... def close(self) -> None: ... closed: bool @@ -124,7 +125,7 @@ if sys.platform == "linux": def unregister(self, fd: FileDescriptorLike) -> None: ... def poll(self, timeout: float | None = None, maxevents: int = -1) -> list[tuple[int, int]]: ... @classmethod - def fromfd(cls, __fd: FileDescriptorLike) -> epoll: ... + def fromfd(cls, fd: FileDescriptorLike, /) -> epoll: ... EPOLLERR: int EPOLLEXCLUSIVE: int diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index 544473df9932..d1fb3ba963d4 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -67,15 +67,15 @@ SIG_IGN: Handlers _SIGNUM: TypeAlias = int | Signals _HANDLER: TypeAlias = Callable[[int, FrameType | None], Any] | int | Handlers | None -def default_int_handler(__signalnum: int, __frame: FrameType | None) -> Never: ... +def default_int_handler(signalnum: int, frame: FrameType | None, /) -> Never: ... if sys.version_info >= (3, 10): # arguments changed in 3.10.2 def getsignal(signalnum: _SIGNUM) -> _HANDLER: ... def signal(signalnum: _SIGNUM, handler: _HANDLER) -> _HANDLER: ... else: - def getsignal(__signalnum: _SIGNUM) -> _HANDLER: ... - def signal(__signalnum: _SIGNUM, __handler: _HANDLER) -> _HANDLER: ... + def getsignal(signalnum: _SIGNUM, /) -> _HANDLER: ... + def signal(signalnum: _SIGNUM, handler: _HANDLER, /) -> _HANDLER: ... SIGABRT: Signals SIGFPE: Signals @@ -130,22 +130,22 @@ else: SIG_BLOCK = Sigmasks.SIG_BLOCK SIG_UNBLOCK = Sigmasks.SIG_UNBLOCK SIG_SETMASK = Sigmasks.SIG_SETMASK - def alarm(__seconds: int) -> int: ... - def getitimer(__which: int) -> tuple[float, float]: ... + def alarm(seconds: int, /) -> int: ... + def getitimer(which: int, /) -> tuple[float, float]: ... def pause() -> None: ... - def pthread_kill(__thread_id: int, __signalnum: int) -> None: ... + def pthread_kill(thread_id: int, signalnum: int, /) -> None: ... if sys.version_info >= (3, 10): # arguments changed in 3.10.2 def pthread_sigmask(how: int, mask: Iterable[int]) -> set[_SIGNUM]: ... else: - def pthread_sigmask(__how: int, __mask: Iterable[int]) -> set[_SIGNUM]: ... + def pthread_sigmask(how: int, mask: Iterable[int], /) -> set[_SIGNUM]: ... - def setitimer(__which: int, __seconds: float, __interval: float = 0.0) -> tuple[float, float]: ... - def siginterrupt(__signalnum: int, __flag: bool) -> None: ... + def setitimer(which: int, seconds: float, interval: float = 0.0, /) -> tuple[float, float]: ... + def siginterrupt(signalnum: int, flag: bool, /) -> None: ... def sigpending() -> Any: ... if sys.version_info >= (3, 10): # argument changed in 3.10.2 def sigwait(sigset: Iterable[int]) -> _SIGNUM: ... else: - def sigwait(__sigset: Iterable[int]) -> _SIGNUM: ... + def sigwait(sigset: Iterable[int], /) -> _SIGNUM: ... if sys.platform != "darwin": SIGCLD: Signals SIGPOLL: Signals @@ -176,17 +176,17 @@ else: def si_band(self) -> int: ... if sys.version_info >= (3, 10): - def sigtimedwait(__sigset: Iterable[int], __timeout: float) -> struct_siginfo | None: ... - def sigwaitinfo(__sigset: Iterable[int]) -> struct_siginfo: ... + def sigtimedwait(sigset: Iterable[int], timeout: float, /) -> struct_siginfo | None: ... + def sigwaitinfo(sigset: Iterable[int], /) -> struct_siginfo: ... else: def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... -def strsignal(__signalnum: _SIGNUM) -> str | None: ... +def strsignal(signalnum: _SIGNUM, /) -> str | None: ... def valid_signals() -> set[Signals]: ... -def raise_signal(__signalnum: _SIGNUM) -> None: ... +def raise_signal(signalnum: _SIGNUM, /) -> None: ... def set_wakeup_fd(fd: int, *, warn_on_full_buffer: bool = ...) -> int: ... if sys.version_info >= (3, 9): if sys.platform == "linux": - def pidfd_send_signal(__pidfd: int, __sig: int, __siginfo: None = None, __flags: int = ...) -> None: ... + def pidfd_send_signal(pidfd: int, sig: int, siginfo: None = None, flags: int = ..., /) -> None: ... diff --git a/mypy/typeshed/stdlib/smtplib.pyi b/mypy/typeshed/stdlib/smtplib.pyi index 6db7daebbb41..a762427bcab3 100644 --- a/mypy/typeshed/stdlib/smtplib.pyi +++ b/mypy/typeshed/stdlib/smtplib.pyi @@ -68,9 +68,9 @@ def quotedata(data: str) -> str: ... class _AuthObject(Protocol): @overload - def __call__(self, __challenge: None = None) -> str | None: ... + def __call__(self, challenge: None = None, /) -> str | None: ... @overload - def __call__(self, __challenge: bytes) -> str: ... + def __call__(self, challenge: bytes, /) -> str: ... class SMTP: debuglevel: int diff --git a/mypy/typeshed/stdlib/socket.pyi b/mypy/typeshed/stdlib/socket.pyi index ce5e35228fe4..cdbd70533714 100644 --- a/mypy/typeshed/stdlib/socket.pyi +++ b/mypy/typeshed/stdlib/socket.pyi @@ -682,8 +682,8 @@ if sys.platform == "win32": errorTab: dict[int, str] # undocumented class _SendableFile(Protocol): - def read(self, __size: int) -> bytes: ... - def seek(self, __offset: int) -> object: ... + def read(self, size: int, /) -> bytes: ... + def seek(self, offset: int, /) -> object: ... # optional fields: # @@ -803,7 +803,7 @@ def getfqdn(name: str = "") -> str: ... if sys.version_info >= (3, 11): def create_connection( address: tuple[str | None, int], - timeout: float | None = ..., # noqa: F811 + timeout: float | None = ..., source_address: _Address | None = None, *, all_errors: bool = False, @@ -811,7 +811,7 @@ if sys.version_info >= (3, 11): else: def create_connection( - address: tuple[str | None, int], timeout: float | None = ..., source_address: _Address | None = None # noqa: F811 + address: tuple[str | None, int], timeout: float | None = ..., source_address: _Address | None = None ) -> socket: ... def has_dualstack_ipv6() -> bool: ... diff --git a/mypy/typeshed/stdlib/spwd.pyi b/mypy/typeshed/stdlib/spwd.pyi index d362a0b77573..67ad3bfc751b 100644 --- a/mypy/typeshed/stdlib/spwd.pyi +++ b/mypy/typeshed/stdlib/spwd.pyi @@ -38,4 +38,4 @@ if sys.platform != "win32": def sp_flag(self) -> int: ... def getspall() -> list[struct_spwd]: ... - def getspnam(__arg: str) -> struct_spwd: ... + def getspnam(arg: str, /) -> struct_spwd: ... diff --git a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi index 7cf75bbc33c5..068ce1514c3c 100644 --- a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi +++ b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi @@ -8,6 +8,7 @@ from typing import Any, Literal, Protocol, SupportsIndex, TypeVar, final, overlo from typing_extensions import Self, TypeAlias _T = TypeVar("_T") +_ConnectionT = TypeVar("_ConnectionT", bound=Connection) _CursorT = TypeVar("_CursorT", bound=Cursor) _SqliteData: TypeAlias = str | ReadableBuffer | int | float | None # Data that is passed through adapters can be of any type accepted by an adapter. @@ -217,57 +218,107 @@ if sys.version_info >= (3, 12): # Can take or return anything depending on what's in the registry. @overload -def adapt(__obj: Any, __proto: Any) -> Any: ... +def adapt(obj: Any, proto: Any, /) -> Any: ... @overload -def adapt(__obj: Any, __proto: Any, __alt: _T) -> Any | _T: ... +def adapt(obj: Any, proto: Any, alt: _T, /) -> Any | _T: ... def complete_statement(statement: str) -> bool: ... if sys.version_info >= (3, 12): + @overload def connect( database: StrOrBytesPath, - timeout: float = ..., - detect_types: int = ..., - isolation_level: str | None = ..., - check_same_thread: bool = ..., - factory: type[Connection] | None = ..., - cached_statements: int = ..., - uri: bool = ..., + timeout: float = 5.0, + detect_types: int = 0, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None = "DEFERRED", + check_same_thread: bool = True, + cached_statements: int = 128, + uri: bool = False, + *, autocommit: bool = ..., ) -> Connection: ... + @overload + def connect( + database: StrOrBytesPath, + timeout: float, + detect_types: int, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None, + check_same_thread: bool, + factory: type[_ConnectionT], + cached_statements: int = 128, + uri: bool = False, + *, + autocommit: bool = ..., + ) -> _ConnectionT: ... + @overload + def connect( + database: StrOrBytesPath, + timeout: float = 5.0, + detect_types: int = 0, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None = "DEFERRED", + check_same_thread: bool = True, + *, + factory: type[_ConnectionT], + cached_statements: int = 128, + uri: bool = False, + autocommit: bool = ..., + ) -> _ConnectionT: ... else: + @overload def connect( database: StrOrBytesPath, - timeout: float = ..., - detect_types: int = ..., - isolation_level: str | None = ..., - check_same_thread: bool = ..., - factory: type[Connection] | None = ..., - cached_statements: int = ..., - uri: bool = ..., + timeout: float = 5.0, + detect_types: int = 0, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None = "DEFERRED", + check_same_thread: bool = True, + cached_statements: int = 128, + uri: bool = False, ) -> Connection: ... + @overload + def connect( + database: StrOrBytesPath, + timeout: float, + detect_types: int, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None, + check_same_thread: bool, + factory: type[_ConnectionT], + cached_statements: int = 128, + uri: bool = False, + ) -> _ConnectionT: ... + @overload + def connect( + database: StrOrBytesPath, + timeout: float = 5.0, + detect_types: int = 0, + isolation_level: Literal["DEFERRED", "EXCLUSIVE", "IMMEDIATE"] | None = "DEFERRED", + check_same_thread: bool = True, + *, + factory: type[_ConnectionT], + cached_statements: int = 128, + uri: bool = False, + ) -> _ConnectionT: ... -def enable_callback_tracebacks(__enable: bool) -> None: ... +def enable_callback_tracebacks(enable: bool, /) -> None: ... if sys.version_info < (3, 12): # takes a pos-or-keyword argument because there is a C wrapper def enable_shared_cache(enable: int) -> None: ... if sys.version_info >= (3, 10): - def register_adapter(__type: type[_T], __adapter: _Adapter[_T]) -> None: ... - def register_converter(__typename: str, __converter: _Converter) -> None: ... + def register_adapter(type: type[_T], adapter: _Adapter[_T], /) -> None: ... + def register_converter(typename: str, converter: _Converter, /) -> None: ... else: - def register_adapter(__type: type[_T], __caster: _Adapter[_T]) -> None: ... - def register_converter(__name: str, __converter: _Converter) -> None: ... + def register_adapter(type: type[_T], caster: _Adapter[_T], /) -> None: ... + def register_converter(name: str, converter: _Converter, /) -> None: ... class _AggregateProtocol(Protocol): - def step(self, __value: int) -> object: ... + def step(self, value: int, /) -> object: ... def finalize(self) -> int: ... class _SingleParamWindowAggregateClass(Protocol): - def step(self, __param: Any) -> object: ... - def inverse(self, __param: Any) -> object: ... + def step(self, param: Any, /) -> object: ... + def inverse(self, param: Any, /) -> object: ... def value(self) -> _SqliteData: ... def finalize(self) -> _SqliteData: ... @@ -344,7 +395,7 @@ class Connection: def close(self) -> None: ... if sys.version_info >= (3, 11): - def blobopen(self, __table: str, __column: str, __row: int, *, readonly: bool = False, name: str = "main") -> Blob: ... + def blobopen(self, table: str, column: str, row: int, /, *, readonly: bool = False, name: str = "main") -> Blob: ... def commit(self) -> None: ... def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol]) -> None: ... @@ -353,19 +404,19 @@ class Connection: # for the case where num_params = 1, which is expected to be the common case. @overload def create_window_function( - self, __name: str, __num_params: Literal[1], __aggregate_class: Callable[[], _SingleParamWindowAggregateClass] | None + self, name: str, num_params: Literal[1], aggregate_class: Callable[[], _SingleParamWindowAggregateClass] | None, / ) -> None: ... # And for num_params = -1, which means the aggregate must accept any number of parameters. @overload def create_window_function( - self, __name: str, __num_params: Literal[-1], __aggregate_class: Callable[[], _AnyParamWindowAggregateClass] | None + self, name: str, num_params: Literal[-1], aggregate_class: Callable[[], _AnyParamWindowAggregateClass] | None, / ) -> None: ... @overload def create_window_function( - self, __name: str, __num_params: int, __aggregate_class: Callable[[], _WindowAggregateClass] | None + self, name: str, num_params: int, aggregate_class: Callable[[], _WindowAggregateClass] | None, / ) -> None: ... - def create_collation(self, __name: str, __callback: Callable[[str, str], int | SupportsIndex] | None) -> None: ... + def create_collation(self, name: str, callback: Callable[[str, str], int | SupportsIndex] | None, /) -> None: ... def create_function( self, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False ) -> None: ... @@ -373,9 +424,9 @@ class Connection: def cursor(self, factory: None = None) -> Cursor: ... @overload def cursor(self, factory: Callable[[Connection], _CursorT]) -> _CursorT: ... - def execute(self, __sql: str, __parameters: _Parameters = ...) -> Cursor: ... - def executemany(self, __sql: str, __parameters: Iterable[_Parameters]) -> Cursor: ... - def executescript(self, __sql_script: str) -> Cursor: ... + def execute(self, sql: str, parameters: _Parameters = ..., /) -> Cursor: ... + def executemany(self, sql: str, parameters: Iterable[_Parameters], /) -> Cursor: ... + def executescript(self, sql_script: str, /) -> Cursor: ... def interrupt(self) -> None: ... def iterdump(self) -> Generator[str, None, None]: ... def rollback(self) -> None: ... @@ -386,8 +437,8 @@ class Connection: def set_trace_callback(self, trace_callback: Callable[[str], object] | None) -> None: ... # enable_load_extension and load_extension is not available on python distributions compiled # without sqlite3 loadable extension support. see footnotes https://docs.python.org/3/library/sqlite3.html#f1 - def enable_load_extension(self, __enable: bool) -> None: ... - def load_extension(self, __name: str) -> None: ... + def enable_load_extension(self, enable: bool, /) -> None: ... + def load_extension(self, name: str, /) -> None: ... def backup( self, target: Connection, @@ -398,18 +449,18 @@ class Connection: sleep: float = 0.25, ) -> None: ... if sys.version_info >= (3, 11): - def setlimit(self, __category: int, __limit: int) -> int: ... - def getlimit(self, __category: int) -> int: ... + def setlimit(self, category: int, limit: int, /) -> int: ... + def getlimit(self, category: int, /) -> int: ... def serialize(self, *, name: str = "main") -> bytes: ... - def deserialize(self, __data: ReadableBuffer, *, name: str = "main") -> None: ... + def deserialize(self, data: ReadableBuffer, /, *, name: str = "main") -> None: ... if sys.version_info >= (3, 12): - def getconfig(self, __op: int) -> bool: ... - def setconfig(self, __op: int, __enable: bool = True) -> bool: ... + def getconfig(self, op: int, /) -> bool: ... + def setconfig(self, op: int, enable: bool = True, /) -> bool: ... - def __call__(self, __sql: str) -> _Statement: ... + def __call__(self, sql: str, /) -> _Statement: ... def __enter__(self) -> Self: ... def __exit__( - self, __type: type[BaseException] | None, __value: BaseException | None, __traceback: TracebackType | None + self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None, / ) -> Literal[False]: ... class Cursor(Iterator[Any]): @@ -424,18 +475,18 @@ class Cursor(Iterator[Any]): row_factory: Callable[[Cursor, Row], object] | None @property def rowcount(self) -> int: ... - def __init__(self, __cursor: Connection) -> None: ... + def __init__(self, cursor: Connection, /) -> None: ... def close(self) -> None: ... - def execute(self, __sql: str, __parameters: _Parameters = ()) -> Self: ... - def executemany(self, __sql: str, __seq_of_parameters: Iterable[_Parameters]) -> Self: ... - def executescript(self, __sql_script: str) -> Cursor: ... + def execute(self, sql: str, parameters: _Parameters = (), /) -> Self: ... + def executemany(self, sql: str, seq_of_parameters: Iterable[_Parameters], /) -> Self: ... + def executescript(self, sql_script: str, /) -> Cursor: ... def fetchall(self) -> list[Any]: ... def fetchmany(self, size: int | None = 1) -> list[Any]: ... # Returns either a row (as created by the row_factory) or None, but # putting None in the return annotation causes annoying false positives. def fetchone(self) -> Any: ... - def setinputsizes(self, __sizes: Unused) -> None: ... # does nothing - def setoutputsize(self, __size: Unused, __column: Unused = None) -> None: ... # does nothing + def setinputsizes(self, sizes: Unused, /) -> None: ... # does nothing + def setoutputsize(self, size: Unused, column: Unused = None, /) -> None: ... # does nothing def __iter__(self) -> Self: ... def __next__(self) -> Any: ... @@ -462,22 +513,22 @@ class PrepareProtocol: class ProgrammingError(DatabaseError): ... class Row: - def __init__(self, __cursor: Cursor, __data: tuple[Any, ...]) -> None: ... + def __init__(self, cursor: Cursor, data: tuple[Any, ...], /) -> None: ... def keys(self) -> list[str]: ... @overload - def __getitem__(self, __key: int | str) -> Any: ... + def __getitem__(self, key: int | str, /) -> Any: ... @overload - def __getitem__(self, __key: slice) -> tuple[Any, ...]: ... + def __getitem__(self, key: slice, /) -> tuple[Any, ...]: ... def __hash__(self) -> int: ... def __iter__(self) -> Iterator[Any]: ... def __len__(self) -> int: ... # These return NotImplemented for anything that is not a Row. - def __eq__(self, __value: object) -> bool: ... - def __ge__(self, __value: object) -> bool: ... - def __gt__(self, __value: object) -> bool: ... - def __le__(self, __value: object) -> bool: ... - def __lt__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... + def __ge__(self, value: object, /) -> bool: ... + def __gt__(self, value: object, /) -> bool: ... + def __le__(self, value: object, /) -> bool: ... + def __lt__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... @final class _Statement: ... @@ -488,13 +539,13 @@ if sys.version_info >= (3, 11): @final class Blob: def close(self) -> None: ... - def read(self, __length: int = -1) -> bytes: ... - def write(self, __data: ReadableBuffer) -> None: ... + def read(self, length: int = -1, /) -> bytes: ... + def write(self, data: ReadableBuffer, /) -> None: ... def tell(self) -> int: ... # whence must be one of os.SEEK_SET, os.SEEK_CUR, os.SEEK_END - def seek(self, __offset: int, __origin: int = 0) -> None: ... + def seek(self, offset: int, origin: int = 0, /) -> None: ... def __len__(self) -> int: ... def __enter__(self) -> Self: ... - def __exit__(self, __type: object, __val: object, __tb: object) -> Literal[False]: ... - def __getitem__(self, __key: SupportsIndex | slice) -> int: ... - def __setitem__(self, __key: SupportsIndex | slice, __value: int) -> None: ... + def __exit__(self, type: object, val: object, tb: object, /) -> Literal[False]: ... + def __getitem__(self, key: SupportsIndex | slice, /) -> int: ... + def __setitem__(self, key: SupportsIndex | slice, value: int, /) -> None: ... diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index 583ac82750ac..b2263df1337d 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -15,6 +15,8 @@ _PasswordType: TypeAlias = Callable[[], str | bytes | bytearray] | str | bytes | _SrvnmeCbType: TypeAlias = Callable[[SSLSocket | SSLObject, str | None, SSLSocket], int | None] +socket_error = OSError + class _Cipher(TypedDict): aead: bool alg_bits: int @@ -96,14 +98,14 @@ else: _create_default_https_context: Callable[..., SSLContext] -def RAND_bytes(__n: int) -> bytes: ... +def RAND_bytes(n: int, /) -> bytes: ... if sys.version_info < (3, 12): - def RAND_pseudo_bytes(__n: int) -> tuple[bytes, bool]: ... + def RAND_pseudo_bytes(n: int, /) -> tuple[bytes, bool]: ... def RAND_status() -> bool: ... def RAND_egd(path: str) -> None: ... -def RAND_add(__string: str | ReadableBuffer, __entropy: float) -> None: ... +def RAND_add(string: str | ReadableBuffer, entropy: float, /) -> None: ... if sys.version_info < (3, 12): def match_hostname(cert: _PeerCertRetDictType, hostname: str) -> None: ... @@ -420,12 +422,12 @@ class SSLContext: def get_ca_certs(self, binary_form: bool = False) -> Any: ... def get_ciphers(self) -> list[_Cipher]: ... def set_default_verify_paths(self) -> None: ... - def set_ciphers(self, __cipherlist: str) -> None: ... + def set_ciphers(self, cipherlist: str, /) -> None: ... def set_alpn_protocols(self, alpn_protocols: Iterable[str]) -> None: ... def set_npn_protocols(self, npn_protocols: Iterable[str]) -> None: ... def set_servername_callback(self, server_name_callback: _SrvnmeCbType | None) -> None: ... - def load_dh_params(self, __path: str) -> None: ... - def set_ecdh_curve(self, __name: str) -> None: ... + def load_dh_params(self, path: str, /) -> None: ... + def set_ecdh_curve(self, name: str, /) -> None: ... def wrap_socket( self, sock: socket.socket, @@ -479,8 +481,8 @@ class SSLObject: class MemoryBIO: pending: int eof: bool - def read(self, __size: int = -1) -> bytes: ... - def write(self, __b: ReadableBuffer) -> int: ... + def read(self, size: int = -1, /) -> bytes: ... + def write(self, b: ReadableBuffer, /) -> int: ... def write_eof(self) -> None: ... @final @@ -495,7 +497,7 @@ class SSLSession: def time(self) -> int: ... @property def timeout(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... class SSLErrorNumber(enum.IntEnum): SSL_ERROR_EOF: int diff --git a/mypy/typeshed/stdlib/statistics.pyi b/mypy/typeshed/stdlib/statistics.pyi index f3f013fc93e7..c5f5ed64b328 100644 --- a/mypy/typeshed/stdlib/statistics.pyi +++ b/mypy/typeshed/stdlib/statistics.pyi @@ -110,14 +110,14 @@ class NormalDist: if sys.version_info >= (3, 12): def correlation( - __x: Sequence[_Number], __y: Sequence[_Number], *, method: Literal["linear", "ranked"] = "linear" + x: Sequence[_Number], y: Sequence[_Number], /, *, method: Literal["linear", "ranked"] = "linear" ) -> float: ... elif sys.version_info >= (3, 10): - def correlation(__x: Sequence[_Number], __y: Sequence[_Number]) -> float: ... + def correlation(x: Sequence[_Number], y: Sequence[_Number], /) -> float: ... if sys.version_info >= (3, 10): - def covariance(__x: Sequence[_Number], __y: Sequence[_Number]) -> float: ... + def covariance(x: Sequence[_Number], y: Sequence[_Number], /) -> float: ... class LinearRegression(NamedTuple): slope: float @@ -125,8 +125,8 @@ if sys.version_info >= (3, 10): if sys.version_info >= (3, 11): def linear_regression( - __regressor: Sequence[_Number], __dependent_variable: Sequence[_Number], *, proportional: bool = False + regressor: Sequence[_Number], dependent_variable: Sequence[_Number], /, *, proportional: bool = False ) -> LinearRegression: ... elif sys.version_info >= (3, 10): - def linear_regression(__regressor: Sequence[_Number], __dependent_variable: Sequence[_Number]) -> LinearRegression: ... + def linear_regression(regressor: Sequence[_Number], dependent_variable: Sequence[_Number], /) -> LinearRegression: ... diff --git a/mypy/typeshed/stdlib/string.pyi b/mypy/typeshed/stdlib/string.pyi index 8b60243f2333..35a76e9c8628 100644 --- a/mypy/typeshed/stdlib/string.pyi +++ b/mypy/typeshed/stdlib/string.pyi @@ -47,17 +47,17 @@ class Template(metaclass=_TemplateMetaclass): flags: ClassVar[RegexFlag] pattern: ClassVar[Pattern[str]] def __init__(self, template: str) -> None: ... - def substitute(self, __mapping: Mapping[str, object] = {}, **kwds: object) -> str: ... - def safe_substitute(self, __mapping: Mapping[str, object] = {}, **kwds: object) -> str: ... + def substitute(self, mapping: Mapping[str, object] = {}, /, **kwds: object) -> str: ... + def safe_substitute(self, mapping: Mapping[str, object] = {}, /, **kwds: object) -> str: ... if sys.version_info >= (3, 11): def get_identifiers(self) -> list[str]: ... def is_valid(self) -> bool: ... class Formatter: @overload - def format(self, __format_string: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... + def format(self, format_string: LiteralString, /, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ... @overload - def format(self, __format_string: str, *args: Any, **kwargs: Any) -> str: ... + def format(self, format_string: str, /, *args: Any, **kwargs: Any) -> str: ... @overload def vformat( self, format_string: LiteralString, args: Sequence[LiteralString], kwargs: Mapping[LiteralString, LiteralString] diff --git a/mypy/typeshed/stdlib/struct.pyi b/mypy/typeshed/stdlib/struct.pyi index 4220cd825b76..e684632489ea 100644 --- a/mypy/typeshed/stdlib/struct.pyi +++ b/mypy/typeshed/stdlib/struct.pyi @@ -6,12 +6,12 @@ __all__ = ["calcsize", "pack", "pack_into", "unpack", "unpack_from", "iter_unpac class error(Exception): ... -def pack(__fmt: str | bytes, *v: Any) -> bytes: ... -def pack_into(__fmt: str | bytes, __buffer: WriteableBuffer, __offset: int, *v: Any) -> None: ... -def unpack(__format: str | bytes, __buffer: ReadableBuffer) -> tuple[Any, ...]: ... -def unpack_from(__format: str | bytes, buffer: ReadableBuffer, offset: int = 0) -> tuple[Any, ...]: ... -def iter_unpack(__format: str | bytes, __buffer: ReadableBuffer) -> Iterator[tuple[Any, ...]]: ... -def calcsize(__format: str | bytes) -> int: ... +def pack(fmt: str | bytes, /, *v: Any) -> bytes: ... +def pack_into(fmt: str | bytes, buffer: WriteableBuffer, offset: int, /, *v: Any) -> None: ... +def unpack(format: str | bytes, buffer: ReadableBuffer, /) -> tuple[Any, ...]: ... +def unpack_from(format: str | bytes, /, buffer: ReadableBuffer, offset: int = 0) -> tuple[Any, ...]: ... +def iter_unpack(format: str | bytes, buffer: ReadableBuffer, /) -> Iterator[tuple[Any, ...]]: ... +def calcsize(format: str | bytes, /) -> int: ... class Struct: @property @@ -21,6 +21,6 @@ class Struct: def __init__(self, format: str | bytes) -> None: ... def pack(self, *v: Any) -> bytes: ... def pack_into(self, buffer: WriteableBuffer, offset: int, *v: Any) -> None: ... - def unpack(self, __buffer: ReadableBuffer) -> tuple[Any, ...]: ... + def unpack(self, buffer: ReadableBuffer, /) -> tuple[Any, ...]: ... def unpack_from(self, buffer: ReadableBuffer, offset: int = 0) -> tuple[Any, ...]: ... - def iter_unpack(self, __buffer: ReadableBuffer) -> Iterator[tuple[Any, ...]]: ... + def iter_unpack(self, buffer: ReadableBuffer, /) -> Iterator[tuple[Any, ...]]: ... diff --git a/mypy/typeshed/stdlib/sys/__init__.pyi b/mypy/typeshed/stdlib/sys/__init__.pyi index bb1d244bdac9..353e20c4b2e1 100644 --- a/mypy/typeshed/stdlib/sys/__init__.pyi +++ b/mypy/typeshed/stdlib/sys/__init__.pyi @@ -17,9 +17,7 @@ _OptExcInfo: TypeAlias = OptExcInfo # noqa: Y047 # TODO: obsolete, remove fall # Intentionally omits one deprecated and one optional method of `importlib.abc.MetaPathFinder` class _MetaPathFinder(Protocol): - def find_spec( - self, __fullname: str, __path: Sequence[str] | None, __target: ModuleType | None = ... - ) -> ModuleSpec | None: ... + def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = ..., /) -> ModuleSpec | None: ... # ----- sys variables ----- if sys.platform != "win32": @@ -245,19 +243,19 @@ class _version_info(_UninstantiableStructseq, tuple[int, int, int, _ReleaseLevel version_info: _version_info -def call_tracing(__func: Callable[..., _T], __args: Any) -> _T: ... +def call_tracing(func: Callable[..., _T], args: Any, /) -> _T: ... def _clear_type_cache() -> None: ... def _current_frames() -> dict[int, FrameType]: ... -def _getframe(__depth: int = 0) -> FrameType: ... +def _getframe(depth: int = 0, /) -> FrameType: ... def _debugmallocstats() -> None: ... -def __displayhook__(__object: object) -> None: ... -def __excepthook__(__exctype: type[BaseException], __value: BaseException, __traceback: TracebackType | None) -> None: ... +def __displayhook__(object: object, /) -> None: ... +def __excepthook__(exctype: type[BaseException], value: BaseException, traceback: TracebackType | None, /) -> None: ... def exc_info() -> OptExcInfo: ... if sys.version_info >= (3, 11): def exception() -> BaseException | None: ... -def exit(__status: _ExitCode = None) -> NoReturn: ... +def exit(status: _ExitCode = None, /) -> NoReturn: ... def getallocatedblocks() -> int: ... def getdefaultencoding() -> str: ... @@ -266,7 +264,7 @@ if sys.platform != "win32": def getfilesystemencoding() -> str: ... def getfilesystemencodeerrors() -> str: ... -def getrefcount(__object: Any) -> int: ... +def getrefcount(object: Any, /) -> int: ... def getrecursionlimit() -> int: ... def getsizeof(obj: object, default: int = ...) -> int: ... def getswitchinterval() -> float: ... @@ -302,22 +300,22 @@ if sys.platform == "win32": def getwindowsversion() -> _WinVersion: ... -def intern(__string: str) -> str: ... +def intern(string: str, /) -> str: ... def is_finalizing() -> bool: ... def breakpointhook(*args: Any, **kwargs: Any) -> Any: ... __breakpointhook__ = breakpointhook # Contains the original value of breakpointhook if sys.platform != "win32": - def setdlopenflags(__flags: int) -> None: ... + def setdlopenflags(flags: int, /) -> None: ... -def setrecursionlimit(__limit: int) -> None: ... -def setswitchinterval(__interval: float) -> None: ... +def setrecursionlimit(limit: int, /) -> None: ... +def setswitchinterval(interval: float, /) -> None: ... def gettotalrefcount() -> int: ... # Debug builds only if sys.version_info < (3, 9): def getcheckinterval() -> int: ... # deprecated - def setcheckinterval(__n: int) -> None: ... # deprecated + def setcheckinterval(n: int, /) -> None: ... # deprecated if sys.version_info < (3, 9): # An 11-tuple or None @@ -333,9 +331,9 @@ class UnraisableHookArgs(Protocol): unraisablehook: Callable[[UnraisableHookArgs], Any] -def __unraisablehook__(__unraisable: UnraisableHookArgs) -> Any: ... +def __unraisablehook__(unraisable: UnraisableHookArgs, /) -> Any: ... def addaudithook(hook: Callable[[str, tuple[Any, ...]], Any]) -> None: ... -def audit(__event: str, *args: Any) -> None: ... +def audit(event: str, /, *args: Any) -> None: ... _AsyncgenHook: TypeAlias = Callable[[AsyncGenerator[Any, Any]], None] | None @@ -366,9 +364,9 @@ if sys.version_info >= (3, 12): def is_stack_trampoline_active() -> bool: ... # It always exists, but raises on non-linux platforms: if sys.platform == "linux": - def activate_stack_trampoline(__backend: str) -> None: ... + def activate_stack_trampoline(backend: str, /) -> None: ... else: - def activate_stack_trampoline(__backend: str) -> NoReturn: ... + def activate_stack_trampoline(backend: str, /) -> NoReturn: ... from . import _monitoring diff --git a/mypy/typeshed/stdlib/sys/_monitoring.pyi b/mypy/typeshed/stdlib/sys/_monitoring.pyi index 40aeb9cb5bdb..0507eeedc26d 100644 --- a/mypy/typeshed/stdlib/sys/_monitoring.pyi +++ b/mypy/typeshed/stdlib/sys/_monitoring.pyi @@ -14,9 +14,9 @@ COVERAGE_ID: int PROFILER_ID: int OPTIMIZER_ID: int -def use_tool_id(__tool_id: int, __name: str) -> None: ... -def free_tool_id(__tool_id: int) -> None: ... -def get_tool(__tool_id: int) -> str | None: ... +def use_tool_id(tool_id: int, name: str, /) -> None: ... +def free_tool_id(tool_id: int, /) -> None: ... +def get_tool(tool_id: int, /) -> str | None: ... events: _events @@ -40,13 +40,13 @@ class _events: RERAISE: int STOP_ITERATION: int -def get_events(__tool_id: int) -> int: ... -def set_events(__tool_id: int, __event_set: int) -> None: ... -def get_local_events(__tool_id: int, __code: CodeType) -> int: ... -def set_local_events(__tool_id: int, __code: CodeType, __event_set: int) -> int: ... +def get_events(tool_id: int, /) -> int: ... +def set_events(tool_id: int, event_set: int, /) -> None: ... +def get_local_events(tool_id: int, code: CodeType, /) -> int: ... +def set_local_events(tool_id: int, code: CodeType, event_set: int, /) -> int: ... def restart_events() -> None: ... DISABLE: object MISSING: object -def register_callback(__tool_id: int, __event: int, __func: Callable[..., Any] | None) -> Callable[..., Any] | None: ... +def register_callback(tool_id: int, event: int, func: Callable[..., Any] | None, /) -> Callable[..., Any] | None: ... diff --git a/mypy/typeshed/stdlib/syslog.pyi b/mypy/typeshed/stdlib/syslog.pyi index 164334f60a6f..02876e0b7e85 100644 --- a/mypy/typeshed/stdlib/syslog.pyi +++ b/mypy/typeshed/stdlib/syslog.pyi @@ -35,11 +35,11 @@ if sys.platform != "win32": LOG_USER: Literal[8] LOG_UUCP: Literal[64] LOG_WARNING: Literal[4] - def LOG_MASK(__pri: int) -> int: ... - def LOG_UPTO(__pri: int) -> int: ... + def LOG_MASK(pri: int, /) -> int: ... + def LOG_UPTO(pri: int, /) -> int: ... def closelog() -> None: ... def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... - def setlogmask(__maskpri: int) -> int: ... + def setlogmask(maskpri: int, /) -> int: ... @overload def syslog(priority: int, message: str) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/tarfile.pyi b/mypy/typeshed/stdlib/tarfile.pyi index 47c831190286..b6fe454eff78 100644 --- a/mypy/typeshed/stdlib/tarfile.pyi +++ b/mypy/typeshed/stdlib/tarfile.pyi @@ -43,10 +43,10 @@ _FilterFunction: TypeAlias = Callable[[TarInfo, str], TarInfo | None] _TarfileFilter: TypeAlias = Literal["fully_trusted", "tar", "data"] | _FilterFunction class _Fileobj(Protocol): - def read(self, __size: int) -> bytes: ... - def write(self, __b: bytes) -> object: ... + def read(self, size: int, /) -> bytes: ... + def write(self, b: bytes, /) -> object: ... def tell(self) -> int: ... - def seek(self, __pos: int) -> object: ... + def seek(self, pos: int, /) -> object: ... def close(self) -> object: ... # Optional fields: # name: str | bytes diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index 2c4b548458ea..ce8f2f1f5929 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -364,14 +364,14 @@ class SpooledTemporaryFile(IO[AnyStr], _SpooledTemporaryFileBase): if sys.version_info >= (3, 11): # These three work only if the SpooledTemporaryFile is opened in binary mode, # because the underlying object in text mode does not have these methods. - def read1(self, __size: int = ...) -> AnyStr: ... + def read1(self, size: int = ..., /) -> AnyStr: ... def readinto(self, b: WriteableBuffer) -> int: ... def readinto1(self, b: WriteableBuffer) -> int: ... def detach(self) -> io.RawIOBase: ... - def read(self, __n: int = ...) -> AnyStr: ... - def readline(self, __limit: int | None = ...) -> AnyStr: ... # type: ignore[override] - def readlines(self, __hint: int = ...) -> list[AnyStr]: ... # type: ignore[override] + def read(self, n: int = ..., /) -> AnyStr: ... + def readline(self, limit: int | None = ..., /) -> AnyStr: ... # type: ignore[override] + def readlines(self, hint: int = ..., /) -> list[AnyStr]: ... # type: ignore[override] def seek(self, offset: int, whence: int = ...) -> int: ... def tell(self) -> int: ... def truncate(self, size: int | None = None) -> None: ... # type: ignore[override] diff --git a/mypy/typeshed/stdlib/termios.pyi b/mypy/typeshed/stdlib/termios.pyi index 776396cce407..a5378e40fdf2 100644 --- a/mypy/typeshed/stdlib/termios.pyi +++ b/mypy/typeshed/stdlib/termios.pyi @@ -254,14 +254,14 @@ if sys.platform != "win32": XCASE: int XTABS: int - def tcgetattr(__fd: FileDescriptorLike) -> _AttrReturn: ... - def tcsetattr(__fd: FileDescriptorLike, __when: int, __attributes: _Attr) -> None: ... - def tcsendbreak(__fd: FileDescriptorLike, __duration: int) -> None: ... - def tcdrain(__fd: FileDescriptorLike) -> None: ... - def tcflush(__fd: FileDescriptorLike, __queue: int) -> None: ... - def tcflow(__fd: FileDescriptorLike, __action: int) -> None: ... + def tcgetattr(fd: FileDescriptorLike, /) -> _AttrReturn: ... + def tcsetattr(fd: FileDescriptorLike, when: int, attributes: _Attr, /) -> None: ... + def tcsendbreak(fd: FileDescriptorLike, duration: int, /) -> None: ... + def tcdrain(fd: FileDescriptorLike, /) -> None: ... + def tcflush(fd: FileDescriptorLike, queue: int, /) -> None: ... + def tcflow(fd: FileDescriptorLike, action: int, /) -> None: ... if sys.version_info >= (3, 11): - def tcgetwinsize(__fd: FileDescriptorLike) -> tuple[int, int]: ... - def tcsetwinsize(__fd: FileDescriptorLike, __winsize: tuple[int, int]) -> None: ... + def tcgetwinsize(fd: FileDescriptorLike, /) -> tuple[int, int]: ... + def tcsetwinsize(fd: FileDescriptorLike, winsize: tuple[int, int], /) -> None: ... class error(Exception): ... diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index 3f65eb2c8fe4..80bc56ef53f3 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -618,18 +618,18 @@ class Wm: @overload def wm_attributes(self) -> tuple[Any, ...]: ... @overload - def wm_attributes(self, __option: str): ... + def wm_attributes(self, option: str, /): ... @overload - def wm_attributes(self, __option: str, __value, *__other_option_value_pairs: Any) -> None: ... + def wm_attributes(self, option: str, value, /, *__other_option_value_pairs: Any) -> None: ... attributes = wm_attributes def wm_client(self, name: str | None = None) -> str: ... client = wm_client @overload def wm_colormapwindows(self) -> list[Misc]: ... @overload - def wm_colormapwindows(self, __wlist: list[Misc] | tuple[Misc, ...]) -> None: ... + def wm_colormapwindows(self, wlist: list[Misc] | tuple[Misc, ...], /) -> None: ... @overload - def wm_colormapwindows(self, __first_wlist_item: Misc, *other_wlist_items: Misc) -> None: ... + def wm_colormapwindows(self, first_wlist_item: Misc, /, *other_wlist_items: Misc) -> None: ... colormapwindows = wm_colormapwindows def wm_command(self, value: str | None = None) -> str: ... command = wm_command @@ -767,31 +767,31 @@ class Tk(Misc, Wm): # Tk has __getattr__ so that tk_instance.foo falls back to tk_instance.tk.foo # Please keep in sync with _tkinter.TkappType. # Some methods are intentionally missing because they are inherited from Misc instead. - def adderrorinfo(self, __msg): ... - def call(self, __command: Any, *args: Any) -> Any: ... - def createcommand(self, __name, __func): ... + def adderrorinfo(self, msg, /): ... + def call(self, command: Any, /, *args: Any) -> Any: ... + def createcommand(self, name, func, /): ... if sys.platform != "win32": - def createfilehandler(self, __file, __mask, __func): ... - def deletefilehandler(self, __file): ... - - def createtimerhandler(self, __milliseconds, __func): ... - def dooneevent(self, __flags: int = ...): ... - def eval(self, __script: str) -> str: ... - def evalfile(self, __fileName): ... - def exprboolean(self, __s): ... - def exprdouble(self, __s): ... - def exprlong(self, __s): ... - def exprstring(self, __s): ... + def createfilehandler(self, file, mask, func, /): ... + def deletefilehandler(self, file, /): ... + + def createtimerhandler(self, milliseconds, func, /): ... + def dooneevent(self, flags: int = ..., /): ... + def eval(self, script: str, /) -> str: ... + def evalfile(self, fileName, /): ... + def exprboolean(self, s, /): ... + def exprdouble(self, s, /): ... + def exprlong(self, s, /): ... + def exprstring(self, s, /): ... def globalgetvar(self, *args, **kwargs): ... def globalsetvar(self, *args, **kwargs): ... def globalunsetvar(self, *args, **kwargs): ... def interpaddr(self): ... def loadtk(self) -> None: ... - def record(self, __script): ... + def record(self, script, /): ... if sys.version_info < (3, 11): - def split(self, __arg): ... + def split(self, arg, /): ... - def splitlist(self, __arg): ... + def splitlist(self, arg, /): ... def unsetvar(self, *args, **kwargs): ... def wantobjects(self, *args, **kwargs): ... def willdispatch(self): ... @@ -1214,11 +1214,11 @@ class Canvas(Widget, XView, YView): def canvasx(self, screenx, gridspacing: Incomplete | None = None): ... def canvasy(self, screeny, gridspacing: Incomplete | None = None): ... @overload - def coords(self, __tagOrId: str | int) -> list[float]: ... + def coords(self, tagOrId: str | int, /) -> list[float]: ... @overload - def coords(self, __tagOrId: str | int, __args: list[int] | list[float] | tuple[float, ...]) -> None: ... + def coords(self, tagOrId: str | int, args: list[int] | list[float] | tuple[float, ...], /) -> None: ... @overload - def coords(self, __tagOrId: str | int, __x1: float, __y1: float, *args: float) -> None: ... + def coords(self, tagOrId: str | int, x1: float, y1: float, /, *args: float) -> None: ... # create_foo() methods accept coords as a list or tuple, or as separate arguments. # Lists and tuples can be flat as in [1, 2, 3, 4], or nested as in [(1, 2), (3, 4)]. # Keyword arguments should be the same in all overloads of each method. @@ -1228,10 +1228,11 @@ class Canvas(Widget, XView, YView): @overload def create_line( self, - __x0: float, - __y0: float, - __x1: float, - __y1: float, + x0: float, + y0: float, + x1: float, + y1: float, + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1259,8 +1260,9 @@ class Canvas(Widget, XView, YView): @overload def create_line( self, - __xy_pair_0: tuple[float, float], - __xy_pair_1: tuple[float, float], + xy_pair_0: tuple[float, float], + xy_pair_1: tuple[float, float], + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1288,7 +1290,7 @@ class Canvas(Widget, XView, YView): @overload def create_line( self, - __coords: ( + coords: ( tuple[float, float, float, float] | tuple[tuple[float, float], tuple[float, float]] | list[int] @@ -1296,6 +1298,7 @@ class Canvas(Widget, XView, YView): | list[tuple[int, int]] | list[tuple[float, float]] ), + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1323,10 +1326,11 @@ class Canvas(Widget, XView, YView): @overload def create_oval( self, - __x0: float, - __y0: float, - __x1: float, - __y1: float, + x0: float, + y0: float, + x1: float, + y1: float, + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1355,8 +1359,9 @@ class Canvas(Widget, XView, YView): @overload def create_oval( self, - __xy_pair_0: tuple[float, float], - __xy_pair_1: tuple[float, float], + xy_pair_0: tuple[float, float], + xy_pair_1: tuple[float, float], + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1385,7 +1390,7 @@ class Canvas(Widget, XView, YView): @overload def create_oval( self, - __coords: ( + coords: ( tuple[float, float, float, float] | tuple[tuple[float, float], tuple[float, float]] | list[int] @@ -1393,6 +1398,7 @@ class Canvas(Widget, XView, YView): | list[tuple[int, int]] | list[tuple[float, float]] ), + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1421,10 +1427,11 @@ class Canvas(Widget, XView, YView): @overload def create_polygon( self, - __x0: float, - __y0: float, - __x1: float, - __y1: float, + x0: float, + y0: float, + x1: float, + y1: float, + /, *xy_pairs: float, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1456,8 +1463,9 @@ class Canvas(Widget, XView, YView): @overload def create_polygon( self, - __xy_pair_0: tuple[float, float], - __xy_pair_1: tuple[float, float], + xy_pair_0: tuple[float, float], + xy_pair_1: tuple[float, float], + /, *xy_pairs: tuple[float, float], activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1489,7 +1497,7 @@ class Canvas(Widget, XView, YView): @overload def create_polygon( self, - __coords: ( + coords: ( tuple[float, ...] | tuple[tuple[float, float], ...] | list[int] @@ -1497,6 +1505,7 @@ class Canvas(Widget, XView, YView): | list[tuple[int, int]] | list[tuple[float, float]] ), + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1528,10 +1537,11 @@ class Canvas(Widget, XView, YView): @overload def create_rectangle( self, - __x0: float, - __y0: float, - __x1: float, - __y1: float, + x0: float, + y0: float, + x1: float, + y1: float, + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1560,8 +1570,9 @@ class Canvas(Widget, XView, YView): @overload def create_rectangle( self, - __xy_pair_0: tuple[float, float], - __xy_pair_1: tuple[float, float], + xy_pair_0: tuple[float, float], + xy_pair_1: tuple[float, float], + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1590,7 +1601,7 @@ class Canvas(Widget, XView, YView): @overload def create_rectangle( self, - __coords: ( + coords: ( tuple[float, float, float, float] | tuple[tuple[float, float], tuple[float, float]] | list[int] @@ -1598,6 +1609,7 @@ class Canvas(Widget, XView, YView): | list[tuple[int, int]] | list[tuple[float, float]] ), + /, *, activedash: str | int | list[int] | tuple[int, ...] = ..., activefill: str = ..., @@ -1626,8 +1638,9 @@ class Canvas(Widget, XView, YView): @overload def create_text( self, - __x: float, - __y: float, + x: float, + y: float, + /, *, activefill: str = ..., activestipple: str = ..., @@ -1648,7 +1661,8 @@ class Canvas(Widget, XView, YView): @overload def create_text( self, - __coords: tuple[float, float] | list[int] | list[float], + coords: tuple[float, float] | list[int] | list[float], + /, *, activefill: str = ..., activestipple: str = ..., @@ -1669,8 +1683,9 @@ class Canvas(Widget, XView, YView): @overload def create_window( self, - __x: float, - __y: float, + x: float, + y: float, + /, *, anchor: _Anchor = ..., height: _ScreenUnits = ..., @@ -1682,7 +1697,8 @@ class Canvas(Widget, XView, YView): @overload def create_window( self, - __coords: tuple[float, float] | list[int] | list[float], + coords: tuple[float, float] | list[int] | list[float], + /, *, anchor: _Anchor = ..., height: _ScreenUnits = ..., @@ -1694,11 +1710,11 @@ class Canvas(Widget, XView, YView): def dchars(self, *args) -> None: ... def delete(self, *tagsOrCanvasIds: str | int) -> None: ... @overload - def dtag(self, __tag: str, __tag_to_delete: str | None = ...) -> None: ... + def dtag(self, tag: str, tag_to_delete: str | None = ..., /) -> None: ... @overload - def dtag(self, __id: int, __tag_to_delete: str) -> None: ... + def dtag(self, id: int, tag_to_delete: str, /) -> None: ... def focus(self, *args): ... - def gettags(self, __tagOrId: str | int) -> tuple[str, ...]: ... + def gettags(self, tagOrId: str | int, /) -> tuple[str, ...]: ... def icursor(self, *args) -> None: ... def index(self, *args): ... def insert(self, *args) -> None: ... @@ -1716,13 +1732,13 @@ class Canvas(Widget, XView, YView): # lift = tkraise = tag_raise # # But mypy doesn't like aliasing here (maybe because Misc defines the same names) - def tag_lower(self, __first: str | int, __second: str | int | None = ...) -> None: ... - def lower(self, __first: str | int, __second: str | int | None = ...) -> None: ... # type: ignore[override] - def tag_raise(self, __first: str | int, __second: str | int | None = ...) -> None: ... - def tkraise(self, __first: str | int, __second: str | int | None = ...) -> None: ... # type: ignore[override] - def lift(self, __first: str | int, __second: str | int | None = ...) -> None: ... # type: ignore[override] + def tag_lower(self, first: str | int, second: str | int | None = ..., /) -> None: ... + def lower(self, first: str | int, second: str | int | None = ..., /) -> None: ... # type: ignore[override] + def tag_raise(self, first: str | int, second: str | int | None = ..., /) -> None: ... + def tkraise(self, first: str | int, second: str | int | None = ..., /) -> None: ... # type: ignore[override] + def lift(self, first: str | int, second: str | int | None = ..., /) -> None: ... # type: ignore[override] def scale( - self, __tagOrId: str | int, __xOrigin: _ScreenUnits, __yOrigin: _ScreenUnits, __xScale: float, __yScale: float + self, tagOrId: str | int, xOrigin: _ScreenUnits, yOrigin: _ScreenUnits, xScale: float, yScale: float, / ) -> None: ... def scan_mark(self, x, y) -> None: ... def scan_dragto(self, x, y, gain: int = 10) -> None: ... @@ -3182,7 +3198,7 @@ class Text(Widget, XView, YView): @overload def tag_configure(self, tagName: str, cnf: str) -> tuple[str, str, str, Any, Any]: ... tag_config = tag_configure - def tag_delete(self, __first_tag_name: str, *tagNames: str) -> None: ... # error if no tag names given + def tag_delete(self, first_tag_name: str, /, *tagNames: str) -> None: ... # error if no tag names given def tag_lower(self, tagName: str, belowThis: str | None = None) -> None: ... def tag_names(self, index: _TextIndex | None = None) -> tuple[str, ...]: ... def tag_nextrange( diff --git a/mypy/typeshed/stdlib/tkinter/dnd.pyi b/mypy/typeshed/stdlib/tkinter/dnd.pyi index 5a83bb56679f..d806be74068e 100644 --- a/mypy/typeshed/stdlib/tkinter/dnd.pyi +++ b/mypy/typeshed/stdlib/tkinter/dnd.pyi @@ -6,7 +6,7 @@ if sys.version_info >= (3, 9): __all__ = ["dnd_start", "DndHandler"] class _DndSource(Protocol): - def dnd_end(self, __target: Widget | None, __event: Event[Misc] | None) -> None: ... + def dnd_end(self, target: Widget | None, event: Event[Misc] | None, /) -> None: ... class DndHandler: root: ClassVar[Tk | None] diff --git a/mypy/typeshed/stdlib/tkinter/font.pyi b/mypy/typeshed/stdlib/tkinter/font.pyi index 448e2b0054a5..46625014d4ac 100644 --- a/mypy/typeshed/stdlib/tkinter/font.pyi +++ b/mypy/typeshed/stdlib/tkinter/font.pyi @@ -97,9 +97,9 @@ class Font: configure = config def copy(self) -> Font: ... @overload - def metrics(self, __option: Literal["ascent", "descent", "linespace"], *, displayof: tkinter.Misc | None = ...) -> int: ... + def metrics(self, option: Literal["ascent", "descent", "linespace"], /, *, displayof: tkinter.Misc | None = ...) -> int: ... @overload - def metrics(self, __option: Literal["fixed"], *, displayof: tkinter.Misc | None = ...) -> bool: ... + def metrics(self, option: Literal["fixed"], /, *, displayof: tkinter.Misc | None = ...) -> bool: ... @overload def metrics(self, *, displayof: tkinter.Misc | None = ...) -> _MetricsDict: ... def measure(self, text: str, displayof: tkinter.Misc | None = None) -> int: ... diff --git a/mypy/typeshed/stdlib/tkinter/ttk.pyi b/mypy/typeshed/stdlib/tkinter/ttk.pyi index f1b132b33657..86a23ce82211 100644 --- a/mypy/typeshed/stdlib/tkinter/ttk.pyi +++ b/mypy/typeshed/stdlib/tkinter/ttk.pyi @@ -1105,19 +1105,19 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): def see(self, item: str | int) -> None: ... def selection(self) -> tuple[str, ...]: ... @overload - def selection_set(self, __items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...]) -> None: ... + def selection_set(self, items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...], /) -> None: ... @overload def selection_set(self, *items: str | int) -> None: ... @overload - def selection_add(self, __items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...]) -> None: ... + def selection_add(self, items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...], /) -> None: ... @overload def selection_add(self, *items: str | int) -> None: ... @overload - def selection_remove(self, __items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...]) -> None: ... + def selection_remove(self, items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...], /) -> None: ... @overload def selection_remove(self, *items: str | int) -> None: ... @overload - def selection_toggle(self, __items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...]) -> None: ... + def selection_toggle(self, items: list[str] | tuple[str, ...] | list[int] | tuple[int, ...], /) -> None: ... @overload def selection_toggle(self, *items: str | int) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/tomllib.pyi b/mypy/typeshed/stdlib/tomllib.pyi index 3a6ce93f87e1..d559568b912b 100644 --- a/mypy/typeshed/stdlib/tomllib.pyi +++ b/mypy/typeshed/stdlib/tomllib.pyi @@ -6,5 +6,5 @@ __all__ = ("loads", "load", "TOMLDecodeError") class TOMLDecodeError(ValueError): ... -def load(__fp: SupportsRead[bytes], *, parse_float: Callable[[str], Any] = ...) -> dict[str, Any]: ... -def loads(__s: str, *, parse_float: Callable[[str], Any] = ...) -> dict[str, Any]: ... +def load(fp: SupportsRead[bytes], /, *, parse_float: Callable[[str], Any] = ...) -> dict[str, Any]: ... +def loads(s: str, /, *, parse_float: Callable[[str], Any] = ...) -> dict[str, Any]: ... diff --git a/mypy/typeshed/stdlib/trace.pyi b/mypy/typeshed/stdlib/trace.pyi index 14a921c5e6cc..d32647a55cb5 100644 --- a/mypy/typeshed/stdlib/trace.pyi +++ b/mypy/typeshed/stdlib/trace.pyi @@ -65,7 +65,7 @@ class Trace: self, cmd: str | types.CodeType, globals: Mapping[str, Any] | None = None, locals: Mapping[str, Any] | None = None ) -> None: ... if sys.version_info >= (3, 9): - def runfunc(self, __func: Callable[_P, _T], *args: _P.args, **kw: _P.kwargs) -> _T: ... + def runfunc(self, func: Callable[_P, _T], /, *args: _P.args, **kw: _P.kwargs) -> _T: ... else: def runfunc(self, func: Callable[_P, _T], *args: _P.args, **kw: _P.kwargs) -> _T: ... diff --git a/mypy/typeshed/stdlib/traceback.pyi b/mypy/typeshed/stdlib/traceback.pyi index f6720155936f..928858f81d1c 100644 --- a/mypy/typeshed/stdlib/traceback.pyi +++ b/mypy/typeshed/stdlib/traceback.pyi @@ -34,7 +34,8 @@ def print_tb(tb: TracebackType | None, limit: int | None = None, file: SupportsW if sys.version_info >= (3, 10): @overload def print_exception( - __exc: type[BaseException] | None, + exc: type[BaseException] | None, + /, value: BaseException | None = ..., tb: TracebackType | None = ..., limit: int | None = None, @@ -43,18 +44,19 @@ if sys.version_info >= (3, 10): ) -> None: ... @overload def print_exception( - __exc: BaseException, *, limit: int | None = None, file: SupportsWrite[str] | None = None, chain: bool = True + exc: BaseException, /, *, limit: int | None = None, file: SupportsWrite[str] | None = None, chain: bool = True ) -> None: ... @overload def format_exception( - __exc: type[BaseException] | None, + exc: type[BaseException] | None, + /, value: BaseException | None = ..., tb: TracebackType | None = ..., limit: int | None = None, chain: bool = True, ) -> list[str]: ... @overload - def format_exception(__exc: BaseException, *, limit: int | None = None, chain: bool = True) -> list[str]: ... + def format_exception(exc: BaseException, /, *, limit: int | None = None, chain: bool = True) -> list[str]: ... else: def print_exception( @@ -85,9 +87,9 @@ def print_list(extracted_list: list[FrameSummary], file: SupportsWrite[str] | No if sys.version_info >= (3, 10): @overload - def format_exception_only(__exc: BaseException | None) -> list[str]: ... + def format_exception_only(exc: BaseException | None, /) -> list[str]: ... @overload - def format_exception_only(__exc: Unused, value: BaseException | None) -> list[str]: ... + def format_exception_only(exc: Unused, /, value: BaseException | None) -> list[str]: ... else: def format_exception_only(etype: type[BaseException] | None, value: BaseException | None) -> list[str]: ... diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index 05c5e85e4a9e..f2d79b7f3ade 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -66,8 +66,8 @@ _VT_co = TypeVar("_VT_co", covariant=True) @final class _Cell: - def __new__(cls, __contents: object = ...) -> Self: ... - def __eq__(self, __value: object) -> bool: ... + def __new__(cls, contents: object = ..., /) -> Self: ... + def __eq__(self, value: object, /) -> bool: ... __hash__: ClassVar[None] # type: ignore[assignment] cell_contents: Any @@ -102,15 +102,15 @@ class FunctionType: ) -> Self: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... @overload - def __get__(self, __instance: None, __owner: type) -> FunctionType: ... + def __get__(self, instance: None, owner: type, /) -> FunctionType: ... @overload - def __get__(self, __instance: object, __owner: type | None = None) -> MethodType: ... + def __get__(self, instance: object, owner: type | None = None, /) -> MethodType: ... LambdaType = FunctionType @final class CodeType: - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @property def co_argcount(self) -> int: ... @@ -164,64 +164,67 @@ class CodeType: if sys.version_info >= (3, 11): 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, - __qualname: str, - __firstlineno: int, - __linetable: bytes, - __exceptiontable: bytes, - __freevars: tuple[str, ...] = ..., - __cellvars: tuple[str, ...] = ..., + 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, + qualname: str, + firstlineno: int, + linetable: bytes, + exceptiontable: bytes, + freevars: tuple[str, ...] = ..., + cellvars: tuple[str, ...] = ..., + /, ) -> Self: ... elif sys.version_info >= (3, 10): 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, - __linetable: bytes, - __freevars: tuple[str, ...] = ..., - __cellvars: tuple[str, ...] = ..., + 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, + linetable: bytes, + freevars: tuple[str, ...] = ..., + cellvars: tuple[str, ...] = ..., + /, ) -> Self: ... else: 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, ...] = ..., + 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: ... if sys.version_info >= (3, 11): def replace( @@ -293,10 +296,10 @@ class CodeType: class MappingProxyType(Mapping[_KT, _VT_co]): __hash__: ClassVar[None] # type: ignore[assignment] def __new__(cls, mapping: SupportsKeysAndGetItem[_KT, _VT_co]) -> Self: ... - def __getitem__(self, __key: _KT) -> _VT_co: ... + def __getitem__(self, key: _KT, /) -> _VT_co: ... def __iter__(self) -> Iterator[_KT]: ... def __len__(self) -> int: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def copy(self) -> dict[_KT, _VT_co]: ... def keys(self) -> KeysView[_KT]: ... def values(self) -> ValuesView[_VT_co]: ... @@ -304,19 +307,19 @@ class MappingProxyType(Mapping[_KT, _VT_co]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... def __reversed__(self) -> Iterator[_KT]: ... - def __or__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT_co | _T2]: ... - def __ror__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT_co | _T2]: ... + def __or__(self, value: Mapping[_T1, _T2], /) -> dict[_KT | _T1, _VT_co | _T2]: ... + def __ror__(self, value: Mapping[_T1, _T2], /) -> dict[_KT | _T1, _VT_co | _T2]: ... class SimpleNamespace: __hash__: ClassVar[None] # type: ignore[assignment] def __init__(self, **kwargs: Any) -> None: ... - def __eq__(self, __value: object) -> bool: ... - def __getattribute__(self, __name: str) -> Any: ... - def __setattr__(self, __name: str, __value: Any) -> None: ... - def __delattr__(self, __name: str) -> None: ... + def __eq__(self, value: object, /) -> bool: ... + def __getattribute__(self, name: str, /) -> Any: ... + def __setattr__(self, name: str, value: Any, /) -> None: ... + def __delattr__(self, name: str, /) -> None: ... class _LoaderProtocol(Protocol): - def load_module(self, __fullname: str) -> ModuleType: ... + def load_module(self, fullname: str, /) -> ModuleType: ... class ModuleType: __name__: str @@ -348,13 +351,13 @@ class GeneratorType(Generator[_YieldT_co, _SendT_contra, _ReturnT_co]): __qualname__: str def __iter__(self) -> Self: ... def __next__(self) -> _YieldT_co: ... - def send(self, __arg: _SendT_contra) -> _YieldT_co: ... + def send(self, arg: _SendT_contra, /) -> _YieldT_co: ... @overload def throw( - self, __typ: type[BaseException], __val: BaseException | object = ..., __tb: TracebackType | None = ... + self, typ: type[BaseException], val: BaseException | object = ..., tb: TracebackType | None = ..., / ) -> _YieldT_co: ... @overload - def throw(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = ...) -> _YieldT_co: ... + def throw(self, typ: BaseException, val: None = None, tb: TracebackType | None = ..., /) -> _YieldT_co: ... @final class AsyncGeneratorType(AsyncGenerator[_YieldT_co, _SendT_contra]): @@ -368,16 +371,16 @@ class AsyncGeneratorType(AsyncGenerator[_YieldT_co, _SendT_contra]): def __aiter__(self) -> Self: ... def __anext__(self) -> Coroutine[Any, Any, _YieldT_co]: ... - def asend(self, __val: _SendT_contra) -> Coroutine[Any, Any, _YieldT_co]: ... + def asend(self, val: _SendT_contra, /) -> Coroutine[Any, Any, _YieldT_co]: ... @overload async def athrow( - self, __typ: type[BaseException], __val: BaseException | object = ..., __tb: TracebackType | None = ... + self, typ: type[BaseException], val: BaseException | object = ..., tb: TracebackType | None = ..., / ) -> _YieldT_co: ... @overload - async def athrow(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = ...) -> _YieldT_co: ... + async def athrow(self, typ: BaseException, val: None = None, tb: TracebackType | None = ..., /) -> _YieldT_co: ... def aclose(self) -> Coroutine[Any, Any, None]: ... if sys.version_info >= (3, 9): - def __class_getitem__(cls, __item: Any) -> GenericAlias: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @final class CoroutineType(Coroutine[_YieldT_co, _SendT_contra, _ReturnT_co]): @@ -391,13 +394,13 @@ class CoroutineType(Coroutine[_YieldT_co, _SendT_contra, _ReturnT_co]): def close(self) -> None: ... def __await__(self) -> Generator[Any, None, _ReturnT_co]: ... - def send(self, __arg: _SendT_contra) -> _YieldT_co: ... + def send(self, arg: _SendT_contra, /) -> _YieldT_co: ... @overload def throw( - self, __typ: type[BaseException], __val: BaseException | object = ..., __tb: TracebackType | None = ... + self, typ: type[BaseException], val: BaseException | object = ..., tb: TracebackType | None = ..., / ) -> _YieldT_co: ... @overload - def throw(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = ...) -> _YieldT_co: ... + def throw(self, typ: BaseException, val: None = None, tb: TracebackType | None = ..., /) -> _YieldT_co: ... @final class MethodType: @@ -413,9 +416,9 @@ class MethodType: def __name__(self) -> str: ... # inherited from the added function @property def __qualname__(self) -> str: ... # inherited from the added function - def __new__(cls, __func: Callable[..., Any], __obj: object) -> Self: ... + def __new__(cls, func: Callable[..., Any], obj: object, /) -> Self: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @final @@ -427,7 +430,7 @@ class BuiltinFunctionType: @property def __qualname__(self) -> str: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __eq__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... BuiltinMethodType = BuiltinFunctionType @@ -441,7 +444,7 @@ class WrapperDescriptorType: @property def __objclass__(self) -> type: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... @final class MethodWrapperType: @@ -454,8 +457,8 @@ class MethodWrapperType: @property def __objclass__(self) -> type: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __eq__(self, __value: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __eq__(self, value: object, /) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... @final @@ -467,7 +470,7 @@ class MethodDescriptorType: @property def __objclass__(self) -> type: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... @final class ClassMethodDescriptorType: @@ -478,7 +481,7 @@ class ClassMethodDescriptorType: @property def __objclass__(self) -> type: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... @final class TracebackType: @@ -524,9 +527,9 @@ class GetSetDescriptorType: def __qualname__(self) -> str: ... @property def __objclass__(self) -> type: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... - def __set__(self, __instance: Any, __value: Any) -> None: ... - def __delete__(self, __instance: Any) -> None: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... + def __set__(self, instance: Any, value: Any, /) -> None: ... + def __delete__(self, instance: Any, /) -> None: ... @final class MemberDescriptorType: @@ -536,9 +539,9 @@ class MemberDescriptorType: def __qualname__(self) -> str: ... @property def __objclass__(self) -> type: ... - def __get__(self, __instance: Any, __owner: type | None = None) -> Any: ... - def __set__(self, __instance: Any, __value: Any) -> None: ... - def __delete__(self, __instance: Any) -> None: ... + def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ... + def __set__(self, instance: Any, value: Any, /) -> None: ... + def __delete__(self, instance: Any, /) -> None: ... def new_class( name: str, @@ -552,7 +555,7 @@ def prepare_class( ) -> tuple[type, dict[str, Any], dict[str, Any]]: ... if sys.version_info >= (3, 12): - def get_original_bases(__cls: type) -> tuple[Any, ...]: ... + def get_original_bases(cls: type, /) -> tuple[Any, ...]: ... # Actually a different type, but `property` is special and we want that too. DynamicClassAttribute = property @@ -578,8 +581,8 @@ if sys.version_info >= (3, 9): @property def __parameters__(self) -> tuple[Any, ...]: ... def __new__(cls, origin: type, args: Any) -> Self: ... - def __getitem__(self, __typeargs: Any) -> GenericAlias: ... - def __eq__(self, __value: object) -> bool: ... + def __getitem__(self, typeargs: Any, /) -> GenericAlias: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... if sys.version_info >= (3, 11): @property @@ -605,7 +608,7 @@ if sys.version_info >= (3, 10): class UnionType: @property def __args__(self) -> tuple[Any, ...]: ... - def __or__(self, __value: Any) -> UnionType: ... - def __ror__(self, __value: Any) -> UnionType: ... - def __eq__(self, __value: object) -> bool: ... + def __or__(self, value: Any, /) -> UnionType: ... + def __ror__(self, value: Any, /) -> UnionType: ... + def __eq__(self, value: object, /) -> bool: ... def __hash__(self) -> int: ... diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 5d01be539016..be0c29c89f8d 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -1,3 +1,5 @@ +# Since this module defines "overload" it is not recognized by Ruff as typing.overload +# ruff: noqa: F811 # TODO: The collections import is required, otherwise mypy crashes. # https://github.com/python/mypy/issues/16744 import collections # noqa: F401 # pyright: ignore @@ -282,7 +284,7 @@ if sys.version_info >= (3, 10): def __init__(self, name: str, tp: Any) -> None: ... if sys.version_info >= (3, 11): @staticmethod - def __call__(__x: _T) -> _T: ... + def __call__(x: _T, /) -> _T: ... else: def __call__(self, x: _T) -> _T: ... @@ -372,7 +374,7 @@ class SupportsRound(Protocol[_T_co]): def __round__(self) -> int: ... @overload @abstractmethod - def __round__(self, __ndigits: int) -> _T_co: ... + def __round__(self, ndigits: int, /) -> _T_co: ... @runtime_checkable class Sized(Protocol, metaclass=ABCMeta): @@ -410,15 +412,15 @@ _ReturnT_co = TypeVar("_ReturnT_co", covariant=True) class Generator(Iterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra, _ReturnT_co]): def __next__(self) -> _YieldT_co: ... @abstractmethod - def send(self, __value: _SendT_contra) -> _YieldT_co: ... + def send(self, value: _SendT_contra, /) -> _YieldT_co: ... @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 - def throw(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = None) -> _YieldT_co: ... + def throw(self, typ: BaseException, val: None = None, tb: TracebackType | None = None, /) -> _YieldT_co: ... def close(self) -> None: ... def __iter__(self) -> Generator[_YieldT_co, _SendT_contra, _ReturnT_co]: ... @property @@ -447,15 +449,15 @@ class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _Retu @property def cr_running(self) -> bool: ... @abstractmethod - def send(self, __value: _SendT_contra) -> _YieldT_co: ... + def send(self, value: _SendT_contra, /) -> _YieldT_co: ... @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 - def throw(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = None) -> _YieldT_co: ... + def throw(self, typ: BaseException, val: None = None, tb: TracebackType | None = None, /) -> _YieldT_co: ... @abstractmethod def close(self) -> None: ... @@ -483,15 +485,15 @@ class AsyncIterator(AsyncIterable[_T_co], Protocol[_T_co]): class AsyncGenerator(AsyncIterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra]): def __anext__(self) -> Awaitable[_YieldT_co]: ... @abstractmethod - def asend(self, __value: _SendT_contra) -> Awaitable[_YieldT_co]: ... + def asend(self, value: _SendT_contra, /) -> Awaitable[_YieldT_co]: ... @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 - def athrow(self, __typ: BaseException, __val: None = None, __tb: TracebackType | None = None) -> Awaitable[_YieldT_co]: ... + def athrow(self, typ: BaseException, val: None = None, tb: TracebackType | None = None, /) -> Awaitable[_YieldT_co]: ... def aclose(self) -> Awaitable[None]: ... @property def ag_await(self) -> Any: ... @@ -506,7 +508,7 @@ class AsyncGenerator(AsyncIterator[_YieldT_co], Generic[_YieldT_co, _SendT_contr class Container(Protocol[_T_co]): # This is generic more on vibes than anything else @abstractmethod - def __contains__(self, __x: object) -> bool: ... + def __contains__(self, x: object, /) -> bool: ... @runtime_checkable class Collection(Iterable[_T_co], Container[_T_co], Protocol[_T_co]): @@ -630,30 +632,30 @@ class Mapping(Collection[_KT], Generic[_KT, _VT_co]): # TODO: We wish the key type could also be covariant, but that doesn't work, # see discussion in https://github.com/python/typing/pull/273. @abstractmethod - def __getitem__(self, __key: _KT) -> _VT_co: ... + def __getitem__(self, key: _KT, /) -> _VT_co: ... # Mixin methods @overload - def get(self, __key: _KT) -> _VT_co | None: ... + def get(self, key: _KT, /) -> _VT_co | None: ... @overload - def get(self, __key: _KT, default: _VT_co | _T) -> _VT_co | _T: ... + def get(self, key: _KT, /, default: _VT_co | _T) -> _VT_co | _T: ... def items(self) -> ItemsView[_KT, _VT_co]: ... def keys(self) -> KeysView[_KT]: ... def values(self) -> ValuesView[_VT_co]: ... - def __contains__(self, __key: object) -> bool: ... - def __eq__(self, __other: object) -> bool: ... + def __contains__(self, key: object, /) -> bool: ... + def __eq__(self, other: object, /) -> bool: ... class MutableMapping(Mapping[_KT, _VT]): @abstractmethod - def __setitem__(self, __key: _KT, __value: _VT) -> None: ... + def __setitem__(self, key: _KT, value: _VT, /) -> None: ... @abstractmethod - def __delitem__(self, __key: _KT) -> None: ... + def __delitem__(self, key: _KT, /) -> None: ... def clear(self) -> None: ... @overload - def pop(self, __key: _KT) -> _VT: ... + def pop(self, key: _KT, /) -> _VT: ... @overload - def pop(self, __key: _KT, default: _VT) -> _VT: ... + def pop(self, key: _KT, /, default: _VT) -> _VT: ... @overload - def pop(self, __key: _KT, default: _T) -> _VT | _T: ... + def pop(self, key: _KT, /, default: _T) -> _VT | _T: ... def popitem(self) -> tuple[_KT, _VT]: ... # This overload should be allowed only if the value type is compatible with None. # @@ -662,9 +664,9 @@ class MutableMapping(Mapping[_KT, _VT]): # -- collections.ChainMap.setdefault # -- weakref.WeakKeyDictionary.setdefault @overload - def setdefault(self: MutableMapping[_KT, _T | None], __key: _KT, __default: None = None) -> _T | None: ... + def setdefault(self: MutableMapping[_KT, _T | None], key: _KT, default: None = None, /) -> _T | None: ... @overload - def setdefault(self, __key: _KT, __default: _VT) -> _VT: ... + def setdefault(self, key: _KT, default: _VT, /) -> _VT: ... # 'update' used to take a Union, but using overloading is better. # The second overloaded type here is a bit too general, because # Mapping[tuple[_KT, _VT], W] is a subclass of Iterable[tuple[_KT, _VT]], @@ -686,9 +688,9 @@ class MutableMapping(Mapping[_KT, _VT]): # -- weakref.WeakValueDictionary.__ior__ # -- weakref.WeakKeyDictionary.__ior__ @overload - def update(self, __m: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ... + def update(self, m: SupportsKeysAndGetItem[_KT, _VT], /, **kwargs: _VT) -> None: ... @overload - def update(self, __m: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ... + def update(self, m: Iterable[tuple[_KT, _VT]], /, **kwargs: _VT) -> None: ... @overload def update(self, **kwargs: _VT) -> None: ... @@ -720,41 +722,41 @@ class IO(Iterator[AnyStr]): @abstractmethod def isatty(self) -> bool: ... @abstractmethod - def read(self, __n: int = -1) -> AnyStr: ... + def read(self, n: int = -1, /) -> AnyStr: ... @abstractmethod def readable(self) -> bool: ... @abstractmethod - def readline(self, __limit: int = -1) -> AnyStr: ... + def readline(self, limit: int = -1, /) -> AnyStr: ... @abstractmethod - def readlines(self, __hint: int = -1) -> list[AnyStr]: ... + def readlines(self, hint: int = -1, /) -> list[AnyStr]: ... @abstractmethod - def seek(self, __offset: int, __whence: int = 0) -> int: ... + def seek(self, offset: int, whence: int = 0, /) -> int: ... @abstractmethod def seekable(self) -> bool: ... @abstractmethod def tell(self) -> int: ... @abstractmethod - def truncate(self, __size: int | None = None) -> int: ... + def truncate(self, size: int | None = None, /) -> int: ... @abstractmethod def writable(self) -> bool: ... @abstractmethod @overload - def write(self: IO[str], __s: str) -> int: ... + def write(self: IO[str], s: str, /) -> int: ... @abstractmethod @overload - def write(self: IO[bytes], __s: ReadableBuffer) -> int: ... + def write(self: IO[bytes], s: ReadableBuffer, /) -> int: ... @abstractmethod @overload - def write(self, __s: AnyStr) -> int: ... + def write(self, s: AnyStr, /) -> int: ... @abstractmethod @overload - def writelines(self: IO[str], __lines: Iterable[str]) -> None: ... + def writelines(self: IO[str], lines: Iterable[str], /) -> None: ... @abstractmethod @overload - def writelines(self: IO[bytes], __lines: Iterable[ReadableBuffer]) -> None: ... + def writelines(self: IO[bytes], lines: Iterable[ReadableBuffer], /) -> None: ... @abstractmethod @overload - def writelines(self, __lines: Iterable[AnyStr]) -> None: ... + def writelines(self, lines: Iterable[AnyStr], /) -> None: ... @abstractmethod def __next__(self) -> AnyStr: ... @abstractmethod @@ -763,7 +765,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]): @@ -839,9 +841,9 @@ def cast(typ: str, val: Any) -> Any: ... def cast(typ: object, val: Any) -> Any: ... if sys.version_info >= (3, 11): - def reveal_type(__obj: _T) -> _T: ... - def assert_never(__arg: Never) -> Never: ... - def assert_type(__val: _T, __typ: Any) -> _T: ... + def reveal_type(obj: _T, /) -> _T: ... + def assert_never(arg: Never, /) -> Never: ... + def assert_type(val: _T, typ: Any, /) -> _T: ... def clear_overloads() -> None: ... def get_overloads(func: Callable[..., object]) -> Sequence[Callable[..., object]]: ... def dataclass_transform( @@ -867,9 +869,12 @@ class NamedTuple(tuple[Any, ...]): __orig_bases__: ClassVar[tuple[Any, ...]] @overload - def __init__(self, __typename: str, __fields: Iterable[tuple[str, Any]]) -> None: ... + def __init__(self, typename: str, fields: Iterable[tuple[str, Any]], /) -> None: ... @overload - def __init__(self, __typename: str, __fields: None = None, **kwargs: Any) -> None: ... + @typing_extensions.deprecated( + "Creating a typing.NamedTuple using keyword arguments is deprecated and support will be removed in Python 3.15" + ) + def __init__(self, typename: str, fields: None = None, /, **kwargs: Any) -> None: ... @classmethod def _make(cls, iterable: Iterable[Any]) -> typing_extensions.Self: ... def _asdict(self) -> dict[str, Any]: ... @@ -894,22 +899,22 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): def setdefault(self, k: _Never, default: object) -> object: ... # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. def pop(self, k: _Never, default: _T = ...) -> object: ... # pyright: ignore[reportInvalidTypeVarUse] - def update(self: _T, __m: _T) -> None: ... + def update(self: _T, m: _T, /) -> None: ... def __delitem__(self, k: _Never) -> None: ... def items(self) -> dict_items[str, object]: ... def keys(self) -> dict_keys[str, object]: ... def values(self) -> dict_values[str, object]: ... if sys.version_info >= (3, 9): @overload - def __or__(self, __value: typing_extensions.Self) -> typing_extensions.Self: ... + def __or__(self, value: typing_extensions.Self, /) -> typing_extensions.Self: ... @overload - def __or__(self, __value: dict[str, Any]) -> dict[str, object]: ... + def __or__(self, value: dict[str, Any], /) -> dict[str, object]: ... @overload - def __ror__(self, __value: typing_extensions.Self) -> typing_extensions.Self: ... + def __ror__(self, value: typing_extensions.Self, /) -> typing_extensions.Self: ... @overload - def __ror__(self, __value: dict[str, Any]) -> dict[str, object]: ... + def __ror__(self, value: dict[str, Any], /) -> dict[str, object]: ... # supposedly incompatible definitions of __or__ and __ior__ - def __ior__(self, __value: typing_extensions.Self) -> typing_extensions.Self: ... # type: ignore[misc] + def __ior__(self, value: typing_extensions.Self, /) -> typing_extensions.Self: ... # type: ignore[misc] @final class ForwardRef: @@ -945,7 +950,7 @@ if sys.version_info >= (3, 10): def _type_repr(obj: object) -> str: ... if sys.version_info >= (3, 12): - def override(__method: _F) -> _F: ... + def override(method: _F, /) -> _F: ... @final class TypeAliasType: def __init__( @@ -967,5 +972,5 @@ if sys.version_info >= (3, 12): def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 13): - def is_protocol(__tp: type) -> bool: ... - def get_protocol_members(__tp: type) -> frozenset[str]: ... + def is_protocol(tp: type, /) -> bool: ... + def get_protocol_members(tp: type, /) -> frozenset[str]: ... diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index 921c1334cfe4..f9e94ca683d6 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -235,22 +235,22 @@ class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): def setdefault(self, k: Never, default: object) -> object: ... # Mypy plugin hook for 'pop' expects that 'default' has a type variable type. def pop(self, k: Never, default: _T = ...) -> object: ... # pyright: ignore[reportInvalidTypeVarUse] - def update(self: _T, __m: _T) -> None: ... + def update(self: _T, m: _T, /) -> None: ... def items(self) -> dict_items[str, object]: ... def keys(self) -> dict_keys[str, object]: ... def values(self) -> dict_values[str, object]: ... def __delitem__(self, k: Never) -> None: ... if sys.version_info >= (3, 9): @overload - def __or__(self, __value: Self) -> Self: ... + def __or__(self, value: Self, /) -> Self: ... @overload - def __or__(self, __value: dict[str, Any]) -> dict[str, object]: ... + def __or__(self, value: dict[str, Any], /) -> dict[str, object]: ... @overload - def __ror__(self, __value: Self) -> Self: ... + def __ror__(self, value: Self, /) -> Self: ... @overload - def __ror__(self, __value: dict[str, Any]) -> dict[str, object]: ... + def __ror__(self, value: dict[str, Any], /) -> dict[str, object]: ... # supposedly incompatible definitions of `__ior__` and `__or__`: - def __ior__(self, __value: Self) -> Self: ... # type: ignore[misc] + def __ior__(self, value: Self, /) -> Self: ... # type: ignore[misc] # TypedDict is a (non-subscriptable) special form. TypedDict: object @@ -335,9 +335,9 @@ if sys.version_info >= (3, 11): else: Self: _SpecialForm Never: _SpecialForm - def reveal_type(__obj: _T) -> _T: ... - def assert_never(__arg: Never) -> Never: ... - def assert_type(__val: _T, __typ: Any) -> _T: ... + def reveal_type(obj: _T, /) -> _T: ... + def assert_never(arg: Never, /) -> Never: ... + def assert_type(val: _T, typ: Any, /) -> _T: ... def clear_overloads() -> None: ... def get_overloads(func: Callable[..., object]) -> Sequence[Callable[..., object]]: ... @@ -373,7 +373,7 @@ else: class NewType: def __init__(self, name: str, tp: Any) -> None: ... - def __call__(self, __obj: _T) -> _T: ... + def __call__(self, obj: _T, /) -> _T: ... __supertype__: type if sys.version_info >= (3, 10): def __or__(self, other: Any) -> _SpecialForm: ... @@ -456,16 +456,16 @@ class deprecated: message: str category: type[Warning] | None stacklevel: int - def __init__(self, __message: str, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> None: ... - def __call__(self, __arg: _T) -> _T: ... + def __init__(self, message: str, /, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> None: ... + def __call__(self, arg: _T, /) -> _T: ... if sys.version_info >= (3, 12): from collections.abc import Buffer as Buffer from types import get_original_bases as get_original_bases from typing import TypeAliasType as TypeAliasType, override as override else: - def override(__arg: _F) -> _F: ... - def get_original_bases(__cls: type) -> tuple[Any, ...]: ... + def override(arg: _F, /) -> _F: ... + def get_original_bases(cls: type, /) -> tuple[Any, ...]: ... @final class TypeAliasType: def __init__( @@ -491,17 +491,17 @@ else: class Buffer(Protocol): # Not actually a Protocol at runtime; see # https://github.com/python/typeshed/issues/10224 for why we're defining it this way - def __buffer__(self, __flags: int) -> memoryview: ... + def __buffer__(self, flags: int, /) -> memoryview: ... if sys.version_info >= (3, 13): from typing import get_protocol_members as get_protocol_members, is_protocol as is_protocol else: - def is_protocol(__tp: type) -> bool: ... - def get_protocol_members(__tp: type) -> frozenset[str]: ... + def is_protocol(tp: type, /) -> bool: ... + def get_protocol_members(tp: type, /) -> frozenset[str]: ... class Doc: documentation: str - def __init__(self, __documentation: str) -> None: ... + def __init__(self, documentation: str, /) -> None: ... def __hash__(self) -> int: ... def __eq__(self, other: object) -> bool: ... diff --git a/mypy/typeshed/stdlib/unicodedata.pyi b/mypy/typeshed/stdlib/unicodedata.pyi index 5c6749c8a1ae..77d69edf06af 100644 --- a/mypy/typeshed/stdlib/unicodedata.pyi +++ b/mypy/typeshed/stdlib/unicodedata.pyi @@ -13,61 +13,61 @@ _T = TypeVar("_T") _NormalizationForm: TypeAlias = Literal["NFC", "NFD", "NFKC", "NFKD"] -def bidirectional(__chr: str) -> str: ... -def category(__chr: str) -> str: ... -def combining(__chr: str) -> int: ... +def bidirectional(chr: str, /) -> str: ... +def category(chr: str, /) -> str: ... +def combining(chr: str, /) -> int: ... @overload -def decimal(__chr: str) -> int: ... +def decimal(chr: str, /) -> int: ... @overload -def decimal(__chr: str, __default: _T) -> int | _T: ... -def decomposition(__chr: str) -> str: ... +def decimal(chr: str, default: _T, /) -> int | _T: ... +def decomposition(chr: str, /) -> str: ... @overload -def digit(__chr: str) -> int: ... +def digit(chr: str, /) -> int: ... @overload -def digit(__chr: str, __default: _T) -> int | _T: ... +def digit(chr: str, default: _T, /) -> int | _T: ... _EastAsianWidth: TypeAlias = Literal["F", "H", "W", "Na", "A", "N"] -def east_asian_width(__chr: str) -> _EastAsianWidth: ... -def is_normalized(__form: _NormalizationForm, __unistr: str) -> bool: ... -def lookup(__name: str | ReadOnlyBuffer) -> str: ... -def mirrored(__chr: str) -> int: ... +def east_asian_width(chr: str, /) -> _EastAsianWidth: ... +def is_normalized(form: _NormalizationForm, unistr: str, /) -> bool: ... +def lookup(name: str | ReadOnlyBuffer, /) -> str: ... +def mirrored(chr: str, /) -> int: ... @overload -def name(__chr: str) -> str: ... +def name(chr: str, /) -> str: ... @overload -def name(__chr: str, __default: _T) -> str | _T: ... -def normalize(__form: _NormalizationForm, __unistr: str) -> str: ... +def name(chr: str, default: _T, /) -> str | _T: ... +def normalize(form: _NormalizationForm, unistr: str, /) -> str: ... @overload -def numeric(__chr: str) -> float: ... +def numeric(chr: str, /) -> float: ... @overload -def numeric(__chr: str, __default: _T) -> float | _T: ... +def numeric(chr: str, default: _T, /) -> float | _T: ... @final class UCD: # The methods below are constructed from the same array in C # (unicodedata_functions) and hence identical to the functions above. unidata_version: str - def bidirectional(self, __chr: str) -> str: ... - def category(self, __chr: str) -> str: ... - def combining(self, __chr: str) -> int: ... + def bidirectional(self, chr: str, /) -> str: ... + def category(self, chr: str, /) -> str: ... + def combining(self, chr: str, /) -> int: ... @overload - def decimal(self, __chr: str) -> int: ... + def decimal(self, chr: str, /) -> int: ... @overload - def decimal(self, __chr: str, __default: _T) -> int | _T: ... - def decomposition(self, __chr: str) -> str: ... + def decimal(self, chr: str, default: _T, /) -> int | _T: ... + def decomposition(self, chr: str, /) -> str: ... @overload - def digit(self, __chr: str) -> int: ... + def digit(self, chr: str, /) -> int: ... @overload - def digit(self, __chr: str, __default: _T) -> int | _T: ... - def east_asian_width(self, __chr: str) -> _EastAsianWidth: ... - def is_normalized(self, __form: _NormalizationForm, __unistr: str) -> bool: ... - def lookup(self, __name: str | ReadOnlyBuffer) -> str: ... - def mirrored(self, __chr: str) -> int: ... + def digit(self, chr: str, default: _T, /) -> int | _T: ... + def east_asian_width(self, chr: str, /) -> _EastAsianWidth: ... + def is_normalized(self, form: _NormalizationForm, unistr: str, /) -> bool: ... + def lookup(self, name: str | ReadOnlyBuffer, /) -> str: ... + def mirrored(self, chr: str, /) -> int: ... @overload - def name(self, __chr: str) -> str: ... + def name(self, chr: str, /) -> str: ... @overload - def name(self, __chr: str, __default: _T) -> str | _T: ... - def normalize(self, __form: _NormalizationForm, __unistr: str) -> str: ... + def name(self, chr: str, default: _T, /) -> str | _T: ... + def normalize(self, form: _NormalizationForm, unistr: str, /) -> str: ... @overload - def numeric(self, __chr: str) -> float: ... + def numeric(self, chr: str, /) -> float: ... @overload - def numeric(self, __chr: str, __default: _T) -> float | _T: ... + def numeric(self, chr: str, default: _T, /) -> float | _T: ... diff --git a/mypy/typeshed/stdlib/unittest/async_case.pyi b/mypy/typeshed/stdlib/unittest/async_case.pyi index b71eec2e0644..12d6ef49e828 100644 --- a/mypy/typeshed/stdlib/unittest/async_case.pyi +++ b/mypy/typeshed/stdlib/unittest/async_case.pyi @@ -14,7 +14,7 @@ _P = ParamSpec("_P") class IsolatedAsyncioTestCase(TestCase): async def asyncSetUp(self) -> None: ... async def asyncTearDown(self) -> None: ... - def addAsyncCleanup(self, __func: Callable[_P, Awaitable[object]], *args: _P.args, **kwargs: _P.kwargs) -> None: ... + def addAsyncCleanup(self, func: Callable[_P, Awaitable[object]], /, *args: _P.args, **kwargs: _P.kwargs) -> None: ... if sys.version_info >= (3, 11): async def enterAsyncContext(self, cm: AbstractAsyncContextManager[_T]) -> _T: ... if sys.version_info >= (3, 9): diff --git a/mypy/typeshed/stdlib/unittest/case.pyi b/mypy/typeshed/stdlib/unittest/case.pyi index 120bb96d761b..bd1c064f0270 100644 --- a/mypy/typeshed/stdlib/unittest/case.pyi +++ b/mypy/typeshed/stdlib/unittest/case.pyi @@ -68,7 +68,7 @@ else: self, exc_type: type[BaseException] | None, exc_value: BaseException | None, tb: TracebackType | None ) -> bool | None: ... -def addModuleCleanup(__function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... +def addModuleCleanup(function: Callable[_P, object], /, *args: _P.args, **kwargs: _P.kwargs) -> None: ... def doModuleCleanups() -> None: ... if sys.version_info >= (3, 11): @@ -273,14 +273,14 @@ class TestCase: def defaultTestResult(self) -> unittest.result.TestResult: ... def id(self) -> str: ... def shortDescription(self) -> str | None: ... - 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: ... @classmethod - def addClassCleanup(cls, __function: Callable[_P, object], *args: _P.args, **kwargs: _P.kwargs) -> None: ... + def addClassCleanup(cls, function: Callable[_P, object], /, *args: _P.args, **kwargs: _P.kwargs) -> None: ... @classmethod def doClassCleanups(cls) -> None: ... diff --git a/mypy/typeshed/stdlib/unittest/main.pyi b/mypy/typeshed/stdlib/unittest/main.pyi index 3e8cb7b764c2..55bc1ec741db 100644 --- a/mypy/typeshed/stdlib/unittest/main.pyi +++ b/mypy/typeshed/stdlib/unittest/main.pyi @@ -11,7 +11,7 @@ MAIN_EXAMPLES: str MODULE_EXAMPLES: str class _TestRunner(Protocol): - def run(self, __test: unittest.suite.TestSuite | unittest.case.TestCase) -> unittest.result.TestResult: ... + def run(self, test: unittest.suite.TestSuite | unittest.case.TestCase, /) -> unittest.result.TestResult: ... # not really documented class TestProgram: diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index c6014d4bb886..6e64e7a85560 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -65,7 +65,7 @@ class _Call(tuple[Any, ...]): from_kall: bool = True, ) -> None: ... def __eq__(self, other: object) -> bool: ... - def __ne__(self, __value: object) -> bool: ... + def __ne__(self, value: object, /) -> bool: ... def __call__(self, *args: Any, **kwargs: Any) -> _Call: ... def __getattr__(self, attr: str) -> Any: ... def __getattribute__(self, attr: str) -> Any: ... @@ -103,7 +103,7 @@ class NonCallableMock(Base, Any): **kwargs: Any, ) -> Self: ... else: - def __new__(__cls, *args: Any, **kw: Any) -> Self: ... + def __new__(cls, /, *args: Any, **kw: Any) -> Self: ... def __init__( self, @@ -234,7 +234,7 @@ class _patch(Generic[_T]): is_local: bool def __enter__(self) -> _T: ... def __exit__( - self, __exc_type: type[BaseException] | None, __exc_value: BaseException | None, __traceback: TracebackType | None + self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / ) -> None: ... def start(self) -> _T: ... def stop(self) -> None: ... diff --git a/mypy/typeshed/stdlib/urllib/request.pyi b/mypy/typeshed/stdlib/urllib/request.pyi index ca3feaea262a..3442be8b8ea4 100644 --- a/mypy/typeshed/stdlib/urllib/request.pyi +++ b/mypy/typeshed/stdlib/urllib/request.pyi @@ -227,7 +227,8 @@ class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): class _HTTPConnectionProtocol(Protocol): def __call__( self, - __host: str, + host: str, + /, *, port: int | None = ..., timeout: float = ..., diff --git a/mypy/typeshed/stdlib/weakref.pyi b/mypy/typeshed/stdlib/weakref.pyi index 1bb2eacfb46a..8f3ad0631c10 100644 --- a/mypy/typeshed/stdlib/weakref.pyi +++ b/mypy/typeshed/stdlib/weakref.pyi @@ -51,10 +51,10 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): @overload def __init__(self) -> None: ... @overload - def __init__(self: WeakValueDictionary[_KT, _VT], __other: Mapping[_KT, _VT] | Iterable[tuple[_KT, _VT]]) -> None: ... + def __init__(self: WeakValueDictionary[_KT, _VT], other: Mapping[_KT, _VT] | Iterable[tuple[_KT, _VT]], /) -> None: ... @overload def __init__( - self: WeakValueDictionary[str, _VT], __other: Mapping[str, _VT] | Iterable[tuple[str, _VT]] = (), **kwargs: _VT + self: WeakValueDictionary[str, _VT], other: Mapping[str, _VT] | Iterable[tuple[str, _VT]] = (), /, **kwargs: _VT ) -> None: ... def __len__(self) -> int: ... def __getitem__(self, key: _KT) -> _VT: ... @@ -93,7 +93,6 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): class KeyedRef(ref[_T], Generic[_KT, _T]): key: _KT - # This __new__ method uses a non-standard name for the "cls" parameter def __new__(type, ob: _T, callback: Callable[[_T], Any], key: _KT) -> Self: ... def __init__(self, ob: _T, callback: Callable[[_T], Any], key: _KT) -> None: ... @@ -141,7 +140,7 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]): def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ... class finalize: # TODO: This is a good candidate for to be a `Generic[_P, _T]` class - def __init__(self, __obj: object, __func: Callable[_P, Any], *args: _P.args, **kwargs: _P.kwargs) -> None: ... + def __init__(self, obj: object, func: Callable[_P, Any], /, *args: _P.args, **kwargs: _P.kwargs) -> None: ... def __call__(self, _: Any = None) -> Any | None: ... def detach(self) -> tuple[Any, Any, tuple[Any, ...], dict[str, Any]] | None: ... def peek(self) -> tuple[Any, Any, tuple[Any, ...], dict[str, Any]] | None: ... diff --git a/mypy/typeshed/stdlib/winreg.pyi b/mypy/typeshed/stdlib/winreg.pyi index 897177547c71..ffb0a4cb8094 100644 --- a/mypy/typeshed/stdlib/winreg.pyi +++ b/mypy/typeshed/stdlib/winreg.pyi @@ -5,31 +5,31 @@ from typing_extensions import Self, TypeAlias if sys.platform == "win32": _KeyType: TypeAlias = HKEYType | int - def CloseKey(__hkey: _KeyType) -> None: ... - def ConnectRegistry(__computer_name: str | None, __key: _KeyType) -> HKEYType: ... - def CreateKey(__key: _KeyType, __sub_key: str | None) -> HKEYType: ... + def CloseKey(hkey: _KeyType, /) -> None: ... + def ConnectRegistry(computer_name: str | None, key: _KeyType, /) -> HKEYType: ... + def CreateKey(key: _KeyType, sub_key: str | None, /) -> HKEYType: ... def CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = 0, access: int = 131078) -> HKEYType: ... - def DeleteKey(__key: _KeyType, __sub_key: str) -> None: ... + def DeleteKey(key: _KeyType, sub_key: str, /) -> None: ... def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = 256, reserved: int = 0) -> None: ... - def DeleteValue(__key: _KeyType, __value: str) -> None: ... - def EnumKey(__key: _KeyType, __index: int) -> str: ... - def EnumValue(__key: _KeyType, __index: int) -> tuple[str, Any, int]: ... - def ExpandEnvironmentStrings(__string: str) -> str: ... - def FlushKey(__key: _KeyType) -> None: ... - def LoadKey(__key: _KeyType, __sub_key: str, __file_name: str) -> None: ... + def DeleteValue(key: _KeyType, value: str, /) -> None: ... + def EnumKey(key: _KeyType, index: int, /) -> str: ... + def EnumValue(key: _KeyType, index: int, /) -> tuple[str, Any, int]: ... + def ExpandEnvironmentStrings(string: str, /) -> str: ... + def FlushKey(key: _KeyType, /) -> None: ... + def LoadKey(key: _KeyType, sub_key: str, file_name: str, /) -> None: ... def OpenKey(key: _KeyType, sub_key: str, reserved: int = 0, access: int = 131097) -> HKEYType: ... def OpenKeyEx(key: _KeyType, sub_key: str, reserved: int = 0, access: int = 131097) -> HKEYType: ... - def QueryInfoKey(__key: _KeyType) -> tuple[int, int, int]: ... - def QueryValue(__key: _KeyType, __sub_key: str | None) -> str: ... - def QueryValueEx(__key: _KeyType, __name: str) -> tuple[Any, int]: ... - def SaveKey(__key: _KeyType, __file_name: str) -> None: ... - def SetValue(__key: _KeyType, __sub_key: str, __type: int, __value: str) -> None: ... + def QueryInfoKey(key: _KeyType, /) -> tuple[int, int, int]: ... + def QueryValue(key: _KeyType, sub_key: str | None, /) -> str: ... + def QueryValueEx(key: _KeyType, name: str, /) -> tuple[Any, int]: ... + def SaveKey(key: _KeyType, file_name: str, /) -> None: ... + def SetValue(key: _KeyType, sub_key: str, type: int, value: str, /) -> None: ... def SetValueEx( - __key: _KeyType, __value_name: str | None, __reserved: Any, __type: int, __value: str | int + key: _KeyType, value_name: str | None, reserved: Any, type: int, value: str | int, / ) -> None: ... # reserved is ignored - def DisableReflectionKey(__key: _KeyType) -> None: ... - def EnableReflectionKey(__key: _KeyType) -> None: ... - def QueryReflectionKey(__key: _KeyType) -> bool: ... + def DisableReflectionKey(key: _KeyType, /) -> None: ... + def EnableReflectionKey(key: _KeyType, /) -> None: ... + def QueryReflectionKey(key: _KeyType, /) -> bool: ... HKEY_CLASSES_ROOT: int HKEY_CURRENT_USER: int HKEY_LOCAL_MACHINE: int diff --git a/mypy/typeshed/stdlib/wsgiref/types.pyi b/mypy/typeshed/stdlib/wsgiref/types.pyi index 4e8f47264f3a..86212df8ccdc 100644 --- a/mypy/typeshed/stdlib/wsgiref/types.pyi +++ b/mypy/typeshed/stdlib/wsgiref/types.pyi @@ -7,26 +7,26 @@ __all__ = ["StartResponse", "WSGIEnvironment", "WSGIApplication", "InputStream", class StartResponse(Protocol): def __call__( - self, __status: str, __headers: list[tuple[str, str]], __exc_info: _OptExcInfo | None = ... + self, status: str, headers: list[tuple[str, str]], exc_info: _OptExcInfo | None = ..., / ) -> Callable[[bytes], object]: ... WSGIEnvironment: TypeAlias = dict[str, Any] WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] class InputStream(Protocol): - def read(self, __size: int = ...) -> bytes: ... - def readline(self, __size: int = ...) -> bytes: ... - def readlines(self, __hint: int = ...) -> list[bytes]: ... + def read(self, size: int = ..., /) -> bytes: ... + def readline(self, size: int = ..., /) -> bytes: ... + def readlines(self, hint: int = ..., /) -> list[bytes]: ... def __iter__(self) -> Iterator[bytes]: ... class ErrorStream(Protocol): def flush(self) -> object: ... - def write(self, __s: str) -> object: ... - def writelines(self, __seq: list[str]) -> object: ... + def write(self, s: str, /) -> object: ... + def writelines(self, seq: list[str], /) -> object: ... class _Readable(Protocol): - def read(self, __size: int = ...) -> bytes: ... + def read(self, size: int = ..., /) -> bytes: ... # Optional: def close(self) -> object: ... class FileWrapper(Protocol): - def __call__(self, __file: _Readable, __block_size: int = ...) -> Iterable[bytes]: ... + def __call__(self, file: _Readable, block_size: int = ..., /) -> Iterable[bytes]: ... diff --git a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi index 2a363a504dec..a8af66938344 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi @@ -84,9 +84,9 @@ class Element: text: str | None tail: str | None def __init__(self, tag: str, attrib: dict[str, str] = ..., **extra: str) -> None: ... - def append(self, __subelement: Element) -> None: ... + def append(self, subelement: Element, /) -> None: ... def clear(self) -> None: ... - def extend(self, __elements: Iterable[Element]) -> None: ... + def extend(self, elements: Iterable[Element], /) -> None: ... def find(self, path: str, namespaces: dict[str, str] | None = None) -> Element | None: ... def findall(self, path: str, namespaces: dict[str, str] | None = None) -> list[Element]: ... @overload @@ -97,30 +97,30 @@ class Element: def get(self, key: str, default: None = None) -> str | None: ... @overload def get(self, key: str, default: _T) -> str | _T: ... - def insert(self, __index: int, __subelement: Element) -> None: ... + def insert(self, index: int, subelement: Element, /) -> None: ... def items(self) -> ItemsView[str, str]: ... def iter(self, tag: str | None = None) -> Generator[Element, None, None]: ... def iterfind(self, path: str, namespaces: dict[str, str] | None = None) -> Generator[Element, None, None]: ... def itertext(self) -> Generator[str, None, None]: ... def keys(self) -> dict_keys[str, str]: ... # makeelement returns the type of self in Python impl, but not in C impl - def makeelement(self, __tag: str, __attrib: dict[str, str]) -> Element: ... - def remove(self, __subelement: Element) -> None: ... - def set(self, __key: str, __value: str) -> None: ... + def makeelement(self, tag: str, attrib: dict[str, str], /) -> Element: ... + def remove(self, subelement: Element, /) -> None: ... + def set(self, key: str, value: str, /) -> None: ... def __copy__(self) -> Element: ... # returns the type of self in Python impl, but not in C impl - def __deepcopy__(self, __memo: Any) -> Element: ... # Only exists in C impl - def __delitem__(self, __key: SupportsIndex | slice) -> None: ... + def __deepcopy__(self, memo: Any, /) -> Element: ... # Only exists in C impl + def __delitem__(self, key: SupportsIndex | slice, /) -> None: ... @overload - def __getitem__(self, __key: SupportsIndex) -> Element: ... + def __getitem__(self, key: SupportsIndex, /) -> Element: ... @overload - def __getitem__(self, __key: slice) -> list[Element]: ... + def __getitem__(self, key: slice, /) -> list[Element]: ... def __len__(self) -> int: ... # Doesn't actually exist at runtime, but instance of the class are indeed iterable due to __getitem__. def __iter__(self) -> Iterator[Element]: ... @overload - def __setitem__(self, __key: SupportsIndex, __value: Element) -> None: ... + def __setitem__(self, key: SupportsIndex, value: Element, /) -> None: ... @overload - def __setitem__(self, __key: slice, __value: Iterable[Element]) -> None: ... + def __setitem__(self, key: slice, value: Iterable[Element], /) -> None: ... # Doesn't really exist in earlier versions, where __len__ is called implicitly instead @deprecated("Testing an element's truth value is deprecated.") @@ -285,14 +285,14 @@ class TreeBuilder: insert_pis: bool def close(self) -> Element: ... - def data(self, __data: str) -> None: ... + def data(self, data: str, /) -> None: ... # tag and attrs are passed to the element_factory, so they could be anything # depending on what the particular factory supports. - def start(self, __tag: Any, __attrs: dict[Any, Any]) -> Element: ... - def end(self, __tag: str) -> Element: ... + def start(self, tag: Any, attrs: dict[Any, Any], /) -> Element: ... + def end(self, tag: str, /) -> 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: ... + def comment(self, text: str | None, /) -> Element: ... + def pi(self, target: str, text: str | None = None, /) -> Element: ... class C14NWriterTarget: def __init__( @@ -322,4 +322,4 @@ class XMLParser: version: str def __init__(self, *, target: Any = ..., encoding: str | None = ...) -> None: ... def close(self) -> Any: ... - def feed(self, __data: str | ReadableBuffer) -> None: ... + def feed(self, data: str | ReadableBuffer, /) -> None: ... diff --git a/mypy/typeshed/stdlib/xmlrpc/server.pyi b/mypy/typeshed/stdlib/xmlrpc/server.pyi index 832fe265e0a5..8ca3a4d1a33c 100644 --- a/mypy/typeshed/stdlib/xmlrpc/server.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/server.pyi @@ -12,17 +12,17 @@ class _DispatchArity0(Protocol): def __call__(self) -> _Marshallable: ... class _DispatchArity1(Protocol): - def __call__(self, __arg1: _Marshallable) -> _Marshallable: ... + def __call__(self, arg1: _Marshallable, /) -> _Marshallable: ... class _DispatchArity2(Protocol): - def __call__(self, __arg1: _Marshallable, __arg2: _Marshallable) -> _Marshallable: ... + def __call__(self, arg1: _Marshallable, arg2: _Marshallable, /) -> _Marshallable: ... class _DispatchArity3(Protocol): - def __call__(self, __arg1: _Marshallable, __arg2: _Marshallable, __arg3: _Marshallable) -> _Marshallable: ... + def __call__(self, arg1: _Marshallable, arg2: _Marshallable, arg3: _Marshallable, /) -> _Marshallable: ... class _DispatchArity4(Protocol): def __call__( - self, __arg1: _Marshallable, __arg2: _Marshallable, __arg3: _Marshallable, __arg4: _Marshallable + self, arg1: _Marshallable, arg2: _Marshallable, arg3: _Marshallable, arg4: _Marshallable, / ) -> _Marshallable: ... class _DispatchArityN(Protocol): diff --git a/mypy/typeshed/stdlib/xxlimited.pyi b/mypy/typeshed/stdlib/xxlimited.pyi index 3e6e78de3f70..6bae87a8db2a 100644 --- a/mypy/typeshed/stdlib/xxlimited.pyi +++ b/mypy/typeshed/stdlib/xxlimited.pyi @@ -9,7 +9,7 @@ class Xxo: if sys.version_info >= (3, 11) and sys.platform != "win32": x_exports: int -def foo(__i: int, __j: int) -> Any: ... +def foo(i: int, j: int, /) -> Any: ... def new() -> Xxo: ... if sys.version_info >= (3, 10): @@ -19,4 +19,4 @@ else: class error(Exception): ... class Null: ... - def roj(__b: Any) -> None: ... + def roj(b: Any, /) -> None: ... diff --git a/mypy/typeshed/stdlib/zipfile/__init__.pyi b/mypy/typeshed/stdlib/zipfile/__init__.pyi index be0cdf12a4a9..b61e07f8b90d 100644 --- a/mypy/typeshed/stdlib/zipfile/__init__.pyi +++ b/mypy/typeshed/stdlib/zipfile/__init__.pyi @@ -40,16 +40,16 @@ error = BadZipfile class LargeZipFile(Exception): ... class _ZipStream(Protocol): - def read(self, __n: int) -> bytes: ... + def read(self, n: int, /) -> bytes: ... # The following methods are optional: # def seekable(self) -> bool: ... # def tell(self) -> int: ... - # def seek(self, __n: int) -> object: ... + # def seek(self, n: int, /) -> object: ... # Stream shape as required by _EndRecData() and _EndRecData64(). class _SupportsReadSeekTell(Protocol): - def read(self, __n: int = ...) -> bytes: ... - def seek(self, __cookie: int, __whence: int) -> object: ... + def read(self, n: int = ..., /) -> bytes: ... + def seek(self, cookie: int, whence: int, /) -> object: ... def tell(self) -> int: ... class _ClosableZipStream(_ZipStream, Protocol): @@ -92,7 +92,7 @@ class ZipExtFile(io.BufferedIOBase): def seek(self, offset: int, whence: int = 0) -> int: ... class _Writer(Protocol): - def write(self, __s: str) -> object: ... + def write(self, s: str, /) -> object: ... class ZipFile: filename: str | None diff --git a/mypy/typeshed/stdlib/zlib.pyi b/mypy/typeshed/stdlib/zlib.pyi index efeb5a88a76f..234770172d40 100644 --- a/mypy/typeshed/stdlib/zlib.pyi +++ b/mypy/typeshed/stdlib/zlib.pyi @@ -40,17 +40,17 @@ class _Decompress: def flush(self, length: int = ...) -> bytes: ... def copy(self) -> _Decompress: ... -def adler32(__data: ReadableBuffer, __value: int = 1) -> int: ... +def adler32(data: ReadableBuffer, value: int = 1, /) -> int: ... if sys.version_info >= (3, 11): - def compress(__data: ReadableBuffer, level: int = -1, wbits: int = 15) -> bytes: ... + def compress(data: ReadableBuffer, /, level: int = -1, wbits: int = 15) -> bytes: ... else: - def compress(__data: ReadableBuffer, level: int = -1) -> bytes: ... + def compress(data: ReadableBuffer, /, level: int = -1) -> bytes: ... def compressobj( level: int = -1, method: int = 8, wbits: int = 15, memLevel: int = 8, strategy: int = 0, zdict: ReadableBuffer | None = None ) -> _Compress: ... -def crc32(__data: ReadableBuffer, __value: int = 0) -> int: ... -def decompress(__data: ReadableBuffer, wbits: int = 15, bufsize: int = 16384) -> bytes: ... +def crc32(data: ReadableBuffer, value: int = 0, /) -> int: ... +def decompress(data: ReadableBuffer, /, wbits: int = 15, bufsize: int = 16384) -> bytes: ... def decompressobj(wbits: int = 15, zdict: ReadableBuffer = b"") -> _Decompress: ... diff --git a/mypy/typeshed/stdlib/zoneinfo/__init__.pyi b/mypy/typeshed/stdlib/zoneinfo/__init__.pyi index a95530ed461a..77930ac79dd5 100644 --- a/mypy/typeshed/stdlib/zoneinfo/__init__.pyi +++ b/mypy/typeshed/stdlib/zoneinfo/__init__.pyi @@ -7,8 +7,8 @@ from typing_extensions import Self __all__ = ["ZoneInfo", "reset_tzpath", "available_timezones", "TZPATH", "ZoneInfoNotFoundError", "InvalidTZPathWarning"] class _IOBytes(Protocol): - def read(self, __size: int) -> bytes: ... - def seek(self, __size: int, __whence: int = ...) -> Any: ... + def read(self, size: int, /) -> bytes: ... + def seek(self, size: int, whence: int = ..., /) -> Any: ... class ZoneInfo(tzinfo): @property @@ -17,12 +17,12 @@ class ZoneInfo(tzinfo): @classmethod def no_cache(cls, key: str) -> Self: ... @classmethod - def from_file(cls, __fobj: _IOBytes, key: str | None = None) -> Self: ... + def from_file(cls, fobj: _IOBytes, /, key: str | None = None) -> Self: ... @classmethod def clear_cache(cls, *, only_keys: Iterable[str] | None = None) -> None: ... - def tzname(self, __dt: datetime | None) -> str | None: ... - def utcoffset(self, __dt: datetime | None) -> timedelta | None: ... - def dst(self, __dt: datetime | None) -> timedelta | None: ... + def tzname(self, dt: datetime | None, /) -> str | None: ... + def utcoffset(self, dt: datetime | None, /) -> timedelta | None: ... + def dst(self, dt: datetime | None, /) -> timedelta | None: ... # Note: Both here and in clear_cache, the types allow the use of `str` where # a sequence of strings is required. This should be remedied if a solution From 5c00e362d40aa26e0a22a740f05a52d05edf0f91 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 126/172] Remove use of LiteralString in builtins (#13743) --- mypy/typeshed/stdlib/builtins.pyi | 88 ------------------------------- 1 file changed, 88 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index b4765b26c8e5..99919c64c50d 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, @@ -434,31 +433,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, sub: 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: ... @@ -474,89 +458,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 @@ -567,9 +494,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] @@ -578,25 +502,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 44bc98bd50e7170887f0740b53ed95a8eb04f00e 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 127/172] 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 99919c64c50d..680cd556172f 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1596,7 +1596,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 61a490091d7c941780919660dc4fdfa88ae6474a Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Mon, 1 May 2023 20:34:55 +0100 Subject: [PATCH 128/172] 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 60bbc51d9411..cf9cb81a44a3 100644 --- a/mypy/typeshed/stdlib/_ctypes.pyi +++ b/mypy/typeshed/stdlib/_ctypes.pyi @@ -169,11 +169,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 b013cc016a3e3c8c7caa6a27bdf7b5e22998dd41 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sat, 16 Mar 2024 14:38:05 +0100 Subject: [PATCH 129/172] Support `TypeAliasType` in a class scope (#17038) Fixes https://github.com/python/mypy/issues/16614#issuecomment-2000428700 --- mypy/semanal.py | 2 +- test-data/unit/check-type-aliases.test | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 93e84ced4639..5aaf2bc6f433 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -3657,7 +3657,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: return False non_global_scope = self.type or self.is_func_scope() - if not pep_613 and isinstance(rvalue, RefExpr) and non_global_scope: + if not pep_613 and not pep_695 and isinstance(rvalue, RefExpr) and non_global_scope: # Fourth rule (special case): Non-subscripted right hand side creates a variable # at class and function scopes. For example: # diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 79a443dbeedc..7330a04c3647 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1074,6 +1074,11 @@ TestType = TypeAliasType("TestType", Union[int, str]) x: TestType = 42 y: TestType = 'a' z: TestType = object() # E: Incompatible types in assignment (expression has type "object", variable has type "Union[int, str]") + +class A: + ClassAlias = TypeAliasType("ClassAlias", int) +xc: A.ClassAlias = 1 +yc: A.ClassAlias = "" # E: Incompatible types in assignment (expression has type "str", variable has type "int") [builtins fixtures/tuple.pyi] [case testTypeAliasTypeInvalid] From 00220bd095f42b080e0844bb2b0c11f37afc35a5 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Sat, 16 Mar 2024 15:39:13 +0000 Subject: [PATCH 130/172] Update commit hashes in sync-typeshed.py (#17042) Followup to #17039 --- misc/sync-typeshed.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/misc/sync-typeshed.py b/misc/sync-typeshed.py index 56bc1624d5d0..2dc6e230df00 100644 --- a/misc/sync-typeshed.py +++ b/misc/sync-typeshed.py @@ -179,9 +179,9 @@ def main() -> None: print("Created typeshed sync commit.") commits_to_cherry_pick = [ - "d25e4a9eb", # LiteralString reverts - "d132999ba", # sum reverts - "dd12a2d81", # ctypes reverts + "5c00e362d", # LiteralString reverts + "44bc98bd5", # sum reverts + "61a490091", # ctypes reverts ] for commit in commits_to_cherry_pick: try: From 7d0a8e79dfa3219135baf4d227ab4975aef710b7 Mon Sep 17 00:00:00 2001 From: Roman Solomatin <36135455+Samoed@users.noreply.github.com> Date: Mon, 18 Mar 2024 21:19:27 +0300 Subject: [PATCH 131/172] Update running_mypy.rst add closing bracket (#17046) --- docs/source/running_mypy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/running_mypy.rst b/docs/source/running_mypy.rst index 25b34b247b4b..42474ae94c48 100644 --- a/docs/source/running_mypy.rst +++ b/docs/source/running_mypy.rst @@ -405,7 +405,7 @@ this error, try: For example, suppose you are trying to add the module ``foo.bar.baz`` which is located at ``~/foo-project/src/foo/bar/baz.py``. In this case, you must run ``mypy ~/foo-project/src`` (or set the ``MYPYPATH`` to - ``~/foo-project/src``. + ``~/foo-project/src``). .. _finding-imports: From afdd9d5b2bb8a9ed9819571b266903396f47c5d9 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Tue, 19 Mar 2024 17:08:51 +0000 Subject: [PATCH 132/172] [mypyc] Implement lowering for remaining tagged integer comparisons (#17040) Support lowering of tagged integer `<`, `<=`, `>` and `>=` operations. Previously we had separate code paths for integer comparisons in values vs conditions. Unify these and remove the duplicate code path. The different code paths produced subtly different code, but now they are identical. The generated code is now sometimes slightly more verbose in the slow path (big integer). I may look into simplifying it in a follow-up PR. This also makes the output of many irbuild test cases significantly more compact. Follow-up to #17027. Work on mypyc/mypyc#854. --- mypyc/ir/pprint.py | 2 +- mypyc/irbuild/ast_helpers.py | 9 +- mypyc/irbuild/builder.py | 3 - mypyc/irbuild/expression.py | 6 - mypyc/irbuild/function.py | 5 +- mypyc/irbuild/ll_builder.py | 94 +---- mypyc/lower/int_ops.py | 20 + mypyc/primitives/int_ops.py | 4 + mypyc/test-data/analysis.test | 205 +++------ mypyc/test-data/exceptions.test | 58 +-- mypyc/test-data/irbuild-basic.test | 435 +++++--------------- mypyc/test-data/irbuild-bool.test | 56 +-- mypyc/test-data/irbuild-dunders.test | 20 +- mypyc/test-data/irbuild-int.test | 51 +-- mypyc/test-data/irbuild-lists.test | 13 +- mypyc/test-data/irbuild-set.test | 126 +++--- mypyc/test-data/irbuild-singledispatch.test | 2 +- mypyc/test-data/irbuild-statements.test | 140 ++----- mypyc/test-data/irbuild-tuple.test | 8 +- mypyc/test-data/lowering-int.test | 273 +++++++++++- mypyc/test-data/refcount.test | 60 +-- 21 files changed, 622 insertions(+), 968 deletions(-) diff --git a/mypyc/ir/pprint.py b/mypyc/ir/pprint.py index 8d6723917ea0..2ca6a47921fc 100644 --- a/mypyc/ir/pprint.py +++ b/mypyc/ir/pprint.py @@ -232,7 +232,7 @@ def visit_primitive_op(self, op: PrimitiveOp) -> str: type_arg_index += 1 args_str = ", ".join(args) - return self.format("%r = %s %s ", op, op.desc.name, args_str) + return self.format("%r = %s %s", op, op.desc.name, args_str) def visit_truncate(self, op: Truncate) -> str: return self.format("%r = truncate %r: %t to %t", op, op.src, op.src_type, op.type) diff --git a/mypyc/irbuild/ast_helpers.py b/mypyc/irbuild/ast_helpers.py index 8490eaa03477..bc976647675d 100644 --- a/mypyc/irbuild/ast_helpers.py +++ b/mypyc/irbuild/ast_helpers.py @@ -93,12 +93,9 @@ def maybe_process_conditional_comparison( self.add_bool_branch(reg, true, false) else: # "left op right" for two tagged integers - if op in ("==", "!="): - reg = self.builder.binary_op(left, right, op, e.line) - self.flush_keep_alives() - self.add_bool_branch(reg, true, false) - else: - self.builder.compare_tagged_condition(left, right, op, true, false, e.line) + reg = self.builder.binary_op(left, right, op, e.line) + self.flush_keep_alives() + self.add_bool_branch(reg, true, false) return True diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 52891d68e3b2..cca771e82c83 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -378,9 +378,6 @@ def call_c(self, desc: CFunctionDescription, args: list[Value], line: int) -> Va def int_op(self, type: RType, lhs: Value, rhs: Value, op: int, line: int) -> Value: return self.builder.int_op(type, lhs, rhs, op, line) - def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: - return self.builder.compare_tagged(lhs, rhs, op, line) - def compare_tuples(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: return self.builder.compare_tuples(lhs, rhs, op, line) diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index 021b7a1dbe90..ba62d71d0ad3 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -814,12 +814,6 @@ def translate_is_none(builder: IRBuilder, expr: Expression, negated: bool) -> Va def transform_basic_comparison( builder: IRBuilder, op: str, left: Value, right: Value, line: int ) -> Value: - if ( - is_int_rprimitive(left.type) - and is_int_rprimitive(right.type) - and op in int_comparison_op_mapping - ): - return builder.compare_tagged(left, right, op, line) if is_fixed_width_rtype(left.type) and op in int_comparison_op_mapping: if right.type == left.type: if left.type.is_signed: diff --git a/mypyc/irbuild/function.py b/mypyc/irbuild/function.py index b1785f40550e..c985e88b0e0c 100644 --- a/mypyc/irbuild/function.py +++ b/mypyc/irbuild/function.py @@ -889,9 +889,8 @@ def gen_native_func_call_and_return(fdef: FuncDef) -> None: call_impl, next_impl = BasicBlock(), BasicBlock() current_id = builder.load_int(i) - builder.builder.compare_tagged_condition( - passed_id, current_id, "==", call_impl, next_impl, line - ) + cond = builder.binary_op(passed_id, current_id, "==", line) + builder.add_bool_branch(cond, call_impl, next_impl) # Call the registered implementation builder.activate_block(call_impl) diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index f9bacb43bc3e..548b391030fe 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -1315,13 +1315,6 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: return self.compare_strings(lreg, rreg, op, line) if is_bytes_rprimitive(ltype) and is_bytes_rprimitive(rtype) and op in ("==", "!="): return self.compare_bytes(lreg, rreg, op, line) - if ( - is_tagged(ltype) - and is_tagged(rtype) - and op in int_comparison_op_mapping - and op not in ("==", "!=") - ): - return self.compare_tagged(lreg, rreg, op, line) if is_bool_rprimitive(ltype) and is_bool_rprimitive(rtype) and op in BOOL_BINARY_OPS: if op in ComparisonOp.signed_ops: return self.bool_comparison_op(lreg, rreg, op, line) @@ -1384,16 +1377,6 @@ def binary_op(self, lreg: Value, rreg: Value, op: str, line: int) -> Value: if is_fixed_width_rtype(lreg.type): return self.comparison_op(lreg, rreg, op_id, line) - # Mixed int comparisons - if op in ("==", "!="): - pass # TODO: Do we need anything here? - elif op in op in int_comparison_op_mapping: - if is_tagged(ltype) and is_subtype(rtype, ltype): - rreg = self.coerce(rreg, short_int_rprimitive, line) - return self.compare_tagged(lreg, rreg, op, line) - if is_tagged(rtype) and is_subtype(ltype, rtype): - lreg = self.coerce(lreg, short_int_rprimitive, line) - return self.compare_tagged(lreg, rreg, op, line) if is_float_rprimitive(ltype) or is_float_rprimitive(rtype): if isinstance(lreg, Integer): lreg = Float(float(lreg.numeric_value())) @@ -1445,18 +1428,16 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] result = Register(bool_rprimitive) short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock() - check_lhs = self.check_tagged_short_int(lhs, line) + check_lhs = self.check_tagged_short_int(lhs, line, negated=True) if op in ("==", "!="): - check = check_lhs + self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) else: # for non-equality logical ops (less/greater than, etc.), need to check both sides - check_rhs = self.check_tagged_short_int(rhs, line) - check = self.int_op(bit_rprimitive, check_lhs, check_rhs, IntOp.AND, line) - self.add(Branch(check, short_int_block, int_block, Branch.BOOL)) - self.activate_block(short_int_block) - eq = self.comparison_op(lhs, rhs, op_type, line) - self.add(Assign(result, eq, line)) - self.goto(out) + short_lhs = BasicBlock() + self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL)) + self.activate_block(short_lhs) + check_rhs = self.check_tagged_short_int(rhs, line, negated=True) + self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) self.activate_block(int_block) if swap_op: args = [rhs, lhs] @@ -1469,62 +1450,12 @@ def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: else: call_result = call self.add(Assign(result, call_result, line)) - self.goto_and_activate(out) - return result - - def compare_tagged_condition( - self, lhs: Value, rhs: Value, op: str, true: BasicBlock, false: BasicBlock, line: int - ) -> None: - """Compare two tagged integers using given operator (conditional context). - - Assume lhs and rhs are tagged integers. - - Args: - lhs: Left operand - rhs: Right operand - op: Operation, one of '==', '!=', '<', '<=', '>', '<=' - true: Branch target if comparison is true - false: Branch target if comparison is false - """ - is_eq = op in ("==", "!=") - if (is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type)) or ( - is_eq and (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) - ): - # We can skip the tag check - check = self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line) - self.flush_keep_alives() - self.add(Branch(check, true, false, Branch.BOOL)) - return - op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] - int_block, short_int_block = BasicBlock(), BasicBlock() - check_lhs = self.check_tagged_short_int(lhs, line, negated=True) - if is_eq or is_short_int_rprimitive(rhs.type): - self.flush_keep_alives() - self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) - else: - # For non-equality logical ops (less/greater than, etc.), need to check both sides - rhs_block = BasicBlock() - self.add(Branch(check_lhs, int_block, rhs_block, Branch.BOOL)) - self.activate_block(rhs_block) - check_rhs = self.check_tagged_short_int(rhs, line, negated=True) - self.flush_keep_alives() - self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) - # Arbitrary integers (slow path) - self.activate_block(int_block) - if swap_op: - args = [rhs, lhs] - else: - args = [lhs, rhs] - call = self.call_c(c_func_desc, args, line) - if negate_result: - self.add(Branch(call, false, true, Branch.BOOL)) - else: - self.flush_keep_alives() - self.add(Branch(call, true, false, Branch.BOOL)) - # Short integers (fast path) + self.goto(out) self.activate_block(short_int_block) eq = self.comparison_op(lhs, rhs, op_type, line) - self.add(Branch(eq, true, false, Branch.BOOL)) + self.add(Assign(result, eq, line)) + self.goto_and_activate(out) + return result def compare_strings(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: """Compare two strings""" @@ -2309,7 +2240,8 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val length = self.gen_method_call(val, "__len__", [], int_rprimitive, line) length = self.coerce(length, int_rprimitive, line) ok, fail = BasicBlock(), BasicBlock() - self.compare_tagged_condition(length, Integer(0), ">=", ok, fail, line) + cond = self.binary_op(length, Integer(0), ">=", line) + self.add_bool_branch(cond, ok, fail) self.activate_block(fail) self.add( RaiseStandardError( diff --git a/mypyc/lower/int_ops.py b/mypyc/lower/int_ops.py index 40fba7af4f4d..5255a64b647d 100644 --- a/mypyc/lower/int_ops.py +++ b/mypyc/lower/int_ops.py @@ -13,3 +13,23 @@ def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Va @lower_binary_op("int_ne") def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return builder.compare_tagged(args[0], args[1], "!=", line) + + +@lower_binary_op("int_lt") +def lower_int_lt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "<", line) + + +@lower_binary_op("int_le") +def lower_int_le(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], "<=", line) + + +@lower_binary_op("int_gt") +def lower_int_gt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], ">", line) + + +@lower_binary_op("int_ge") +def lower_int_ge(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + return builder.compare_tagged(args[0], args[1], ">=", line) diff --git a/mypyc/primitives/int_ops.py b/mypyc/primitives/int_ops.py index 4103fe349a74..029d71606886 100644 --- a/mypyc/primitives/int_ops.py +++ b/mypyc/primitives/int_ops.py @@ -122,6 +122,10 @@ def int_binary_primitive( int_eq = int_binary_primitive(op="==", primitive_name="int_eq", return_type=bit_rprimitive) int_ne = int_binary_primitive(op="!=", primitive_name="int_ne", return_type=bit_rprimitive) +int_lt = int_binary_primitive(op="<", primitive_name="int_lt", return_type=bit_rprimitive) +int_le = int_binary_primitive(op="<=", primitive_name="int_le", return_type=bit_rprimitive) +int_gt = int_binary_primitive(op=">", primitive_name="int_gt", return_type=bit_rprimitive) +int_ge = int_binary_primitive(op=">=", primitive_name="int_ge", return_type=bit_rprimitive) def int_binary_op( diff --git a/mypyc/test-data/analysis.test b/mypyc/test-data/analysis.test index 8e067aed4d79..35677b8ea56d 100644 --- a/mypyc/test-data/analysis.test +++ b/mypyc/test-data/analysis.test @@ -148,40 +148,27 @@ def f(n: int) -> None: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, m :: int + r0 :: bit + r1, m :: int L0: L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool -L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: - r4 = CPyTagged_Add(n, 2) - n = r4 + r1 = CPyTagged_Add(n, 2) + n = r1 m = n goto L1 -L5: +L3: return 1 (0, 0) {n} {n} (1, 0) {n} {n} (1, 1) {n} {n} -(1, 2) {n} {n} (2, 0) {n} {n} (2, 1) {n} {n} +(2, 2) {n} {m, n} +(2, 3) {m, n} {m, n} (3, 0) {n} {n} -(3, 1) {n} {n} -(4, 0) {n} {n} -(4, 1) {n} {n} -(4, 2) {n} {m, n} -(4, 3) {m, n} {m, n} -(5, 0) {n} {n} [case testMultiPass_Liveness] def f(n: int) -> None: @@ -195,67 +182,40 @@ def f(n: int) -> None: [out] def f(n): n, x, y :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: x = 2 y = 2 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 2 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 2) - if r2 goto L4 else goto L10 :: bool + n = y L3: - r3 = n < 2 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 4 + if r1 goto L4 else goto L5 :: bool L4: - n = y -L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool -L6: - r6 = CPyTagged_IsLt_(n, 4) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 4 :: signed - if r7 goto L8 else goto L9 :: bool -L8: n = 2 n = x - goto L5 -L9: + goto L3 +L5: goto L1 -L10: +L6: return 1 (0, 0) {n} {n, x} (0, 1) {n, x} {n, x, y} (0, 2) {n, x, y} {n, x, y} -(1, 0) {n, x, y} {n, r0, x, y} -(1, 1) {n, r0, x, y} {n, r1, x, y} -(1, 2) {n, r1, x, y} {n, x, y} -(2, 0) {n, x, y} {r2, x, y} -(2, 1) {r2, x, y} {x, y} -(3, 0) {n, x, y} {r3, x, y} -(3, 1) {r3, x, y} {x, y} -(4, 0) {x, y} {n, x, y} -(4, 1) {n, x, y} {n, x, y} -(5, 0) {n, x, y} {n, r4, x, y} -(5, 1) {n, r4, x, y} {n, r5, x, y} -(5, 2) {n, r5, x, y} {n, x, y} -(6, 0) {n, x, y} {n, r6, x, y} -(6, 1) {n, r6, x, y} {n, x, y} -(7, 0) {n, x, y} {n, r7, x, y} -(7, 1) {n, r7, x, y} {n, x, y} -(8, 0) {x, y} {x, y} -(8, 1) {x, y} {n, x, y} -(8, 2) {n, x, y} {n, x, y} -(9, 0) {n, x, y} {n, x, y} -(10, 0) {} {} +(1, 0) {n, x, y} {r0, x, y} +(1, 1) {r0, x, y} {x, y} +(2, 0) {x, y} {n, x, y} +(2, 1) {n, x, y} {n, x, y} +(3, 0) {n, x, y} {n, r1, x, y} +(3, 1) {n, r1, x, y} {n, x, y} +(4, 0) {x, y} {x, y} +(4, 1) {x, y} {n, x, y} +(4, 2) {n, x, y} {n, x, y} +(5, 0) {n, x, y} {n, x, y} +(6, 0) {} {} [case testCall_Liveness] def f(x: int) -> int: @@ -296,80 +256,35 @@ def f(a: int) -> None: [out] def f(a): a :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit y, x :: int L0: L1: - r0 = a & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_lt a, a + if r0 goto L2 else goto L6 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool L3: - r4 = CPyTagged_IsLt_(a, a) - if r4 goto L5 else goto L12 :: bool + r1 = int_lt a, a + if r1 goto L4 else goto L5 :: bool L4: - r5 = a < a :: signed - if r5 goto L5 else goto L12 :: bool -L5: -L6: - r6 = a & 1 - r7 = r6 != 0 - if r7 goto L8 else goto L7 :: bool -L7: - r8 = a & 1 - r9 = r8 != 0 - if r9 goto L8 else goto L9 :: bool -L8: - r10 = CPyTagged_IsLt_(a, a) - if r10 goto L10 else goto L11 :: bool -L9: - r11 = a < a :: signed - if r11 goto L10 else goto L11 :: bool -L10: y = a - goto L6 -L11: + goto L3 +L5: x = a goto L1 -L12: +L6: return 1 (0, 0) {a} {a} (1, 0) {a, x, y} {a, x, y} (1, 1) {a, x, y} {a, x, y} -(1, 2) {a, x, y} {a, x, y} (2, 0) {a, x, y} {a, x, y} -(2, 1) {a, x, y} {a, x, y} -(2, 2) {a, x, y} {a, x, y} (3, 0) {a, x, y} {a, x, y} (3, 1) {a, x, y} {a, x, y} (4, 0) {a, x, y} {a, x, y} (4, 1) {a, x, y} {a, x, y} (5, 0) {a, x, y} {a, x, y} +(5, 1) {a, x, y} {a, x, y} (6, 0) {a, x, y} {a, x, y} -(6, 1) {a, x, y} {a, x, y} -(6, 2) {a, x, y} {a, x, y} -(7, 0) {a, x, y} {a, x, y} -(7, 1) {a, x, y} {a, x, y} -(7, 2) {a, x, y} {a, x, y} -(8, 0) {a, x, y} {a, x, y} -(8, 1) {a, x, y} {a, x, y} -(9, 0) {a, x, y} {a, x, y} -(9, 1) {a, x, y} {a, x, y} -(10, 0) {a, x, y} {a, x, y} -(10, 1) {a, x, y} {a, x, y} -(11, 0) {a, x, y} {a, x, y} -(11, 1) {a, x, y} {a, x, y} -(12, 0) {a, x, y} {a, x, y} [case testTrivial_BorrowedArgument] def f(a: int, b: int) -> int: @@ -441,55 +356,33 @@ def f(a: int) -> int: [out] def f(a): a, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6, r7 :: int + r0 :: bit + r1, r2 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_le i, a + if r0 goto L2 else goto L3 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(a, i) - if r4 goto L6 else goto L5 :: bool -L4: - r5 = i <= a :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Add(sum, i) - sum = r6 - r7 = CPyTagged_Add(i, 2) - i = r7 + r1 = CPyTagged_Add(sum, i) + sum = r1 + r2 = CPyTagged_Add(i, 2) + i = r2 goto L1 -L6: +L3: return sum (0, 0) {a} {a} (0, 1) {a} {a} (0, 2) {a} {a} (1, 0) {a} {a} (1, 1) {a} {a} -(1, 2) {a} {a} (2, 0) {a} {a} (2, 1) {a} {a} (2, 2) {a} {a} +(2, 3) {a} {a} +(2, 4) {a} {a} (3, 0) {a} {a} -(3, 1) {a} {a} -(4, 0) {a} {a} -(4, 1) {a} {a} -(5, 0) {a} {a} -(5, 1) {a} {a} -(5, 2) {a} {a} -(5, 3) {a} {a} -(5, 4) {a} {a} -(6, 0) {a} {a} [case testError] def f(x: List[int]) -> None: pass # E: Name "List" is not defined \ diff --git a/mypyc/test-data/exceptions.test b/mypyc/test-data/exceptions.test index ed43b86ebdb4..1ec03dd9a671 100644 --- a/mypyc/test-data/exceptions.test +++ b/mypyc/test-data/exceptions.test @@ -111,56 +111,42 @@ def sum(a: List[int], l: int) -> int: def sum(a, l): a :: list l, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: object - r7, r8, r9, r10 :: int + r0 :: bit + r1 :: object + r2, r3, r4, r5 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_lt i, l + if r0 goto L2 else goto L7 :: bool L2: - r2 = l & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool + r1 = CPyList_GetItemBorrow(a, i) + if is_error(r1) goto L8 (error at sum:6) else goto L3 L3: - r4 = CPyTagged_IsLt_(i, l) - if r4 goto L5 else goto L10 :: bool + r2 = unbox(int, r1) + if is_error(r2) goto L8 (error at sum:6) else goto L4 L4: - r5 = i < l :: signed - if r5 goto L5 else goto L10 :: bool -L5: - r6 = CPyList_GetItemBorrow(a, i) - if is_error(r6) goto L11 (error at sum:6) else goto L6 -L6: - r7 = unbox(int, r6) - if is_error(r7) goto L11 (error at sum:6) else goto L7 -L7: - r8 = CPyTagged_Add(sum, r7) + r3 = CPyTagged_Add(sum, r2) dec_ref sum :: int - dec_ref r7 :: int - sum = r8 - r9 = CPyTagged_Add(i, 2) + dec_ref r2 :: int + sum = r3 + r4 = CPyTagged_Add(i, 2) dec_ref i :: int - i = r9 + i = r4 goto L1 -L8: +L5: return sum -L9: - r10 = :: int - return r10 -L10: +L6: + r5 = :: int + return r5 +L7: dec_ref i :: int - goto L8 -L11: + goto L5 +L8: dec_ref sum :: int dec_ref i :: int - goto L9 + goto L6 [case testTryExcept] def g() -> None: diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 981460dae371..164fc213a8a2 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -76,27 +76,13 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 -L5: +L2: return x [case testIfElse] @@ -109,30 +95,16 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 - goto L6 -L5: + goto L3 +L2: x = 4 -L6: +L3: return x [case testAnd1] @@ -145,48 +117,19 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L3 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L2 else goto L3 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L9 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L9 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L8 else goto L9 :: bool -L7: - r11 = x > y :: signed - if r11 goto L8 else goto L9 :: bool -L8: x = 2 - goto L10 -L9: + goto L4 +L3: x = 4 -L10: +L4: return x [case testAnd2] @@ -221,48 +164,19 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L2 else goto L1 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L2 else goto L3 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L8 else goto L4 :: bool -L3: - r5 = x < y :: signed - if r5 goto L8 else goto L4 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L8 else goto L9 :: bool -L7: - r11 = x > y :: signed - if r11 goto L8 else goto L9 :: bool -L8: x = 2 - goto L10 -L9: + goto L4 +L3: x = 4 -L10: +L4: return x [case testOr2] @@ -295,27 +209,13 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L2 else goto L1 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L5 else goto L4 :: bool -L3: - r5 = x < y :: signed - if r5 goto L5 else goto L4 :: bool -L4: x = 2 -L5: +L2: return x [case testNotAnd] @@ -326,45 +226,16 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: native_int - r7 :: bit - r8 :: native_int - r9, r10, r11 :: bit + r0, r1 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool + r1 = int_gt x, y + if r1 goto L3 else goto L2 :: bool L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L8 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L8 :: bool -L4: - r6 = x & 1 - r7 = r6 != 0 - if r7 goto L6 else goto L5 :: bool -L5: - r8 = y & 1 - r9 = r8 != 0 - if r9 goto L6 else goto L7 :: bool -L6: - r10 = CPyTagged_IsLt_(y, x) - if r10 goto L9 else goto L8 :: bool -L7: - r11 = x > y :: signed - if r11 goto L9 else goto L8 :: bool -L8: x = 2 -L9: +L3: return x [case testWhile] @@ -375,31 +246,17 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: int + r0 :: bit + r1 :: int L0: L1: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_gt x, y + if r0 goto L2 else goto L3 :: bool L2: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(y, x) - if r4 goto L5 else goto L6 :: bool -L4: - r5 = x > y :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Subtract(x, y) - x = r6 + r1 = CPyTagged_Subtract(x, y) + x = r1 goto L1 -L6: +L3: return x [case testWhile2] @@ -411,32 +268,18 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: int + r0 :: bit + r1 :: int L0: x = 2 L1: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_gt x, y + if r0 goto L2 else goto L3 :: bool L2: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(y, x) - if r4 goto L5 else goto L6 :: bool -L4: - r5 = x > y :: signed - if r5 goto L5 else goto L6 :: bool -L5: - r6 = CPyTagged_Subtract(x, y) - x = r6 + r1 = CPyTagged_Subtract(x, y) + x = r1 goto L1 -L6: +L3: return x [case testImplicitNoneReturn] @@ -466,30 +309,16 @@ def f(x: int, y: int) -> None: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit + r0 :: bit L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L1 :: bool + r0 = int_lt x, y + if r0 goto L1 else goto L2 :: bool L1: - r2 = y & 1 - r3 = r2 != 0 - if r3 goto L2 else goto L3 :: bool -L2: - r4 = CPyTagged_IsLt_(x, y) - if r4 goto L4 else goto L5 :: bool -L3: - r5 = x < y :: signed - if r5 goto L4 else goto L5 :: bool -L4: x = 2 - goto L6 -L5: + goto L3 +L2: y = 4 -L6: +L3: return 1 [case testRecursion] @@ -501,29 +330,21 @@ def f(n: int) -> int: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, r5, r6, r7, r8 :: int + r0 :: bit + r1, r2, r3, r4, r5 :: int L0: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_le n, 2 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(2, n) - if r2 goto L4 else goto L3 :: bool + return 2 L2: - r3 = n <= 2 :: signed - if r3 goto L3 else goto L4 :: bool + r1 = CPyTagged_Subtract(n, 2) + r2 = f(r1) + r3 = CPyTagged_Subtract(n, 4) + r4 = f(r3) + r5 = CPyTagged_Add(r2, r4) + return r5 L3: - return 2 -L4: - r4 = CPyTagged_Subtract(n, 2) - r5 = f(r4) - r6 = CPyTagged_Subtract(n, 4) - r7 = f(r6) - r8 = CPyTagged_Add(r5, r7) - return r8 -L5: unreachable [case testReportTypeCheckError] @@ -550,33 +371,25 @@ def f(n: int) -> int: [out] def f(n): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit x :: int - r4 :: bit + r1 :: bit L0: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_lt n, 0 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(n, 0) - if r2 goto L3 else goto L4 :: bool + x = 2 + goto L6 L2: - r3 = n < 0 :: signed - if r3 goto L3 else goto L4 :: bool + r1 = int_eq n, 0 + if r1 goto L3 else goto L4 :: bool L3: x = 2 - goto L8 + goto L5 L4: - r4 = int_eq n, 0 - if r4 goto L5 else goto L6 :: bool + x = 4 L5: - x = 2 - goto L7 L6: - x = 4 -L7: -L8: return x [case testUnaryMinus] @@ -1272,27 +1085,19 @@ def f(x: int) -> int: [out] def absolute_value(x): x :: int - r0 :: native_int - r1, r2, r3 :: bit - r4, r5 :: int + r0 :: bit + r1, r2 :: int L0: - r0 = x & 1 - r1 = r0 != 0 - if r1 goto L1 else goto L2 :: bool + r0 = int_gt x, 0 + if r0 goto L1 else goto L2 :: bool L1: - r2 = CPyTagged_IsLt_(0, x) - if r2 goto L3 else goto L4 :: bool + r1 = x + goto L3 L2: - r3 = x > 0 :: signed - if r3 goto L3 else goto L4 :: bool + r2 = CPyTagged_Negate(x) + r1 = r2 L3: - r4 = x - goto L5 -L4: - r5 = CPyTagged_Negate(x) - r4 = r5 -L5: - return r4 + return r1 def call_native_function(x): x, r0 :: int L0: @@ -2078,7 +1883,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive r1 r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) @@ -2148,7 +1953,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive r1 r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L8 :: bool L2: r14 = CPyList_GetItemUnsafe(r1, r9) @@ -2215,7 +2020,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive l r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(l, r0) @@ -2241,7 +2046,7 @@ L5: r16 = load_mem r15 :: native_int* keep_alive l r17 = r16 << 1 - r18 = r14 < r17 :: signed + r18 = int_lt r14, r17 if r18 goto L6 else goto L8 :: bool L6: r19 = CPyList_GetItemUnsafe(l, r14) @@ -2504,60 +2309,24 @@ L0: return x def f(x, y, z): x, y, z, r0, r1 :: int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit - r10 :: bool - r11 :: int - r12 :: native_int - r13 :: bit - r14 :: native_int - r15, r16, r17 :: bit - r18 :: bool - r19 :: bit + r2 :: bit + r3 :: bool + r4 :: int + r5 :: bit L0: r0 = g(x) r1 = g(y) - r2 = r0 & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool + r2 = int_lt r0, r1 + if r2 goto L2 else goto L1 :: bool L1: - r7 = r0 < r1 :: signed - r8 = r7 + r3 = r2 goto L3 L2: - r9 = CPyTagged_IsLt_(r0, r1) - r8 = r9 + r4 = g(z) + r5 = int_gt r1, r4 + r3 = r5 L3: - if r8 goto L5 else goto L4 :: bool -L4: - r10 = r8 - goto L9 -L5: - r11 = g(z) - r12 = r1 & 1 - r13 = r12 == 0 - r14 = r11 & 1 - r15 = r14 == 0 - r16 = r13 & r15 - if r16 goto L6 else goto L7 :: bool -L6: - r17 = r1 > r11 :: signed - r18 = r17 - goto L8 -L7: - r19 = CPyTagged_IsLt_(r11, r1) - r18 = r19 -L8: - r10 = r18 -L9: - return r10 + return r3 [case testEq] class A: @@ -3577,7 +3346,7 @@ L0: r0 = 8 i = r0 L1: - r1 = r0 < 24 :: signed + r1 = int_lt r0, 24 if r1 goto L2 else goto L4 :: bool L2: r2 = CPyTagged_Add(sum, i) diff --git a/mypyc/test-data/irbuild-bool.test b/mypyc/test-data/irbuild-bool.test index f0b0b480bc0d..795a3360fcd2 100644 --- a/mypyc/test-data/irbuild-bool.test +++ b/mypyc/test-data/irbuild-bool.test @@ -272,59 +272,23 @@ def lt1(x, y): x :: bool y :: int r0 :: bool - r1 :: short_int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r1 :: int + r2 :: bit L0: r0 = x << 1 - r1 = extend r0: builtins.bool to short_int - r2 = r1 & 1 - r3 = r2 == 0 - r4 = y & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = r1 < y :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(r1, y) - r8 = r9 -L3: - return r8 + r1 = extend r0: builtins.bool to builtins.int + r2 = int_lt r1, y + return r2 def lt2(x, y): x :: int y, r0 :: bool - r1 :: short_int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r1 :: int + r2 :: bit L0: r0 = y << 1 - r1 = extend r0: builtins.bool to short_int - r2 = x & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = x < r1 :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(x, r1) - r8 = r9 -L3: - return r8 + r1 = extend r0: builtins.bool to builtins.int + r2 = int_lt x, r1 + return r2 def gt1(x, y): x :: bool y, r0 :: i64 diff --git a/mypyc/test-data/irbuild-dunders.test b/mypyc/test-data/irbuild-dunders.test index b50b6eeae162..1796a7e2160e 100644 --- a/mypyc/test-data/irbuild-dunders.test +++ b/mypyc/test-data/irbuild-dunders.test @@ -15,24 +15,16 @@ L0: def f(c): c :: __main__.C r0 :: int - r1 :: native_int - r2, r3, r4 :: bit - r5 :: bool + r1 :: bit + r2 :: bool L0: r0 = c.__len__() - r1 = r0 & 1 - r2 = r1 != 0 - if r2 goto L1 else goto L2 :: bool + r1 = int_ge r0, 0 + if r1 goto L2 else goto L1 :: bool L1: - r3 = CPyTagged_IsLt_(r0, 0) - if r3 goto L3 else goto L4 :: bool -L2: - r4 = r0 >= 0 :: signed - if r4 goto L4 else goto L3 :: bool -L3: - r5 = raise ValueError('__len__() should return >= 0') + r2 = raise ValueError('__len__() should return >= 0') unreachable -L4: +L2: return r0 [case testDundersSetItem] diff --git a/mypyc/test-data/irbuild-int.test b/mypyc/test-data/irbuild-int.test index 1489f2f470dd..b1a712103e70 100644 --- a/mypyc/test-data/irbuild-int.test +++ b/mypyc/test-data/irbuild-int.test @@ -25,9 +25,7 @@ def f(x: int) -> int: [out] def f(x): x :: int - r0, r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1, r2, r3, r4 :: bit L0: r0 = int_eq x, 6 if r0 goto L1 else goto L2 :: bool @@ -49,22 +47,15 @@ L6: L7: return 8 L8: - r4 = x & 1 - r5 = r4 != 0 - if r5 goto L9 else goto L10 :: bool + r4 = int_lt x, 8 + if r4 goto L9 else goto L10 :: bool L9: - r6 = CPyTagged_IsLt_(x, 8) - if r6 goto L11 else goto L12 :: bool + return 10 L10: - r7 = x < 8 :: signed - if r7 goto L11 else goto L12 :: bool L11: - return 10 L12: L13: L14: -L15: -L16: return 12 [case testIntMin] @@ -73,36 +64,18 @@ def f(x: int, y: int) -> int: [out] def f(x, y): x, y :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6 :: bool - r7 :: bit - r8 :: int -L0: - r0 = y & 1 - r1 = r0 == 0 - r2 = x & 1 - r3 = r2 == 0 - r4 = r1 & r3 - if r4 goto L1 else goto L2 :: bool + r0 :: bit + r1 :: int +L0: + r0 = int_lt y, x + if r0 goto L1 else goto L2 :: bool L1: - r5 = y < x :: signed - r6 = r5 + r1 = y goto L3 L2: - r7 = CPyTagged_IsLt_(y, x) - r6 = r7 + r1 = x L3: - if r6 goto L4 else goto L5 :: bool -L4: - r8 = y - goto L6 -L5: - r8 = x -L6: - return r8 + return r1 [case testIntFloorDivideByPowerOfTwo] def divby1(x: int) -> int: diff --git a/mypyc/test-data/irbuild-lists.test b/mypyc/test-data/irbuild-lists.test index 80c4fe5fcd5e..ced4646922a3 100644 --- a/mypyc/test-data/irbuild-lists.test +++ b/mypyc/test-data/irbuild-lists.test @@ -230,7 +230,7 @@ L0: r3 = 0 i = r3 L1: - r4 = r3 < r2 :: signed + r4 = int_lt r3, r2 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItem(l, i) @@ -357,7 +357,7 @@ L1: r5 = load_mem r4 :: native_int* keep_alive source r6 = r5 << 1 - r7 = r3 < r6 :: signed + r7 = int_lt r3, r6 if r7 goto L2 else goto L4 :: bool L2: r8 = CPyList_GetItemUnsafe(source, r3) @@ -382,7 +382,7 @@ L5: r19 = load_mem r18 :: native_int* keep_alive source r20 = r19 << 1 - r21 = r17 < r20 :: signed + r21 = int_lt r17, r20 if r21 goto L6 else goto L8 :: bool L6: r22 = CPyList_GetItemUnsafe(source, r17) @@ -398,6 +398,7 @@ L7: L8: b = r16 return 1 + [case testGeneratorNext] from typing import List, Optional @@ -425,7 +426,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive x r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(x, r0) @@ -504,7 +505,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive a r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(a, r0) @@ -533,7 +534,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive a r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(a, r0) diff --git a/mypyc/test-data/irbuild-set.test b/mypyc/test-data/irbuild-set.test index a56ebe3438fa..51feab332593 100644 --- a/mypyc/test-data/irbuild-set.test +++ b/mypyc/test-data/irbuild-set.test @@ -115,7 +115,7 @@ L1: r11 = load_mem r10 :: native_int* keep_alive tmp_list r12 = r11 << 1 - r13 = r9 < r12 :: signed + r13 = int_lt r9, r12 if r13 goto L2 else goto L4 :: bool L2: r14 = CPyList_GetItemUnsafe(tmp_list, r9) @@ -234,7 +234,7 @@ L0: r1 = 2 x = r1 L1: - r2 = r1 < 12 :: signed + r2 = int_lt r1, 12 if r2 goto L2 else goto L4 :: bool L2: r3 = f(x) @@ -265,7 +265,7 @@ L0: r1 = 2 x = r1 L1: - r2 = r1 < 12 :: signed + r2 = int_lt r1, 12 if r2 goto L2 else goto L4 :: bool L2: r3 = f(x) @@ -323,27 +323,22 @@ def test(): r19 :: bit r20 :: object r21, z :: int - r22 :: native_int - r23 :: bit - r24 :: native_int - r25, r26, r27 :: bit - r28 :: bool - r29 :: bit - r30 :: int - r31 :: object - r32 :: i32 - r33 :: bit - r34 :: short_int - r35, r36, r37 :: object - r38, y, r39 :: int - r40 :: object - r41 :: i32 - r42, r43 :: bit - r44, r45, r46 :: object - r47, x, r48 :: int - r49 :: object - r50 :: i32 - r51, r52 :: bit + r22 :: bit + r23 :: int + r24 :: object + r25 :: i32 + r26 :: bit + r27 :: short_int + r28, r29, r30 :: object + r31, y, r32 :: int + r33 :: object + r34 :: i32 + r35, r36 :: bit + r37, r38, r39 :: object + r40, x, r41 :: int + r42 :: object + r43 :: i32 + r44, r45 :: bit a :: set L0: r0 = PyList_New(5) @@ -374,73 +369,60 @@ L1: r17 = load_mem r16 :: native_int* keep_alive tmp_list r18 = r17 << 1 - r19 = r15 < r18 :: signed - if r19 goto L2 else goto L9 :: bool + r19 = int_lt r15, r18 + if r19 goto L2 else goto L6 :: bool L2: r20 = CPyList_GetItemUnsafe(tmp_list, r15) r21 = unbox(int, r20) z = r21 - r22 = z & 1 - r23 = r22 == 0 - r24 = 8 & 1 - r25 = r24 == 0 - r26 = r23 & r25 - if r26 goto L3 else goto L4 :: bool + r22 = int_lt z, 8 + if r22 goto L4 else goto L3 :: bool L3: - r27 = z < 8 :: signed - r28 = r27 goto L5 L4: - r29 = CPyTagged_IsLt_(z, 8) - r28 = r29 + r23 = f1(z) + r24 = box(int, r23) + r25 = PyList_Append(r14, r24) + r26 = r25 >= 0 :: signed L5: - if r28 goto L7 else goto L6 :: bool + r27 = r15 + 2 + r15 = r27 + goto L1 L6: - goto L8 + r28 = PyObject_GetIter(r14) + r29 = PyObject_GetIter(r28) L7: - r30 = f1(z) - r31 = box(int, r30) - r32 = PyList_Append(r14, r31) - r33 = r32 >= 0 :: signed + r30 = PyIter_Next(r29) + if is_error(r30) goto L10 else goto L8 L8: - r34 = r15 + 2 - r15 = r34 - goto L1 + r31 = unbox(int, r30) + y = r31 + r32 = f2(y) + r33 = box(int, r32) + r34 = PyList_Append(r13, r33) + r35 = r34 >= 0 :: signed L9: - r35 = PyObject_GetIter(r14) - r36 = PyObject_GetIter(r35) + goto L7 L10: - r37 = PyIter_Next(r36) - if is_error(r37) goto L13 else goto L11 + r36 = CPy_NoErrOccured() L11: - r38 = unbox(int, r37) - y = r38 - r39 = f2(y) - r40 = box(int, r39) - r41 = PyList_Append(r13, r40) - r42 = r41 >= 0 :: signed + r37 = PyObject_GetIter(r13) + r38 = PyObject_GetIter(r37) L12: - goto L10 + r39 = PyIter_Next(r38) + if is_error(r39) goto L15 else goto L13 L13: - r43 = CPy_NoErrOccured() + r40 = unbox(int, r39) + x = r40 + r41 = f3(x) + r42 = box(int, r41) + r43 = PySet_Add(r12, r42) + r44 = r43 >= 0 :: signed L14: - r44 = PyObject_GetIter(r13) - r45 = PyObject_GetIter(r44) + goto L12 L15: - r46 = PyIter_Next(r45) - if is_error(r46) goto L18 else goto L16 + r45 = CPy_NoErrOccured() L16: - r47 = unbox(int, r46) - x = r47 - r48 = f3(x) - r49 = box(int, r48) - r50 = PySet_Add(r12, r49) - r51 = r50 >= 0 :: signed -L17: - goto L15 -L18: - r52 = CPy_NoErrOccured() -L19: a = r12 return 1 diff --git a/mypyc/test-data/irbuild-singledispatch.test b/mypyc/test-data/irbuild-singledispatch.test index 10970a385966..e1053397546f 100644 --- a/mypyc/test-data/irbuild-singledispatch.test +++ b/mypyc/test-data/irbuild-singledispatch.test @@ -81,7 +81,7 @@ L3: if r17 goto L4 else goto L7 :: bool L4: r18 = unbox(int, r6) - r19 = r18 == 0 + r19 = int_eq r18, 0 if r19 goto L5 else goto L6 :: bool L5: r20 = unbox(int, arg) diff --git a/mypyc/test-data/irbuild-statements.test b/mypyc/test-data/irbuild-statements.test index b7c67730a05f..ed97c4cd4138 100644 --- a/mypyc/test-data/irbuild-statements.test +++ b/mypyc/test-data/irbuild-statements.test @@ -16,7 +16,7 @@ L0: r0 = 0 i = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: r2 = CPyTagged_Add(x, i) @@ -36,39 +36,21 @@ def f(a: int) -> None: [out] def f(a): a, r0, i :: int - r1 :: native_int - r2 :: bit - r3 :: native_int - r4, r5, r6 :: bit - r7 :: bool - r8 :: bit - r9 :: int + r1 :: bit + r2 :: int L0: r0 = 0 i = r0 L1: - r1 = r0 & 1 - r2 = r1 == 0 - r3 = a & 1 - r4 = r3 == 0 - r5 = r2 & r4 - if r5 goto L2 else goto L3 :: bool + r1 = int_lt r0, a + if r1 goto L2 else goto L4 :: bool L2: - r6 = r0 < a :: signed - r7 = r6 - goto L4 L3: - r8 = CPyTagged_IsLt_(r0, a) - r7 = r8 -L4: - if r7 goto L5 else goto L7 :: bool -L5: -L6: - r9 = CPyTagged_Add(r0, 2) - r0 = r9 - i = r9 + r2 = CPyTagged_Add(r0, 2) + r0 = r2 + i = r2 goto L1 -L7: +L4: return 1 [case testForInNegativeRange] @@ -85,7 +67,7 @@ L0: r0 = 20 i = r0 L1: - r1 = r0 > 0 :: signed + r1 = int_gt r0, 0 if r1 goto L2 else goto L4 :: bool L2: L3: @@ -104,22 +86,14 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: -L5: return 1 [case testBreakFor] @@ -136,7 +110,7 @@ L0: r0 = 0 n = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: goto L4 @@ -158,36 +132,19 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L10 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 8 + if r1 goto L4 else goto L5 :: bool L4: L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool L6: - r6 = CPyTagged_IsLt_(n, 8) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 8 :: signed - if r7 goto L8 else goto L9 :: bool -L8: -L9: -L10: return 1 [case testContinue] @@ -198,23 +155,15 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit + r0 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L3 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L5 :: bool -L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L5 :: bool -L4: goto L1 -L5: +L3: return 1 [case testContinueFor] @@ -231,7 +180,7 @@ L0: r0 = 0 n = r0 L1: - r1 = r0 < 10 :: signed + r1 = int_lt r0, 10 if r1 goto L2 else goto L4 :: bool L2: L3: @@ -252,38 +201,21 @@ def f() -> None: [out] def f(): n :: int - r0 :: native_int - r1, r2, r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit + r0, r1 :: bit L0: n = 0 L1: - r0 = n & 1 - r1 = r0 != 0 - if r1 goto L2 else goto L3 :: bool + r0 = int_lt n, 10 + if r0 goto L2 else goto L6 :: bool L2: - r2 = CPyTagged_IsLt_(n, 10) - if r2 goto L4 else goto L10 :: bool L3: - r3 = n < 10 :: signed - if r3 goto L4 else goto L10 :: bool + r1 = int_lt n, 8 + if r1 goto L4 else goto L5 :: bool L4: + goto L3 L5: - r4 = n & 1 - r5 = r4 != 0 - if r5 goto L6 else goto L7 :: bool -L6: - r6 = CPyTagged_IsLt_(n, 8) - if r6 goto L8 else goto L9 :: bool -L7: - r7 = n < 8 :: signed - if r7 goto L8 else goto L9 :: bool -L8: - goto L5 -L9: goto L1 -L10: +L6: return 1 [case testForList] @@ -314,7 +246,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive ls r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPyList_GetItemUnsafe(ls, r0) @@ -963,7 +895,7 @@ L1: r3 = load_mem r2 :: native_int* keep_alive a r4 = r3 << 1 - r5 = r1 < r4 :: signed + r5 = int_lt r1, r4 if r5 goto L2 else goto L4 :: bool L2: r6 = CPyList_GetItemUnsafe(a, r1) @@ -1045,7 +977,7 @@ L1: r3 = load_mem r2 :: native_int* keep_alive a r4 = r3 << 1 - r5 = r0 < r4 :: signed + r5 = int_lt r0, r4 if r5 goto L2 else goto L7 :: bool L2: r6 = PyIter_Next(r1) @@ -1100,10 +1032,10 @@ L2: r5 = load_mem r4 :: native_int* keep_alive b r6 = r5 << 1 - r7 = r1 < r6 :: signed + r7 = int_lt r1, r6 if r7 goto L3 else goto L6 :: bool L3: - r8 = r2 < 10 :: signed + r8 = int_lt r2, 10 if r8 goto L4 else goto L6 :: bool L4: r9 = unbox(bool, r3) diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index ab0e2fa09a9d..342bb19b5360 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -147,7 +147,7 @@ L1: r2 = load_mem r1 :: native_int* keep_alive xs r3 = r2 << 1 - r4 = r0 < r3 :: signed + r4 = int_lt r0, r3 if r4 goto L2 else goto L4 :: bool L2: r5 = CPySequenceTuple_GetItem(xs, r0) @@ -279,7 +279,7 @@ L1: r13 = load_mem r12 :: native_int* keep_alive source r14 = r13 << 1 - r15 = r11 < r14 :: signed + r15 = int_lt r11, r14 if r15 goto L2 else goto L4 :: bool L2: r16 = CPyList_GetItemUnsafe(source, r11) @@ -335,7 +335,7 @@ L1: r5 = CPyStr_Size_size_t(source) r6 = r5 >= 0 :: signed r7 = r5 << 1 - r8 = r4 < r7 :: signed + r8 = int_lt r4, r7 if r8 goto L2 else goto L4 :: bool L2: r9 = CPyStr_GetItem(source, r4) @@ -391,7 +391,7 @@ L1: r5 = load_mem r4 :: native_int* keep_alive source r6 = r5 << 1 - r7 = r3 < r6 :: signed + r7 = int_lt r3, r6 if r7 goto L2 else goto L4 :: bool L2: r8 = CPySequenceTuple_GetItem(source, r3) diff --git a/mypyc/test-data/lowering-int.test b/mypyc/test-data/lowering-int.test index 8c813563d0e6..e7df944c4458 100644 --- a/mypyc/test-data/lowering-int.test +++ b/mypyc/test-data/lowering-int.test @@ -13,13 +13,13 @@ def f(x, y): r1, r2, r3 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x == y + r2 = CPyTagged_IsEq_(x, y) if r2 goto L3 else goto L4 :: bool L2: - r3 = CPyTagged_IsEq_(x, y) + r3 = x == y if r3 goto L3 else goto L4 :: bool L3: return 2 @@ -39,14 +39,14 @@ def f(x, y): r1, r2, r3, r4 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x != y - if r2 goto L3 else goto L4 :: bool + r2 = CPyTagged_IsEq_(x, y) + r3 = r2 ^ 1 + if r3 goto L3 else goto L4 :: bool L2: - r3 = CPyTagged_IsEq_(x, y) - r4 = r3 ^ 1 + r4 = x != y if r4 goto L3 else goto L4 :: bool L3: return 2 @@ -113,14 +113,265 @@ def f(x, y): r4 :: bit L0: r0 = x & 1 - r1 = r0 == 0 + r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: - r2 = x == y + r2 = CPyTagged_IsEq_(x, y) r3 = r2 goto L3 L2: - r4 = CPyTagged_IsEq_(x, y) + r4 = x == y r3 = r4 L3: return r3 + +[case testLowerIntLt] +def f(x: int, y: int) -> int: + if x < y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, y) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x < y :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntLe] +def f(x: int, y: int) -> int: + if x <= y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5, r6 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(y, x) + r5 = r4 ^ 1 + if r5 goto L4 else goto L5 :: bool +L3: + r6 = x <= y :: signed + if r6 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntGt] +def f(x: int, y: int) -> int: + if x > y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(y, x) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x > y :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntGe] +def f(x: int, y: int) -> int: + if x >= y: + return 1 + else: + return 2 +[out] +def f(x, y): + x, y :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5, r6 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = y & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, y) + r5 = r4 ^ 1 + if r5 goto L4 else goto L5 :: bool +L3: + r6 = x >= y :: signed + if r6 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntLtShort] +def both() -> int: + if 3 < 5: + return 1 + else: + return 2 + +def rhs_only(x: int) -> int: + if x < 5: + return 1 + else: + return 2 + +def lhs_only(x: int) -> int: + if 5 < x: + return 1 + else: + return 2 +[out] +def both(): + r0 :: bit +L0: + r0 = 6 < 10 :: signed + if r0 goto L1 else goto L2 :: bool +L1: + return 2 +L2: + return 4 +def rhs_only(x): + x :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = x & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = 10 & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(x, 10) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = x < 10 :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 +def lhs_only(x): + x :: int + r0 :: native_int + r1 :: bit + r2 :: native_int + r3, r4, r5 :: bit +L0: + r0 = 10 & 1 + r1 = r0 != 0 + if r1 goto L2 else goto L1 :: bool +L1: + r2 = x & 1 + r3 = r2 != 0 + if r3 goto L2 else goto L3 :: bool +L2: + r4 = CPyTagged_IsLt_(10, x) + if r4 goto L4 else goto L5 :: bool +L3: + r5 = 10 < x :: signed + if r5 goto L4 else goto L5 :: bool +L4: + return 2 +L5: + return 4 + +[case testLowerIntForLoop] +from __future__ import annotations + +def f(l: list[int]) -> None: + for x in l: + pass +[out] +def f(l): + l :: list + r0 :: short_int + r1 :: ptr + r2 :: native_int + r3 :: short_int + r4 :: bit + r5 :: object + r6, x :: int + r7 :: short_int + r8 :: None +L0: + r0 = 0 +L1: + r1 = get_element_ptr l ob_size :: PyVarObject + r2 = load_mem r1 :: native_int* + r3 = r2 << 1 + r4 = r0 < r3 :: signed + if r4 goto L2 else goto L5 :: bool +L2: + r5 = CPyList_GetItemUnsafe(l, r0) + r6 = unbox(int, r5) + dec_ref r5 + if is_error(r6) goto L6 (error at f:4) else goto L3 +L3: + x = r6 + dec_ref x :: int +L4: + r7 = r0 + 2 + r0 = r7 + goto L1 +L5: + return 1 +L6: + r8 = :: None + return r8 diff --git a/mypyc/test-data/refcount.test b/mypyc/test-data/refcount.test index df980af8a7c7..3021381abded 100644 --- a/mypyc/test-data/refcount.test +++ b/mypyc/test-data/refcount.test @@ -452,41 +452,27 @@ def f(a: int) -> int: [out] def f(a): a, sum, i :: int - r0 :: native_int - r1 :: bit - r2 :: native_int - r3, r4, r5 :: bit - r6, r7 :: int + r0 :: bit + r1, r2 :: int L0: sum = 0 i = 0 L1: - r0 = i & 1 - r1 = r0 != 0 - if r1 goto L3 else goto L2 :: bool + r0 = int_le i, a + if r0 goto L2 else goto L4 :: bool L2: - r2 = a & 1 - r3 = r2 != 0 - if r3 goto L3 else goto L4 :: bool -L3: - r4 = CPyTagged_IsLt_(a, i) - if r4 goto L7 else goto L5 :: bool -L4: - r5 = i <= a :: signed - if r5 goto L5 else goto L7 :: bool -L5: - r6 = CPyTagged_Add(sum, i) + r1 = CPyTagged_Add(sum, i) dec_ref sum :: int - sum = r6 - r7 = CPyTagged_Add(i, 2) + sum = r1 + r2 = CPyTagged_Add(i, 2) dec_ref i :: int - i = r7 + i = r2 goto L1 -L6: +L3: return sum -L7: +L4: dec_ref i :: int - goto L6 + goto L3 [case testCall] def f(a: int) -> int: @@ -1357,30 +1343,12 @@ class C: def add(c): c :: __main__.C r0, r1 :: int - r2 :: native_int - r3 :: bit - r4 :: native_int - r5, r6, r7 :: bit - r8 :: bool - r9 :: bit + r2 :: bit L0: r0 = borrow c.x r1 = borrow c.y - r2 = r0 & 1 - r3 = r2 == 0 - r4 = r1 & 1 - r5 = r4 == 0 - r6 = r3 & r5 - if r6 goto L1 else goto L2 :: bool -L1: - r7 = r0 < r1 :: signed - r8 = r7 - goto L3 -L2: - r9 = CPyTagged_IsLt_(r0, r1) - r8 = r9 -L3: - return r8 + r2 = int_lt r0, r1 + return r2 [case testBorrowIntCompareFinal] from typing_extensions import Final From 952c6162bff63ef0cde9d0944471351130bcc107 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Wed, 20 Mar 2024 19:38:06 +0000 Subject: [PATCH 133/172] [mypyc] Refactor: move tagged int related code to mypyc.lower.int_ops (#17052) --- mypyc/irbuild/expression.py | 5 +- mypyc/irbuild/ll_builder.py | 45 ------------------ mypyc/lower/int_ops.py | 92 ++++++++++++++++++++++++++++++++++--- mypyc/primitives/int_ops.py | 28 ----------- 4 files changed, 87 insertions(+), 83 deletions(-) diff --git a/mypyc/irbuild/expression.py b/mypyc/irbuild/expression.py index ba62d71d0ad3..a16faf6cd7d7 100644 --- a/mypyc/irbuild/expression.py +++ b/mypyc/irbuild/expression.py @@ -95,7 +95,6 @@ from mypyc.primitives.bytes_ops import bytes_slice_op from mypyc.primitives.dict_ops import dict_get_item_op, dict_new_op, dict_set_item_op from mypyc.primitives.generic_ops import iter_op -from mypyc.primitives.int_ops import int_comparison_op_mapping from mypyc.primitives.list_ops import list_append_op, list_extend_op, list_slice_op from mypyc.primitives.misc_ops import ellipsis_op, get_module_dict_op, new_slice_op, type_op from mypyc.primitives.registry import CFunctionDescription, builtin_names @@ -814,7 +813,7 @@ def translate_is_none(builder: IRBuilder, expr: Expression, negated: bool) -> Va def transform_basic_comparison( builder: IRBuilder, op: str, left: Value, right: Value, line: int ) -> Value: - if is_fixed_width_rtype(left.type) and op in int_comparison_op_mapping: + if is_fixed_width_rtype(left.type) and op in ComparisonOp.signed_ops: if right.type == left.type: if left.type.is_signed: op_id = ComparisonOp.signed_ops[op] @@ -831,7 +830,7 @@ def transform_basic_comparison( ) elif ( is_fixed_width_rtype(right.type) - and op in int_comparison_op_mapping + and op in ComparisonOp.signed_ops and isinstance(left, Integer) ): if right.type.is_signed: diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index 548b391030fe..e989471ceb59 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -159,7 +159,6 @@ int64_divide_op, int64_mod_op, int64_to_int_op, - int_comparison_op_mapping, int_to_int32_op, int_to_int64_op, ssize_t_to_int_op, @@ -1413,50 +1412,6 @@ def check_tagged_short_int(self, val: Value, line: int, negated: bool = False) - check = self.comparison_op(bitwise_and, zero, op, line) return check - def compare_tagged(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: - """Compare two tagged integers using given operator (value context).""" - # generate fast binary logic ops on short ints - if (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) and op in ( - "==", - "!=", - ): - quick = True - else: - quick = is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type) - if quick: - return self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line) - op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] - result = Register(bool_rprimitive) - short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock() - check_lhs = self.check_tagged_short_int(lhs, line, negated=True) - if op in ("==", "!="): - self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) - else: - # for non-equality logical ops (less/greater than, etc.), need to check both sides - short_lhs = BasicBlock() - self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL)) - self.activate_block(short_lhs) - check_rhs = self.check_tagged_short_int(rhs, line, negated=True) - self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) - self.activate_block(int_block) - if swap_op: - args = [rhs, lhs] - else: - args = [lhs, rhs] - call = self.call_c(c_func_desc, args, line) - if negate_result: - # TODO: introduce UnaryIntOp? - call_result = self.unary_op(call, "not", line) - else: - call_result = call - self.add(Assign(result, call_result, line)) - self.goto(out) - self.activate_block(short_int_block) - eq = self.comparison_op(lhs, rhs, op_type, line) - self.add(Assign(result, eq, line)) - self.goto_and_activate(out) - return result - def compare_strings(self, lhs: Value, rhs: Value, op: str, line: int) -> Value: """Compare two strings""" compare_result = self.call_c(unicode_compare, [lhs, rhs], line) diff --git a/mypyc/lower/int_ops.py b/mypyc/lower/int_ops.py index 5255a64b647d..90a3253ba093 100644 --- a/mypyc/lower/int_ops.py +++ b/mypyc/lower/int_ops.py @@ -1,35 +1,113 @@ +"""Convert tagged int primitive ops to lower-level ops.""" + from __future__ import annotations -from mypyc.ir.ops import Value +from typing import NamedTuple + +from mypyc.ir.ops import Assign, BasicBlock, Branch, ComparisonOp, Register, Value +from mypyc.ir.rtypes import bool_rprimitive, is_short_int_rprimitive from mypyc.irbuild.ll_builder import LowLevelIRBuilder from mypyc.lower.registry import lower_binary_op +from mypyc.primitives.int_ops import int_equal_, int_less_than_ +from mypyc.primitives.registry import CFunctionDescription + + +# Description for building int comparison ops +# +# Fields: +# binary_op_variant: identify which IntOp to use when operands are short integers +# c_func_description: the C function to call when operands are tagged integers +# c_func_negated: whether to negate the C function call's result +# c_func_swap_operands: whether to swap lhs and rhs when call the function +class IntComparisonOpDescription(NamedTuple): + binary_op_variant: int + c_func_description: CFunctionDescription + c_func_negated: bool + c_func_swap_operands: bool + + +# Provide mapping from textual op to short int's op variant and boxed int's description. +# Note that these are not complete implementations and require extra IR. +int_comparison_op_mapping: dict[str, IntComparisonOpDescription] = { + "==": IntComparisonOpDescription(ComparisonOp.EQ, int_equal_, False, False), + "!=": IntComparisonOpDescription(ComparisonOp.NEQ, int_equal_, True, False), + "<": IntComparisonOpDescription(ComparisonOp.SLT, int_less_than_, False, False), + "<=": IntComparisonOpDescription(ComparisonOp.SLE, int_less_than_, True, True), + ">": IntComparisonOpDescription(ComparisonOp.SGT, int_less_than_, False, True), + ">=": IntComparisonOpDescription(ComparisonOp.SGE, int_less_than_, True, False), +} + + +def compare_tagged(self: LowLevelIRBuilder, lhs: Value, rhs: Value, op: str, line: int) -> Value: + """Compare two tagged integers using given operator (value context).""" + # generate fast binary logic ops on short ints + if (is_short_int_rprimitive(lhs.type) or is_short_int_rprimitive(rhs.type)) and op in ( + "==", + "!=", + ): + quick = True + else: + quick = is_short_int_rprimitive(lhs.type) and is_short_int_rprimitive(rhs.type) + if quick: + return self.comparison_op(lhs, rhs, int_comparison_op_mapping[op][0], line) + op_type, c_func_desc, negate_result, swap_op = int_comparison_op_mapping[op] + result = Register(bool_rprimitive) + short_int_block, int_block, out = BasicBlock(), BasicBlock(), BasicBlock() + check_lhs = self.check_tagged_short_int(lhs, line, negated=True) + if op in ("==", "!="): + self.add(Branch(check_lhs, int_block, short_int_block, Branch.BOOL)) + else: + # for non-equality logical ops (less/greater than, etc.), need to check both sides + short_lhs = BasicBlock() + self.add(Branch(check_lhs, int_block, short_lhs, Branch.BOOL)) + self.activate_block(short_lhs) + check_rhs = self.check_tagged_short_int(rhs, line, negated=True) + self.add(Branch(check_rhs, int_block, short_int_block, Branch.BOOL)) + self.activate_block(int_block) + if swap_op: + args = [rhs, lhs] + else: + args = [lhs, rhs] + call = self.call_c(c_func_desc, args, line) + if negate_result: + # TODO: introduce UnaryIntOp? + call_result = self.unary_op(call, "not", line) + else: + call_result = call + self.add(Assign(result, call_result, line)) + self.goto(out) + self.activate_block(short_int_block) + eq = self.comparison_op(lhs, rhs, op_type, line) + self.add(Assign(result, eq, line)) + self.goto_and_activate(out) + return result @lower_binary_op("int_eq") def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], "==", line) + return compare_tagged(builder, args[0], args[1], "==", line) @lower_binary_op("int_ne") def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], "!=", line) + return compare_tagged(builder, args[0], args[1], "!=", line) @lower_binary_op("int_lt") def lower_int_lt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], "<", line) + return compare_tagged(builder, args[0], args[1], "<", line) @lower_binary_op("int_le") def lower_int_le(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], "<=", line) + return compare_tagged(builder, args[0], args[1], "<=", line) @lower_binary_op("int_gt") def lower_int_gt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], ">", line) + return compare_tagged(builder, args[0], args[1], ">", line) @lower_binary_op("int_ge") def lower_int_ge(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: - return builder.compare_tagged(args[0], args[1], ">=", line) + return compare_tagged(builder, args[0], args[1], ">=", line) diff --git a/mypyc/primitives/int_ops.py b/mypyc/primitives/int_ops.py index 029d71606886..4413028a0e83 100644 --- a/mypyc/primitives/int_ops.py +++ b/mypyc/primitives/int_ops.py @@ -10,14 +10,11 @@ from __future__ import annotations -from typing import NamedTuple - from mypyc.ir.ops import ( ERR_ALWAYS, ERR_MAGIC, ERR_MAGIC_OVERLAPPING, ERR_NEVER, - ComparisonOp, PrimitiveDescription, ) from mypyc.ir.rtypes import ( @@ -196,20 +193,6 @@ def int_unary_op(name: str, c_function_name: str) -> CFunctionDescription: # Primitives related to integer comparison operations: -# Description for building int comparison ops -# -# Fields: -# binary_op_variant: identify which IntOp to use when operands are short integers -# c_func_description: the C function to call when operands are tagged integers -# c_func_negated: whether to negate the C function call's result -# c_func_swap_operands: whether to swap lhs and rhs when call the function -class IntComparisonOpDescription(NamedTuple): - binary_op_variant: int - c_func_description: CFunctionDescription - c_func_negated: bool - c_func_swap_operands: bool - - # Equals operation on two boxed tagged integers int_equal_ = custom_op( arg_types=[int_rprimitive, int_rprimitive], @@ -226,17 +209,6 @@ class IntComparisonOpDescription(NamedTuple): error_kind=ERR_NEVER, ) -# Provide mapping from textual op to short int's op variant and boxed int's description. -# Note that these are not complete implementations and require extra IR. -int_comparison_op_mapping: dict[str, IntComparisonOpDescription] = { - "==": IntComparisonOpDescription(ComparisonOp.EQ, int_equal_, False, False), - "!=": IntComparisonOpDescription(ComparisonOp.NEQ, int_equal_, True, False), - "<": IntComparisonOpDescription(ComparisonOp.SLT, int_less_than_, False, False), - "<=": IntComparisonOpDescription(ComparisonOp.SLE, int_less_than_, True, True), - ">": IntComparisonOpDescription(ComparisonOp.SGT, int_less_than_, False, True), - ">=": IntComparisonOpDescription(ComparisonOp.SGE, int_less_than_, True, False), -} - int64_divide_op = custom_op( arg_types=[int64_rprimitive, int64_rprimitive], return_type=int64_rprimitive, From a505e5fb018c673644d6b1c044fe8df0c836895f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:08:35 -0700 Subject: [PATCH 134/172] Bump black from 24.1.1 to 24.3.0 (#17051) --- test-requirements.in | 2 +- test-requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-requirements.in b/test-requirements.in index 8eeef206018e..166bdf934d47 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==24.1.1 # must match version in .pre-commit-config.yaml +black==24.3.0 # 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 525edbc252d8..f105b753799f 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -6,7 +6,7 @@ # attrs==23.1.0 # via -r test-requirements.in -black==24.1.1 +black==24.3.0 # via -r test-requirements.in cfgv==3.4.0 # via pre-commit From 394d17b758bae6c95cbe91b84c5cccf0f4d73c28 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 20 Mar 2024 19:08:56 -0700 Subject: [PATCH 135/172] Improve yield from inference for unions of generators (#16717) Fixes #15141, closes #15168 --- mypy/checker.py | 5 +-- mypy/checkexpr.py | 12 +------ mypyc/test-data/run-generators.test | 9 +++--- test-data/unit/check-statements.test | 47 +++++++++++++++++++++++++++- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index 941dc06f1c71..5d243195d50f 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -989,8 +989,9 @@ def get_generator_return_type(self, return_type: Type, is_coroutine: bool) -> Ty # AwaitableGenerator, Generator: tr is args[2]. return return_type.args[2] else: - # Supertype of Generator (Iterator, Iterable, object): tr is any. - return AnyType(TypeOfAny.special_form) + # We have a supertype of Generator (Iterator, Iterable, object) + # Treat `Iterator[X]` as a shorthand for `Generator[X, Any, None]`. + return NoneType() def visit_func_def(self, defn: FuncDef) -> None: if not self.recurse_into_functions: diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 37a90ce55b9e..e7567eafb8fe 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -5963,17 +5963,7 @@ def visit_yield_from_expr(self, e: YieldFromExpr, allow_none_return: bool = Fals # Determine the type of the entire yield from expression. iter_type = get_proper_type(iter_type) - if isinstance(iter_type, Instance) and iter_type.type.fullname == "typing.Generator": - expr_type = self.chk.get_generator_return_type(iter_type, False) - else: - # Non-Generators don't return anything from `yield from` expressions. - # However special-case Any (which might be produced by an error). - actual_item_type = get_proper_type(actual_item_type) - if isinstance(actual_item_type, AnyType): - expr_type = AnyType(TypeOfAny.from_another_any, source_any=actual_item_type) - else: - # Treat `Iterator[X]` as a shorthand for `Generator[X, None, Any]`. - expr_type = NoneType() + expr_type = self.chk.get_generator_return_type(iter_type, is_coroutine=False) if not allow_none_return and isinstance(get_proper_type(expr_type), NoneType): self.chk.msg.does_not_return_value(None, e) diff --git a/mypyc/test-data/run-generators.test b/mypyc/test-data/run-generators.test index bcf9da1846ae..7e9804c49582 100644 --- a/mypyc/test-data/run-generators.test +++ b/mypyc/test-data/run-generators.test @@ -246,12 +246,12 @@ assert run_generator(another_triple()()) == ((1,), None) assert run_generator(outer()) == ((0, 1, 2, 3, 4), None) [case testYieldThrow] -from typing import Generator, Iterable, Any +from typing import Generator, Iterable, Any, Union from traceback import print_tb from contextlib import contextmanager import wrapsys -def generator() -> Iterable[int]: +def generator() -> Generator[int, None, Union[int, None]]: try: yield 1 yield 2 @@ -264,6 +264,7 @@ def generator() -> Iterable[int]: else: print('caught exception without value') return 0 + return None def no_except() -> Iterable[int]: yield 1 @@ -355,11 +356,11 @@ with ctx_manager() as c: raise Exception File "native.py", line 10, in generator yield 3 - File "native.py", line 30, in wrapper + File "native.py", line 31, in wrapper return (yield from x) File "native.py", line 9, in generator yield 2 - File "native.py", line 30, in wrapper + File "native.py", line 31, in wrapper return (yield from x) caught exception without value caught exception with value some string diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index f5b47e7ab97f..71cc80719779 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -85,7 +85,7 @@ def f() -> Generator[int, None, None]: from typing import Iterator def f() -> Iterator[int]: yield 1 - return "foo" + return "foo" # E: No return value expected [out] @@ -2231,6 +2231,51 @@ class B: pass def foo(x: int) -> Union[Generator[A, None, None], Generator[B, None, None]]: yield x # E: Incompatible types in "yield" (actual type "int", expected type "Union[A, B]") +[case testYieldFromUnionOfGenerators] +from typing import Generator, Union + +class T: pass + +def foo(arg: Union[Generator[int, None, T], Generator[str, None, T]]) -> Generator[Union[int, str], None, T]: + return (yield from arg) + +[case testYieldFromInvalidUnionReturn] +from typing import Generator, Union + +class A: pass +class B: pass + +def foo(arg: Union[A, B]) -> Generator[Union[int, str], None, A]: + return (yield from arg) # E: "yield from" can't be applied to "Union[A, B]" + +[case testYieldFromUnionOfGeneratorWithIterableStr] +from typing import Generator, Union, Iterable, Optional + +def foo(arg: Union[Generator[int, None, bytes], Iterable[str]]) -> Generator[Union[int, str], None, Optional[bytes]]: + return (yield from arg) + +def bar(arg: Generator[str, None, str]) -> Generator[str, None, str]: + return foo(arg) # E: Incompatible return value type (got "Generator[Union[int, str], None, Optional[bytes]]", expected "Generator[str, None, str]") + +def launder(arg: Iterable[str]) -> Generator[Union[int, str], None, Optional[bytes]]: + return foo(arg) + +def baz(arg: Generator[str, None, str]) -> Generator[Union[int, str], None, Optional[bytes]]: + # this is unsound, the Generator return type will actually be str + return launder(arg) +[builtins fixtures/tuple.pyi] + +[case testYieldIteratorReturn] +from typing import Iterator + +def get_strings(foo: bool) -> Iterator[str]: + if foo: + return ["foo1", "foo2"] # E: No return value expected + else: + yield "bar1" + yield "bar2" +[builtins fixtures/tuple.pyi] + [case testNoCrashOnStarRightHandSide] x = *(1, 2, 3) # E: can't use starred expression here [builtins fixtures/tuple.pyi] From a0a0ada29905b786faf05770b13501fd6a20c891 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 22 Mar 2024 10:01:25 +0000 Subject: [PATCH 136/172] [mypyc] Refactor: use primitive op for initializing list item (#17056) Add a new primitive op for initializing list items. Also add support for primitive ops that steal operands (reference counting wise). This will also remove most instances of `WORD_SIZE` in irbuild tests, which were a bit painful, since running tests with `--update-data` removed these and they had to be manually added back for 32-bit tests to pass. --- mypyc/ir/ops.py | 8 + mypyc/ir/pprint.py | 5 +- mypyc/irbuild/ll_builder.py | 14 +- mypyc/lower/int_ops.py | 14 +- mypyc/lower/list_ops.py | 34 ++++ mypyc/lower/registry.py | 7 +- mypyc/primitives/misc_ops.py | 22 ++- mypyc/primitives/registry.py | 35 ++++ mypyc/test-data/irbuild-any.test | 7 +- mypyc/test-data/irbuild-basic.test | 182 ++++++++++---------- mypyc/test-data/irbuild-classes.test | 2 +- mypyc/test-data/irbuild-dict.test | 2 +- mypyc/test-data/irbuild-generics.test | 2 +- mypyc/test-data/irbuild-i64.test | 4 +- mypyc/test-data/irbuild-lists.test | 32 ++-- mypyc/test-data/irbuild-set.test | 216 ++++++++++++------------ mypyc/test-data/irbuild-statements.test | 67 ++++---- mypyc/test-data/irbuild-str.test | 21 ++- mypyc/test-data/irbuild-tuple.test | 103 ++++++----- mypyc/test-data/lowering-list.test | 33 ++++ mypyc/test-data/refcount.test | 11 +- mypyc/test/test_lowering.py | 4 +- 22 files changed, 463 insertions(+), 362 deletions(-) create mode 100644 mypyc/lower/list_ops.py create mode 100644 mypyc/test-data/lowering-list.test diff --git a/mypyc/ir/ops.py b/mypyc/ir/ops.py index 3acfb0933e5a..7df4347171da 100644 --- a/mypyc/ir/ops.py +++ b/mypyc/ir/ops.py @@ -644,6 +644,14 @@ def __init__(self, args: list[Value], desc: PrimitiveDescription, line: int = -1 def sources(self) -> list[Value]: return self.args + def stolen(self) -> list[Value]: + steals = self.desc.steals + if isinstance(steals, list): + assert len(steals) == len(self.args) + return [arg for arg, steal in zip(self.args, steals) if steal] + else: + return [] if not steals else self.sources() + def accept(self, visitor: OpVisitor[T]) -> T: return visitor.visit_primitive_op(self) diff --git a/mypyc/ir/pprint.py b/mypyc/ir/pprint.py index 2ca6a47921fc..59ee994f012d 100644 --- a/mypyc/ir/pprint.py +++ b/mypyc/ir/pprint.py @@ -232,7 +232,10 @@ def visit_primitive_op(self, op: PrimitiveOp) -> str: type_arg_index += 1 args_str = ", ".join(args) - return self.format("%r = %s %s", op, op.desc.name, args_str) + if op.is_void: + return self.format("%s %s", op.desc.name, args_str) + else: + return self.format("%r = %s %s", op, op.desc.name, args_str) def visit_truncate(self, op: Truncate) -> str: return self.format("%r = truncate %r: %t to %t", op, op.src, op.src_type, op.type) diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index e989471ceb59..134265852b2f 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -67,7 +67,6 @@ PrimitiveOp, RaiseStandardError, Register, - SetMem, Truncate, TupleGet, TupleSet, @@ -165,7 +164,7 @@ uint8_overflow, ) from mypyc.primitives.list_ops import list_build_op, list_extend_op, new_list_op -from mypyc.primitives.misc_ops import bool_op, fast_isinstance_op, none_object_op +from mypyc.primitives.misc_ops import bool_op, buf_init_item, fast_isinstance_op, none_object_op from mypyc.primitives.registry import ( ERR_NEG_INT, CFunctionDescription, @@ -1627,14 +1626,9 @@ def new_list_op(self, values: list[Value], line: int) -> Value: ob_item_ptr = self.add(GetElementPtr(result_list, PyListObject, "ob_item", line)) ob_item_base = self.add(LoadMem(pointer_rprimitive, ob_item_ptr, line)) for i in range(len(values)): - if i == 0: - item_address = ob_item_base - else: - offset = Integer(PLATFORM_SIZE * i, c_pyssize_t_rprimitive, line) - item_address = self.add( - IntOp(pointer_rprimitive, ob_item_base, offset, IntOp.ADD, line) - ) - self.add(SetMem(object_rprimitive, item_address, args[i], line)) + self.primitive_op( + buf_init_item, [ob_item_base, Integer(i, c_pyssize_t_rprimitive), args[i]], line + ) self.add(KeepAlive([result_list])) return result_list diff --git a/mypyc/lower/int_ops.py b/mypyc/lower/int_ops.py index 90a3253ba093..adfb4c21e2de 100644 --- a/mypyc/lower/int_ops.py +++ b/mypyc/lower/int_ops.py @@ -7,7 +7,7 @@ from mypyc.ir.ops import Assign, BasicBlock, Branch, ComparisonOp, Register, Value from mypyc.ir.rtypes import bool_rprimitive, is_short_int_rprimitive from mypyc.irbuild.ll_builder import LowLevelIRBuilder -from mypyc.lower.registry import lower_binary_op +from mypyc.lower.registry import lower_primitive_op from mypyc.primitives.int_ops import int_equal_, int_less_than_ from mypyc.primitives.registry import CFunctionDescription @@ -83,31 +83,31 @@ def compare_tagged(self: LowLevelIRBuilder, lhs: Value, rhs: Value, op: str, lin return result -@lower_binary_op("int_eq") +@lower_primitive_op("int_eq") def lower_int_eq(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], "==", line) -@lower_binary_op("int_ne") +@lower_primitive_op("int_ne") def lower_int_ne(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], "!=", line) -@lower_binary_op("int_lt") +@lower_primitive_op("int_lt") def lower_int_lt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], "<", line) -@lower_binary_op("int_le") +@lower_primitive_op("int_le") def lower_int_le(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], "<=", line) -@lower_binary_op("int_gt") +@lower_primitive_op("int_gt") def lower_int_gt(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], ">", line) -@lower_binary_op("int_ge") +@lower_primitive_op("int_ge") def lower_int_ge(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: return compare_tagged(builder, args[0], args[1], ">=", line) diff --git a/mypyc/lower/list_ops.py b/mypyc/lower/list_ops.py new file mode 100644 index 000000000000..f4619e07dc7e --- /dev/null +++ b/mypyc/lower/list_ops.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from mypyc.common import PLATFORM_SIZE +from mypyc.ir.ops import Integer, IntOp, SetMem, Value +from mypyc.ir.rtypes import c_pyssize_t_rprimitive, object_rprimitive, pointer_rprimitive +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.lower.registry import lower_primitive_op + + +@lower_primitive_op("buf_init_item") +def buf_init_item(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + """Initialize an item in a buffer of "PyObject *" values at given index. + + This can be used to initialize the data buffer of a freshly allocated list + object. + """ + base = args[0] + index_value = args[1] + value = args[2] + assert isinstance(index_value, Integer) + index = index_value.numeric_value() + if index == 0: + ptr = base + else: + ptr = builder.add( + IntOp( + pointer_rprimitive, + base, + Integer(index * PLATFORM_SIZE, c_pyssize_t_rprimitive), + IntOp.ADD, + line, + ) + ) + return builder.add(SetMem(object_rprimitive, ptr, value, line)) diff --git a/mypyc/lower/registry.py b/mypyc/lower/registry.py index cc53eb93f4dd..d1599dc98cf4 100644 --- a/mypyc/lower/registry.py +++ b/mypyc/lower/registry.py @@ -11,8 +11,8 @@ lowering_registry: Final[dict[str, LowerFunc]] = {} -def lower_binary_op(name: str) -> Callable[[LowerFunc], LowerFunc]: - """Register a handler that generates low-level IR for a primitive binary op.""" +def lower_primitive_op(name: str) -> Callable[[LowerFunc], LowerFunc]: + """Register a handler that generates low-level IR for a primitive op.""" def wrapper(f: LowerFunc) -> LowerFunc: assert name not in lowering_registry @@ -23,4 +23,5 @@ def wrapper(f: LowerFunc) -> LowerFunc: # Import various modules that set up global state. -import mypyc.lower.int_ops # noqa: F401 +import mypyc.lower.int_ops +import mypyc.lower.list_ops # noqa: F401 diff --git a/mypyc/primitives/misc_ops.py b/mypyc/primitives/misc_ops.py index 5a8cc111ebc2..87d009f7bbab 100644 --- a/mypyc/primitives/misc_ops.py +++ b/mypyc/primitives/misc_ops.py @@ -13,9 +13,17 @@ int_rprimitive, object_pointer_rprimitive, object_rprimitive, + pointer_rprimitive, str_rprimitive, + void_rtype, +) +from mypyc.primitives.registry import ( + ERR_NEG_INT, + custom_op, + custom_primitive_op, + function_op, + load_address_op, ) -from mypyc.primitives.registry import ERR_NEG_INT, custom_op, function_op, load_address_op # Get the 'bool' type object. load_address_op(name="builtins.bool", type=object_rprimitive, src="PyBool_Type") @@ -232,10 +240,20 @@ ) -# register an implementation for a singledispatch function +# Register an implementation for a singledispatch function register_function = custom_op( arg_types=[object_rprimitive, object_rprimitive, object_rprimitive], return_type=object_rprimitive, c_function_name="CPySingledispatch_RegisterFunction", error_kind=ERR_MAGIC, ) + + +# Initialize a PyObject * item in a memory buffer (steal the value) +buf_init_item = custom_primitive_op( + name="buf_init_item", + arg_types=[pointer_rprimitive, c_pyssize_t_rprimitive, object_rprimitive], + return_type=void_rtype, + error_kind=ERR_NEVER, + steals=[False, False, True], +) diff --git a/mypyc/primitives/registry.py b/mypyc/primitives/registry.py index d4768b4df532..1472885a4829 100644 --- a/mypyc/primitives/registry.py +++ b/mypyc/primitives/registry.py @@ -267,6 +267,41 @@ def custom_op( ) +def custom_primitive_op( + name: str, + arg_types: list[RType], + return_type: RType, + error_kind: int, + c_function_name: str | None = None, + var_arg_type: RType | None = None, + truncated_type: RType | None = None, + ordering: list[int] | None = None, + extra_int_constants: list[tuple[int, RType]] | None = None, + steals: StealsDescription = False, + is_borrowed: bool = False, +) -> PrimitiveDescription: + """Define a primitive op that can't be automatically generated based on the AST. + + Most arguments are similar to method_op(). + """ + if extra_int_constants is None: + extra_int_constants = [] + return PrimitiveDescription( + name=name, + arg_types=arg_types, + return_type=return_type, + var_arg_type=var_arg_type, + truncated_type=truncated_type, + c_function_name=c_function_name, + error_kind=error_kind, + steals=steals, + is_borrowed=is_borrowed, + ordering=ordering, + extra_int_constants=extra_int_constants, + priority=0, + ) + + def unary_op( name: str, arg_type: RType, diff --git a/mypyc/test-data/irbuild-any.test b/mypyc/test-data/irbuild-any.test index 98f3dae9ee88..dd1931ba40f3 100644 --- a/mypyc/test-data/irbuild-any.test +++ b/mypyc/test-data/irbuild-any.test @@ -106,7 +106,7 @@ def f2(a, n, l): r9, r10 :: bit r11 :: list r12 :: object - r13, r14, r15 :: ptr + r13, r14 :: ptr L0: r0 = box(int, n) r1 = PyObject_GetItem(a, r0) @@ -123,9 +123,8 @@ L0: r12 = box(int, n) r13 = get_element_ptr r11 ob_item :: PyListObject r14 = load_mem r13 :: ptr* - set_mem r14, a :: builtins.object* - r15 = r14 + WORD_SIZE*1 - set_mem r15, r12 :: builtins.object* + buf_init_item r14, 0, a + buf_init_item r14, 1, r12 keep_alive r11 return 1 def f3(a, n): diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 164fc213a8a2..766e584d4149 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -771,7 +771,7 @@ L0: r2 = object 1 r3 = get_element_ptr r1 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r2 :: builtins.object* + buf_init_item r4, 0, r2 keep_alive r1 r5 = g(r1) r6 = box(None, 1) @@ -801,7 +801,7 @@ L0: r2 = PyList_New(1) r3 = get_element_ptr r2 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, y :: builtins.object* + buf_init_item r4, 0, y keep_alive r2 a = r2 r5 = (2, 4) @@ -1676,7 +1676,7 @@ L0: r5 = object 1 r6 = get_element_ptr r4 ob_item :: PyListObject r7 = load_mem r6 :: ptr* - set_mem r7, r5 :: builtins.object* + buf_init_item r7, 0, r5 keep_alive r4 r8 = box(tuple[int, int], r0) r9 = CPyList_Extend(r4, r8) @@ -1849,20 +1849,20 @@ def f() -> List[int]: def f(): r0, r1 :: list r2, r3, r4 :: object - r5, r6, r7, r8 :: ptr - r9 :: short_int - r10 :: ptr - r11 :: native_int - r12 :: short_int - r13 :: bit - r14 :: object - r15, x :: int - r16, r17 :: bit - r18 :: int - r19 :: object - r20 :: i32 - r21 :: bit - r22 :: short_int + r5, r6 :: ptr + r7 :: short_int + r8 :: ptr + r9 :: native_int + r10 :: short_int + r11 :: bit + r12 :: object + r13, x :: int + r14, r15 :: bit + r16 :: int + r17 :: object + r18 :: i32 + r19 :: bit + r20 :: short_int L0: r0 = PyList_New(0) r1 = PyList_New(3) @@ -1871,41 +1871,39 @@ L0: r4 = object 3 r5 = get_element_ptr r1 ob_item :: PyListObject r6 = load_mem r5 :: ptr* - set_mem r6, r2 :: builtins.object* - r7 = r6 + WORD_SIZE*1 - set_mem r7, r3 :: builtins.object* - r8 = r6 + WORD_SIZE*2 - set_mem r8, r4 :: builtins.object* + buf_init_item r6, 0, r2 + buf_init_item r6, 1, r3 + buf_init_item r6, 2, r4 keep_alive r1 - r9 = 0 + r7 = 0 L1: - r10 = get_element_ptr r1 ob_size :: PyVarObject - r11 = load_mem r10 :: native_int* + r8 = get_element_ptr r1 ob_size :: PyVarObject + r9 = load_mem r8 :: native_int* keep_alive r1 - r12 = r11 << 1 - r13 = int_lt r9, r12 - if r13 goto L2 else goto L8 :: bool + r10 = r9 << 1 + r11 = int_lt r7, r10 + if r11 goto L2 else goto L8 :: bool L2: - r14 = CPyList_GetItemUnsafe(r1, r9) - r15 = unbox(int, r14) - x = r15 - r16 = int_ne x, 4 - if r16 goto L4 else goto L3 :: bool + r12 = CPyList_GetItemUnsafe(r1, r7) + r13 = unbox(int, r12) + x = r13 + r14 = int_ne x, 4 + if r14 goto L4 else goto L3 :: bool L3: goto L7 L4: - r17 = int_ne x, 6 - if r17 goto L6 else goto L5 :: bool + r15 = int_ne x, 6 + if r15 goto L6 else goto L5 :: bool L5: goto L7 L6: - r18 = CPyTagged_Multiply(x, x) - r19 = box(int, r18) - r20 = PyList_Append(r0, r19) - r21 = r20 >= 0 :: signed + r16 = CPyTagged_Multiply(x, x) + r17 = box(int, r16) + r18 = PyList_Append(r0, r17) + r19 = r18 >= 0 :: signed L7: - r22 = r9 + 2 - r9 = r22 + r20 = r7 + 2 + r7 = r20 goto L1 L8: return r0 @@ -1919,20 +1917,20 @@ def f(): r0 :: dict r1 :: list r2, r3, r4 :: object - r5, r6, r7, r8 :: ptr - r9 :: short_int - r10 :: ptr - r11 :: native_int - r12 :: short_int - r13 :: bit - r14 :: object - r15, x :: int - r16, r17 :: bit - r18 :: int - r19, r20 :: object - r21 :: i32 - r22 :: bit - r23 :: short_int + r5, r6 :: ptr + r7 :: short_int + r8 :: ptr + r9 :: native_int + r10 :: short_int + r11 :: bit + r12 :: object + r13, x :: int + r14, r15 :: bit + r16 :: int + r17, r18 :: object + r19 :: i32 + r20 :: bit + r21 :: short_int L0: r0 = PyDict_New() r1 = PyList_New(3) @@ -1941,42 +1939,40 @@ L0: r4 = object 3 r5 = get_element_ptr r1 ob_item :: PyListObject r6 = load_mem r5 :: ptr* - set_mem r6, r2 :: builtins.object* - r7 = r6 + WORD_SIZE*1 - set_mem r7, r3 :: builtins.object* - r8 = r6 + WORD_SIZE*2 - set_mem r8, r4 :: builtins.object* + buf_init_item r6, 0, r2 + buf_init_item r6, 1, r3 + buf_init_item r6, 2, r4 keep_alive r1 - r9 = 0 + r7 = 0 L1: - r10 = get_element_ptr r1 ob_size :: PyVarObject - r11 = load_mem r10 :: native_int* + r8 = get_element_ptr r1 ob_size :: PyVarObject + r9 = load_mem r8 :: native_int* keep_alive r1 - r12 = r11 << 1 - r13 = int_lt r9, r12 - if r13 goto L2 else goto L8 :: bool + r10 = r9 << 1 + r11 = int_lt r7, r10 + if r11 goto L2 else goto L8 :: bool L2: - r14 = CPyList_GetItemUnsafe(r1, r9) - r15 = unbox(int, r14) - x = r15 - r16 = int_ne x, 4 - if r16 goto L4 else goto L3 :: bool + r12 = CPyList_GetItemUnsafe(r1, r7) + r13 = unbox(int, r12) + x = r13 + r14 = int_ne x, 4 + if r14 goto L4 else goto L3 :: bool L3: goto L7 L4: - r17 = int_ne x, 6 - if r17 goto L6 else goto L5 :: bool + r15 = int_ne x, 6 + if r15 goto L6 else goto L5 :: bool L5: goto L7 L6: - r18 = CPyTagged_Multiply(x, x) - r19 = box(int, x) - r20 = box(int, r18) - r21 = CPyDict_SetItem(r0, r19, r20) - r22 = r21 >= 0 :: signed + r16 = CPyTagged_Multiply(x, x) + r17 = box(int, x) + r18 = box(int, r16) + r19 = CPyDict_SetItem(r0, r17, r18) + r20 = r19 >= 0 :: signed L7: - r23 = r9 + 2 - r9 = r23 + r21 = r7 + 2 + r7 = r21 goto L1 L8: return r0 @@ -2208,11 +2204,11 @@ def __top_level__(): r59 :: bit r60 :: list r61, r62, r63 :: object - r64, r65, r66, r67 :: ptr - r68 :: dict - r69 :: str - r70 :: i32 - r71 :: bit + r64, r65 :: ptr + r66 :: dict + r67 :: str + r68 :: i32 + r69 :: bit L0: r0 = builtins :: module r1 = load_address _Py_NoneStruct @@ -2285,16 +2281,14 @@ L2: r63 = object 3 r64 = get_element_ptr r60 ob_item :: PyListObject r65 = load_mem r64 :: ptr* - set_mem r65, r61 :: builtins.object* - r66 = r65 + WORD_SIZE*1 - set_mem r66, r62 :: builtins.object* - r67 = r65 + WORD_SIZE*2 - set_mem r67, r63 :: builtins.object* + buf_init_item r65, 0, r61 + buf_init_item r65, 1, r62 + buf_init_item r65, 2, r63 keep_alive r60 - r68 = __main__.globals :: static - r69 = 'y' - r70 = CPyDict_SetItem(r68, r69, r60) - r71 = r70 >= 0 :: signed + r66 = __main__.globals :: static + r67 = 'y' + r68 = CPyDict_SetItem(r66, r67, r60) + r69 = r68 >= 0 :: signed return 1 [case testChainedConditional] diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index 8c4743c6a47f..cbed51ebcfb0 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -53,7 +53,7 @@ L0: r2 = PyList_New(1) r3 = get_element_ptr r2 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, c :: builtins.object* + buf_init_item r4, 0, c keep_alive r2 a = r2 r5 = CPyList_GetItemShort(a, 0) diff --git a/mypyc/test-data/irbuild-dict.test b/mypyc/test-data/irbuild-dict.test index 1a84f3fe3098..9445219a08ce 100644 --- a/mypyc/test-data/irbuild-dict.test +++ b/mypyc/test-data/irbuild-dict.test @@ -551,7 +551,7 @@ L2: r4 = object 1 r5 = get_element_ptr r3 ob_item :: PyListObject r6 = load_mem r5 :: ptr* - set_mem r6, r4 :: builtins.object* + buf_init_item r6, 0, r4 keep_alive r3 r7 = CPyDict_SetDefault(d, r2, r3) return r7 diff --git a/mypyc/test-data/irbuild-generics.test b/mypyc/test-data/irbuild-generics.test index 35920889e596..50f6ed6cda1e 100644 --- a/mypyc/test-data/irbuild-generics.test +++ b/mypyc/test-data/irbuild-generics.test @@ -23,7 +23,7 @@ L0: r1 = PyList_New(1) r2 = get_element_ptr r1 ob_item :: PyListObject r3 = load_mem r2 :: ptr* - set_mem r3, r0 :: builtins.object* + buf_init_item r3, 0, r0 keep_alive r1 return r1 def h(x, y): diff --git a/mypyc/test-data/irbuild-i64.test b/mypyc/test-data/irbuild-i64.test index 07f549c9fcc2..ad2a97e6eeff 100644 --- a/mypyc/test-data/irbuild-i64.test +++ b/mypyc/test-data/irbuild-i64.test @@ -1150,7 +1150,7 @@ L0: r1 = PyList_New(1) r2 = get_element_ptr r1 ob_item :: PyListObject r3 = load_mem r2 :: ptr* - set_mem r3, r0 :: builtins.object* + buf_init_item r3, 0, r0 keep_alive r1 a = r1 r4 = CPyList_GetItemInt64Borrow(a, n) @@ -1260,7 +1260,7 @@ L0: r1 = box(i64, n) r2 = get_element_ptr r0 ob_item :: PyListObject r3 = load_mem r2 :: ptr* - set_mem r3, r1 :: builtins.object* + buf_init_item r3, 0, r1 keep_alive r0 r4 = n <= 4611686018427387903 :: signed if r4 goto L1 else goto L2 :: bool diff --git a/mypyc/test-data/irbuild-lists.test b/mypyc/test-data/irbuild-lists.test index ced4646922a3..66aa1dc748be 100644 --- a/mypyc/test-data/irbuild-lists.test +++ b/mypyc/test-data/irbuild-lists.test @@ -108,7 +108,7 @@ def f() -> None: def f(): r0 :: list r1, r2 :: object - r3, r4, r5 :: ptr + r3, r4 :: ptr x :: list L0: r0 = PyList_New(2) @@ -116,9 +116,8 @@ L0: r2 = object 2 r3 = get_element_ptr r0 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r1 :: builtins.object* - r5 = r4 + WORD_SIZE*1 - set_mem r5, r2 :: builtins.object* + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 keep_alive r0 x = r0 return 1 @@ -165,7 +164,7 @@ L0: r2 = object 4 r3 = get_element_ptr r1 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r2 :: builtins.object* + buf_init_item r4, 0, r2 keep_alive r1 r5 = CPySequence_RMultiply(6, r1) b = r5 @@ -253,25 +252,24 @@ def f(x: List[int], y: List[int]) -> List[int]: def f(x, y): x, y, r0 :: list r1, r2 :: object - r3, r4, r5 :: ptr - r6, r7, r8 :: object - r9 :: i32 - r10 :: bit + r3, r4 :: ptr + r5, r6, r7 :: object + r8 :: i32 + r9 :: bit L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 r3 = get_element_ptr r0 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r1 :: builtins.object* - r5 = r4 + WORD_SIZE*1 - set_mem r5, r2 :: builtins.object* + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 keep_alive r0 - r6 = CPyList_Extend(r0, x) - r7 = CPyList_Extend(r0, y) - r8 = object 3 - r9 = PyList_Append(r0, r8) - r10 = r9 >= 0 :: signed + r5 = CPyList_Extend(r0, x) + r6 = CPyList_Extend(r0, y) + r7 = object 3 + r8 = PyList_Append(r0, r7) + r9 = r8 >= 0 :: signed return r0 [case testListIn] diff --git a/mypyc/test-data/irbuild-set.test b/mypyc/test-data/irbuild-set.test index 51feab332593..ea900f2e4789 100644 --- a/mypyc/test-data/irbuild-set.test +++ b/mypyc/test-data/irbuild-set.test @@ -79,20 +79,20 @@ L0: def test1(): r0 :: list r1, r2, r3 :: object - r4, r5, r6, r7 :: ptr + r4, r5 :: ptr tmp_list :: list - r8 :: set - r9 :: short_int - r10 :: ptr - r11 :: native_int - r12 :: short_int - r13 :: bit - r14 :: object - r15, x, r16 :: int - r17 :: object - r18 :: i32 - r19 :: bit - r20 :: short_int + r6 :: set + r7 :: short_int + r8 :: ptr + r9 :: native_int + r10 :: short_int + r11 :: bit + r12 :: object + r13, x, r14 :: int + r15 :: object + r16 :: i32 + r17 :: bit + r18 :: short_int a :: set L0: r0 = PyList_New(3) @@ -101,36 +101,34 @@ L0: r3 = object 5 r4 = get_element_ptr r0 ob_item :: PyListObject r5 = load_mem r4 :: ptr* - set_mem r5, r1 :: builtins.object* - r6 = r5 + WORD_SIZE*1 - set_mem r6, r2 :: builtins.object* - r7 = r5 + WORD_SIZE*2 - set_mem r7, r3 :: builtins.object* + buf_init_item r5, 0, r1 + buf_init_item r5, 1, r2 + buf_init_item r5, 2, r3 keep_alive r0 tmp_list = r0 - r8 = PySet_New(0) - r9 = 0 + r6 = PySet_New(0) + r7 = 0 L1: - r10 = get_element_ptr tmp_list ob_size :: PyVarObject - r11 = load_mem r10 :: native_int* + r8 = get_element_ptr tmp_list ob_size :: PyVarObject + r9 = load_mem r8 :: native_int* keep_alive tmp_list - r12 = r11 << 1 - r13 = int_lt r9, r12 - if r13 goto L2 else goto L4 :: bool + r10 = r9 << 1 + r11 = int_lt r7, r10 + if r11 goto L2 else goto L4 :: bool L2: - r14 = CPyList_GetItemUnsafe(tmp_list, r9) - r15 = unbox(int, r14) - x = r15 - r16 = f(x) - r17 = box(int, r16) - r18 = PySet_Add(r8, r17) - r19 = r18 >= 0 :: signed + r12 = CPyList_GetItemUnsafe(tmp_list, r7) + r13 = unbox(int, r12) + x = r13 + r14 = f(x) + r15 = box(int, r14) + r16 = PySet_Add(r6, r15) + r17 = r16 >= 0 :: signed L3: - r20 = r9 + 2 - r9 = r20 + r18 = r7 + 2 + r7 = r18 goto L1 L4: - a = r8 + a = r6 return 1 def test2(): r0, tmp_tuple :: tuple[int, int, int] @@ -312,33 +310,33 @@ L0: def test(): r0 :: list r1, r2, r3, r4, r5 :: object - r6, r7, r8, r9, r10, r11 :: ptr + r6, r7 :: ptr tmp_list :: list - r12 :: set - r13, r14 :: list - r15 :: short_int - r16 :: ptr - r17 :: native_int - r18 :: short_int - r19 :: bit + r8 :: set + r9, r10 :: list + r11 :: short_int + r12 :: ptr + r13 :: native_int + r14 :: short_int + r15 :: bit + r16 :: object + r17, z :: int + r18 :: bit + r19 :: int r20 :: object - r21, z :: int + r21 :: i32 r22 :: bit - r23 :: int - r24 :: object - r25 :: i32 - r26 :: bit - r27 :: short_int - r28, r29, r30 :: object - r31, y, r32 :: int - r33 :: object - r34 :: i32 - r35, r36 :: bit - r37, r38, r39 :: object - r40, x, r41 :: int - r42 :: object - r43 :: i32 - r44, r45 :: bit + r23 :: short_int + r24, r25, r26 :: object + r27, y, r28 :: int + r29 :: object + r30 :: i32 + r31, r32 :: bit + r33, r34, r35 :: object + r36, x, r37 :: int + r38 :: object + r39 :: i32 + r40, r41 :: bit a :: set L0: r0 = PyList_New(5) @@ -349,81 +347,77 @@ L0: r5 = object 5 r6 = get_element_ptr r0 ob_item :: PyListObject r7 = load_mem r6 :: ptr* - set_mem r7, r1 :: builtins.object* - r8 = r7 + WORD_SIZE*1 - set_mem r8, r2 :: builtins.object* - r9 = r7 + WORD_SIZE*2 - set_mem r9, r3 :: builtins.object* - r10 = r7 + WORD_SIZE*3 - set_mem r10, r4 :: builtins.object* - r11 = r7 + WORD_SIZE*4 - set_mem r11, r5 :: builtins.object* + buf_init_item r7, 0, r1 + buf_init_item r7, 1, r2 + buf_init_item r7, 2, r3 + buf_init_item r7, 3, r4 + buf_init_item r7, 4, r5 keep_alive r0 tmp_list = r0 - r12 = PySet_New(0) - r13 = PyList_New(0) - r14 = PyList_New(0) - r15 = 0 + r8 = PySet_New(0) + r9 = PyList_New(0) + r10 = PyList_New(0) + r11 = 0 L1: - r16 = get_element_ptr tmp_list ob_size :: PyVarObject - r17 = load_mem r16 :: native_int* + r12 = get_element_ptr tmp_list ob_size :: PyVarObject + r13 = load_mem r12 :: native_int* keep_alive tmp_list - r18 = r17 << 1 - r19 = int_lt r15, r18 - if r19 goto L2 else goto L6 :: bool + r14 = r13 << 1 + r15 = int_lt r11, r14 + if r15 goto L2 else goto L6 :: bool L2: - r20 = CPyList_GetItemUnsafe(tmp_list, r15) - r21 = unbox(int, r20) - z = r21 - r22 = int_lt z, 8 - if r22 goto L4 else goto L3 :: bool + r16 = CPyList_GetItemUnsafe(tmp_list, r11) + r17 = unbox(int, r16) + z = r17 + r18 = int_lt z, 8 + if r18 goto L4 else goto L3 :: bool L3: goto L5 L4: - r23 = f1(z) - r24 = box(int, r23) - r25 = PyList_Append(r14, r24) - r26 = r25 >= 0 :: signed + r19 = f1(z) + r20 = box(int, r19) + r21 = PyList_Append(r10, r20) + r22 = r21 >= 0 :: signed L5: - r27 = r15 + 2 - r15 = r27 + r23 = r11 + 2 + r11 = r23 goto L1 L6: - r28 = PyObject_GetIter(r14) - r29 = PyObject_GetIter(r28) + r24 = PyObject_GetIter(r10) + r25 = PyObject_GetIter(r24) L7: - r30 = PyIter_Next(r29) - if is_error(r30) goto L10 else goto L8 + r26 = PyIter_Next(r25) + if is_error(r26) goto L10 else goto L8 L8: - r31 = unbox(int, r30) - y = r31 - r32 = f2(y) - r33 = box(int, r32) - r34 = PyList_Append(r13, r33) - r35 = r34 >= 0 :: signed + r27 = unbox(int, r26) + y = r27 + r28 = f2(y) + r29 = box(int, r28) + r30 = PyList_Append(r9, r29) + r31 = r30 >= 0 :: signed L9: goto L7 L10: - r36 = CPy_NoErrOccured() + r32 = CPy_NoErrOccured() L11: - r37 = PyObject_GetIter(r13) - r38 = PyObject_GetIter(r37) + r33 = PyObject_GetIter(r9) + r34 = PyObject_GetIter(r33) L12: - r39 = PyIter_Next(r38) - if is_error(r39) goto L15 else goto L13 + r35 = PyIter_Next(r34) + if is_error(r35) goto L15 else goto L13 L13: - r40 = unbox(int, r39) - x = r40 - r41 = f3(x) - r42 = box(int, r41) - r43 = PySet_Add(r12, r42) - r44 = r43 >= 0 :: signed + r36 = unbox(int, r35) + x = r36 + r37 = f3(x) + r38 = box(int, r37) + r39 = PySet_Add(r8, r38) + r40 = r39 >= 0 :: signed L14: goto L12 L15: - r45 = CPy_NoErrOccured() + r41 = CPy_NoErrOccured() L16: - a = r12 + a = r8 return 1 [case testSetSize] diff --git a/mypyc/test-data/irbuild-statements.test b/mypyc/test-data/irbuild-statements.test index ed97c4cd4138..628d692c85c1 100644 --- a/mypyc/test-data/irbuild-statements.test +++ b/mypyc/test-data/irbuild-statements.test @@ -688,40 +688,39 @@ def delListMultiple() -> None: def delList(): r0 :: list r1, r2 :: object - r3, r4, r5 :: ptr + r3, r4 :: ptr l :: list - r6 :: object - r7 :: i32 - r8 :: bit + r5 :: object + r6 :: i32 + r7 :: bit L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 r3 = get_element_ptr r0 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r1 :: builtins.object* - r5 = r4 + WORD_SIZE*1 - set_mem r5, r2 :: builtins.object* + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 keep_alive r0 l = r0 - r6 = object 1 - r7 = PyObject_DelItem(l, r6) - r8 = r7 >= 0 :: signed + r5 = object 1 + r6 = PyObject_DelItem(l, r5) + r7 = r6 >= 0 :: signed return 1 def delListMultiple(): r0 :: list r1, r2, r3, r4, r5, r6, r7 :: object - r8, r9, r10, r11, r12, r13, r14, r15 :: ptr + r8, r9 :: ptr l :: list + r10 :: object + r11 :: i32 + r12 :: bit + r13 :: object + r14 :: i32 + r15 :: bit r16 :: object r17 :: i32 r18 :: bit - r19 :: object - r20 :: i32 - r21 :: bit - r22 :: object - r23 :: i32 - r24 :: bit L0: r0 = PyList_New(7) r1 = object 1 @@ -733,30 +732,24 @@ L0: r7 = object 7 r8 = get_element_ptr r0 ob_item :: PyListObject r9 = load_mem r8 :: ptr* - set_mem r9, r1 :: builtins.object* - r10 = r9 + WORD_SIZE*1 - set_mem r10, r2 :: builtins.object* - r11 = r9 + WORD_SIZE*2 - set_mem r11, r3 :: builtins.object* - r12 = r9 + WORD_SIZE*3 - set_mem r12, r4 :: builtins.object* - r13 = r9 + WORD_SIZE*4 - set_mem r13, r5 :: builtins.object* - r14 = r9 + WORD_SIZE*5 - set_mem r14, r6 :: builtins.object* - r15 = r9 + WORD_SIZE*6 - set_mem r15, r7 :: builtins.object* + buf_init_item r9, 0, r1 + buf_init_item r9, 1, r2 + buf_init_item r9, 2, r3 + buf_init_item r9, 3, r4 + buf_init_item r9, 4, r5 + buf_init_item r9, 5, r6 + buf_init_item r9, 6, r7 keep_alive r0 l = r0 - r16 = object 1 + r10 = object 1 + r11 = PyObject_DelItem(l, r10) + r12 = r11 >= 0 :: signed + r13 = object 2 + r14 = PyObject_DelItem(l, r13) + r15 = r14 >= 0 :: signed + r16 = object 3 r17 = PyObject_DelItem(l, r16) r18 = r17 >= 0 :: signed - r19 = object 2 - r20 = PyObject_DelItem(l, r19) - r21 = r20 >= 0 :: signed - r22 = object 3 - r23 = PyObject_DelItem(l, r22) - r24 = r23 >= 0 :: signed return 1 [case testDelDict] diff --git a/mypyc/test-data/irbuild-str.test b/mypyc/test-data/irbuild-str.test index 9851e0f4fb24..dfaa50520364 100644 --- a/mypyc/test-data/irbuild-str.test +++ b/mypyc/test-data/irbuild-str.test @@ -203,8 +203,8 @@ def f(var, num): r12 :: object r13 :: str r14 :: list - r15, r16, r17 :: ptr - r18, s2, r19, s3, r20, s4 :: str + r15, r16 :: ptr + r17, s2, r18, s3, r19, s4 :: str L0: r0 = "Hi! I'm " r1 = '. I am ' @@ -224,16 +224,15 @@ L0: r14 = PyList_New(2) r15 = get_element_ptr r14 ob_item :: PyListObject r16 = load_mem r15 :: ptr* - set_mem r16, r6 :: builtins.object* - r17 = r16 + WORD_SIZE*1 - set_mem r17, r13 :: builtins.object* + buf_init_item r16, 0, r6 + buf_init_item r16, 1, r13 keep_alive r14 - r18 = PyUnicode_Join(r5, r14) - s2 = r18 - r19 = '' - s3 = r19 - r20 = 'abc' - s4 = r20 + r17 = PyUnicode_Join(r5, r14) + s2 = r17 + r18 = '' + s3 = r18 + r19 = 'abc' + s4 = r19 return 1 [case testStringFormattingCStyle] diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index 342bb19b5360..0a26d8aa1d3d 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -101,28 +101,27 @@ def f(x, y): x, y :: object r0 :: list r1, r2 :: object - r3, r4, r5 :: ptr - r6, r7, r8 :: object - r9 :: i32 - r10 :: bit - r11 :: tuple + r3, r4 :: ptr + r5, r6, r7 :: object + r8 :: i32 + r9 :: bit + r10 :: tuple L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 r3 = get_element_ptr r0 ob_item :: PyListObject r4 = load_mem r3 :: ptr* - set_mem r4, r1 :: builtins.object* - r5 = r4 + WORD_SIZE*1 - set_mem r5, r2 :: builtins.object* + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 keep_alive r0 - r6 = CPyList_Extend(r0, x) - r7 = CPyList_Extend(r0, y) - r8 = object 3 - r9 = PyList_Append(r0, r8) - r10 = r9 >= 0 :: signed - r11 = PyList_AsTuple(r0) - return r11 + r5 = CPyList_Extend(r0, x) + r6 = CPyList_Extend(r0, y) + r7 = object 3 + r8 = PyList_Append(r0, r7) + r9 = r8 >= 0 :: signed + r10 = PyList_AsTuple(r0) + return r10 [case testTupleFor] from typing import Tuple, List @@ -238,22 +237,22 @@ L0: def test(): r0 :: list r1, r2, r3 :: object - r4, r5, r6, r7 :: ptr + r4, r5 :: ptr source :: list - r8 :: ptr - r9 :: native_int - r10 :: tuple - r11 :: short_int - r12 :: ptr - r13 :: native_int - r14 :: short_int - r15 :: bit - r16 :: object - r17, x :: int - r18 :: bool - r19 :: object - r20 :: bit - r21 :: short_int + r6 :: ptr + r7 :: native_int + r8 :: tuple + r9 :: short_int + r10 :: ptr + r11 :: native_int + r12 :: short_int + r13 :: bit + r14 :: object + r15, x :: int + r16 :: bool + r17 :: object + r18 :: bit + r19 :: short_int a :: tuple L0: r0 = PyList_New(3) @@ -262,38 +261,36 @@ L0: r3 = object 3 r4 = get_element_ptr r0 ob_item :: PyListObject r5 = load_mem r4 :: ptr* - set_mem r5, r1 :: builtins.object* - r6 = r5 + WORD_SIZE*1 - set_mem r6, r2 :: builtins.object* - r7 = r5 + WORD_SIZE*2 - set_mem r7, r3 :: builtins.object* + buf_init_item r5, 0, r1 + buf_init_item r5, 1, r2 + buf_init_item r5, 2, r3 keep_alive r0 source = r0 - r8 = get_element_ptr source ob_size :: PyVarObject - r9 = load_mem r8 :: native_int* + r6 = get_element_ptr source ob_size :: PyVarObject + r7 = load_mem r6 :: native_int* keep_alive source - r10 = PyTuple_New(r9) - r11 = 0 + r8 = PyTuple_New(r7) + r9 = 0 L1: - r12 = get_element_ptr source ob_size :: PyVarObject - r13 = load_mem r12 :: native_int* + r10 = get_element_ptr source ob_size :: PyVarObject + r11 = load_mem r10 :: native_int* keep_alive source - r14 = r13 << 1 - r15 = int_lt r11, r14 - if r15 goto L2 else goto L4 :: bool + r12 = r11 << 1 + r13 = int_lt r9, r12 + if r13 goto L2 else goto L4 :: bool L2: - r16 = CPyList_GetItemUnsafe(source, r11) - r17 = unbox(int, r16) - x = r17 - r18 = f(x) - r19 = box(bool, r18) - r20 = CPySequenceTuple_SetItemUnsafe(r10, r11, r19) + r14 = CPyList_GetItemUnsafe(source, r9) + r15 = unbox(int, r14) + x = r15 + r16 = f(x) + r17 = box(bool, r16) + r18 = CPySequenceTuple_SetItemUnsafe(r8, r9, r17) L3: - r21 = r11 + 2 - r11 = r21 + r19 = r9 + 2 + r9 = r19 goto L1 L4: - a = r10 + a = r8 return 1 [case testTupleBuiltFromStr] diff --git a/mypyc/test-data/lowering-list.test b/mypyc/test-data/lowering-list.test new file mode 100644 index 000000000000..c8438d869970 --- /dev/null +++ b/mypyc/test-data/lowering-list.test @@ -0,0 +1,33 @@ +[case testLowerListDisplay] +def f() -> None: + a = [4, 6, 7] +[out] +def f(): + r0 :: list + r1, r2, r3 :: object + r4, r5, r6, r7 :: ptr + a :: list + r8 :: None +L0: + r0 = PyList_New(3) + if is_error(r0) goto L2 (error at f:2) else goto L1 +L1: + r1 = object 4 + r2 = object 6 + r3 = object 7 + r4 = get_element_ptr r0 ob_item :: PyListObject + r5 = load_mem r4 :: ptr* + inc_ref r1 + set_mem r5, r1 :: builtins.object* + inc_ref r2 + r6 = r5 + WORD_SIZE*1 + set_mem r6, r2 :: builtins.object* + inc_ref r3 + r7 = r5 + WORD_SIZE*2 + set_mem r7, r3 :: builtins.object* + a = r0 + dec_ref a + return 1 +L2: + r8 = :: None + return r8 diff --git a/mypyc/test-data/refcount.test b/mypyc/test-data/refcount.test index 3021381abded..b8d598e3b533 100644 --- a/mypyc/test-data/refcount.test +++ b/mypyc/test-data/refcount.test @@ -498,7 +498,7 @@ def f() -> int: def f(): r0 :: list r1, r2 :: object - r3, r4, r5 :: ptr + r3, r4 :: ptr a :: list L0: r0 = PyList_New(2) @@ -507,10 +507,9 @@ L0: r3 = get_element_ptr r0 ob_item :: PyListObject r4 = load_mem r3 :: ptr* inc_ref r1 - set_mem r4, r1 :: builtins.object* - r5 = r4 + WORD_SIZE*1 + buf_init_item r4, 0, r1 inc_ref r2 - set_mem r5, r2 :: builtins.object* + buf_init_item r4, 1, r2 a = r0 dec_ref a return 0 @@ -586,7 +585,7 @@ L0: r1 = PyList_New(1) r2 = get_element_ptr r1 ob_item :: PyListObject r3 = load_mem r2 :: ptr* - set_mem r3, r0 :: builtins.object* + buf_init_item r3, 0, r0 a = r1 r4 = CPyList_GetItemShort(a, 0) dec_ref a @@ -1266,7 +1265,7 @@ L0: r1 = PyList_New(1) r2 = get_element_ptr r1 ob_item :: PyListObject r3 = load_mem r2 :: ptr* - set_mem r3, r0 :: builtins.object* + buf_init_item r3, 0, r0 a = r1 r4 = CPyList_GetItemShortBorrow(a, 0) r5 = borrow cast(__main__.C, r4) diff --git a/mypyc/test/test_lowering.py b/mypyc/test/test_lowering.py index e32dba2e1021..50a9a7390855 100644 --- a/mypyc/test/test_lowering.py +++ b/mypyc/test/test_lowering.py @@ -16,6 +16,7 @@ assert_test_output, build_ir_for_single_file, remove_comment_lines, + replace_word_size, use_custom_builtins, ) from mypyc.transform.exceptions import insert_exception_handling @@ -26,12 +27,13 @@ class TestLowering(MypycDataSuite): - files = ["lowering-int.test"] + files = ["lowering-int.test", "lowering-list.test"] base_path = test_temp_dir def run_case(self, testcase: DataDrivenTestCase) -> None: with use_custom_builtins(os.path.join(self.data_prefix, ICODE_GEN_BUILTINS), testcase): expected_output = remove_comment_lines(testcase.output) + expected_output = replace_word_size(expected_output) try: ir = build_ir_for_single_file(testcase.input) except CompileError as e: From 5db161ffbfd7d9cdd837410cd5d581c0ba597623 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Fri, 22 Mar 2024 12:55:06 -0700 Subject: [PATCH 137/172] Store typeshed patches in repo (#17054) This way, we don't have to do the two step rebase and merge + update hashes dance. We also get a cleaner commit history --- .pre-commit-config.yaml | 2 +- misc/sync-typeshed.py | 101 +++++----- ...e-of-LiteralString-in-builtins-13743.patch | 182 ++++++++++++++++++ ...ert-sum-literal-integer-change-13961.patch | 36 ++++ .../0001-Revert-typeshed-ctypes-change.patch | 32 +++ 5 files changed, 306 insertions(+), 47 deletions(-) create mode 100644 misc/typeshed_patches/0001-Remove-use-of-LiteralString-in-builtins-13743.patch create mode 100644 misc/typeshed_patches/0001-Revert-sum-literal-integer-change-13961.patch create mode 100644 misc/typeshed_patches/0001-Revert-typeshed-ctypes-change.patch diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4cfb8297a66a..a7ff48051aad 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: '^(mypyc/external/)|(mypy/typeshed/)' # Exclude all vendored code from lints +exclude: '^(mypyc/external/)|(mypy/typeshed/)|misc/typeshed_patches' # Exclude all vendored code from lints repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 # must match test-requirements.txt diff --git a/misc/sync-typeshed.py b/misc/sync-typeshed.py index 2dc6e230df00..3101b4bfa72a 100644 --- a/misc/sync-typeshed.py +++ b/misc/sync-typeshed.py @@ -11,6 +11,7 @@ import argparse import functools +import glob import os import re import shutil @@ -148,58 +149,66 @@ def main() -> None: if os.environ.get("GITHUB_TOKEN") is None: raise ValueError("GITHUB_TOKEN environment variable must be set") - branch_name = "mypybot/sync-typeshed" - subprocess.run(["git", "checkout", "-B", branch_name, "origin/master"], check=True) - - if not args.typeshed_dir: - # Clone typeshed repo if no directory given. - with tempfile.TemporaryDirectory() as tempdir: - print(f"Cloning typeshed in {tempdir}...") + with tempfile.TemporaryDirectory() as tmpdir: + # Stash patches before checking out a new branch + typeshed_patches = os.path.join("misc", "typeshed_patches") + tmp_patches = os.path.join(tmpdir, "typeshed_patches") + shutil.copytree(typeshed_patches, tmp_patches) + + branch_name = "mypybot/sync-typeshed" + subprocess.run(["git", "checkout", "-B", branch_name, "origin/master"], check=True) + + # Copy the stashed patches back + shutil.rmtree(typeshed_patches, ignore_errors=True) + shutil.copytree(tmp_patches, typeshed_patches) + if subprocess.run(["git", "diff", "--quiet", "--exit-code"], check=False).returncode != 0: + subprocess.run(["git", "commit", "-am", "Update typeshed patches"], check=True) + + if not args.typeshed_dir: + tmp_typeshed = os.path.join(tmpdir, "typeshed") + os.makedirs(tmp_typeshed) + # Clone typeshed repo if no directory given. + print(f"Cloning typeshed in {tmp_typeshed}...") subprocess.run( - ["git", "clone", "https://github.com/python/typeshed.git"], check=True, cwd=tempdir + ["git", "clone", "https://github.com/python/typeshed.git"], + check=True, + cwd=tmp_typeshed, ) - repo = os.path.join(tempdir, "typeshed") + repo = os.path.join(tmp_typeshed, "typeshed") commit = update_typeshed(repo, args.commit) - else: - commit = update_typeshed(args.typeshed_dir, args.commit) + else: + commit = update_typeshed(args.typeshed_dir, args.commit) - assert commit + assert commit - # Create a commit - message = textwrap.dedent( - f"""\ - Sync typeshed + # Create a commit + message = textwrap.dedent( + f"""\ + Sync typeshed - Source commit: - https://github.com/python/typeshed/commit/{commit} - """ - ) - subprocess.run(["git", "add", "--all", os.path.join("mypy", "typeshed")], check=True) - subprocess.run(["git", "commit", "-m", message], check=True) - print("Created typeshed sync commit.") - - commits_to_cherry_pick = [ - "5c00e362d", # LiteralString reverts - "44bc98bd5", # sum reverts - "61a490091", # ctypes reverts - ] - for commit in commits_to_cherry_pick: - try: - subprocess.run(["git", "cherry-pick", commit], check=True) - except subprocess.CalledProcessError: - if not sys.__stdin__.isatty(): - # We're in an automated context - raise - - # Allow the option to merge manually - print( - f"Commit {commit} failed to cherry pick." - " In a separate shell, please manually merge and continue cherry pick." - ) - rsp = input("Did you finish the cherry pick? [y/N]: ") - if rsp.lower() not in {"y", "yes"}: - raise - print(f"Cherry-picked {commit}.") + Source commit: + https://github.com/python/typeshed/commit/{commit} + """ + ) + subprocess.run(["git", "add", "--all", os.path.join("mypy", "typeshed")], check=True) + subprocess.run(["git", "commit", "-m", message], check=True) + print("Created typeshed sync commit.") + + patches = sorted(glob.glob(os.path.join(typeshed_patches, "*.patch"))) + for patch in patches: + cmd = ["git", "am", "--3way", patch] + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + raise RuntimeError( + f"\n\nFailed to apply patch {patch}\n" + "1. Resolve the conflict, `git add --update`, then run `git am --continue`\n" + "2. Run `git format-patch -1 -o misc/typeshed_patches ` " + "to update the patch file.\n" + "3. Re-run sync-typeshed.py" + ) from e + + print(f"Applied patch {patch}") if args.make_pr: subprocess.run(["git", "push", "--force", "origin", branch_name], check=True) diff --git a/misc/typeshed_patches/0001-Remove-use-of-LiteralString-in-builtins-13743.patch b/misc/typeshed_patches/0001-Remove-use-of-LiteralString-in-builtins-13743.patch new file mode 100644 index 000000000000..6a0977dfc489 --- /dev/null +++ b/misc/typeshed_patches/0001-Remove-use-of-LiteralString-in-builtins-13743.patch @@ -0,0 +1,182 @@ +From 5c00e362d40aa26e0a22a740f05a52d05edf0f91 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] Remove use of LiteralString in builtins (#13743) + +--- + mypy/typeshed/stdlib/builtins.pyi | 88 ------------------------------- + 1 file changed, 88 deletions(-) + +diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi +index b4765b26c..99919c64c 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, +@@ -434,31 +433,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, sub: 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: ... +@@ -474,89 +458,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 +@@ -567,9 +494,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] +@@ -578,25 +502,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]: ... + +-- +2.39.3 (Apple Git-146) + diff --git a/misc/typeshed_patches/0001-Revert-sum-literal-integer-change-13961.patch b/misc/typeshed_patches/0001-Revert-sum-literal-integer-change-13961.patch new file mode 100644 index 000000000000..044e672bfda5 --- /dev/null +++ b/misc/typeshed_patches/0001-Revert-sum-literal-integer-change-13961.patch @@ -0,0 +1,36 @@ +From 44bc98bd50e7170887f0740b53ed95a8eb04f00e 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] 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 99919c64c..680cd5561 100644 +--- a/mypy/typeshed/stdlib/builtins.pyi ++++ b/mypy/typeshed/stdlib/builtins.pyi +@@ -1596,7 +1596,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 +-- +2.39.3 (Apple Git-146) + diff --git a/misc/typeshed_patches/0001-Revert-typeshed-ctypes-change.patch b/misc/typeshed_patches/0001-Revert-typeshed-ctypes-change.patch new file mode 100644 index 000000000000..27066bf3c25b --- /dev/null +++ b/misc/typeshed_patches/0001-Revert-typeshed-ctypes-change.patch @@ -0,0 +1,32 @@ +From 61a490091d7c941780919660dc4fdfa88ae6474a Mon Sep 17 00:00:00 2001 +From: AlexWaygood +Date: Mon, 1 May 2023 20:34:55 +0100 +Subject: [PATCH] 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 60bbc51d9..cf9cb81a4 100644 +--- a/mypy/typeshed/stdlib/_ctypes.pyi ++++ b/mypy/typeshed/stdlib/_ctypes.pyi +@@ -169,11 +169,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 +-- +2.39.3 (Apple Git-146) + From 433e8c92947fc2673084561b4c0d76db4d4a4aa4 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Mon, 25 Mar 2024 12:47:46 +0000 Subject: [PATCH 138/172] [mypyc] Refactor: add two list primitive ops (#17058) Add ops for getting list size and a pointer to list item data. This simplifies the IR generated in the main irbuild pass. Continue work on mypyc/mypyc#854. --- mypyc/irbuild/ll_builder.py | 19 +- mypyc/lower/list_ops.py | 15 +- mypyc/lower/misc_ops.py | 12 + mypyc/lower/registry.py | 3 +- mypyc/primitives/list_ops.py | 10 + mypyc/primitives/misc_ops.py | 8 + mypyc/test-data/irbuild-any.test | 9 +- mypyc/test-data/irbuild-basic.test | 390 +++++++++++------------- mypyc/test-data/irbuild-bool.test | 19 +- mypyc/test-data/irbuild-bytes.test | 13 +- mypyc/test-data/irbuild-classes.test | 25 +- mypyc/test-data/irbuild-dict.test | 17 +- mypyc/test-data/irbuild-generics.test | 7 +- mypyc/test-data/irbuild-i64.test | 178 +++++------ mypyc/test-data/irbuild-lists.test | 353 ++++++++++----------- mypyc/test-data/irbuild-set.test | 216 +++++++------ mypyc/test-data/irbuild-statements.test | 268 ++++++++-------- mypyc/test-data/irbuild-str.test | 23 +- mypyc/test-data/irbuild-tuple.test | 206 ++++++------- mypyc/test-data/refcount.test | 71 ++--- 20 files changed, 883 insertions(+), 979 deletions(-) create mode 100644 mypyc/lower/misc_ops.py diff --git a/mypyc/irbuild/ll_builder.py b/mypyc/irbuild/ll_builder.py index 134265852b2f..a05040e25f76 100644 --- a/mypyc/irbuild/ll_builder.py +++ b/mypyc/irbuild/ll_builder.py @@ -78,10 +78,8 @@ int_op_to_id, ) from mypyc.ir.rtypes import ( - PyListObject, PyObject, PySetObject, - PyVarObject, RArray, RInstance, RPrimitive, @@ -163,8 +161,14 @@ ssize_t_to_int_op, uint8_overflow, ) -from mypyc.primitives.list_ops import list_build_op, list_extend_op, new_list_op -from mypyc.primitives.misc_ops import bool_op, buf_init_item, fast_isinstance_op, none_object_op +from mypyc.primitives.list_ops import list_build_op, list_extend_op, list_items, new_list_op +from mypyc.primitives.misc_ops import ( + bool_op, + buf_init_item, + fast_isinstance_op, + none_object_op, + var_object_size, +) from mypyc.primitives.registry import ( ERR_NEG_INT, CFunctionDescription, @@ -1623,8 +1627,7 @@ def new_list_op(self, values: list[Value], line: int) -> Value: if not values: return result_list args = [self.coerce(item, object_rprimitive, line) for item in values] - ob_item_ptr = self.add(GetElementPtr(result_list, PyListObject, "ob_item", line)) - ob_item_base = self.add(LoadMem(pointer_rprimitive, ob_item_ptr, line)) + ob_item_base = self.add(PrimitiveOp([result_list], list_items, line)) for i in range(len(values)): self.primitive_op( buf_init_item, [ob_item_base, Integer(i, c_pyssize_t_rprimitive), args[i]], line @@ -2165,9 +2168,7 @@ def builtin_len(self, val: Value, line: int, use_pyssize_t: bool = False) -> Val typ = val.type size_value = None if is_list_rprimitive(typ) or is_tuple_rprimitive(typ) or is_bytes_rprimitive(typ): - elem_address = self.add(GetElementPtr(val, PyVarObject, "ob_size")) - size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) - self.add(KeepAlive([val])) + size_value = self.primitive_op(var_object_size, [val], line) elif is_set_rprimitive(typ): elem_address = self.add(GetElementPtr(val, PySetObject, "used")) size_value = self.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) diff --git a/mypyc/lower/list_ops.py b/mypyc/lower/list_ops.py index f4619e07dc7e..0d2e3e7169d8 100644 --- a/mypyc/lower/list_ops.py +++ b/mypyc/lower/list_ops.py @@ -1,8 +1,13 @@ from __future__ import annotations from mypyc.common import PLATFORM_SIZE -from mypyc.ir.ops import Integer, IntOp, SetMem, Value -from mypyc.ir.rtypes import c_pyssize_t_rprimitive, object_rprimitive, pointer_rprimitive +from mypyc.ir.ops import GetElementPtr, Integer, IntOp, LoadMem, SetMem, Value +from mypyc.ir.rtypes import ( + PyListObject, + c_pyssize_t_rprimitive, + object_rprimitive, + pointer_rprimitive, +) from mypyc.irbuild.ll_builder import LowLevelIRBuilder from mypyc.lower.registry import lower_primitive_op @@ -32,3 +37,9 @@ def buf_init_item(builder: LowLevelIRBuilder, args: list[Value], line: int) -> V ) ) return builder.add(SetMem(object_rprimitive, ptr, value, line)) + + +@lower_primitive_op("list_items") +def list_items(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + ob_item_ptr = builder.add(GetElementPtr(args[0], PyListObject, "ob_item", line)) + return builder.add(LoadMem(pointer_rprimitive, ob_item_ptr, line)) diff --git a/mypyc/lower/misc_ops.py b/mypyc/lower/misc_ops.py new file mode 100644 index 000000000000..1effcd4f42ac --- /dev/null +++ b/mypyc/lower/misc_ops.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +from mypyc.ir.ops import GetElementPtr, LoadMem, Value +from mypyc.ir.rtypes import PyVarObject, c_pyssize_t_rprimitive +from mypyc.irbuild.ll_builder import LowLevelIRBuilder +from mypyc.lower.registry import lower_primitive_op + + +@lower_primitive_op("var_object_size") +def var_object_size(builder: LowLevelIRBuilder, args: list[Value], line: int) -> Value: + elem_address = builder.add(GetElementPtr(args[0], PyVarObject, "ob_size")) + return builder.add(LoadMem(c_pyssize_t_rprimitive, elem_address)) diff --git a/mypyc/lower/registry.py b/mypyc/lower/registry.py index d1599dc98cf4..084d57df4608 100644 --- a/mypyc/lower/registry.py +++ b/mypyc/lower/registry.py @@ -23,5 +23,4 @@ def wrapper(f: LowerFunc) -> LowerFunc: # Import various modules that set up global state. -import mypyc.lower.int_ops -import mypyc.lower.list_ops # noqa: F401 +from mypyc.lower import int_ops, list_ops, misc_ops # noqa: F401 diff --git a/mypyc/primitives/list_ops.py b/mypyc/primitives/list_ops.py index 7fe3157f3a38..cb75e19a8dea 100644 --- a/mypyc/primitives/list_ops.py +++ b/mypyc/primitives/list_ops.py @@ -11,12 +11,14 @@ int_rprimitive, list_rprimitive, object_rprimitive, + pointer_rprimitive, short_int_rprimitive, ) from mypyc.primitives.registry import ( ERR_NEG_INT, binary_op, custom_op, + custom_primitive_op, function_op, load_address_op, method_op, @@ -60,6 +62,14 @@ steals=True, ) +# Get pointer to list items (ob_item PyListObject field) +list_items = custom_primitive_op( + name="list_items", + arg_types=[list_rprimitive], + return_type=pointer_rprimitive, + error_kind=ERR_NEVER, +) + # list[index] (for an integer index) list_get_item_op = method_op( name="__getitem__", diff --git a/mypyc/primitives/misc_ops.py b/mypyc/primitives/misc_ops.py index 87d009f7bbab..fea62bbb19c4 100644 --- a/mypyc/primitives/misc_ops.py +++ b/mypyc/primitives/misc_ops.py @@ -257,3 +257,11 @@ error_kind=ERR_NEVER, steals=[False, False, True], ) + +# Get length of PyVarObject instance (e.g. list or tuple) +var_object_size = custom_primitive_op( + name="var_object_size", + arg_types=[object_rprimitive], + return_type=c_pyssize_t_rprimitive, + error_kind=ERR_NEVER, +) diff --git a/mypyc/test-data/irbuild-any.test b/mypyc/test-data/irbuild-any.test index dd1931ba40f3..0d14e1a5dfc8 100644 --- a/mypyc/test-data/irbuild-any.test +++ b/mypyc/test-data/irbuild-any.test @@ -106,7 +106,7 @@ def f2(a, n, l): r9, r10 :: bit r11 :: list r12 :: object - r13, r14 :: ptr + r13 :: ptr L0: r0 = box(int, n) r1 = PyObject_GetItem(a, r0) @@ -121,10 +121,9 @@ L0: r10 = CPyList_SetItem(l, n, a) r11 = PyList_New(2) r12 = box(int, n) - r13 = get_element_ptr r11 ob_item :: PyListObject - r14 = load_mem r13 :: ptr* - buf_init_item r14, 0, a - buf_init_item r14, 1, r12 + r13 = list_items r11 + buf_init_item r13, 0, a + buf_init_item r13, 1, r12 keep_alive r11 return 1 def f3(a, n): diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 766e584d4149..11df241b5074 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -761,21 +761,20 @@ def g(y): r0 :: None r1 :: list r2 :: object - r3, r4 :: ptr - r5 :: None - r6 :: object - r7 :: None + r3 :: ptr + r4 :: None + r5 :: object + r6 :: None L0: r0 = g(y) r1 = PyList_New(1) r2 = object 1 - r3 = get_element_ptr r1 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r2 + r3 = list_items r1 + buf_init_item r3, 0, r2 keep_alive r1 - r5 = g(r1) - r6 = box(None, 1) - r7 = g(r6) + r4 = g(r1) + r5 = box(None, 1) + r6 = g(r5) return 1 [case testCoerceToObject1] @@ -789,28 +788,27 @@ def g(y: object) -> object: def g(y): y, r0, r1 :: object r2 :: list - r3, r4 :: ptr + r3 :: ptr a :: list - r5 :: tuple[int, int] - r6 :: object - r7 :: bit - r8, r9 :: object + r4 :: tuple[int, int] + r5 :: object + r6 :: bit + r7, r8 :: object L0: r0 = object 1 r1 = g(r0) r2 = PyList_New(1) - r3 = get_element_ptr r2 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, y + r3 = list_items r2 + buf_init_item r3, 0, y keep_alive r2 a = r2 - r5 = (2, 4) - r6 = box(tuple[int, int], r5) - r7 = CPyList_SetItem(a, 0, r6) - r8 = box(bool, 1) - y = r8 - r9 = object 3 - return r9 + r4 = (2, 4) + r5 = box(tuple[int, int], r4) + r6 = CPyList_SetItem(a, 0, r5) + r7 = box(bool, 1) + y = r7 + r8 = object 3 + return r8 [case testCoerceToObject2] class A: @@ -1258,17 +1256,14 @@ L3: unreachable def lst(x): x :: list - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: bit + r0 :: native_int + r1 :: short_int + r2 :: bit L0: - r0 = get_element_ptr x ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive x - r2 = r1 << 1 - r3 = int_ne r2, 0 - if r3 goto L1 else goto L2 :: bool + r0 = var_object_size x + r1 = r0 << 1 + r2 = int_ne r1, 0 + if r2 goto L1 else goto L2 :: bool L1: return 2 L2: @@ -1661,12 +1656,12 @@ def h(): r3 :: object r4 :: list r5 :: object - r6, r7 :: ptr - r8, r9 :: object - r10 :: tuple - r11 :: dict - r12 :: object - r13 :: tuple[int, int, int] + r6 :: ptr + r7, r8 :: object + r9 :: tuple + r10 :: dict + r11 :: object + r12 :: tuple[int, int, int] L0: r0 = (4, 6) r1 = __main__.globals :: static @@ -1674,17 +1669,16 @@ L0: r3 = CPyDict_GetItem(r1, r2) r4 = PyList_New(1) r5 = object 1 - r6 = get_element_ptr r4 ob_item :: PyListObject - r7 = load_mem r6 :: ptr* - buf_init_item r7, 0, r5 + r6 = list_items r4 + buf_init_item r6, 0, r5 keep_alive r4 - r8 = box(tuple[int, int], r0) - r9 = CPyList_Extend(r4, r8) - r10 = PyList_AsTuple(r4) - r11 = PyDict_New() - r12 = PyObject_Call(r3, r10, r11) - r13 = unbox(tuple[int, int, int], r12) - return r13 + r7 = box(tuple[int, int], r0) + r8 = CPyList_Extend(r4, r7) + r9 = PyList_AsTuple(r4) + r10 = PyDict_New() + r11 = PyObject_Call(r3, r9, r10) + r12 = unbox(tuple[int, int, int], r11) + return r12 [case testStar2Args] from typing import Tuple @@ -1849,61 +1843,57 @@ def f() -> List[int]: def f(): r0, r1 :: list r2, r3, r4 :: object - r5, r6 :: ptr - r7 :: short_int - r8 :: ptr - r9 :: native_int - r10 :: short_int - r11 :: bit - r12 :: object - r13, x :: int - r14, r15 :: bit - r16 :: int - r17 :: object - r18 :: i32 - r19 :: bit - r20 :: short_int + r5 :: ptr + r6 :: short_int + r7 :: native_int + r8 :: short_int + r9 :: bit + r10 :: object + r11, x :: int + r12, r13 :: bit + r14 :: int + r15 :: object + r16 :: i32 + r17 :: bit + r18 :: short_int L0: r0 = PyList_New(0) r1 = PyList_New(3) r2 = object 1 r3 = object 2 r4 = object 3 - r5 = get_element_ptr r1 ob_item :: PyListObject - r6 = load_mem r5 :: ptr* - buf_init_item r6, 0, r2 - buf_init_item r6, 1, r3 - buf_init_item r6, 2, r4 + r5 = list_items r1 + buf_init_item r5, 0, r2 + buf_init_item r5, 1, r3 + buf_init_item r5, 2, r4 keep_alive r1 - r7 = 0 + r6 = 0 L1: - r8 = get_element_ptr r1 ob_size :: PyVarObject - r9 = load_mem r8 :: native_int* - keep_alive r1 - r10 = r9 << 1 - r11 = int_lt r7, r10 - if r11 goto L2 else goto L8 :: bool + r7 = var_object_size r1 + r8 = r7 << 1 + r9 = int_lt r6, r8 + if r9 goto L2 else goto L8 :: bool L2: - r12 = CPyList_GetItemUnsafe(r1, r7) - r13 = unbox(int, r12) - x = r13 - r14 = int_ne x, 4 - if r14 goto L4 else goto L3 :: bool + r10 = CPyList_GetItemUnsafe(r1, r6) + r11 = unbox(int, r10) + x = r11 + r12 = int_ne x, 4 + if r12 goto L4 else goto L3 :: bool L3: goto L7 L4: - r15 = int_ne x, 6 - if r15 goto L6 else goto L5 :: bool + r13 = int_ne x, 6 + if r13 goto L6 else goto L5 :: bool L5: goto L7 L6: - r16 = CPyTagged_Multiply(x, x) - r17 = box(int, r16) - r18 = PyList_Append(r0, r17) - r19 = r18 >= 0 :: signed + r14 = CPyTagged_Multiply(x, x) + r15 = box(int, r14) + r16 = PyList_Append(r0, r15) + r17 = r16 >= 0 :: signed L7: - r20 = r7 + 2 - r7 = r20 + r18 = r6 + 2 + r6 = r18 goto L1 L8: return r0 @@ -1917,62 +1907,58 @@ def f(): r0 :: dict r1 :: list r2, r3, r4 :: object - r5, r6 :: ptr - r7 :: short_int - r8 :: ptr - r9 :: native_int - r10 :: short_int - r11 :: bit - r12 :: object - r13, x :: int - r14, r15 :: bit - r16 :: int - r17, r18 :: object - r19 :: i32 - r20 :: bit - r21 :: short_int + r5 :: ptr + r6 :: short_int + r7 :: native_int + r8 :: short_int + r9 :: bit + r10 :: object + r11, x :: int + r12, r13 :: bit + r14 :: int + r15, r16 :: object + r17 :: i32 + r18 :: bit + r19 :: short_int L0: r0 = PyDict_New() r1 = PyList_New(3) r2 = object 1 r3 = object 2 r4 = object 3 - r5 = get_element_ptr r1 ob_item :: PyListObject - r6 = load_mem r5 :: ptr* - buf_init_item r6, 0, r2 - buf_init_item r6, 1, r3 - buf_init_item r6, 2, r4 + r5 = list_items r1 + buf_init_item r5, 0, r2 + buf_init_item r5, 1, r3 + buf_init_item r5, 2, r4 keep_alive r1 - r7 = 0 + r6 = 0 L1: - r8 = get_element_ptr r1 ob_size :: PyVarObject - r9 = load_mem r8 :: native_int* - keep_alive r1 - r10 = r9 << 1 - r11 = int_lt r7, r10 - if r11 goto L2 else goto L8 :: bool + r7 = var_object_size r1 + r8 = r7 << 1 + r9 = int_lt r6, r8 + if r9 goto L2 else goto L8 :: bool L2: - r12 = CPyList_GetItemUnsafe(r1, r7) - r13 = unbox(int, r12) - x = r13 - r14 = int_ne x, 4 - if r14 goto L4 else goto L3 :: bool + r10 = CPyList_GetItemUnsafe(r1, r6) + r11 = unbox(int, r10) + x = r11 + r12 = int_ne x, 4 + if r12 goto L4 else goto L3 :: bool L3: goto L7 L4: - r15 = int_ne x, 6 - if r15 goto L6 else goto L5 :: bool + r13 = int_ne x, 6 + if r13 goto L6 else goto L5 :: bool L5: goto L7 L6: - r16 = CPyTagged_Multiply(x, x) - r17 = box(int, x) - r18 = box(int, r16) - r19 = CPyDict_SetItem(r0, r17, r18) - r20 = r19 >= 0 :: signed + r14 = CPyTagged_Multiply(x, x) + r15 = box(int, x) + r16 = box(int, r14) + r17 = CPyDict_SetItem(r0, r15, r16) + r18 = r17 >= 0 :: signed L7: - r21 = r7 + 2 - r7 = r21 + r19 = r6 + 2 + r6 = r19 goto L1 L8: return r0 @@ -1987,82 +1973,73 @@ def f(l: List[Tuple[int, int, int]]) -> List[int]: def f(l): l :: list r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6 :: tuple[int, int, int] - r7, x, r8, y, r9, z :: int - r10 :: short_int - r11 :: ptr - r12 :: native_int - r13 :: list + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5 :: tuple[int, int, int] + r6, x, r7, y, r8, z :: int + r9 :: short_int + r10 :: native_int + r11 :: list + r12 :: short_int + r13 :: native_int r14 :: short_int - r15 :: ptr - r16 :: native_int - r17 :: short_int - r18 :: bit - r19 :: object - r20 :: tuple[int, int, int] - r21, x_2, r22, y_2, r23, z_2, r24, r25 :: int - r26 :: object - r27 :: bit - r28 :: short_int + r15 :: bit + r16 :: object + r17 :: tuple[int, int, int] + r18, x_2, r19, y_2, r20, z_2, r21, r22 :: int + r23 :: object + r24 :: bit + r25 :: short_int L0: r0 = 0 L1: - r1 = get_element_ptr l ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive l - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size l + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItemUnsafe(l, r0) - r6 = unbox(tuple[int, int, int], r5) - r7 = r6[0] - x = r7 - r8 = r6[1] - y = r8 - r9 = r6[2] - z = r9 + r4 = CPyList_GetItemUnsafe(l, r0) + r5 = unbox(tuple[int, int, int], r4) + r6 = r5[0] + x = r6 + r7 = r5[1] + y = r7 + r8 = r5[2] + z = r8 L3: - r10 = r0 + 2 - r0 = r10 + r9 = r0 + 2 + r0 = r9 goto L1 L4: - r11 = get_element_ptr l ob_size :: PyVarObject - r12 = load_mem r11 :: native_int* - keep_alive l - r13 = PyList_New(r12) - r14 = 0 + r10 = var_object_size l + r11 = PyList_New(r10) + r12 = 0 L5: - r15 = get_element_ptr l ob_size :: PyVarObject - r16 = load_mem r15 :: native_int* - keep_alive l - r17 = r16 << 1 - r18 = int_lt r14, r17 - if r18 goto L6 else goto L8 :: bool + r13 = var_object_size l + r14 = r13 << 1 + r15 = int_lt r12, r14 + if r15 goto L6 else goto L8 :: bool L6: - r19 = CPyList_GetItemUnsafe(l, r14) - r20 = unbox(tuple[int, int, int], r19) - r21 = r20[0] - x_2 = r21 - r22 = r20[1] - y_2 = r22 - r23 = r20[2] - z_2 = r23 - r24 = CPyTagged_Add(x_2, y_2) - r25 = CPyTagged_Add(r24, z_2) - r26 = box(int, r25) - r27 = CPyList_SetItemUnsafe(r13, r14, r26) + r16 = CPyList_GetItemUnsafe(l, r12) + r17 = unbox(tuple[int, int, int], r16) + r18 = r17[0] + x_2 = r18 + r19 = r17[1] + y_2 = r19 + r20 = r17[2] + z_2 = r20 + r21 = CPyTagged_Add(x_2, y_2) + r22 = CPyTagged_Add(r21, z_2) + r23 = box(int, r22) + r24 = CPyList_SetItemUnsafe(r11, r12, r23) L7: - r28 = r14 + 2 - r14 = r28 + r25 = r12 + 2 + r12 = r25 goto L5 L8: - return r13 + return r11 [case testProperty] class PropertyHolder: @@ -2204,11 +2181,11 @@ def __top_level__(): r59 :: bit r60 :: list r61, r62, r63 :: object - r64, r65 :: ptr - r66 :: dict - r67 :: str - r68 :: i32 - r69 :: bit + r64 :: ptr + r65 :: dict + r66 :: str + r67 :: i32 + r68 :: bit L0: r0 = builtins :: module r1 = load_address _Py_NoneStruct @@ -2279,16 +2256,15 @@ L2: r61 = object 1 r62 = object 2 r63 = object 3 - r64 = get_element_ptr r60 ob_item :: PyListObject - r65 = load_mem r64 :: ptr* - buf_init_item r65, 0, r61 - buf_init_item r65, 1, r62 - buf_init_item r65, 2, r63 + r64 = list_items r60 + buf_init_item r64, 0, r61 + buf_init_item r64, 1, r62 + buf_init_item r64, 2, r63 keep_alive r60 - r66 = __main__.globals :: static - r67 = 'y' - r68 = CPyDict_SetItem(r66, r67, r60) - r69 = r68 >= 0 :: signed + r65 = __main__.globals :: static + r66 = 'y' + r67 = CPyDict_SetItem(r65, r66, r60) + r68 = r67 >= 0 :: signed return 1 [case testChainedConditional] diff --git a/mypyc/test-data/irbuild-bool.test b/mypyc/test-data/irbuild-bool.test index 795a3360fcd2..128266e6b1d7 100644 --- a/mypyc/test-data/irbuild-bool.test +++ b/mypyc/test-data/irbuild-bool.test @@ -87,17 +87,14 @@ L0: return 1 def list_to_bool(l): l :: list - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: bit -L0: - r0 = get_element_ptr l ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive l - r2 = r1 << 1 - r3 = int_ne r2, 0 - return r3 + r0 :: native_int + r1 :: short_int + r2 :: bit +L0: + r0 = var_object_size l + r1 = r0 << 1 + r2 = int_ne r1, 0 + return r2 def always_truthy_instance_to_bool(o): o :: __main__.C r0 :: i32 diff --git a/mypyc/test-data/irbuild-bytes.test b/mypyc/test-data/irbuild-bytes.test index 8e97a7f4a569..b41836d8829f 100644 --- a/mypyc/test-data/irbuild-bytes.test +++ b/mypyc/test-data/irbuild-bytes.test @@ -140,15 +140,12 @@ def f(b: bytes) -> int: [out] def f(b): b :: bytes - r0 :: ptr - r1 :: native_int - r2 :: short_int + r0 :: native_int + r1 :: short_int L0: - r0 = get_element_ptr b ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive b - r2 = r1 << 1 - return r2 + r0 = var_object_size b + r1 = r0 << 1 + return r1 [case testBytesFormatting] def f(var: bytes, num: int) -> None: diff --git a/mypyc/test-data/irbuild-classes.test b/mypyc/test-data/irbuild-classes.test index cbed51ebcfb0..2c15f09c9c34 100644 --- a/mypyc/test-data/irbuild-classes.test +++ b/mypyc/test-data/irbuild-classes.test @@ -41,28 +41,27 @@ def f(): r0, c :: __main__.C r1 :: bool r2 :: list - r3, r4 :: ptr + r3 :: ptr a :: list - r5 :: object - r6, d :: __main__.C - r7, r8 :: int + r4 :: object + r5, d :: __main__.C + r6, r7 :: int L0: r0 = C() c = r0 c.x = 10; r1 = is_error r2 = PyList_New(1) - r3 = get_element_ptr r2 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, c + r3 = list_items r2 + buf_init_item r3, 0, c keep_alive r2 a = r2 - r5 = CPyList_GetItemShort(a, 0) - r6 = cast(__main__.C, r5) - d = r6 - r7 = borrow d.x - r8 = CPyTagged_Add(r7, 2) + r4 = CPyList_GetItemShort(a, 0) + r5 = cast(__main__.C, r4) + d = r5 + r6 = borrow d.x + r7 = CPyTagged_Add(r6, 2) keep_alive d - return r8 + return r7 [case testMethodCall] class A: diff --git a/mypyc/test-data/irbuild-dict.test b/mypyc/test-data/irbuild-dict.test index 9445219a08ce..6139a02029b9 100644 --- a/mypyc/test-data/irbuild-dict.test +++ b/mypyc/test-data/irbuild-dict.test @@ -537,8 +537,8 @@ def f3(d, flag): r2 :: str r3 :: list r4 :: object - r5, r6 :: ptr - r7, r8 :: object + r5 :: ptr + r6, r7 :: object L0: if flag goto L1 else goto L2 :: bool L1: @@ -549,15 +549,14 @@ L2: r2 = 'a' r3 = PyList_New(1) r4 = object 1 - r5 = get_element_ptr r3 ob_item :: PyListObject - r6 = load_mem r5 :: ptr* - buf_init_item r6, 0, r4 + r5 = list_items r3 + buf_init_item r5, 0, r4 keep_alive r3 - r7 = CPyDict_SetDefault(d, r2, r3) - return r7 + r6 = CPyDict_SetDefault(d, r2, r3) + return r6 L3: - r8 = box(None, 1) - return r8 + r7 = box(None, 1) + return r7 def f4(d, flag): d :: dict flag :: bool diff --git a/mypyc/test-data/irbuild-generics.test b/mypyc/test-data/irbuild-generics.test index 50f6ed6cda1e..4f9d0ab83a16 100644 --- a/mypyc/test-data/irbuild-generics.test +++ b/mypyc/test-data/irbuild-generics.test @@ -17,13 +17,12 @@ def g(x): x :: list r0 :: object r1 :: list - r2, r3 :: ptr + r2 :: ptr L0: r0 = CPyList_GetItemShort(x, 0) r1 = PyList_New(1) - r2 = get_element_ptr r1 ob_item :: PyListObject - r3 = load_mem r2 :: ptr* - buf_init_item r3, 0, r0 + r2 = list_items r1 + buf_init_item r2, 0, r0 keep_alive r1 return r1 def h(x, y): diff --git a/mypyc/test-data/irbuild-i64.test b/mypyc/test-data/irbuild-i64.test index ad2a97e6eeff..a52de16f3a6c 100644 --- a/mypyc/test-data/irbuild-i64.test +++ b/mypyc/test-data/irbuild-i64.test @@ -1140,24 +1140,23 @@ def f(n): n :: i64 r0 :: __main__.C r1 :: list - r2, r3 :: ptr + r2 :: ptr a :: list - r4 :: object - r5 :: __main__.C - r6 :: str + r3 :: object + r4 :: __main__.C + r5 :: str L0: r0 = C() r1 = PyList_New(1) - r2 = get_element_ptr r1 ob_item :: PyListObject - r3 = load_mem r2 :: ptr* - buf_init_item r3, 0, r0 + r2 = list_items r1 + buf_init_item r2, 0, r0 keep_alive r1 a = r1 - r4 = CPyList_GetItemInt64Borrow(a, n) - r5 = borrow cast(__main__.C, r4) - r6 = r5.s - keep_alive a, n, r4 - return r6 + r3 = CPyList_GetItemInt64Borrow(a, n) + r4 = borrow cast(__main__.C, r3) + r5 = r4.s + keep_alive a, n, r3 + return r5 [case testBorrowOverI64ListGetItem2] from typing import List @@ -1202,19 +1201,16 @@ def g(a: List[i64], y: i64) -> bool: def f(a, y): a :: list y :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: i64 - r4 :: bit + r0 :: native_int + r1 :: short_int + r2 :: i64 + r3 :: bit L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = r3 < y :: signed - if r4 goto L1 else goto L2 :: bool + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = r2 < y :: signed + if r3 goto L1 else goto L2 :: bool L1: return 1 L2: @@ -1222,19 +1218,16 @@ L2: def g(a, y): a :: list y :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: i64 - r4 :: bit + r0 :: native_int + r1 :: short_int + r2 :: i64 + r3 :: bit L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = y < r3 :: signed - if r4 goto L1 else goto L2 :: bool + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = y < r2 :: signed + if r3 goto L1 else goto L2 :: bool L1: return 1 L2: @@ -1251,32 +1244,31 @@ def f(n): n :: i64 r0 :: list r1 :: object - r2, r3 :: ptr - r4, r5 :: bit - r6, r7, r8 :: int - r9 :: list + r2 :: ptr + r3, r4 :: bit + r5, r6, r7 :: int + r8 :: list L0: r0 = PyList_New(1) r1 = box(i64, n) - r2 = get_element_ptr r0 ob_item :: PyListObject - r3 = load_mem r2 :: ptr* - buf_init_item r3, 0, r1 + r2 = list_items r0 + buf_init_item r2, 0, r1 keep_alive r0 - r4 = n <= 4611686018427387903 :: signed - if r4 goto L1 else goto L2 :: bool + r3 = n <= 4611686018427387903 :: signed + if r3 goto L1 else goto L2 :: bool L1: - r5 = n >= -4611686018427387904 :: signed - if r5 goto L3 else goto L2 :: bool + r4 = n >= -4611686018427387904 :: signed + if r4 goto L3 else goto L2 :: bool L2: - r6 = CPyTagged_FromInt64(n) - r7 = r6 + r5 = CPyTagged_FromInt64(n) + r6 = r5 goto L4 L3: - r8 = n << 1 - r7 = r8 + r7 = n << 1 + r6 = r7 L4: - r9 = CPySequence_Multiply(r0, r7) - return r9 + r8 = CPySequence_Multiply(r0, r6) + return r8 [case testShortIntAndI64Op] from mypy_extensions import i64 @@ -1298,49 +1290,40 @@ def lt_i64(a: List[i64], n: i64) -> bool: def add_i64(a, n): a :: list n :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3, r4 :: i64 + r0 :: native_int + r1 :: short_int + r2, r3 :: i64 L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = r3 + n - return r4 + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = r2 + n + return r3 def add_i64_2(a, n): a :: list n :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3, r4 :: i64 + r0 :: native_int + r1 :: short_int + r2, r3 :: i64 L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = n + r3 - return r4 + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = n + r2 + return r3 def eq_i64(a, n): a :: list n :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: i64 - r4 :: bit + r0 :: native_int + r1 :: short_int + r2 :: i64 + r3 :: bit L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = r3 == n - if r4 goto L1 else goto L2 :: bool + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = r2 == n + if r3 goto L1 else goto L2 :: bool L1: return 1 L2: @@ -1348,19 +1331,16 @@ L2: def lt_i64(a, n): a :: list n :: i64 - r0 :: ptr - r1 :: native_int - r2 :: short_int - r3 :: i64 - r4 :: bit + r0 :: native_int + r1 :: short_int + r2 :: i64 + r3 :: bit L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - r3 = r2 >> 1 - r4 = n < r3 :: signed - if r4 goto L1 else goto L2 :: bool + r0 = var_object_size a + r1 = r0 << 1 + r2 = r1 >> 1 + r3 = n < r2 :: signed + if r3 goto L1 else goto L2 :: bool L1: return 1 L2: diff --git a/mypyc/test-data/irbuild-lists.test b/mypyc/test-data/irbuild-lists.test index 66aa1dc748be..725f218b686a 100644 --- a/mypyc/test-data/irbuild-lists.test +++ b/mypyc/test-data/irbuild-lists.test @@ -108,16 +108,15 @@ def f() -> None: def f(): r0 :: list r1, r2 :: object - r3, r4 :: ptr + r3 :: ptr x :: list L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 - r3 = get_element_ptr r0 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r1 - buf_init_item r4, 1, r2 + r3 = list_items r0 + buf_init_item r3, 0, r1 + buf_init_item r3, 1, r2 keep_alive r0 x = r0 return 1 @@ -155,19 +154,18 @@ def f(a: List[int]) -> None: def f(a): a, r0, b, r1 :: list r2 :: object - r3, r4 :: ptr - r5 :: list + r3 :: ptr + r4 :: list L0: r0 = CPySequence_Multiply(a, 4) b = r0 r1 = PyList_New(1) r2 = object 4 - r3 = get_element_ptr r1 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r2 + r3 = list_items r1 + buf_init_item r3, 0, r2 keep_alive r1 - r5 = CPySequence_RMultiply(6, r1) - b = r5 + r4 = CPySequence_RMultiply(6, r1) + b = r4 return 1 [case testListLen] @@ -177,15 +175,12 @@ def f(a: List[int]) -> int: [out] def f(a): a :: list - r0 :: ptr - r1 :: native_int - r2 :: short_int + r0 :: native_int + r1 :: short_int L0: - r0 = get_element_ptr a ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive a - r2 = r1 << 1 - return r2 + r0 = var_object_size a + r1 = r0 << 1 + return r1 [case testListAppend] from typing import List @@ -213,33 +208,30 @@ def increment(l: List[int]) -> List[int]: [out] def increment(l): l :: list - r0 :: ptr - r1 :: native_int - r2, r3 :: short_int + r0 :: native_int + r1, r2 :: short_int i :: int - r4 :: bit - r5, r6, r7 :: object - r8 :: bit - r9 :: short_int + r3 :: bit + r4, r5, r6 :: object + r7 :: bit + r8 :: short_int L0: - r0 = get_element_ptr l ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive l - r2 = r1 << 1 - r3 = 0 - i = r3 + r0 = var_object_size l + r1 = r0 << 1 + r2 = 0 + i = r2 L1: - r4 = int_lt r3, r2 - if r4 goto L2 else goto L4 :: bool + r3 = int_lt r2, r1 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItem(l, i) - r6 = object 1 - r7 = PyNumber_InPlaceAdd(r5, r6) - r8 = CPyList_SetItem(l, i, r7) + r4 = CPyList_GetItem(l, i) + r5 = object 1 + r6 = PyNumber_InPlaceAdd(r4, r5) + r7 = CPyList_SetItem(l, i, r6) L3: - r9 = r3 + 2 - r3 = r9 - i = r9 + r8 = r2 + 2 + r2 = r8 + i = r8 goto L1 L4: return l @@ -252,24 +244,23 @@ def f(x: List[int], y: List[int]) -> List[int]: def f(x, y): x, y, r0 :: list r1, r2 :: object - r3, r4 :: ptr - r5, r6, r7 :: object - r8 :: i32 - r9 :: bit + r3 :: ptr + r4, r5, r6 :: object + r7 :: i32 + r8 :: bit L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 - r3 = get_element_ptr r0 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r1 - buf_init_item r4, 1, r2 + r3 = list_items r0 + buf_init_item r3, 0, r1 + buf_init_item r3, 1, r2 keep_alive r0 - r5 = CPyList_Extend(r0, x) - r6 = CPyList_Extend(r0, y) - r7 = object 3 - r8 = PyList_Append(r0, r7) - r9 = r8 >= 0 :: signed + r4 = CPyList_Extend(r0, x) + r5 = CPyList_Extend(r0, y) + r6 = object 3 + r7 = PyList_Append(r0, r6) + r8 = r7 >= 0 :: signed return r0 [case testListIn] @@ -316,85 +307,73 @@ def f(source: List[int]) -> None: [out] def f(source): source :: list - r0 :: ptr - r1 :: native_int - r2 :: list - r3 :: short_int - r4 :: ptr - r5 :: native_int - r6 :: short_int - r7 :: bit - r8 :: object - r9, x, r10 :: int - r11 :: object - r12 :: bit - r13 :: short_int + r0 :: native_int + r1 :: list + r2 :: short_int + r3 :: native_int + r4 :: short_int + r5 :: bit + r6 :: object + r7, x, r8 :: int + r9 :: object + r10 :: bit + r11 :: short_int a :: list - r14 :: ptr + r12 :: native_int + r13 :: list + r14 :: short_int r15 :: native_int - r16 :: list - r17 :: short_int - r18 :: ptr - r19 :: native_int - r20 :: short_int - r21 :: bit - r22 :: object - r23, x_2, r24 :: int - r25 :: object - r26 :: bit - r27 :: short_int + r16 :: short_int + r17 :: bit + r18 :: object + r19, x_2, r20 :: int + r21 :: object + r22 :: bit + r23 :: short_int b :: list L0: - r0 = get_element_ptr source ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive source - r2 = PyList_New(r1) - r3 = 0 + r0 = var_object_size source + r1 = PyList_New(r0) + r2 = 0 L1: - r4 = get_element_ptr source ob_size :: PyVarObject - r5 = load_mem r4 :: native_int* - keep_alive source - r6 = r5 << 1 - r7 = int_lt r3, r6 - if r7 goto L2 else goto L4 :: bool + r3 = var_object_size source + r4 = r3 << 1 + r5 = int_lt r2, r4 + if r5 goto L2 else goto L4 :: bool L2: - r8 = CPyList_GetItemUnsafe(source, r3) - r9 = unbox(int, r8) - x = r9 - r10 = CPyTagged_Add(x, 2) - r11 = box(int, r10) - r12 = CPyList_SetItemUnsafe(r2, r3, r11) + r6 = CPyList_GetItemUnsafe(source, r2) + r7 = unbox(int, r6) + x = r7 + r8 = CPyTagged_Add(x, 2) + r9 = box(int, r8) + r10 = CPyList_SetItemUnsafe(r1, r2, r9) L3: - r13 = r3 + 2 - r3 = r13 + r11 = r2 + 2 + r2 = r11 goto L1 L4: - a = r2 - r14 = get_element_ptr source ob_size :: PyVarObject - r15 = load_mem r14 :: native_int* - keep_alive source - r16 = PyList_New(r15) - r17 = 0 + a = r1 + r12 = var_object_size source + r13 = PyList_New(r12) + r14 = 0 L5: - r18 = get_element_ptr source ob_size :: PyVarObject - r19 = load_mem r18 :: native_int* - keep_alive source - r20 = r19 << 1 - r21 = int_lt r17, r20 - if r21 goto L6 else goto L8 :: bool + r15 = var_object_size source + r16 = r15 << 1 + r17 = int_lt r14, r16 + if r17 goto L6 else goto L8 :: bool L6: - r22 = CPyList_GetItemUnsafe(source, r17) - r23 = unbox(int, r22) - x_2 = r23 - r24 = CPyTagged_Add(x_2, 2) - r25 = box(int, r24) - r26 = CPyList_SetItemUnsafe(r16, r17, r25) + r18 = CPyList_GetItemUnsafe(source, r14) + r19 = unbox(int, r18) + x_2 = r19 + r20 = CPyTagged_Add(x_2, 2) + r21 = box(int, r20) + r22 = CPyList_SetItemUnsafe(r13, r14, r21) L7: - r27 = r17 + 2 - r17 = r27 + r23 = r14 + 2 + r14 = r23 goto L5 L8: - b = r16 + b = r13 return 1 [case testGeneratorNext] @@ -406,42 +385,39 @@ def test(x: List[int]) -> None: def test(x): x :: list r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6, i :: int - r7 :: object - r8 :: union[int, None] - r9 :: short_int - r10 :: object + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5, i :: int + r6 :: object + r7 :: union[int, None] + r8 :: short_int + r9 :: object res :: union[int, None] L0: r0 = 0 L1: - r1 = get_element_ptr x ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive x - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size x + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItemUnsafe(x, r0) - r6 = unbox(int, r5) - i = r6 - r7 = box(int, i) - r8 = r7 + r4 = CPyList_GetItemUnsafe(x, r0) + r5 = unbox(int, r4) + i = r5 + r6 = box(int, i) + r7 = r6 goto L5 L3: - r9 = r0 + 2 - r0 = r9 + r8 = r0 + 2 + r0 = r8 goto L1 L4: - r10 = box(None, 1) - r8 = r10 + r9 = box(None, 1) + r7 = r9 L5: - res = r8 + res = r7 return 1 [case testSimplifyListUnion] @@ -465,10 +441,9 @@ def narrow(a): r2 :: bit r3 :: bool r4 :: list - r5 :: ptr - r6 :: native_int - r7 :: short_int - r8 :: int + r5 :: native_int + r6 :: short_int + r7 :: int L0: r0 = load_address PyList_Type r1 = PyObject_IsInstance(a, r0) @@ -477,70 +452,62 @@ L0: if r3 goto L1 else goto L2 :: bool L1: r4 = borrow cast(list, a) - r5 = get_element_ptr r4 ob_size :: PyVarObject - r6 = load_mem r5 :: native_int* - keep_alive r4 - r7 = r6 << 1 + r5 = var_object_size r4 + r6 = r5 << 1 keep_alive a - return r7 + return r6 L2: - r8 = unbox(int, a) - return r8 + r7 = unbox(int, a) + return r7 def loop(a): a :: list r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6, x :: union[str, bytes] - r7 :: short_int + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5, x :: union[str, bytes] + r6 :: short_int L0: r0 = 0 L1: - r1 = get_element_ptr a ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive a - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size a + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItemUnsafe(a, r0) - r6 = cast(union[str, bytes], r5) - x = r6 + r4 = CPyList_GetItemUnsafe(a, r0) + r5 = cast(union[str, bytes], r4) + x = r5 L3: - r7 = r0 + 2 - r0 = r7 + r6 = r0 + 2 + r0 = r6 goto L1 L4: return 1 def nested_union(a): a :: list r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6, x :: union[str, None] - r7 :: short_int + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5, x :: union[str, None] + r6 :: short_int L0: r0 = 0 L1: - r1 = get_element_ptr a ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive a - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size a + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItemUnsafe(a, r0) - r6 = cast(union[str, None], r5) - x = r6 + r4 = CPyList_GetItemUnsafe(a, r0) + r5 = cast(union[str, None], r4) + x = r5 L3: - r7 = r0 + 2 - r0 = r7 + r6 = r0 + 2 + r0 = r6 goto L1 L4: return 1 diff --git a/mypyc/test-data/irbuild-set.test b/mypyc/test-data/irbuild-set.test index ea900f2e4789..1ac638754a8b 100644 --- a/mypyc/test-data/irbuild-set.test +++ b/mypyc/test-data/irbuild-set.test @@ -79,56 +79,52 @@ L0: def test1(): r0 :: list r1, r2, r3 :: object - r4, r5 :: ptr + r4 :: ptr tmp_list :: list - r6 :: set - r7 :: short_int - r8 :: ptr - r9 :: native_int - r10 :: short_int - r11 :: bit - r12 :: object - r13, x, r14 :: int - r15 :: object - r16 :: i32 - r17 :: bit - r18 :: short_int + r5 :: set + r6 :: short_int + r7 :: native_int + r8 :: short_int + r9 :: bit + r10 :: object + r11, x, r12 :: int + r13 :: object + r14 :: i32 + r15 :: bit + r16 :: short_int a :: set L0: r0 = PyList_New(3) r1 = object 1 r2 = object 3 r3 = object 5 - r4 = get_element_ptr r0 ob_item :: PyListObject - r5 = load_mem r4 :: ptr* - buf_init_item r5, 0, r1 - buf_init_item r5, 1, r2 - buf_init_item r5, 2, r3 + r4 = list_items r0 + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 + buf_init_item r4, 2, r3 keep_alive r0 tmp_list = r0 - r6 = PySet_New(0) - r7 = 0 + r5 = PySet_New(0) + r6 = 0 L1: - r8 = get_element_ptr tmp_list ob_size :: PyVarObject - r9 = load_mem r8 :: native_int* - keep_alive tmp_list - r10 = r9 << 1 - r11 = int_lt r7, r10 - if r11 goto L2 else goto L4 :: bool + r7 = var_object_size tmp_list + r8 = r7 << 1 + r9 = int_lt r6, r8 + if r9 goto L2 else goto L4 :: bool L2: - r12 = CPyList_GetItemUnsafe(tmp_list, r7) - r13 = unbox(int, r12) - x = r13 - r14 = f(x) - r15 = box(int, r14) - r16 = PySet_Add(r6, r15) - r17 = r16 >= 0 :: signed + r10 = CPyList_GetItemUnsafe(tmp_list, r6) + r11 = unbox(int, r10) + x = r11 + r12 = f(x) + r13 = box(int, r12) + r14 = PySet_Add(r5, r13) + r15 = r14 >= 0 :: signed L3: - r18 = r7 + 2 - r7 = r18 + r16 = r6 + 2 + r6 = r16 goto L1 L4: - a = r6 + a = r5 return 1 def test2(): r0, tmp_tuple :: tuple[int, int, int] @@ -310,33 +306,32 @@ L0: def test(): r0 :: list r1, r2, r3, r4, r5 :: object - r6, r7 :: ptr + r6 :: ptr tmp_list :: list - r8 :: set - r9, r10 :: list - r11 :: short_int - r12 :: ptr - r13 :: native_int - r14 :: short_int - r15 :: bit - r16 :: object - r17, z :: int - r18 :: bit - r19 :: int - r20 :: object - r21 :: i32 - r22 :: bit - r23 :: short_int - r24, r25, r26 :: object - r27, y, r28 :: int - r29 :: object - r30 :: i32 - r31, r32 :: bit - r33, r34, r35 :: object - r36, x, r37 :: int - r38 :: object - r39 :: i32 - r40, r41 :: bit + r7 :: set + r8, r9 :: list + r10 :: short_int + r11 :: native_int + r12 :: short_int + r13 :: bit + r14 :: object + r15, z :: int + r16 :: bit + r17 :: int + r18 :: object + r19 :: i32 + r20 :: bit + r21 :: short_int + r22, r23, r24 :: object + r25, y, r26 :: int + r27 :: object + r28 :: i32 + r29, r30 :: bit + r31, r32, r33 :: object + r34, x, r35 :: int + r36 :: object + r37 :: i32 + r38, r39 :: bit a :: set L0: r0 = PyList_New(5) @@ -345,79 +340,76 @@ L0: r3 = object 3 r4 = object 4 r5 = object 5 - r6 = get_element_ptr r0 ob_item :: PyListObject - r7 = load_mem r6 :: ptr* - buf_init_item r7, 0, r1 - buf_init_item r7, 1, r2 - buf_init_item r7, 2, r3 - buf_init_item r7, 3, r4 - buf_init_item r7, 4, r5 + r6 = list_items r0 + buf_init_item r6, 0, r1 + buf_init_item r6, 1, r2 + buf_init_item r6, 2, r3 + buf_init_item r6, 3, r4 + buf_init_item r6, 4, r5 keep_alive r0 tmp_list = r0 - r8 = PySet_New(0) + r7 = PySet_New(0) + r8 = PyList_New(0) r9 = PyList_New(0) - r10 = PyList_New(0) - r11 = 0 + r10 = 0 L1: - r12 = get_element_ptr tmp_list ob_size :: PyVarObject - r13 = load_mem r12 :: native_int* - keep_alive tmp_list - r14 = r13 << 1 - r15 = int_lt r11, r14 - if r15 goto L2 else goto L6 :: bool + r11 = var_object_size tmp_list + r12 = r11 << 1 + r13 = int_lt r10, r12 + if r13 goto L2 else goto L6 :: bool L2: - r16 = CPyList_GetItemUnsafe(tmp_list, r11) - r17 = unbox(int, r16) - z = r17 - r18 = int_lt z, 8 - if r18 goto L4 else goto L3 :: bool + r14 = CPyList_GetItemUnsafe(tmp_list, r10) + r15 = unbox(int, r14) + z = r15 + r16 = int_lt z, 8 + if r16 goto L4 else goto L3 :: bool L3: goto L5 L4: - r19 = f1(z) - r20 = box(int, r19) - r21 = PyList_Append(r10, r20) - r22 = r21 >= 0 :: signed + r17 = f1(z) + r18 = box(int, r17) + r19 = PyList_Append(r9, r18) + r20 = r19 >= 0 :: signed L5: - r23 = r11 + 2 - r11 = r23 + r21 = r10 + 2 + r10 = r21 goto L1 L6: - r24 = PyObject_GetIter(r10) - r25 = PyObject_GetIter(r24) + r22 = PyObject_GetIter(r9) + r23 = PyObject_GetIter(r22) L7: - r26 = PyIter_Next(r25) - if is_error(r26) goto L10 else goto L8 + r24 = PyIter_Next(r23) + if is_error(r24) goto L10 else goto L8 L8: - r27 = unbox(int, r26) - y = r27 - r28 = f2(y) - r29 = box(int, r28) - r30 = PyList_Append(r9, r29) - r31 = r30 >= 0 :: signed + r25 = unbox(int, r24) + y = r25 + r26 = f2(y) + r27 = box(int, r26) + r28 = PyList_Append(r8, r27) + r29 = r28 >= 0 :: signed L9: goto L7 L10: - r32 = CPy_NoErrOccured() + r30 = CPy_NoErrOccured() L11: - r33 = PyObject_GetIter(r9) - r34 = PyObject_GetIter(r33) + r31 = PyObject_GetIter(r8) + r32 = PyObject_GetIter(r31) L12: - r35 = PyIter_Next(r34) - if is_error(r35) goto L15 else goto L13 + r33 = PyIter_Next(r32) + if is_error(r33) goto L15 else goto L13 L13: - r36 = unbox(int, r35) - x = r36 - r37 = f3(x) - r38 = box(int, r37) - r39 = PySet_Add(r8, r38) - r40 = r39 >= 0 :: signed + r34 = unbox(int, r33) + x = r34 + r35 = f3(x) + r36 = box(int, r35) + r37 = PySet_Add(r7, r36) + r38 = r37 >= 0 :: signed L14: goto L12 L15: - r41 = CPy_NoErrOccured() + r39 = CPy_NoErrOccured() L16: - a = r8 + a = r7 return 1 [case testSetSize] diff --git a/mypyc/test-data/irbuild-statements.test b/mypyc/test-data/irbuild-statements.test index 628d692c85c1..f9d3354b317c 100644 --- a/mypyc/test-data/irbuild-statements.test +++ b/mypyc/test-data/irbuild-statements.test @@ -231,32 +231,29 @@ def f(ls): ls :: list y :: int r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6, x, r7 :: int - r8 :: short_int + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5, x, r6 :: int + r7 :: short_int L0: y = 0 r0 = 0 L1: - r1 = get_element_ptr ls ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive ls - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size ls + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPyList_GetItemUnsafe(ls, r0) - r6 = unbox(int, r5) - x = r6 - r7 = CPyTagged_Add(y, x) - y = r7 + r4 = CPyList_GetItemUnsafe(ls, r0) + r5 = unbox(int, r4) + x = r5 + r6 = CPyTagged_Add(y, x) + y = r6 L3: - r8 = r0 + 2 - r0 = r8 + r7 = r0 + 2 + r0 = r7 goto L1 L4: return y @@ -688,39 +685,38 @@ def delListMultiple() -> None: def delList(): r0 :: list r1, r2 :: object - r3, r4 :: ptr + r3 :: ptr l :: list - r5 :: object - r6 :: i32 - r7 :: bit + r4 :: object + r5 :: i32 + r6 :: bit L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 - r3 = get_element_ptr r0 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r1 - buf_init_item r4, 1, r2 + r3 = list_items r0 + buf_init_item r3, 0, r1 + buf_init_item r3, 1, r2 keep_alive r0 l = r0 - r5 = object 1 - r6 = PyObject_DelItem(l, r5) - r7 = r6 >= 0 :: signed + r4 = object 1 + r5 = PyObject_DelItem(l, r4) + r6 = r5 >= 0 :: signed return 1 def delListMultiple(): r0 :: list r1, r2, r3, r4, r5, r6, r7 :: object - r8, r9 :: ptr + r8 :: ptr l :: list - r10 :: object - r11 :: i32 - r12 :: bit - r13 :: object - r14 :: i32 - r15 :: bit - r16 :: object - r17 :: i32 - r18 :: bit + r9 :: object + r10 :: i32 + r11 :: bit + r12 :: object + r13 :: i32 + r14 :: bit + r15 :: object + r16 :: i32 + r17 :: bit L0: r0 = PyList_New(7) r1 = object 1 @@ -730,26 +726,25 @@ L0: r5 = object 5 r6 = object 6 r7 = object 7 - r8 = get_element_ptr r0 ob_item :: PyListObject - r9 = load_mem r8 :: ptr* - buf_init_item r9, 0, r1 - buf_init_item r9, 1, r2 - buf_init_item r9, 2, r3 - buf_init_item r9, 3, r4 - buf_init_item r9, 4, r5 - buf_init_item r9, 5, r6 - buf_init_item r9, 6, r7 + r8 = list_items r0 + buf_init_item r8, 0, r1 + buf_init_item r8, 1, r2 + buf_init_item r8, 2, r3 + buf_init_item r8, 3, r4 + buf_init_item r8, 4, r5 + buf_init_item r8, 5, r6 + buf_init_item r8, 6, r7 keep_alive r0 l = r0 - r10 = object 1 - r11 = PyObject_DelItem(l, r10) - r12 = r11 >= 0 :: signed - r13 = object 2 - r14 = PyObject_DelItem(l, r13) - r15 = r14 >= 0 :: signed - r16 = object 3 - r17 = PyObject_DelItem(l, r16) - r18 = r17 >= 0 :: signed + r9 = object 1 + r10 = PyObject_DelItem(l, r9) + r11 = r10 >= 0 :: signed + r12 = object 2 + r13 = PyObject_DelItem(l, r12) + r14 = r13 >= 0 :: signed + r15 = object 3 + r16 = PyObject_DelItem(l, r15) + r17 = r16 >= 0 :: signed return 1 [case testDelDict] @@ -872,35 +867,32 @@ def f(a): r0 :: short_int i :: int r1 :: short_int - r2 :: ptr - r3 :: native_int - r4 :: short_int - r5 :: bit - r6 :: object - r7, x, r8 :: int - r9, r10 :: short_int + r2 :: native_int + r3 :: short_int + r4 :: bit + r5 :: object + r6, x, r7 :: int + r8, r9 :: short_int L0: r0 = 0 i = 0 r1 = 0 L1: - r2 = get_element_ptr a ob_size :: PyVarObject - r3 = load_mem r2 :: native_int* - keep_alive a - r4 = r3 << 1 - r5 = int_lt r1, r4 - if r5 goto L2 else goto L4 :: bool + r2 = var_object_size a + r3 = r2 << 1 + r4 = int_lt r1, r3 + if r4 goto L2 else goto L4 :: bool L2: - r6 = CPyList_GetItemUnsafe(a, r1) - r7 = unbox(int, r6) - x = r7 - r8 = CPyTagged_Add(i, x) + r5 = CPyList_GetItemUnsafe(a, r1) + r6 = unbox(int, r5) + x = r6 + r7 = CPyTagged_Add(i, x) L3: - r9 = r0 + 2 - r0 = r9 - i = r9 - r10 = r1 + 2 - r1 = r10 + r8 = r0 + 2 + r0 = r8 + i = r8 + r9 = r1 + 2 + r1 = r9 goto L1 L4: L5: @@ -950,50 +942,47 @@ def f(a, b): b :: object r0 :: short_int r1 :: object - r2 :: ptr - r3 :: native_int - r4 :: short_int - r5 :: bit - r6, r7 :: object - r8, x :: int - r9, y :: bool - r10 :: i32 - r11 :: bit - r12 :: bool - r13 :: short_int - r14 :: bit + r2 :: native_int + r3 :: short_int + r4 :: bit + r5, r6 :: object + r7, x :: int + r8, y :: bool + r9 :: i32 + r10 :: bit + r11 :: bool + r12 :: short_int + r13 :: bit L0: r0 = 0 r1 = PyObject_GetIter(b) L1: - r2 = get_element_ptr a ob_size :: PyVarObject - r3 = load_mem r2 :: native_int* - keep_alive a - r4 = r3 << 1 - r5 = int_lt r0, r4 - if r5 goto L2 else goto L7 :: bool + r2 = var_object_size a + r3 = r2 << 1 + r4 = int_lt r0, r3 + if r4 goto L2 else goto L7 :: bool L2: - r6 = PyIter_Next(r1) - if is_error(r6) goto L7 else goto L3 + r5 = PyIter_Next(r1) + if is_error(r5) goto L7 else goto L3 L3: - r7 = CPyList_GetItemUnsafe(a, r0) - r8 = unbox(int, r7) - x = r8 - r9 = unbox(bool, r6) - y = r9 - r10 = PyObject_IsTrue(b) - r11 = r10 >= 0 :: signed - r12 = truncate r10: i32 to builtins.bool - if r12 goto L4 else goto L5 :: bool + r6 = CPyList_GetItemUnsafe(a, r0) + r7 = unbox(int, r6) + x = r7 + r8 = unbox(bool, r5) + y = r8 + r9 = PyObject_IsTrue(b) + r10 = r9 >= 0 :: signed + r11 = truncate r9: i32 to builtins.bool + if r11 goto L4 else goto L5 :: bool L4: x = 2 L5: L6: - r13 = r0 + 2 - r0 = r13 + r12 = r0 + 2 + r0 = r12 goto L1 L7: - r14 = CPy_NoErrOccured() + r13 = CPy_NoErrOccured() L8: return 1 def g(a, b): @@ -1003,15 +992,14 @@ def g(a, b): r1, r2 :: short_int z :: int r3 :: object - r4 :: ptr - r5 :: native_int - r6 :: short_int - r7, r8 :: bit - r9, x :: bool - r10 :: object - r11, y :: int - r12, r13 :: short_int - r14 :: bit + r4 :: native_int + r5 :: short_int + r6, r7 :: bit + r8, x :: bool + r9 :: object + r10, y :: int + r11, r12 :: short_int + r13 :: bit L0: r0 = PyObject_GetIter(a) r1 = 0 @@ -1021,31 +1009,29 @@ L1: r3 = PyIter_Next(r0) if is_error(r3) goto L6 else goto L2 L2: - r4 = get_element_ptr b ob_size :: PyVarObject - r5 = load_mem r4 :: native_int* - keep_alive b - r6 = r5 << 1 - r7 = int_lt r1, r6 - if r7 goto L3 else goto L6 :: bool + r4 = var_object_size b + r5 = r4 << 1 + r6 = int_lt r1, r5 + if r6 goto L3 else goto L6 :: bool L3: - r8 = int_lt r2, 10 - if r8 goto L4 else goto L6 :: bool + r7 = int_lt r2, 10 + if r7 goto L4 else goto L6 :: bool L4: - r9 = unbox(bool, r3) - x = r9 - r10 = CPyList_GetItemUnsafe(b, r1) - r11 = unbox(int, r10) - y = r11 + r8 = unbox(bool, r3) + x = r8 + r9 = CPyList_GetItemUnsafe(b, r1) + r10 = unbox(int, r9) + y = r10 x = 0 L5: - r12 = r1 + 2 - r1 = r12 - r13 = r2 + 2 - r2 = r13 - z = r13 + r11 = r1 + 2 + r1 = r11 + r12 = r2 + 2 + r2 = r12 + z = r12 goto L1 L6: - r14 = CPy_NoErrOccured() + r13 = CPy_NoErrOccured() L7: return 1 diff --git a/mypyc/test-data/irbuild-str.test b/mypyc/test-data/irbuild-str.test index dfaa50520364..771dcc4c0e68 100644 --- a/mypyc/test-data/irbuild-str.test +++ b/mypyc/test-data/irbuild-str.test @@ -203,8 +203,8 @@ def f(var, num): r12 :: object r13 :: str r14 :: list - r15, r16 :: ptr - r17, s2, r18, s3, r19, s4 :: str + r15 :: ptr + r16, s2, r17, s3, r18, s4 :: str L0: r0 = "Hi! I'm " r1 = '. I am ' @@ -222,17 +222,16 @@ L0: r12 = CPyObject_CallMethodObjArgs(r7, r11, var, r10, 0) r13 = cast(str, r12) r14 = PyList_New(2) - r15 = get_element_ptr r14 ob_item :: PyListObject - r16 = load_mem r15 :: ptr* - buf_init_item r16, 0, r6 - buf_init_item r16, 1, r13 + r15 = list_items r14 + buf_init_item r15, 0, r6 + buf_init_item r15, 1, r13 keep_alive r14 - r17 = PyUnicode_Join(r5, r14) - s2 = r17 - r18 = '' - s3 = r18 - r19 = 'abc' - s4 = r19 + r16 = PyUnicode_Join(r5, r14) + s2 = r16 + r17 = '' + s3 = r17 + r18 = 'abc' + s4 = r18 return 1 [case testStringFormattingCStyle] diff --git a/mypyc/test-data/irbuild-tuple.test b/mypyc/test-data/irbuild-tuple.test index 0a26d8aa1d3d..a6813de4ee44 100644 --- a/mypyc/test-data/irbuild-tuple.test +++ b/mypyc/test-data/irbuild-tuple.test @@ -62,15 +62,12 @@ def f(x: Tuple[int, ...]) -> int: [out] def f(x): x :: tuple - r0 :: ptr - r1 :: native_int - r2 :: short_int + r0 :: native_int + r1 :: short_int L0: - r0 = get_element_ptr x ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive x - r2 = r1 << 1 - return r2 + r0 = var_object_size x + r1 = r0 << 1 + return r1 [case testSequenceTupleForced] from typing import Tuple @@ -101,27 +98,26 @@ def f(x, y): x, y :: object r0 :: list r1, r2 :: object - r3, r4 :: ptr - r5, r6, r7 :: object - r8 :: i32 - r9 :: bit - r10 :: tuple + r3 :: ptr + r4, r5, r6 :: object + r7 :: i32 + r8 :: bit + r9 :: tuple L0: r0 = PyList_New(2) r1 = object 1 r2 = object 2 - r3 = get_element_ptr r0 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* - buf_init_item r4, 0, r1 - buf_init_item r4, 1, r2 + r3 = list_items r0 + buf_init_item r3, 0, r1 + buf_init_item r3, 1, r2 keep_alive r0 - r5 = CPyList_Extend(r0, x) - r6 = CPyList_Extend(r0, y) - r7 = object 3 - r8 = PyList_Append(r0, r7) - r9 = r8 >= 0 :: signed - r10 = PyList_AsTuple(r0) - return r10 + r4 = CPyList_Extend(r0, x) + r5 = CPyList_Extend(r0, y) + r6 = object 3 + r7 = PyList_Append(r0, r6) + r8 = r7 >= 0 :: signed + r9 = PyList_AsTuple(r0) + return r9 [case testTupleFor] from typing import Tuple, List @@ -132,29 +128,26 @@ def f(xs: Tuple[str, ...]) -> None: def f(xs): xs :: tuple r0 :: short_int - r1 :: ptr - r2 :: native_int - r3 :: short_int - r4 :: bit - r5 :: object - r6, x :: str - r7 :: short_int + r1 :: native_int + r2 :: short_int + r3 :: bit + r4 :: object + r5, x :: str + r6 :: short_int L0: r0 = 0 L1: - r1 = get_element_ptr xs ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - keep_alive xs - r3 = r2 << 1 - r4 = int_lt r0, r3 - if r4 goto L2 else goto L4 :: bool + r1 = var_object_size xs + r2 = r1 << 1 + r3 = int_lt r0, r2 + if r3 goto L2 else goto L4 :: bool L2: - r5 = CPySequenceTuple_GetItem(xs, r0) - r6 = cast(str, r5) - x = r6 + r4 = CPySequenceTuple_GetItem(xs, r0) + r5 = cast(str, r4) + x = r5 L3: - r7 = r0 + 2 - r0 = r7 + r6 = r0 + 2 + r0 = r6 goto L1 L4: return 1 @@ -237,60 +230,53 @@ L0: def test(): r0 :: list r1, r2, r3 :: object - r4, r5 :: ptr + r4 :: ptr source :: list - r6 :: ptr - r7 :: native_int - r8 :: tuple + r5 :: native_int + r6 :: tuple + r7 :: short_int + r8 :: native_int r9 :: short_int - r10 :: ptr - r11 :: native_int - r12 :: short_int - r13 :: bit + r10 :: bit + r11 :: object + r12, x :: int + r13 :: bool r14 :: object - r15, x :: int - r16 :: bool - r17 :: object - r18 :: bit - r19 :: short_int + r15 :: bit + r16 :: short_int a :: tuple L0: r0 = PyList_New(3) r1 = object 1 r2 = object 2 r3 = object 3 - r4 = get_element_ptr r0 ob_item :: PyListObject - r5 = load_mem r4 :: ptr* - buf_init_item r5, 0, r1 - buf_init_item r5, 1, r2 - buf_init_item r5, 2, r3 + r4 = list_items r0 + buf_init_item r4, 0, r1 + buf_init_item r4, 1, r2 + buf_init_item r4, 2, r3 keep_alive r0 source = r0 - r6 = get_element_ptr source ob_size :: PyVarObject - r7 = load_mem r6 :: native_int* - keep_alive source - r8 = PyTuple_New(r7) - r9 = 0 + r5 = var_object_size source + r6 = PyTuple_New(r5) + r7 = 0 L1: - r10 = get_element_ptr source ob_size :: PyVarObject - r11 = load_mem r10 :: native_int* - keep_alive source - r12 = r11 << 1 - r13 = int_lt r9, r12 - if r13 goto L2 else goto L4 :: bool + r8 = var_object_size source + r9 = r8 << 1 + r10 = int_lt r7, r9 + if r10 goto L2 else goto L4 :: bool L2: - r14 = CPyList_GetItemUnsafe(source, r9) - r15 = unbox(int, r14) - x = r15 - r16 = f(x) - r17 = box(bool, r16) - r18 = CPySequenceTuple_SetItemUnsafe(r8, r9, r17) + r11 = CPyList_GetItemUnsafe(source, r7) + r12 = unbox(int, r11) + x = r12 + r13 = f(x) + r14 = box(bool, r13) + r15 = CPySequenceTuple_SetItemUnsafe(r6, r7, r14) L3: - r19 = r9 + 2 - r9 = r19 + r16 = r7 + 2 + r7 = r16 goto L1 L4: - a = r8 + a = r6 return 1 [case testTupleBuiltFromStr] @@ -363,44 +349,38 @@ L0: return r0 def test(source): source :: tuple - r0 :: ptr - r1 :: native_int - r2 :: tuple - r3 :: short_int - r4 :: ptr - r5 :: native_int - r6 :: short_int - r7 :: bit - r8 :: object - r9, x, r10 :: bool - r11 :: object - r12 :: bit - r13 :: short_int + r0 :: native_int + r1 :: tuple + r2 :: short_int + r3 :: native_int + r4 :: short_int + r5 :: bit + r6 :: object + r7, x, r8 :: bool + r9 :: object + r10 :: bit + r11 :: short_int a :: tuple L0: - r0 = get_element_ptr source ob_size :: PyVarObject - r1 = load_mem r0 :: native_int* - keep_alive source - r2 = PyTuple_New(r1) - r3 = 0 + r0 = var_object_size source + r1 = PyTuple_New(r0) + r2 = 0 L1: - r4 = get_element_ptr source ob_size :: PyVarObject - r5 = load_mem r4 :: native_int* - keep_alive source - r6 = r5 << 1 - r7 = int_lt r3, r6 - if r7 goto L2 else goto L4 :: bool + r3 = var_object_size source + r4 = r3 << 1 + r5 = int_lt r2, r4 + if r5 goto L2 else goto L4 :: bool L2: - r8 = CPySequenceTuple_GetItem(source, r3) - r9 = unbox(bool, r8) - x = r9 - r10 = f(x) - r11 = box(bool, r10) - r12 = CPySequenceTuple_SetItemUnsafe(r2, r3, r11) + r6 = CPySequenceTuple_GetItem(source, r2) + r7 = unbox(bool, r6) + x = r7 + r8 = f(x) + r9 = box(bool, r8) + r10 = CPySequenceTuple_SetItemUnsafe(r1, r2, r9) L3: - r13 = r3 + 2 - r3 = r13 + r11 = r2 + 2 + r2 = r11 goto L1 L4: - a = r2 + a = r1 return 1 diff --git a/mypyc/test-data/refcount.test b/mypyc/test-data/refcount.test index b8d598e3b533..e719ecb2afe1 100644 --- a/mypyc/test-data/refcount.test +++ b/mypyc/test-data/refcount.test @@ -498,18 +498,17 @@ def f() -> int: def f(): r0 :: list r1, r2 :: object - r3, r4 :: ptr + r3 :: ptr a :: list L0: r0 = PyList_New(2) r1 = object 0 r2 = object 1 - r3 = get_element_ptr r0 ob_item :: PyListObject - r4 = load_mem r3 :: ptr* + r3 = list_items r0 inc_ref r1 - buf_init_item r4, 0, r1 + buf_init_item r3, 0, r1 inc_ref r2 - buf_init_item r4, 1, r2 + buf_init_item r3, 1, r2 a = r0 dec_ref a return 0 @@ -576,21 +575,20 @@ def f() -> None: def f(): r0 :: __main__.C r1 :: list - r2, r3 :: ptr + r2 :: ptr a :: list - r4 :: object - r5, d :: __main__.C + r3 :: object + r4, d :: __main__.C L0: r0 = C() r1 = PyList_New(1) - r2 = get_element_ptr r1 ob_item :: PyListObject - r3 = load_mem r2 :: ptr* - buf_init_item r3, 0, r0 + r2 = list_items r1 + buf_init_item r2, 0, r0 a = r1 - r4 = CPyList_GetItemShort(a, 0) + r3 = CPyList_GetItemShort(a, 0) dec_ref a - r5 = cast(__main__.C, r4) - d = r5 + r4 = cast(__main__.C, r3) + d = r4 dec_ref d return 1 @@ -815,17 +813,15 @@ def f() -> int: [out] def f(): r0, x :: list - r1 :: ptr - r2 :: native_int - r3 :: short_int + r1 :: native_int + r2 :: short_int L0: r0 = PyList_New(0) x = r0 - r1 = get_element_ptr x ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* + r1 = var_object_size x dec_ref x - r3 = r2 << 1 - return r3 + r2 = r1 << 1 + return r2 [case testSometimesUninitializedVariable] def f(x: bool) -> int: @@ -1066,15 +1062,13 @@ class C: def f(x): x :: __main__.C r0 :: list - r1 :: ptr - r2 :: native_int - r3 :: short_int + r1 :: native_int + r2 :: short_int L0: r0 = borrow x.a - r1 = get_element_ptr r0 ob_size :: PyVarObject - r2 = load_mem r1 :: native_int* - r3 = r2 << 1 - return r3 + r1 = var_object_size r0 + r2 = r1 << 1 + return r2 [case testBorrowIsinstanceArgument] from typing import List @@ -1255,23 +1249,22 @@ class C: def f(): r0 :: __main__.C r1 :: list - r2, r3 :: ptr + r2 :: ptr a :: list - r4 :: object - r5 :: __main__.C - r6 :: str + r3 :: object + r4 :: __main__.C + r5 :: str L0: r0 = C() r1 = PyList_New(1) - r2 = get_element_ptr r1 ob_item :: PyListObject - r3 = load_mem r2 :: ptr* - buf_init_item r3, 0, r0 + r2 = list_items r1 + buf_init_item r2, 0, r0 a = r1 - r4 = CPyList_GetItemShortBorrow(a, 0) - r5 = borrow cast(__main__.C, r4) - r6 = r5.s + r3 = CPyList_GetItemShortBorrow(a, 0) + r4 = borrow cast(__main__.C, r3) + r5 = r4.s dec_ref a - return r6 + return r5 [case testBorrowSetAttrObject] from typing import Optional From 99f4b8138467c9a77003369b01242c202a6599c0 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:17:46 +0100 Subject: [PATCH 139/172] Add classifier for 3.12 (#17065) --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 140020b18bc4..a17ee562eb39 100644 --- a/setup.py +++ b/setup.py @@ -189,6 +189,7 @@ def run(self): "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Software Development", "Typing :: Typed", ] From bebd278092031fc465de00838ef304349e188398 Mon Sep 17 00:00:00 2001 From: "Michael R. Crusoe" <1330696+mr-c@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:06:46 +0100 Subject: [PATCH 140/172] fix for Pytest 8 compat (#17066) In Debian, we upgraded to pytest version 8.1.1+ for the next release. pytest deprecated the name for the first positional argument to `pytest.fail` from `msg` to `reason` in Pytest 7.0 and removed `msg` in Pytest 8.0 https://docs.pytest.org/en/7.0.x/reference/reference.html#pytest-fail https://docs.pytest.org/en/8.0.x/changelog.html#old-deprecations-are-now-errors --- mypy/test/data.py | 4 +--- mypy/test/helpers.py | 2 +- pyproject.toml | 2 +- test-requirements.in | 2 +- test-requirements.txt | 4 ++-- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/mypy/test/data.py b/mypy/test/data.py index de0267daf918..32f6354cc162 100644 --- a/mypy/test/data.py +++ b/mypy/test/data.py @@ -640,9 +640,7 @@ def pytest_pycollect_makeitem(collector: Any, name: str, obj: object) -> Any | N # Non-None result means this obj is a test case. # The collect method of the returned DataSuiteCollector instance will be called later, # with self.obj being obj. - return DataSuiteCollector.from_parent( # type: ignore[no-untyped-call] - parent=collector, name=name - ) + return DataSuiteCollector.from_parent(parent=collector, name=name) return None diff --git a/mypy/test/helpers.py b/mypy/test/helpers.py index bae4f6e81ad1..50de50e60004 100644 --- a/mypy/test/helpers.py +++ b/mypy/test/helpers.py @@ -41,7 +41,7 @@ def run_mypy(args: list[str]) -> None: if status != 0: sys.stdout.write(outval) sys.stderr.write(errval) - pytest.fail(msg="Sample check failed", pytrace=False) + pytest.fail(reason="Sample check failed", pytrace=False) def diff_ranges( diff --git a/pyproject.toml b/pyproject.toml index ef8acda3f95d..35f1592ca83c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ extra-standard-library = ["typing_extensions"] ignore = ["**/.readthedocs.yaml"] [tool.pytest.ini_options] -minversion = "6.0.0" +minversion = "7.0.0" testpaths = ["mypy/test", "mypyc/test"] python_files = 'test*.py' diff --git a/test-requirements.in b/test-requirements.in index 166bdf934d47..637f5b948055 100644 --- a/test-requirements.in +++ b/test-requirements.in @@ -11,7 +11,7 @@ lxml>=4.9.1,<4.9.3; (python_version<'3.11' or sys_platform!='win32') and python_ pre-commit pre-commit-hooks==4.5.0 psutil>=4.0 -pytest>=7.4.0 +pytest>=8.1.0 pytest-xdist>=1.34.0 pytest-cov>=2.10.0 ruff==0.2.0 # must match version in .pre-commit-config.yaml diff --git a/test-requirements.txt b/test-requirements.txt index f105b753799f..9005daab2876 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -44,7 +44,7 @@ platformdirs==3.11.0 # via # black # virtualenv -pluggy==1.3.0 +pluggy==1.4.0 # via pytest pre-commit==3.5.0 # via -r test-requirements.in @@ -52,7 +52,7 @@ pre-commit-hooks==4.5.0 # via -r test-requirements.in psutil==5.9.6 # via -r test-requirements.in -pytest==7.4.2 +pytest==8.1.1 # via # -r test-requirements.in # pytest-cov From 4310586460e0af07fa8994a0b4f03cb323e352f0 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:37:09 +0100 Subject: [PATCH 141/172] Fix TypedDict init from Type with optional keys (#17068) Followup to #16963 Correctly set optional and required keys for the TypedDict init callable. Ref: https://github.com/python/mypy/issues/11644 --- mypy/checkexpr.py | 5 ++- test-data/unit/check-typeddict.test | 32 ++++++++++++++++--- test-data/unit/lib-stub/typing_extensions.pyi | 2 ++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index e7567eafb8fe..24d8447cdf3e 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -949,7 +949,10 @@ def typeddict_callable(self, info: TypeInfo) -> CallableType: def typeddict_callable_from_context(self, callee: TypedDictType) -> CallableType: return CallableType( list(callee.items.values()), - [ArgKind.ARG_NAMED] * len(callee.items), + [ + ArgKind.ARG_NAMED if name in callee.required_keys else ArgKind.ARG_NAMED_OPT + for name in callee.items + ], list(callee.items.keys()), callee, self.named_type("builtins.type"), diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 639be7bde8d8..bd1fbe3f2667 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -3450,16 +3450,40 @@ reveal_type(p) # N: Revealed type is "TypedDict('__main__.Params', {'x': builtin [case testInitTypedDictFromType] from typing import TypedDict, Type +from typing_extensions import Required -class Point(TypedDict): - x: int +class Point(TypedDict, total=False): + x: Required[int] y: int def func(cls: Type[Point]) -> None: - reveal_type(cls) # N: Revealed type is "Type[TypedDict('__main__.Point', {'x': builtins.int, 'y': builtins.int})]" + reveal_type(cls) # N: Revealed type is "Type[TypedDict('__main__.Point', {'x': builtins.int, 'y'?: builtins.int})]" cls(x=1, y=2) cls(1, 2) # E: Too many positional arguments - cls(x=1) # E: Missing named argument "y" + cls(x=1) + cls(y=2) # E: Missing named argument "x" cls(x=1, y=2, error="") # E: Unexpected keyword argument "error" [typing fixtures/typing-full.pyi] [builtins fixtures/tuple.pyi] + +[case testInitTypedDictFromTypeGeneric] +from typing import Generic, TypedDict, Type, TypeVar +from typing_extensions import Required + +class Point(TypedDict, total=False): + x: Required[int] + y: int + +T = TypeVar("T", bound=Point) + +class A(Generic[T]): + def __init__(self, a: Type[T]) -> None: + self.a = a + + def func(self) -> T: + reveal_type(self.a) # N: Revealed type is "Type[T`1]" + self.a(x=1, y=2) + self.a(y=2) # E: Missing named argument "x" + return self.a(x=1) +[typing fixtures/typing-full.pyi] +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index b7b738f63d92..b5bfc1ab3f20 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -39,6 +39,8 @@ Never: _SpecialForm TypeVarTuple: _SpecialForm Unpack: _SpecialForm +Required: _SpecialForm +NotRequired: _SpecialForm @final class TypeAliasType: From 337bcf9ec3de40ec195d52d5615b875c3fb8ea26 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Fri, 29 Mar 2024 00:49:33 +0100 Subject: [PATCH 142/172] Improve error message for bound typevar in TypeAliasType (#17053) Follow up to #17038 When a type variable is bound to a class, it cannot be reused in a type alias. Previously in `TypeAliasType`, this error was reported as "not included in type_params". However in the following example, the error is misleading: ```python from typing import Dict, Generic, TypeVar from typing_extensions import TypeAliasType T = TypeVar("T") class A(Generic[T]): Ta11 = TypeAliasType("Ta11", Dict[str, T], type_params=(T,)) x: A.Ta11 = {"a": 1} reveal_type(x) ``` On the master branch: ``` main.py:8: error: Type variable "T" is not included in type_params [valid-type] main.py:8: error: "T" is a type variable and only valid in type context [misc] main.py:8: error: Free type variable expected in type_params argument to TypeAliasType [type-var] main.py:12: note: Revealed type is "builtins.dict[builtins.str, Any]" Found 3 errors in 1 file (checked 1 source file) ``` With this PR: ``` typealiastype.py:8: error: Can't use bound type variable "T" to define generic alias [valid-type] typealiastype.py:8: error: "T" is a type variable and only valid in type context [misc] typealiastype.py:12: note: Revealed type is "builtins.dict[builtins.str, Any]" Found 2 errors in 1 file (checked 1 source file) ``` This is possible by storing the names of all the declared type_params, even those that are invalid, and checking if the offending type variables are in the list. --- mypy/semanal.py | 49 ++++++++++++++++++-------- mypy/typeanal.py | 26 ++++++++------ test-data/unit/check-type-aliases.test | 5 +++ 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 5aaf2bc6f433..6832e767c3a4 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -3521,6 +3521,7 @@ def analyze_alias( rvalue: Expression, allow_placeholder: bool = False, declared_type_vars: TypeVarLikeList | None = None, + all_declared_type_params_names: list[str] | None = None, ) -> tuple[Type | None, list[TypeVarLikeType], set[str], list[str], bool]: """Check if 'rvalue' is a valid type allowed for aliasing (e.g. not a type variable). @@ -3573,7 +3574,7 @@ def analyze_alias( in_dynamic_func=dynamic, global_scope=global_scope, allowed_alias_tvars=tvar_defs, - has_type_params=declared_type_vars is not None, + alias_type_params_names=all_declared_type_params_names, ) # There can be only one variadic variable at most, the error is reported elsewhere. @@ -3622,14 +3623,16 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: # It can be `A = TypeAliasType('A', ...)` call, in this case, # we just take the second argument and analyze it: type_params: TypeVarLikeList | None + all_type_params_names: list[str] | None if self.check_type_alias_type_call(s.rvalue, name=lvalue.name): rvalue = s.rvalue.args[1] pep_695 = True - type_params = self.analyze_type_alias_type_params(s.rvalue) + type_params, all_type_params_names = self.analyze_type_alias_type_params(s.rvalue) else: rvalue = s.rvalue pep_695 = False type_params = None + all_type_params_names = None if isinstance(rvalue, CallExpr) and rvalue.analyzed: return False @@ -3686,7 +3689,11 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: else: tag = self.track_incomplete_refs() res, alias_tvars, depends_on, qualified_tvars, empty_tuple_index = self.analyze_alias( - lvalue.name, rvalue, allow_placeholder=True, declared_type_vars=type_params + lvalue.name, + rvalue, + allow_placeholder=True, + declared_type_vars=type_params, + all_declared_type_params_names=all_type_params_names, ) if not res: return False @@ -3803,7 +3810,14 @@ def check_type_alias_type_call(self, rvalue: Expression, *, name: str) -> TypeGu return self.check_typevarlike_name(rvalue, name, rvalue) - def analyze_type_alias_type_params(self, rvalue: CallExpr) -> TypeVarLikeList: + def analyze_type_alias_type_params( + self, rvalue: CallExpr + ) -> tuple[TypeVarLikeList, list[str]]: + """Analyze type_params of TypeAliasType. + + Returns declared unbound type variable expressions and a list of all decalred type + variable names for error reporting. + """ if "type_params" in rvalue.arg_names: type_params_arg = rvalue.args[rvalue.arg_names.index("type_params")] if not isinstance(type_params_arg, TupleExpr): @@ -3811,12 +3825,13 @@ def analyze_type_alias_type_params(self, rvalue: CallExpr) -> TypeVarLikeList: "Tuple literal expected as the type_params argument to TypeAliasType", type_params_arg, ) - return [] + return [], [] type_params = type_params_arg.items else: - type_params = [] + return [], [] declared_tvars: TypeVarLikeList = [] + all_declared_tvar_names: list[str] = [] # includes bound type variables have_type_var_tuple = False for tp_expr in type_params: if isinstance(tp_expr, StarExpr): @@ -3843,16 +3858,19 @@ def analyze_type_alias_type_params(self, rvalue: CallExpr) -> TypeVarLikeList: continue have_type_var_tuple = True elif not self.found_incomplete_ref(tag): - self.fail( - "Free type variable expected in type_params argument to TypeAliasType", - base, - code=codes.TYPE_VAR, - ) sym = self.lookup_qualified(base.name, base) - if sym and sym.fullname in ("typing.Unpack", "typing_extensions.Unpack"): - self.note( - "Don't Unpack type variables in type_params", base, code=codes.TYPE_VAR + if sym and isinstance(sym.node, TypeVarLikeExpr): + all_declared_tvar_names.append(sym.node.name) # Error will be reported later + else: + self.fail( + "Free type variable expected in type_params argument to TypeAliasType", + base, + code=codes.TYPE_VAR, ) + if sym and sym.fullname in ("typing.Unpack", "typing_extensions.Unpack"): + self.note( + "Don't Unpack type variables in type_params", base, code=codes.TYPE_VAR + ) continue if tvar in declared_tvars: self.fail( @@ -3862,8 +3880,9 @@ def analyze_type_alias_type_params(self, rvalue: CallExpr) -> TypeVarLikeList: ) continue if tvar: + all_declared_tvar_names.append(tvar[0]) declared_tvars.append(tvar) - return declared_tvars + return declared_tvars, all_declared_tvar_names def disable_invalid_recursive_aliases( self, s: AssignmentStmt, current_node: TypeAlias diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 470b07948535..3f4b86185f2d 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -141,7 +141,7 @@ def analyze_type_alias( in_dynamic_func: bool = False, global_scope: bool = True, allowed_alias_tvars: list[TypeVarLikeType] | None = None, - has_type_params: bool = False, + alias_type_params_names: list[str] | None = None, ) -> tuple[Type, set[str]]: """Analyze r.h.s. of a (potential) type alias definition. @@ -159,7 +159,7 @@ def analyze_type_alias( allow_placeholder=allow_placeholder, prohibit_self_type="type alias target", allowed_alias_tvars=allowed_alias_tvars, - has_type_params=has_type_params, + alias_type_params_names=alias_type_params_names, ) analyzer.in_dynamic_func = in_dynamic_func analyzer.global_scope = global_scope @@ -212,7 +212,7 @@ def __init__( prohibit_self_type: str | None = None, allowed_alias_tvars: list[TypeVarLikeType] | None = None, allow_type_any: bool = False, - has_type_params: bool = False, + alias_type_params_names: list[str] | None = None, ) -> None: self.api = api self.fail_func = api.fail @@ -234,7 +234,7 @@ def __init__( if allowed_alias_tvars is None: allowed_alias_tvars = [] self.allowed_alias_tvars = allowed_alias_tvars - self.has_type_params = has_type_params + self.alias_type_params_names = alias_type_params_names # If false, record incomplete ref if we generate PlaceholderType. self.allow_placeholder = allow_placeholder # Are we in a context where Required[] is allowed? @@ -275,6 +275,12 @@ def visit_unbound_type(self, t: UnboundType, defining_literal: bool = False) -> return make_optional_type(typ) return typ + def not_declared_in_type_params(self, tvar_name: str) -> bool: + return ( + self.alias_type_params_names is not None + and tvar_name not in self.alias_type_params_names + ) + def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) -> Type: sym = self.lookup_qualified(t.name, t) if sym is not None: @@ -329,7 +335,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) if tvar_def is None: if self.allow_unbound_tvars: return t - if self.defining_alias and self.has_type_params: + if self.defining_alias and self.not_declared_in_type_params(t.name): msg = f'ParamSpec "{t.name}" is not included in type_params' else: msg = f'ParamSpec "{t.name}" is unbound' @@ -357,7 +363,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) and not defining_literal and (tvar_def is None or tvar_def not in self.allowed_alias_tvars) ): - if self.has_type_params: + if self.not_declared_in_type_params(t.name): msg = f'Type variable "{t.name}" is not included in type_params' else: msg = f'Can\'t use bound type variable "{t.name}" to define generic alias' @@ -376,7 +382,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) and self.defining_alias and tvar_def not in self.allowed_alias_tvars ): - if self.has_type_params: + if self.not_declared_in_type_params(t.name): msg = f'Type variable "{t.name}" is not included in type_params' else: msg = f'Can\'t use bound type variable "{t.name}" to define generic alias' @@ -386,7 +392,7 @@ def visit_unbound_type_nonoptional(self, t: UnboundType, defining_literal: bool) if tvar_def is None: if self.allow_unbound_tvars: return t - if self.defining_alias and self.has_type_params: + if self.defining_alias and self.not_declared_in_type_params(t.name): msg = f'TypeVarTuple "{t.name}" is not included in type_params' else: msg = f'TypeVarTuple "{t.name}" is unbound' @@ -1281,11 +1287,11 @@ def analyze_callable_args_for_paramspec( return None elif ( self.defining_alias - and self.has_type_params + and self.not_declared_in_type_params(tvar_def.name) and tvar_def not in self.allowed_alias_tvars ): self.fail( - f'ParamSpec "{callable_args.name}" is not included in type_params', + f'ParamSpec "{tvar_def.name}" is not included in type_params', callable_args, code=codes.VALID_TYPE, ) diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index 7330a04c3647..a9c57d46ad22 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1195,6 +1195,11 @@ reveal_type(unbound_ps_alias3) # N: Revealed type is "def [P] (*Any, **Any) -> #unbound_tvt_alias2: Ta10[int] #reveal_type(unbound_tvt_alias2) +class A(Generic[T]): + Ta11 = TypeAliasType("Ta11", Dict[str, T], type_params=(T,)) # E: Can't use bound type variable "T" to define generic alias \ + # E: "T" is a type variable and only valid in type context +x: A.Ta11 = {"a": 1} +reveal_type(x) # N: Revealed type is "builtins.dict[builtins.str, Any]" [builtins fixtures/dict.pyi] [case testTypeAliasTypeNoUnpackInTypeParams311] From 4a7e5d3aa4e434e45746365a24638ecfd8b42b50 Mon Sep 17 00:00:00 2001 From: Evgeniy Slobodkin Date: Fri, 29 Mar 2024 03:38:28 +0300 Subject: [PATCH 143/172] Add TypeGuard and TypeIs traversing in TypeTraverserVisitor (#17071) Fixes #17029. --- mypy/typetraverser.py | 6 ++++++ test-data/unit/check-typeguard.test | 12 ++++++++++++ test-data/unit/check-typeis.test | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py index 1ff5f6685eb8..a28bbf422b61 100644 --- a/mypy/typetraverser.py +++ b/mypy/typetraverser.py @@ -86,6 +86,12 @@ def visit_callable_type(self, t: CallableType) -> None: t.ret_type.accept(self) t.fallback.accept(self) + if t.type_guard is not None: + t.type_guard.accept(self) + + if t.type_is is not None: + t.type_is.accept(self) + def visit_tuple_type(self, t: TupleType) -> None: self.traverse_types(t.items) t.partial_fallback.accept(self) diff --git a/test-data/unit/check-typeguard.test b/test-data/unit/check-typeguard.test index 66c21bf3abe1..27b88553fb43 100644 --- a/test-data/unit/check-typeguard.test +++ b/test-data/unit/check-typeguard.test @@ -54,6 +54,18 @@ def main(a: object, b: object) -> None: reveal_type(b) # N: Revealed type is "builtins.object" [builtins fixtures/tuple.pyi] +[case testTypeGuardTypeVarReturn] +from typing import Callable, Optional, TypeVar +from typing_extensions import TypeGuard +T = TypeVar('T') +def is_str(x: object) -> TypeGuard[str]: pass +def main(x: object, type_check_func: Callable[[object], TypeGuard[T]]) -> T: + if not type_check_func(x): + raise Exception() + return x +reveal_type(main("a", is_str)) # N: Revealed type is "builtins.str" +[builtins fixtures/exception.pyi] + [case testTypeGuardIsBool] from typing_extensions import TypeGuard def f(a: TypeGuard[int]) -> None: pass diff --git a/test-data/unit/check-typeis.test b/test-data/unit/check-typeis.test index 04b64a45c8c1..6b96845504ab 100644 --- a/test-data/unit/check-typeis.test +++ b/test-data/unit/check-typeis.test @@ -92,6 +92,18 @@ def main(a: Tuple[object, ...]): reveal_type(a) # N: Revealed type is "builtins.tuple[builtins.int, ...]" [builtins fixtures/tuple.pyi] +[case testTypeIsTypeVarReturn] +from typing import Callable, Optional, TypeVar +from typing_extensions import TypeIs +T = TypeVar('T') +def is_str(x: object) -> TypeIs[str]: pass +def main(x: object, type_check_func: Callable[[object], TypeIs[T]]) -> T: + if not type_check_func(x): + raise Exception() + return x +reveal_type(main("a", is_str)) # N: Revealed type is "builtins.str" +[builtins fixtures/exception.pyi] + [case testTypeIsUnionIn] from typing import Union from typing_extensions import TypeIs From ec440155ca4eecb7d083d581448abe8f048ded36 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Mar 2024 18:47:16 -0700 Subject: [PATCH 144/172] Sync typeshed (#17081) Sync typeshed Source commit: https://github.com/python/typeshed/commit/d3c831ce7d305a97ab4d3acf61aa22591fc8364a Note that you will need to close and re-open the PR in order to trigger CI. --------- Co-authored-by: mypybot <> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: AlexWaygood --- mypy/typeshed/stdlib/builtins.pyi | 1 + mypy/typeshed/stdlib/dataclasses.pyi | 8 ++++---- mypy/typeshed/stdlib/importlib/resources/simple.pyi | 4 ++-- .../stdlib/multiprocessing/resource_tracker.pyi | 6 +++--- mypy/typeshed/stdlib/multiprocessing/util.pyi | 4 ++-- mypy/typeshed/stdlib/pyexpat/__init__.pyi | 2 ++ mypy/typeshed/stdlib/signal.pyi | 8 ++------ mypy/typeshed/stdlib/tkinter/commondialog.pyi | 4 ++-- mypy/typeshed/stdlib/tkinter/dialog.pyi | 2 +- mypy/typeshed/stdlib/tkinter/scrolledtext.pyi | 3 +-- mypy/typeshed/stdlib/traceback.pyi | 8 ++++---- mypy/typeshed/stdlib/typing.pyi | 10 +++++----- mypy/typeshed/stdlib/typing_extensions.pyi | 4 ++-- mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi | 2 +- mypy/typeshed/stdlib/xml/etree/ElementTree.pyi | 2 ++ 15 files changed, 34 insertions(+), 34 deletions(-) diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 680cd556172f..47dddcadf36d 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1777,6 +1777,7 @@ class MemoryError(Exception): ... class NameError(Exception): if sys.version_info >= (3, 10): + def __init__(self, *args: object, name: str | None = ...) -> None: ... name: str class ReferenceError(Exception): ... diff --git a/mypy/typeshed/stdlib/dataclasses.pyi b/mypy/typeshed/stdlib/dataclasses.pyi index 00e0d31d092a..c361122704a5 100644 --- a/mypy/typeshed/stdlib/dataclasses.pyi +++ b/mypy/typeshed/stdlib/dataclasses.pyi @@ -243,7 +243,7 @@ class InitVar(Generic[_T], metaclass=_InitVarMeta): if sys.version_info >= (3, 12): def make_dataclass( cls_name: str, - fields: Iterable[str | tuple[str, type] | tuple[str, type, Any]], + fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]], *, bases: tuple[type, ...] = (), namespace: dict[str, Any] | None = None, @@ -263,7 +263,7 @@ if sys.version_info >= (3, 12): elif sys.version_info >= (3, 11): def make_dataclass( cls_name: str, - fields: Iterable[str | tuple[str, type] | tuple[str, type, Any]], + fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]], *, bases: tuple[type, ...] = (), namespace: dict[str, Any] | None = None, @@ -282,7 +282,7 @@ elif sys.version_info >= (3, 11): elif sys.version_info >= (3, 10): def make_dataclass( cls_name: str, - fields: Iterable[str | tuple[str, type] | tuple[str, type, Any]], + fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]], *, bases: tuple[type, ...] = (), namespace: dict[str, Any] | None = None, @@ -300,7 +300,7 @@ elif sys.version_info >= (3, 10): else: def make_dataclass( cls_name: str, - fields: Iterable[str | tuple[str, type] | tuple[str, type, Any]], + fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]], *, bases: tuple[type, ...] = (), namespace: dict[str, Any] | None = None, diff --git a/mypy/typeshed/stdlib/importlib/resources/simple.pyi b/mypy/typeshed/stdlib/importlib/resources/simple.pyi index 9ff415156365..c360da96d856 100644 --- a/mypy/typeshed/stdlib/importlib/resources/simple.pyi +++ b/mypy/typeshed/stdlib/importlib/resources/simple.pyi @@ -28,11 +28,11 @@ if sys.version_info >= (3, 11): def is_file(self) -> Literal[True]: ... def is_dir(self) -> Literal[False]: ... @overload - def open(self, mode: OpenTextMode = "r", *args: Incomplete, **kwargs: Incomplete) -> TextIOWrapper: ... + def open(self, mode: OpenTextMode = "r", *args, **kwargs) -> TextIOWrapper: ... @overload def open(self, mode: OpenBinaryMode, *args: Unused, **kwargs: Unused) -> BinaryIO: ... @overload - def open(self, mode: str, *args: Incomplete, **kwargs: Incomplete) -> IO[Any]: ... + def open(self, mode: str, *args: Incomplete, **kwargs) -> IO[Any]: ... def joinpath(self, name: Never) -> NoReturn: ... # type: ignore[override] class ResourceContainer(Traversable, metaclass=abc.ABCMeta): diff --git a/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi b/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi index 7f726a00d73a..78ad79cf925f 100644 --- a/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi @@ -1,4 +1,4 @@ -from _typeshed import FileDescriptorOrPath, Incomplete +from _typeshed import FileDescriptorOrPath from collections.abc import Sized __all__ = ["ensure_running", "register", "unregister"] @@ -6,8 +6,8 @@ __all__ = ["ensure_running", "register", "unregister"] class ResourceTracker: def getfd(self) -> int | None: ... def ensure_running(self) -> None: ... - def register(self, name: Sized, rtype: Incomplete) -> None: ... - def unregister(self, name: Sized, rtype: Incomplete) -> None: ... + def register(self, name: Sized, rtype) -> None: ... + def unregister(self, name: Sized, rtype) -> None: ... _resource_tracker: ResourceTracker ensure_running = _resource_tracker.ensure_running diff --git a/mypy/typeshed/stdlib/multiprocessing/util.pyi b/mypy/typeshed/stdlib/multiprocessing/util.pyi index aeb46f85a327..8b900996f9eb 100644 --- a/mypy/typeshed/stdlib/multiprocessing/util.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/util.pyi @@ -42,7 +42,7 @@ def is_abstract_socket_namespace(address: str | bytes | None) -> bool: ... abstract_sockets_supported: bool def get_temp_dir() -> str: ... -def register_after_fork(obj: Incomplete, func: Callable[[Incomplete], object]) -> None: ... +def register_after_fork(obj, func: Callable[[Incomplete], object]) -> None: ... class Finalize: def __init__( @@ -59,7 +59,7 @@ class Finalize: _finalizer_registry: MutableMapping[Incomplete, Incomplete] = {}, sub_debug: Callable[..., object] = ..., getpid: Callable[[], int] = ..., - ) -> Incomplete: ... + ): ... def cancel(self) -> None: ... def still_active(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/pyexpat/__init__.pyi b/mypy/typeshed/stdlib/pyexpat/__init__.pyi index 10011b437b6a..88bf9464d130 100644 --- a/mypy/typeshed/stdlib/pyexpat/__init__.pyi +++ b/mypy/typeshed/stdlib/pyexpat/__init__.pyi @@ -32,6 +32,8 @@ class XMLParserType: def ExternalEntityParserCreate(self, context: str | None, encoding: str = ..., /) -> XMLParserType: ... def SetParamEntityParsing(self, flag: int, /) -> int: ... def UseForeignDTD(self, flag: bool = True, /) -> None: ... + def GetReparseDeferralEnabled(self) -> bool: ... + def SetReparseDeferralEnabled(self, enabled: bool, /) -> None: ... @property def intern(self) -> dict[str, str]: ... buffer_size: int diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index d1fb3ba963d4..663ee2fe7430 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -175,12 +175,8 @@ else: @property def si_band(self) -> int: ... - if sys.version_info >= (3, 10): - def sigtimedwait(sigset: Iterable[int], timeout: float, /) -> struct_siginfo | None: ... - def sigwaitinfo(sigset: Iterable[int], /) -> struct_siginfo: ... - else: - def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... - def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... + def sigtimedwait(sigset: Iterable[int], timeout: float, /) -> struct_siginfo | None: ... + def sigwaitinfo(sigset: Iterable[int], /) -> struct_siginfo: ... def strsignal(signalnum: _SIGNUM, /) -> str | None: ... def valid_signals() -> set[Signals]: ... diff --git a/mypy/typeshed/stdlib/tkinter/commondialog.pyi b/mypy/typeshed/stdlib/tkinter/commondialog.pyi index eba3ab5be3bd..d06c08df5b76 100644 --- a/mypy/typeshed/stdlib/tkinter/commondialog.pyi +++ b/mypy/typeshed/stdlib/tkinter/commondialog.pyi @@ -10,5 +10,5 @@ class Dialog: command: ClassVar[str | None] master: Incomplete | None options: Mapping[str, Incomplete] - def __init__(self, master: Incomplete | None = None, **options: Incomplete) -> None: ... - def show(self, **options: Incomplete) -> Incomplete: ... + def __init__(self, master: Incomplete | None = None, **options) -> None: ... + def show(self, **options): ... diff --git a/mypy/typeshed/stdlib/tkinter/dialog.pyi b/mypy/typeshed/stdlib/tkinter/dialog.pyi index 7bc77ac6d8b5..f76732a25460 100644 --- a/mypy/typeshed/stdlib/tkinter/dialog.pyi +++ b/mypy/typeshed/stdlib/tkinter/dialog.pyi @@ -12,5 +12,5 @@ DIALOG_ICON: str class Dialog(Widget): widgetName: str num: int - def __init__(self, master: Incomplete | None = None, cnf: Mapping[str, Any] = {}, **kw: Incomplete) -> None: ... + def __init__(self, master: Incomplete | None = None, cnf: Mapping[str, Any] = {}, **kw) -> None: ... def destroy(self) -> None: ... diff --git a/mypy/typeshed/stdlib/tkinter/scrolledtext.pyi b/mypy/typeshed/stdlib/tkinter/scrolledtext.pyi index 114f8c3de3ea..6f1abc714487 100644 --- a/mypy/typeshed/stdlib/tkinter/scrolledtext.pyi +++ b/mypy/typeshed/stdlib/tkinter/scrolledtext.pyi @@ -1,4 +1,3 @@ -from _typeshed import Incomplete from tkinter import Frame, Misc, Scrollbar, Text __all__ = ["ScrolledText"] @@ -7,4 +6,4 @@ __all__ = ["ScrolledText"] class ScrolledText(Text): frame: Frame vbar: Scrollbar - def __init__(self, master: Misc | None = None, **kwargs: Incomplete) -> None: ... + def __init__(self, master: Misc | None = None, **kwargs) -> None: ... diff --git a/mypy/typeshed/stdlib/traceback.pyi b/mypy/typeshed/stdlib/traceback.pyi index 928858f81d1c..39803003cfe5 100644 --- a/mypy/typeshed/stdlib/traceback.pyi +++ b/mypy/typeshed/stdlib/traceback.pyi @@ -27,7 +27,7 @@ __all__ = [ "walk_tb", ] -_PT: TypeAlias = tuple[str, int, str, str | None] +_FrameSummaryTuple: TypeAlias = tuple[str, int, str, str | None] def print_tb(tb: TracebackType | None, limit: int | None = None, file: SupportsWrite[str] | None = None) -> None: ... @@ -80,10 +80,10 @@ def print_last(limit: int | None = None, file: SupportsWrite[str] | None = None, def print_stack(f: FrameType | None = None, limit: int | None = None, file: SupportsWrite[str] | None = None) -> None: ... def extract_tb(tb: TracebackType | None, limit: int | None = None) -> StackSummary: ... def extract_stack(f: FrameType | None = None, limit: int | None = None) -> StackSummary: ... -def format_list(extracted_list: list[FrameSummary]) -> list[str]: ... +def format_list(extracted_list: Iterable[FrameSummary | _FrameSummaryTuple]) -> list[str]: ... # undocumented -def print_list(extracted_list: list[FrameSummary], file: SupportsWrite[str] | None = None) -> None: ... +def print_list(extracted_list: Iterable[FrameSummary | _FrameSummaryTuple], file: SupportsWrite[str] | None = None) -> None: ... if sys.version_info >= (3, 10): @overload @@ -255,7 +255,7 @@ class StackSummary(list[FrameSummary]): capture_locals: bool = False, ) -> StackSummary: ... @classmethod - def from_list(cls, a_list: Iterable[FrameSummary | _PT]) -> StackSummary: ... + def from_list(cls, a_list: Iterable[FrameSummary | _FrameSummaryTuple]) -> StackSummary: ... if sys.version_info >= (3, 11): def format_frame_summary(self, frame_summary: FrameSummary) -> str: ... diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index be0c29c89f8d..a2294f2f579f 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -6,7 +6,7 @@ import collections # noqa: F401 # pyright: ignore import sys import typing_extensions from _collections_abc import dict_items, dict_keys, dict_values -from _typeshed import IdentityFunction, Incomplete, ReadableBuffer, SupportsKeysAndGetItem +from _typeshed import IdentityFunction, ReadableBuffer, SupportsKeysAndGetItem from abc import ABCMeta, abstractmethod from contextlib import AbstractAsyncContextManager, AbstractContextManager from re import Match as Match, Pattern as Pattern @@ -170,7 +170,7 @@ class TypeVar: def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg: Incomplete) -> Incomplete: ... + def __typing_subst__(self, arg): ... # Used for an undocumented mypy feature. Does not exist at runtime. _promote = object() @@ -221,7 +221,7 @@ if sys.version_info >= (3, 11): def __init__(self, name: str) -> None: ... def __iter__(self) -> Any: ... def __typing_subst__(self, arg: Never) -> Never: ... - def __typing_prepare_subst__(self, alias: Incomplete, args: Incomplete) -> Incomplete: ... + def __typing_prepare_subst__(self, alias, args): ... if sys.version_info >= (3, 10): @final @@ -270,8 +270,8 @@ if sys.version_info >= (3, 10): @property def kwargs(self) -> ParamSpecKwargs: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg: Incomplete) -> Incomplete: ... - def __typing_prepare_subst__(self, alias: Incomplete, args: Incomplete) -> Incomplete: ... + def __typing_subst__(self, arg): ... + def __typing_prepare_subst__(self, alias, args): ... def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index f9e94ca683d6..cb67eb612a71 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -2,7 +2,7 @@ import abc import sys import typing from _collections_abc import dict_items, dict_keys, dict_values -from _typeshed import IdentityFunction, Incomplete +from _typeshed import IdentityFunction from typing import ( # noqa: Y022,Y037,Y038,Y039 IO as IO, TYPE_CHECKING as TYPE_CHECKING, @@ -413,7 +413,7 @@ class TypeVar: def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg: Incomplete) -> Incomplete: ... + def __typing_subst__(self, arg): ... @final class ParamSpec: diff --git a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi index 480dd7ce732c..62ca7dd9fc45 100644 --- a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi +++ b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi @@ -60,7 +60,7 @@ class DOMBuilder: def supportsFeature(self, name: str) -> bool: ... def canSetFeature(self, name: str, state: int) -> bool: ... # getFeature could return any attribute from an instance of `Options` - def getFeature(self, name: str) -> Incomplete: ... + def getFeature(self, name: str): ... def parseURI(self, uri: str) -> ExpatBuilder | ExpatBuilderNS: ... def parse(self, input: DOMInputSource) -> ExpatBuilder | ExpatBuilderNS: ... # `input` and `cnode` argtypes for `parseWithContext` are unknowable diff --git a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi index a8af66938344..9198bd3322d9 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi @@ -250,6 +250,7 @@ class XMLPullParser: # Second element in the tuple could be `Element`, `tuple[str, str]` or `None`. # Use `Any` to avoid false-positive errors. def read_events(self) -> Iterator[tuple[str, Any]]: ... + def flush(self) -> None: ... def XML(text: str | ReadableBuffer, parser: XMLParser | None = None) -> Element: ... def XMLID(text: str | ReadableBuffer, parser: XMLParser | None = None) -> tuple[Element, dict[str, Element]]: ... @@ -323,3 +324,4 @@ class XMLParser: def __init__(self, *, target: Any = ..., encoding: str | None = ...) -> None: ... def close(self) -> Any: ... def feed(self, data: str | ReadableBuffer, /) -> None: ... + def flush(self) -> None: ... From 80190101f68b52e960c22572ed6cc814de078b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Simon?= Date: Thu, 4 Apr 2024 12:34:00 +0200 Subject: [PATCH 145/172] Narrow individual items when matching a tuple to a sequence pattern (#16905) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #12364 When matching a tuple to a sequence pattern, this change narrows the type of tuple items inside the matched case: ```py def test(a: bool, b: bool) -> None: match a, b: case True, True: reveal_type(a) # before: "builtins.bool", after: "Literal[True]" ``` This also works with nested tuples, recursively: ```py def test(a: bool, b: bool, c: bool) -> None: match a, (b, c): case _, [True, False]: reveal_type(c) # before: "builtins.bool", after: "Literal[False]" ``` This only partially fixes issue #12364; see [my comment there](https://github.com/python/mypy/issues/12364#issuecomment-1937375271) for more context. --- This is my first contribution to mypy, so I may miss some context or conventions; I'm eager for any feedback! --------- Co-authored-by: Loïc Simon --- mypy/checker.py | 17 ++++++++ test-data/unit/check-python310.test | 66 +++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/mypy/checker.py b/mypy/checker.py index 5d243195d50f..af7535581091 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -5119,6 +5119,9 @@ def visit_match_stmt(self, s: MatchStmt) -> None: ) self.remove_capture_conflicts(pattern_type.captures, inferred_types) self.push_type_map(pattern_map) + if pattern_map: + for expr, typ in pattern_map.items(): + self.push_type_map(self._get_recursive_sub_patterns_map(expr, typ)) self.push_type_map(pattern_type.captures) if g is not None: with self.binder.frame_context(can_skip=False, fall_through=3): @@ -5156,6 +5159,20 @@ def visit_match_stmt(self, s: MatchStmt) -> None: with self.binder.frame_context(can_skip=False, fall_through=2): pass + def _get_recursive_sub_patterns_map( + self, expr: Expression, typ: Type + ) -> dict[Expression, Type]: + sub_patterns_map: dict[Expression, Type] = {} + typ_ = get_proper_type(typ) + if isinstance(expr, TupleExpr) and isinstance(typ_, TupleType): + # When matching a tuple expression with a sequence pattern, narrow individual tuple items + assert len(expr.items) == len(typ_.items) + for item_expr, item_typ in zip(expr.items, typ_.items): + sub_patterns_map[item_expr] = item_typ + sub_patterns_map.update(self._get_recursive_sub_patterns_map(item_expr, item_typ)) + + return sub_patterns_map + def infer_variable_types_from_type_maps(self, type_maps: list[TypeMap]) -> dict[Var, Type]: all_captures: dict[Var, list[tuple[NameExpr, Type]]] = defaultdict(list) for tm in type_maps: diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 3a040d94d7ba..2b56d2db07a9 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -341,6 +341,72 @@ match m: reveal_type(m) # N: Revealed type is "builtins.list[builtins.list[builtins.str]]" [builtins fixtures/list.pyi] +[case testMatchSequencePatternNarrowSubjectItems] +m: int +n: str +o: bool + +match m, n, o: + case [3, "foo", True]: + reveal_type(m) # N: Revealed type is "Literal[3]" + reveal_type(n) # N: Revealed type is "Literal['foo']" + reveal_type(o) # N: Revealed type is "Literal[True]" + case [a, b, c]: + reveal_type(m) # N: Revealed type is "builtins.int" + reveal_type(n) # N: Revealed type is "builtins.str" + reveal_type(o) # N: Revealed type is "builtins.bool" + +reveal_type(m) # N: Revealed type is "builtins.int" +reveal_type(n) # N: Revealed type is "builtins.str" +reveal_type(o) # N: Revealed type is "builtins.bool" +[builtins fixtures/tuple.pyi] + +[case testMatchSequencePatternNarrowSubjectItemsRecursive] +m: int +n: int +o: int +p: int +q: int +r: int + +match m, (n, o), (p, (q, r)): + case [0, [1, 2], [3, [4, 5]]]: + reveal_type(m) # N: Revealed type is "Literal[0]" + reveal_type(n) # N: Revealed type is "Literal[1]" + reveal_type(o) # N: Revealed type is "Literal[2]" + reveal_type(p) # N: Revealed type is "Literal[3]" + reveal_type(q) # N: Revealed type is "Literal[4]" + reveal_type(r) # N: Revealed type is "Literal[5]" +[builtins fixtures/tuple.pyi] + +[case testMatchSequencePatternSequencesLengthMismatchNoNarrowing] +m: int +n: str +o: bool + +match m, n, o: + case [3, "foo"]: + pass + case [3, "foo", True, True]: + pass +[builtins fixtures/tuple.pyi] + +[case testMatchSequencePatternSequencesLengthMismatchNoNarrowingRecursive] +m: int +n: int +o: int + +match m, (n, o): + case [0]: + pass + case [0, 1, [2]]: + pass + case [0, [1]]: + pass + case [0, [1, 2, 3]]: + pass +[builtins fixtures/tuple.pyi] + -- Mapping Pattern -- [case testMatchMappingPatternCaptures] From 732d98ecb2a98e4eaea14aba1ed8ac9c1f5ccdb6 Mon Sep 17 00:00:00 2001 From: roberfi Date: Mon, 8 Apr 2024 08:40:02 +0200 Subject: [PATCH 146/172] Fix string formatting for string enums (#16555) Fixes #7563 Inside `check_str_format_call` method, it checks if expression of `format` method call is an Enum member and it takes Literal value of that Enum member to check the `format` call arguments, if so. --- mypy/checkexpr.py | 12 +++++++- test-data/unit/check-formatting.test | 42 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 24d8447cdf3e..e8a2e501a452 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -636,7 +636,17 @@ def check_str_format_call(self, e: CallExpr) -> None: if isinstance(e.callee.expr, StrExpr): format_value = e.callee.expr.value elif self.chk.has_type(e.callee.expr): - base_typ = try_getting_literal(self.chk.lookup_type(e.callee.expr)) + typ = get_proper_type(self.chk.lookup_type(e.callee.expr)) + if ( + isinstance(typ, Instance) + and typ.type.is_enum + and isinstance(typ.last_known_value, LiteralType) + and isinstance(typ.last_known_value.value, str) + ): + value_type = typ.type.names[typ.last_known_value.value].type + if isinstance(value_type, Type): + typ = get_proper_type(value_type) + base_typ = try_getting_literal(typ) if isinstance(base_typ, LiteralType) and isinstance(base_typ.value, str): format_value = base_typ.value if format_value is not None: diff --git a/test-data/unit/check-formatting.test b/test-data/unit/check-formatting.test index 75651124b76f..83ae9b526f22 100644 --- a/test-data/unit/check-formatting.test +++ b/test-data/unit/check-formatting.test @@ -588,3 +588,45 @@ class S: '{:%}'.format(0.001) [builtins fixtures/primitives.pyi] [typing fixtures/typing-medium.pyi] + +[case testEnumWithStringToFormatValue] +from enum import Enum + +class Responses(str, Enum): + TEMPLATED = 'insert {} here' + TEMPLATED_WITH_KW = 'insert {value} here' + NORMAL = 'something' + +Responses.TEMPLATED.format(42) +Responses.TEMPLATED_WITH_KW.format(value=42) +Responses.TEMPLATED.format() # E: Cannot find replacement for positional format specifier 0 +Responses.TEMPLATED_WITH_KW.format() # E: Cannot find replacement for named format specifier "value" +Responses.NORMAL.format(42) # E: Not all arguments converted during string formatting +Responses.NORMAL.format(value=42) # E: Not all arguments converted during string formatting +[builtins fixtures/primitives.pyi] + +[case testNonStringEnumToFormatValue] +from enum import Enum + +class Responses(Enum): + TEMPLATED = 'insert {value} here' + +Responses.TEMPLATED.format(value=42) # E: "Responses" has no attribute "format" +[builtins fixtures/primitives.pyi] + +[case testStrEnumWithStringToFormatValue] +# flags: --python-version 3.11 +from enum import StrEnum + +class Responses(StrEnum): + TEMPLATED = 'insert {} here' + TEMPLATED_WITH_KW = 'insert {value} here' + NORMAL = 'something' + +Responses.TEMPLATED.format(42) +Responses.TEMPLATED_WITH_KW.format(value=42) +Responses.TEMPLATED.format() # E: Cannot find replacement for positional format specifier 0 +Responses.TEMPLATED_WITH_KW.format() # E: Cannot find replacement for named format specifier "value" +Responses.NORMAL.format(42) # E: Not all arguments converted during string formatting +Responses.NORMAL.format(value=42) # E: Not all arguments converted during string formatting +[builtins fixtures/primitives.pyi] From 3ff6e47c57a67e807e0b4579a816b4f66ab16824 Mon Sep 17 00:00:00 2001 From: Ihor <31508183+nautics889@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:59:51 +0300 Subject: [PATCH 147/172] Docs: docstrings in checker.py, ast_helpers.py (#16908) --- mypy/checker.py | 17 ++++++++++++----- mypyc/irbuild/ast_helpers.py | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/mypy/checker.py b/mypy/checker.py index af7535581091..9c10cd2fc30d 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -2166,11 +2166,18 @@ def check_override( """Check a method override with given signatures. Arguments: - override: The signature of the overriding method. - original: The signature of the original supertype method. - name: The name of the subtype. This and the next argument are - only used for generating error messages. - supertype: The name of the supertype. + override: The signature of the overriding method. + original: The signature of the original supertype method. + name: The name of the overriding method. + Used primarily for generating error messages. + name_in_super: The name of the overridden in the superclass. + Used for generating error messages only. + supertype: The name of the supertype. + original_class_or_static: Indicates whether the original method (from the superclass) + is either a class method or a static method. + override_class_or_static: Indicates whether the overriding method (from the subclass) + is either a class method or a static method. + node: Context node. """ # Use boolean variable to clarify code. fail = False diff --git a/mypyc/irbuild/ast_helpers.py b/mypyc/irbuild/ast_helpers.py index bc976647675d..3b0f50514594 100644 --- a/mypyc/irbuild/ast_helpers.py +++ b/mypyc/irbuild/ast_helpers.py @@ -62,6 +62,7 @@ def maybe_process_conditional_comparison( do nothing and return False. Args: + self: IR form Builder e: Arbitrary expression true: Branch target if comparison is true false: Branch target if comparison is false From e2fc1f28935806ca04b18fab277217f583b51594 Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Mon, 8 Apr 2024 20:38:03 +0200 Subject: [PATCH 148/172] Fix crash when expanding invalid Unpack in a `Callable` alias (#17028) Fixes #16937 --- mypy/expandtype.py | 31 ++++++++++++++----------- test-data/unit/check-python311.test | 31 +++++++++++++++++++++++++ test-data/unit/check-python312.test | 7 +++--- test-data/unit/check-type-aliases.test | 7 +++--- test-data/unit/check-typevar-tuple.test | 16 +++++++++++++ 5 files changed, 70 insertions(+), 22 deletions(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index ec6a2ecfd0d2..f7fa0258f588 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -26,6 +26,7 @@ Type, TypeAliasType, TypedDictType, + TypeOfAny, TypeType, TypeVarId, TypeVarLikeType, @@ -312,24 +313,26 @@ 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) + new_unpack: Type if isinstance(var_arg_type, Instance): # we have something like Unpack[Tuple[Any, ...]] new_unpack = var_arg - else: - 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) + elif 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 new_unpack = UnpackType(TupleType(expanded_items, fallback)) + elif isinstance(var_arg_type, TypeVarTupleType): + # We have plain Unpack[Ts] + fallback = var_arg_type.tuple_fallback + expanded_items = self.expand_unpack(var_arg) + new_unpack = UnpackType(TupleType(expanded_items, fallback)) + else: + # We have invalid type in Unpack. This can happen when expanding aliases + # to Callable[[*Invalid], Ret] + new_unpack = AnyType(TypeOfAny.from_error, line=var_arg.line, column=var_arg.column) return prefix + [new_unpack] + suffix def visit_callable_type(self, t: CallableType) -> CallableType: diff --git a/test-data/unit/check-python311.test b/test-data/unit/check-python311.test index 37dc3ca0f5b4..2d1a09ef3336 100644 --- a/test-data/unit/check-python311.test +++ b/test-data/unit/check-python311.test @@ -142,3 +142,34 @@ myclass3 = MyClass(float, float, float) # E: No overload variant of "MyClass" m # N: def [T1, T2] __init__(Type[T1], Type[T2], /) -> MyClass[T1, T2] reveal_type(myclass3) # N: Revealed type is "Any" [builtins fixtures/tuple.pyi] + +[case testUnpackNewSyntaxInvalidCallableAlias] +from typing import Any, Callable, List, Tuple, TypeVar, Unpack + +T = TypeVar("T") +Ts = TypeVarTuple("Ts") # E: Name "TypeVarTuple" is not defined + +def good(*x: int) -> int: ... +def bad(*x: int, y: int) -> int: ... + +Alias1 = Callable[[*Ts], int] # E: Variable "__main__.Ts" is not valid as a type \ + # N: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases +x1: Alias1[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(x1) # N: Revealed type is "def (*Any) -> builtins.int" +x1 = good +x1 = bad # E: Incompatible types in assignment (expression has type "Callable[[VarArg(int), NamedArg(int, 'y')], int]", variable has type "Callable[[VarArg(Any)], int]") + +Alias2 = Callable[[*T], int] # E: "T" cannot be unpacked (must be tuple or TypeVarTuple) +x2: Alias2[int] +reveal_type(x2) # N: Revealed type is "def (*Any) -> builtins.int" + +Unknown = Any +Alias3 = Callable[[*Unknown], int] +x3: Alias3[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(x3) # N: Revealed type is "def (*Any) -> builtins.int" + +IntList = List[int] +Alias4 = Callable[[*IntList], int] # E: "List[int]" cannot be unpacked (must be tuple or TypeVarTuple) +x4: Alias4[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(x4) # N: Revealed type is "def (*Unpack[builtins.tuple[Any, ...]]) -> builtins.int" +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 188c51f98185..2b99a42628b1 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -76,10 +76,9 @@ BadAlias1 = TypeAliasType("BadAlias1", tuple[*Ts]) # E: TypeVarTuple "Ts" is no ba1: BadAlias1[int] # E: Bad number of arguments for type alias, expected 0, given 1 reveal_type(ba1) # N: Revealed type is "builtins.tuple[Any, ...]" -# TODO this should report errors on the two following lines -#BadAlias2 = TypeAliasType("BadAlias2", Callable[[*Ts], str]) -#ba2: BadAlias2[int] -#reveal_type(ba2) +BadAlias2 = TypeAliasType("BadAlias2", Callable[[*Ts], str]) # E: TypeVarTuple "Ts" is not included in type_params +ba2: BadAlias2[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(ba2) # N: Revealed type is "def (*Any) -> builtins.str" [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index a9c57d46ad22..aebb0381d962 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -1190,10 +1190,9 @@ Ta9 = TypeAliasType("Ta9", Callable[P, T]) # E: ParamSpec "P" is not included i unbound_ps_alias3: Ta9[int, str] # E: Bad number of arguments for type alias, expected 0, given 2 reveal_type(unbound_ps_alias3) # N: Revealed type is "def [P] (*Any, **Any) -> Any" -# TODO this should report errors on the two following lines -#Ta10 = TypeAliasType("Ta10", Callable[[Unpack[Ts]], str]) -#unbound_tvt_alias2: Ta10[int] -#reveal_type(unbound_tvt_alias2) +Ta10 = TypeAliasType("Ta10", Callable[[Unpack[Ts]], str]) # E: TypeVarTuple "Ts" is not included in type_params +unbound_tvt_alias2: Ta10[int] # E: Bad number of arguments for type alias, expected 0, given 1 +reveal_type(unbound_tvt_alias2) # N: Revealed type is "def (*Any) -> builtins.str" class A(Generic[T]): Ta11 = TypeAliasType("Ta11", Dict[str, T], type_params=(T,)) # E: Can't use bound type variable "T" to define generic alias \ diff --git a/test-data/unit/check-typevar-tuple.test b/test-data/unit/check-typevar-tuple.test index cc3dc4ed9f39..f704e3c5c713 100644 --- a/test-data/unit/check-typevar-tuple.test +++ b/test-data/unit/check-typevar-tuple.test @@ -2278,6 +2278,22 @@ higher_order(bad3) # E: Argument 1 to "higher_order" has incompatible type "Cal 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 testAliasToCallableWithUnpackInvalid] +from typing import Any, Callable, List, Tuple, TypeVar, Unpack + +T = TypeVar("T") +Ts = TypeVarTuple("Ts") # E: Name "TypeVarTuple" is not defined + +def good(*x: int) -> int: ... +def bad(*x: int, y: int) -> int: ... + +Alias = Callable[[Unpack[T]], int] # E: "T" cannot be unpacked (must be tuple or TypeVarTuple) +x: Alias[int] +reveal_type(x) # N: Revealed type is "def (*Any) -> builtins.int" +x = good +x = bad # E: Incompatible types in assignment (expression has type "Callable[[VarArg(int), NamedArg(int, 'y')], int]", variable has type "Callable[[VarArg(Any)], int]") +[builtins fixtures/tuple.pyi] + [case testTypeVarTupleInvariant] from typing import Generic, Tuple from typing_extensions import Unpack, TypeVarTuple From 5161ac2e5b73dc7597536eb4444219868317e5d9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 19:50:28 -0700 Subject: [PATCH 149/172] Sync typeshed (#17124) Source commit: https://github.com/python/typeshed/commit/7c8e82fe483a40ec4cb0a2505cfdb0f3e7cc81d9 Co-authored-by: mypybot <> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: AlexWaygood --- mypy/typeshed/stdlib/_curses.pyi | 1091 +++++++++-------- mypy/typeshed/stdlib/asyncio/streams.pyi | 15 +- mypy/typeshed/stdlib/curses/__init__.pyi | 27 +- mypy/typeshed/stdlib/curses/ascii.pyi | 117 +- mypy/typeshed/stdlib/curses/has_key.pyi | 5 +- mypy/typeshed/stdlib/curses/panel.pyi | 41 +- mypy/typeshed/stdlib/curses/textpad.pyi | 18 +- .../stdlib/importlib/resources/simple.pyi | 15 +- mypy/typeshed/stdlib/io.pyi | 10 +- .../multiprocessing/resource_tracker.pyi | 4 +- mypy/typeshed/stdlib/multiprocessing/util.pyi | 31 +- mypy/typeshed/stdlib/ssl.pyi | 6 + mypy/typeshed/stdlib/typing.pyi | 10 +- mypy/typeshed/stdlib/typing_extensions.pyi | 8 +- mypy/typeshed/stdlib/winreg.pyi | 121 +- mypy/typeshed/stdlib/xml/dom/minidom.pyi | 4 +- mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi | 2 +- 17 files changed, 795 insertions(+), 730 deletions(-) diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index 929c6f8f3bc8..6f3fbd807fcc 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -3,557 +3,564 @@ from _typeshed import ReadOnlyBuffer, SupportsRead from typing import IO, Any, NamedTuple, final, overload from typing_extensions import TypeAlias -if sys.platform != "win32": - # Handled by PyCurses_ConvertToChtype in _cursesmodule.c. - _ChType: TypeAlias = str | bytes | int +# NOTE: This module is ordinarily only available on Unix, but the windows-curses +# package makes it available on Windows as well with the same contents. - # ACS codes are only initialized after initscr is called - ACS_BBSS: int - ACS_BLOCK: int - ACS_BOARD: int - ACS_BSBS: int - ACS_BSSB: int - ACS_BSSS: int - ACS_BTEE: int - ACS_BULLET: int - ACS_CKBOARD: int - ACS_DARROW: int - ACS_DEGREE: int - ACS_DIAMOND: int - ACS_GEQUAL: int - ACS_HLINE: int - ACS_LANTERN: int - ACS_LARROW: int - ACS_LEQUAL: int - ACS_LLCORNER: int - ACS_LRCORNER: int - ACS_LTEE: int - ACS_NEQUAL: int - ACS_PI: int - ACS_PLMINUS: int - ACS_PLUS: int - ACS_RARROW: int - ACS_RTEE: int - ACS_S1: int - ACS_S3: int - ACS_S7: int - ACS_S9: int - ACS_SBBS: int - ACS_SBSB: int - ACS_SBSS: int - ACS_SSBB: int - ACS_SSBS: int - ACS_SSSB: int - ACS_SSSS: int - ACS_STERLING: int - ACS_TTEE: int - ACS_UARROW: int - ACS_ULCORNER: int - ACS_URCORNER: int - ACS_VLINE: int - ALL_MOUSE_EVENTS: int - A_ALTCHARSET: int - A_ATTRIBUTES: int - A_BLINK: int - A_BOLD: int - A_CHARTEXT: int - A_COLOR: int - A_DIM: int - A_HORIZONTAL: int - A_INVIS: int - if sys.platform != "darwin": - A_ITALIC: int - A_LEFT: int - A_LOW: int - A_NORMAL: int - A_PROTECT: int - A_REVERSE: int - A_RIGHT: int - A_STANDOUT: int - A_TOP: int - A_UNDERLINE: int - A_VERTICAL: int - BUTTON1_CLICKED: int - BUTTON1_DOUBLE_CLICKED: int - BUTTON1_PRESSED: int - BUTTON1_RELEASED: int - BUTTON1_TRIPLE_CLICKED: int - BUTTON2_CLICKED: int - BUTTON2_DOUBLE_CLICKED: int - BUTTON2_PRESSED: int - BUTTON2_RELEASED: int - BUTTON2_TRIPLE_CLICKED: int - BUTTON3_CLICKED: int - BUTTON3_DOUBLE_CLICKED: int - BUTTON3_PRESSED: int - BUTTON3_RELEASED: int - BUTTON3_TRIPLE_CLICKED: int - BUTTON4_CLICKED: int - BUTTON4_DOUBLE_CLICKED: int - BUTTON4_PRESSED: int - BUTTON4_RELEASED: int - BUTTON4_TRIPLE_CLICKED: int - # Darwin ncurses doesn't provide BUTTON5_* constants - if sys.version_info >= (3, 10) and sys.platform != "darwin": - BUTTON5_PRESSED: int - BUTTON5_RELEASED: int - BUTTON5_CLICKED: int - BUTTON5_DOUBLE_CLICKED: int - BUTTON5_TRIPLE_CLICKED: int - BUTTON_ALT: int - BUTTON_CTRL: int - BUTTON_SHIFT: int - COLOR_BLACK: int - COLOR_BLUE: int - COLOR_CYAN: int - COLOR_GREEN: int - COLOR_MAGENTA: int - COLOR_RED: int - COLOR_WHITE: int - COLOR_YELLOW: int - ERR: int - KEY_A1: int - KEY_A3: int - KEY_B2: int - KEY_BACKSPACE: int - KEY_BEG: int - KEY_BREAK: int - KEY_BTAB: int - KEY_C1: int - KEY_C3: int - KEY_CANCEL: int - KEY_CATAB: int - KEY_CLEAR: int - KEY_CLOSE: int - KEY_COMMAND: int - KEY_COPY: int - KEY_CREATE: int - KEY_CTAB: int - KEY_DC: int - KEY_DL: int - KEY_DOWN: int - KEY_EIC: int - KEY_END: int - KEY_ENTER: int - KEY_EOL: int - KEY_EOS: int - KEY_EXIT: int - KEY_F0: int - KEY_F1: int - KEY_F10: int - KEY_F11: int - KEY_F12: int - KEY_F13: int - KEY_F14: int - KEY_F15: int - KEY_F16: int - KEY_F17: int - KEY_F18: int - KEY_F19: int - KEY_F2: int - KEY_F20: int - KEY_F21: int - KEY_F22: int - KEY_F23: int - KEY_F24: int - KEY_F25: int - KEY_F26: int - KEY_F27: int - KEY_F28: int - KEY_F29: int - KEY_F3: int - KEY_F30: int - KEY_F31: int - KEY_F32: int - KEY_F33: int - KEY_F34: int - KEY_F35: int - KEY_F36: int - KEY_F37: int - KEY_F38: int - KEY_F39: int - KEY_F4: int - KEY_F40: int - KEY_F41: int - KEY_F42: int - KEY_F43: int - KEY_F44: int - KEY_F45: int - KEY_F46: int - KEY_F47: int - KEY_F48: int - KEY_F49: int - KEY_F5: int - KEY_F50: int - KEY_F51: int - KEY_F52: int - KEY_F53: int - KEY_F54: int - KEY_F55: int - KEY_F56: int - KEY_F57: int - KEY_F58: int - KEY_F59: int - KEY_F6: int - KEY_F60: int - KEY_F61: int - KEY_F62: int - KEY_F63: int - KEY_F7: int - KEY_F8: int - KEY_F9: int - KEY_FIND: int - KEY_HELP: int - KEY_HOME: int - KEY_IC: int - KEY_IL: int - KEY_LEFT: int - KEY_LL: int - KEY_MARK: int - KEY_MAX: int - KEY_MESSAGE: int - KEY_MIN: int - KEY_MOUSE: int - KEY_MOVE: int - KEY_NEXT: int - KEY_NPAGE: int - KEY_OPEN: int - KEY_OPTIONS: int - KEY_PPAGE: int - KEY_PREVIOUS: int - KEY_PRINT: int - KEY_REDO: int - KEY_REFERENCE: int - KEY_REFRESH: int - KEY_REPLACE: int - KEY_RESET: int - KEY_RESIZE: int - KEY_RESTART: int - KEY_RESUME: int - KEY_RIGHT: int - KEY_SAVE: int - KEY_SBEG: int - KEY_SCANCEL: int - KEY_SCOMMAND: int - KEY_SCOPY: int - KEY_SCREATE: int - KEY_SDC: int - KEY_SDL: int - KEY_SELECT: int - KEY_SEND: int - KEY_SEOL: int - KEY_SEXIT: int - KEY_SF: int - KEY_SFIND: int - KEY_SHELP: int - KEY_SHOME: int - KEY_SIC: int - KEY_SLEFT: int - KEY_SMESSAGE: int - KEY_SMOVE: int - KEY_SNEXT: int - KEY_SOPTIONS: int - KEY_SPREVIOUS: int - KEY_SPRINT: int - KEY_SR: int - KEY_SREDO: int - KEY_SREPLACE: int - KEY_SRESET: int - KEY_SRIGHT: int - KEY_SRSUME: int - KEY_SSAVE: int - KEY_SSUSPEND: int - KEY_STAB: int - KEY_SUNDO: int - KEY_SUSPEND: int - KEY_UNDO: int - KEY_UP: int - OK: int - REPORT_MOUSE_POSITION: int - _C_API: Any - version: bytes - def baudrate() -> int: ... - def beep() -> None: ... - def can_change_color() -> bool: ... - def cbreak(flag: bool = True, /) -> None: ... - def color_content(color_number: int, /) -> tuple[int, int, int]: ... - def color_pair(pair_number: int, /) -> int: ... - def curs_set(visibility: int, /) -> int: ... - def def_prog_mode() -> None: ... - def def_shell_mode() -> None: ... - def delay_output(ms: int, /) -> None: ... - def doupdate() -> None: ... - def echo(flag: bool = True, /) -> None: ... - def endwin() -> None: ... - def erasechar() -> bytes: ... - def filter() -> None: ... - def flash() -> None: ... - def flushinp() -> None: ... - if sys.version_info >= (3, 9): - def get_escdelay() -> int: ... - def get_tabsize() -> int: ... +# Handled by PyCurses_ConvertToChtype in _cursesmodule.c. +_ChType: TypeAlias = str | bytes | int - def getmouse() -> tuple[int, int, int, int, int]: ... - def getsyx() -> tuple[int, int]: ... - def getwin(file: SupportsRead[bytes], /) -> _CursesWindow: ... - def halfdelay(tenths: int, /) -> None: ... - def has_colors() -> bool: ... - if sys.version_info >= (3, 10): - def has_extended_color_support() -> bool: ... +# ACS codes are only initialized after initscr is called +ACS_BBSS: int +ACS_BLOCK: int +ACS_BOARD: int +ACS_BSBS: int +ACS_BSSB: int +ACS_BSSS: int +ACS_BTEE: int +ACS_BULLET: int +ACS_CKBOARD: int +ACS_DARROW: int +ACS_DEGREE: int +ACS_DIAMOND: int +ACS_GEQUAL: int +ACS_HLINE: int +ACS_LANTERN: int +ACS_LARROW: int +ACS_LEQUAL: int +ACS_LLCORNER: int +ACS_LRCORNER: int +ACS_LTEE: int +ACS_NEQUAL: int +ACS_PI: int +ACS_PLMINUS: int +ACS_PLUS: int +ACS_RARROW: int +ACS_RTEE: int +ACS_S1: int +ACS_S3: int +ACS_S7: int +ACS_S9: int +ACS_SBBS: int +ACS_SBSB: int +ACS_SBSS: int +ACS_SSBB: int +ACS_SSBS: int +ACS_SSSB: int +ACS_SSSS: int +ACS_STERLING: int +ACS_TTEE: int +ACS_UARROW: int +ACS_ULCORNER: int +ACS_URCORNER: int +ACS_VLINE: int +ALL_MOUSE_EVENTS: int +A_ALTCHARSET: int +A_ATTRIBUTES: int +A_BLINK: int +A_BOLD: int +A_CHARTEXT: int +A_COLOR: int +A_DIM: int +A_HORIZONTAL: int +A_INVIS: int +if sys.platform != "darwin": + A_ITALIC: int +A_LEFT: int +A_LOW: int +A_NORMAL: int +A_PROTECT: int +A_REVERSE: int +A_RIGHT: int +A_STANDOUT: int +A_TOP: int +A_UNDERLINE: int +A_VERTICAL: int +BUTTON1_CLICKED: int +BUTTON1_DOUBLE_CLICKED: int +BUTTON1_PRESSED: int +BUTTON1_RELEASED: int +BUTTON1_TRIPLE_CLICKED: int +BUTTON2_CLICKED: int +BUTTON2_DOUBLE_CLICKED: int +BUTTON2_PRESSED: int +BUTTON2_RELEASED: int +BUTTON2_TRIPLE_CLICKED: int +BUTTON3_CLICKED: int +BUTTON3_DOUBLE_CLICKED: int +BUTTON3_PRESSED: int +BUTTON3_RELEASED: int +BUTTON3_TRIPLE_CLICKED: int +BUTTON4_CLICKED: int +BUTTON4_DOUBLE_CLICKED: int +BUTTON4_PRESSED: int +BUTTON4_RELEASED: int +BUTTON4_TRIPLE_CLICKED: int +# Darwin ncurses doesn't provide BUTTON5_* constants +if sys.version_info >= (3, 10) and sys.platform != "darwin": + BUTTON5_PRESSED: int + BUTTON5_RELEASED: int + BUTTON5_CLICKED: int + BUTTON5_DOUBLE_CLICKED: int + BUTTON5_TRIPLE_CLICKED: int +BUTTON_ALT: int +BUTTON_CTRL: int +BUTTON_SHIFT: int +COLOR_BLACK: int +COLOR_BLUE: int +COLOR_CYAN: int +COLOR_GREEN: int +COLOR_MAGENTA: int +COLOR_RED: int +COLOR_WHITE: int +COLOR_YELLOW: int +ERR: int +KEY_A1: int +KEY_A3: int +KEY_B2: int +KEY_BACKSPACE: int +KEY_BEG: int +KEY_BREAK: int +KEY_BTAB: int +KEY_C1: int +KEY_C3: int +KEY_CANCEL: int +KEY_CATAB: int +KEY_CLEAR: int +KEY_CLOSE: int +KEY_COMMAND: int +KEY_COPY: int +KEY_CREATE: int +KEY_CTAB: int +KEY_DC: int +KEY_DL: int +KEY_DOWN: int +KEY_EIC: int +KEY_END: int +KEY_ENTER: int +KEY_EOL: int +KEY_EOS: int +KEY_EXIT: int +KEY_F0: int +KEY_F1: int +KEY_F10: int +KEY_F11: int +KEY_F12: int +KEY_F13: int +KEY_F14: int +KEY_F15: int +KEY_F16: int +KEY_F17: int +KEY_F18: int +KEY_F19: int +KEY_F2: int +KEY_F20: int +KEY_F21: int +KEY_F22: int +KEY_F23: int +KEY_F24: int +KEY_F25: int +KEY_F26: int +KEY_F27: int +KEY_F28: int +KEY_F29: int +KEY_F3: int +KEY_F30: int +KEY_F31: int +KEY_F32: int +KEY_F33: int +KEY_F34: int +KEY_F35: int +KEY_F36: int +KEY_F37: int +KEY_F38: int +KEY_F39: int +KEY_F4: int +KEY_F40: int +KEY_F41: int +KEY_F42: int +KEY_F43: int +KEY_F44: int +KEY_F45: int +KEY_F46: int +KEY_F47: int +KEY_F48: int +KEY_F49: int +KEY_F5: int +KEY_F50: int +KEY_F51: int +KEY_F52: int +KEY_F53: int +KEY_F54: int +KEY_F55: int +KEY_F56: int +KEY_F57: int +KEY_F58: int +KEY_F59: int +KEY_F6: int +KEY_F60: int +KEY_F61: int +KEY_F62: int +KEY_F63: int +KEY_F7: int +KEY_F8: int +KEY_F9: int +KEY_FIND: int +KEY_HELP: int +KEY_HOME: int +KEY_IC: int +KEY_IL: int +KEY_LEFT: int +KEY_LL: int +KEY_MARK: int +KEY_MAX: int +KEY_MESSAGE: int +KEY_MIN: int +KEY_MOUSE: int +KEY_MOVE: int +KEY_NEXT: int +KEY_NPAGE: int +KEY_OPEN: int +KEY_OPTIONS: int +KEY_PPAGE: int +KEY_PREVIOUS: int +KEY_PRINT: int +KEY_REDO: int +KEY_REFERENCE: int +KEY_REFRESH: int +KEY_REPLACE: int +KEY_RESET: int +KEY_RESIZE: int +KEY_RESTART: int +KEY_RESUME: int +KEY_RIGHT: int +KEY_SAVE: int +KEY_SBEG: int +KEY_SCANCEL: int +KEY_SCOMMAND: int +KEY_SCOPY: int +KEY_SCREATE: int +KEY_SDC: int +KEY_SDL: int +KEY_SELECT: int +KEY_SEND: int +KEY_SEOL: int +KEY_SEXIT: int +KEY_SF: int +KEY_SFIND: int +KEY_SHELP: int +KEY_SHOME: int +KEY_SIC: int +KEY_SLEFT: int +KEY_SMESSAGE: int +KEY_SMOVE: int +KEY_SNEXT: int +KEY_SOPTIONS: int +KEY_SPREVIOUS: int +KEY_SPRINT: int +KEY_SR: int +KEY_SREDO: int +KEY_SREPLACE: int +KEY_SRESET: int +KEY_SRIGHT: int +KEY_SRSUME: int +KEY_SSAVE: int +KEY_SSUSPEND: int +KEY_STAB: int +KEY_SUNDO: int +KEY_SUSPEND: int +KEY_UNDO: int +KEY_UP: int +OK: int +REPORT_MOUSE_POSITION: int +_C_API: Any +version: bytes - def has_ic() -> bool: ... - def has_il() -> bool: ... - def has_key(key: int, /) -> bool: ... - def init_color(color_number: int, r: int, g: int, b: int, /) -> None: ... - def init_pair(pair_number: int, fg: int, bg: int, /) -> None: ... - def initscr() -> _CursesWindow: ... - def intrflush(flag: bool, /) -> None: ... - def is_term_resized(nlines: int, ncols: int, /) -> bool: ... - def isendwin() -> bool: ... - def keyname(key: int, /) -> bytes: ... - def killchar() -> bytes: ... - def longname() -> bytes: ... - def meta(yes: bool, /) -> None: ... - def mouseinterval(interval: int, /) -> None: ... - def mousemask(newmask: int, /) -> tuple[int, int]: ... - def napms(ms: int, /) -> int: ... - def newpad(nlines: int, ncols: int, /) -> _CursesWindow: ... - def newwin(nlines: int, ncols: int, begin_y: int = ..., begin_x: int = ..., /) -> _CursesWindow: ... - def nl(flag: bool = True, /) -> None: ... - def nocbreak() -> None: ... - def noecho() -> None: ... - def nonl() -> None: ... - def noqiflush() -> None: ... - def noraw() -> None: ... - def pair_content(pair_number: int, /) -> tuple[int, int]: ... - def pair_number(attr: int, /) -> int: ... - def putp(string: ReadOnlyBuffer, /) -> None: ... - def qiflush(flag: bool = True, /) -> None: ... - def raw(flag: bool = True, /) -> None: ... - def reset_prog_mode() -> None: ... - def reset_shell_mode() -> None: ... - def resetty() -> None: ... - def resize_term(nlines: int, ncols: int, /) -> None: ... - def resizeterm(nlines: int, ncols: int, /) -> None: ... - def savetty() -> None: ... - if sys.version_info >= (3, 9): - def set_escdelay(ms: int, /) -> None: ... - def set_tabsize(size: int, /) -> None: ... +def baudrate() -> int: ... +def beep() -> None: ... +def can_change_color() -> bool: ... +def cbreak(flag: bool = True, /) -> None: ... +def color_content(color_number: int, /) -> tuple[int, int, int]: ... +def color_pair(pair_number: int, /) -> int: ... +def curs_set(visibility: int, /) -> int: ... +def def_prog_mode() -> None: ... +def def_shell_mode() -> None: ... +def delay_output(ms: int, /) -> None: ... +def doupdate() -> None: ... +def echo(flag: bool = True, /) -> None: ... +def endwin() -> None: ... +def erasechar() -> bytes: ... +def filter() -> None: ... +def flash() -> None: ... +def flushinp() -> None: ... - def setsyx(y: int, x: int, /) -> None: ... - def setupterm(term: str | None = None, fd: int = -1) -> None: ... - def start_color() -> None: ... - def termattrs() -> int: ... - def termname() -> bytes: ... - def tigetflag(capname: str, /) -> int: ... - def tigetnum(capname: str, /) -> int: ... - def tigetstr(capname: str, /) -> bytes | None: ... - def tparm( - str: ReadOnlyBuffer, - i1: int = 0, - i2: int = 0, - i3: int = 0, - i4: int = 0, - i5: int = 0, - i6: int = 0, - i7: int = 0, - i8: int = 0, - i9: int = 0, - /, - ) -> bytes: ... - def typeahead(fd: int, /) -> None: ... - def unctrl(ch: _ChType, /) -> bytes: ... - if sys.version_info < (3, 12) or sys.platform != "darwin": - # The support for macos was dropped in 3.12 - def unget_wch(ch: int | str, /) -> None: ... +if sys.version_info >= (3, 9): + def get_escdelay() -> int: ... + def get_tabsize() -> int: ... - def ungetch(ch: _ChType, /) -> None: ... - def ungetmouse(id: int, x: int, y: int, z: int, bstate: int, /) -> None: ... - def update_lines_cols() -> None: ... - def use_default_colors() -> None: ... - def use_env(flag: bool, /) -> None: ... +def getmouse() -> tuple[int, int, int, int, int]: ... +def getsyx() -> tuple[int, int]: ... +def getwin(file: SupportsRead[bytes], /) -> _CursesWindow: ... +def halfdelay(tenths: int, /) -> None: ... +def has_colors() -> bool: ... - class error(Exception): ... +if sys.version_info >= (3, 10): + def has_extended_color_support() -> bool: ... - @final - class _CursesWindow: - encoding: str - @overload - def addch(self, ch: _ChType, attr: int = ...) -> None: ... - @overload - def addch(self, y: int, x: int, ch: _ChType, attr: int = ...) -> None: ... - @overload - def addnstr(self, str: str, n: int, attr: int = ...) -> None: ... - @overload - def addnstr(self, y: int, x: int, str: str, n: int, attr: int = ...) -> None: ... - @overload - def addstr(self, str: str, attr: int = ...) -> None: ... - @overload - def addstr(self, y: int, x: int, str: str, attr: int = ...) -> None: ... - def attroff(self, attr: int, /) -> None: ... - def attron(self, attr: int, /) -> None: ... - def attrset(self, attr: int, /) -> None: ... - def bkgd(self, ch: _ChType, attr: int = ..., /) -> None: ... - def bkgdset(self, ch: _ChType, attr: int = ..., /) -> None: ... - def border( - self, - ls: _ChType = ..., - rs: _ChType = ..., - ts: _ChType = ..., - bs: _ChType = ..., - tl: _ChType = ..., - tr: _ChType = ..., - bl: _ChType = ..., - br: _ChType = ..., - ) -> None: ... - @overload - def box(self) -> None: ... - @overload - def box(self, vertch: _ChType = ..., horch: _ChType = ...) -> None: ... - @overload - def chgat(self, attr: int) -> None: ... - @overload - def chgat(self, num: int, attr: int) -> None: ... - @overload - def chgat(self, y: int, x: int, attr: int) -> None: ... - @overload - def chgat(self, y: int, x: int, num: int, attr: int) -> None: ... - def clear(self) -> None: ... - def clearok(self, yes: int) -> None: ... - def clrtobot(self) -> None: ... - def clrtoeol(self) -> None: ... - def cursyncup(self) -> None: ... - @overload - def delch(self) -> None: ... - @overload - def delch(self, y: int, x: int) -> None: ... - def deleteln(self) -> None: ... - @overload - def derwin(self, begin_y: int, begin_x: int) -> _CursesWindow: ... - @overload - def derwin(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... - def echochar(self, ch: _ChType, attr: int = ..., /) -> None: ... - def enclose(self, y: int, x: int, /) -> bool: ... - def erase(self) -> None: ... - def getbegyx(self) -> tuple[int, int]: ... - def getbkgd(self) -> tuple[int, int]: ... - @overload - def getch(self) -> int: ... - @overload - def getch(self, y: int, x: int) -> int: ... - if sys.version_info < (3, 12) or sys.platform != "darwin": - # The support for macos was dropped in 3.12 - @overload - def get_wch(self) -> int | str: ... - @overload - def get_wch(self, y: int, x: int) -> int | str: ... +def has_ic() -> bool: ... +def has_il() -> bool: ... +def has_key(key: int, /) -> bool: ... +def init_color(color_number: int, r: int, g: int, b: int, /) -> None: ... +def init_pair(pair_number: int, fg: int, bg: int, /) -> None: ... +def initscr() -> _CursesWindow: ... +def intrflush(flag: bool, /) -> None: ... +def is_term_resized(nlines: int, ncols: int, /) -> bool: ... +def isendwin() -> bool: ... +def keyname(key: int, /) -> bytes: ... +def killchar() -> bytes: ... +def longname() -> bytes: ... +def meta(yes: bool, /) -> None: ... +def mouseinterval(interval: int, /) -> None: ... +def mousemask(newmask: int, /) -> tuple[int, int]: ... +def napms(ms: int, /) -> int: ... +def newpad(nlines: int, ncols: int, /) -> _CursesWindow: ... +def newwin(nlines: int, ncols: int, begin_y: int = ..., begin_x: int = ..., /) -> _CursesWindow: ... +def nl(flag: bool = True, /) -> None: ... +def nocbreak() -> None: ... +def noecho() -> None: ... +def nonl() -> None: ... +def noqiflush() -> None: ... +def noraw() -> None: ... +def pair_content(pair_number: int, /) -> tuple[int, int]: ... +def pair_number(attr: int, /) -> int: ... +def putp(string: ReadOnlyBuffer, /) -> None: ... +def qiflush(flag: bool = True, /) -> None: ... +def raw(flag: bool = True, /) -> None: ... +def reset_prog_mode() -> None: ... +def reset_shell_mode() -> None: ... +def resetty() -> None: ... +def resize_term(nlines: int, ncols: int, /) -> None: ... +def resizeterm(nlines: int, ncols: int, /) -> None: ... +def savetty() -> None: ... +if sys.version_info >= (3, 9): + def set_escdelay(ms: int, /) -> None: ... + def set_tabsize(size: int, /) -> None: ... + +def setsyx(y: int, x: int, /) -> None: ... +def setupterm(term: str | None = None, fd: int = -1) -> None: ... +def start_color() -> None: ... +def termattrs() -> int: ... +def termname() -> bytes: ... +def tigetflag(capname: str, /) -> int: ... +def tigetnum(capname: str, /) -> int: ... +def tigetstr(capname: str, /) -> bytes | None: ... +def tparm( + str: ReadOnlyBuffer, + i1: int = 0, + i2: int = 0, + i3: int = 0, + i4: int = 0, + i5: int = 0, + i6: int = 0, + i7: int = 0, + i8: int = 0, + i9: int = 0, + /, +) -> bytes: ... +def typeahead(fd: int, /) -> None: ... +def unctrl(ch: _ChType, /) -> bytes: ... + +if sys.version_info < (3, 12) or sys.platform != "darwin": + # The support for macos was dropped in 3.12 + def unget_wch(ch: int | str, /) -> None: ... + +def ungetch(ch: _ChType, /) -> None: ... +def ungetmouse(id: int, x: int, y: int, z: int, bstate: int, /) -> None: ... +def update_lines_cols() -> None: ... +def use_default_colors() -> None: ... +def use_env(flag: bool, /) -> None: ... + +class error(Exception): ... + +@final +class _CursesWindow: + encoding: str + @overload + def addch(self, ch: _ChType, attr: int = ...) -> None: ... + @overload + def addch(self, y: int, x: int, ch: _ChType, attr: int = ...) -> None: ... + @overload + def addnstr(self, str: str, n: int, attr: int = ...) -> None: ... + @overload + def addnstr(self, y: int, x: int, str: str, n: int, attr: int = ...) -> None: ... + @overload + def addstr(self, str: str, attr: int = ...) -> None: ... + @overload + def addstr(self, y: int, x: int, str: str, attr: int = ...) -> None: ... + def attroff(self, attr: int, /) -> None: ... + def attron(self, attr: int, /) -> None: ... + def attrset(self, attr: int, /) -> None: ... + def bkgd(self, ch: _ChType, attr: int = ..., /) -> None: ... + def bkgdset(self, ch: _ChType, attr: int = ..., /) -> None: ... + def border( + self, + ls: _ChType = ..., + rs: _ChType = ..., + ts: _ChType = ..., + bs: _ChType = ..., + tl: _ChType = ..., + tr: _ChType = ..., + bl: _ChType = ..., + br: _ChType = ..., + ) -> None: ... + @overload + def box(self) -> None: ... + @overload + def box(self, vertch: _ChType = ..., horch: _ChType = ...) -> None: ... + @overload + def chgat(self, attr: int) -> None: ... + @overload + def chgat(self, num: int, attr: int) -> None: ... + @overload + def chgat(self, y: int, x: int, attr: int) -> None: ... + @overload + def chgat(self, y: int, x: int, num: int, attr: int) -> None: ... + def clear(self) -> None: ... + def clearok(self, yes: int) -> None: ... + def clrtobot(self) -> None: ... + def clrtoeol(self) -> None: ... + def cursyncup(self) -> None: ... + @overload + def delch(self) -> None: ... + @overload + def delch(self, y: int, x: int) -> None: ... + def deleteln(self) -> None: ... + @overload + def derwin(self, begin_y: int, begin_x: int) -> _CursesWindow: ... + @overload + def derwin(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... + def echochar(self, ch: _ChType, attr: int = ..., /) -> None: ... + def enclose(self, y: int, x: int, /) -> bool: ... + def erase(self) -> None: ... + def getbegyx(self) -> tuple[int, int]: ... + def getbkgd(self) -> tuple[int, int]: ... + @overload + def getch(self) -> int: ... + @overload + def getch(self, y: int, x: int) -> int: ... + if sys.version_info < (3, 12) or sys.platform != "darwin": + # The support for macos was dropped in 3.12 @overload - def getkey(self) -> str: ... - @overload - def getkey(self, y: int, x: int) -> str: ... - def getmaxyx(self) -> tuple[int, int]: ... - def getparyx(self) -> tuple[int, int]: ... - @overload - def getstr(self) -> bytes: ... - @overload - def getstr(self, n: int) -> bytes: ... - @overload - def getstr(self, y: int, x: int) -> bytes: ... - @overload - def getstr(self, y: int, x: int, n: int) -> bytes: ... - def getyx(self) -> tuple[int, int]: ... - @overload - def hline(self, ch: _ChType, n: int) -> None: ... - @overload - def hline(self, y: int, x: int, ch: _ChType, n: int) -> None: ... - def idcok(self, flag: bool) -> None: ... - def idlok(self, yes: bool) -> None: ... - def immedok(self, flag: bool) -> None: ... - @overload - def inch(self) -> int: ... - @overload - def inch(self, y: int, x: int) -> int: ... - @overload - def insch(self, ch: _ChType, attr: int = ...) -> None: ... - @overload - def insch(self, y: int, x: int, ch: _ChType, attr: int = ...) -> None: ... - def insdelln(self, nlines: int) -> None: ... - def insertln(self) -> None: ... - @overload - def insnstr(self, str: str, n: int, attr: int = ...) -> None: ... - @overload - def insnstr(self, y: int, x: int, str: str, n: int, attr: int = ...) -> None: ... - @overload - def insstr(self, str: str, attr: int = ...) -> None: ... - @overload - def insstr(self, y: int, x: int, str: str, attr: int = ...) -> None: ... - @overload - def instr(self, n: int = ...) -> bytes: ... - @overload - def instr(self, y: int, x: int, n: int = ...) -> bytes: ... - def is_linetouched(self, line: int, /) -> bool: ... - def is_wintouched(self) -> bool: ... - def keypad(self, yes: bool) -> None: ... - def leaveok(self, yes: bool) -> None: ... - def move(self, new_y: int, new_x: int) -> None: ... - def mvderwin(self, y: int, x: int) -> None: ... - def mvwin(self, new_y: int, new_x: int) -> None: ... - def nodelay(self, yes: bool) -> None: ... - def notimeout(self, yes: bool) -> None: ... - @overload - def noutrefresh(self) -> None: ... - @overload - def noutrefresh(self, pminrow: int, pmincol: int, sminrow: int, smincol: int, smaxrow: int, smaxcol: int) -> None: ... - @overload - def overlay(self, destwin: _CursesWindow) -> None: ... - @overload - def overlay( - self, destwin: _CursesWindow, sminrow: int, smincol: int, dminrow: int, dmincol: int, dmaxrow: int, dmaxcol: int - ) -> None: ... - @overload - def overwrite(self, destwin: _CursesWindow) -> None: ... - @overload - def overwrite( - self, destwin: _CursesWindow, sminrow: int, smincol: int, dminrow: int, dmincol: int, dmaxrow: int, dmaxcol: int - ) -> None: ... - def putwin(self, file: IO[Any], /) -> None: ... - def redrawln(self, beg: int, num: int, /) -> None: ... - def redrawwin(self) -> None: ... - @overload - def refresh(self) -> None: ... - @overload - def refresh(self, pminrow: int, pmincol: int, sminrow: int, smincol: int, smaxrow: int, smaxcol: int) -> None: ... - def resize(self, nlines: int, ncols: int) -> None: ... - def scroll(self, lines: int = ...) -> None: ... - def scrollok(self, flag: bool) -> None: ... - def setscrreg(self, top: int, bottom: int, /) -> None: ... - def standend(self) -> None: ... - def standout(self) -> None: ... - @overload - def subpad(self, begin_y: int, begin_x: int) -> _CursesWindow: ... - @overload - def subpad(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... - @overload - def subwin(self, begin_y: int, begin_x: int) -> _CursesWindow: ... - @overload - def subwin(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... - def syncdown(self) -> None: ... - def syncok(self, flag: bool) -> None: ... - def syncup(self) -> None: ... - def timeout(self, delay: int) -> None: ... - def touchline(self, start: int, count: int, changed: bool = ...) -> None: ... - def touchwin(self) -> None: ... - def untouchwin(self) -> None: ... - @overload - def vline(self, ch: _ChType, n: int) -> None: ... + def get_wch(self) -> int | str: ... @overload - def vline(self, y: int, x: int, ch: _ChType, n: int) -> None: ... + def get_wch(self, y: int, x: int) -> int | str: ... + + @overload + def getkey(self) -> str: ... + @overload + def getkey(self, y: int, x: int) -> str: ... + def getmaxyx(self) -> tuple[int, int]: ... + def getparyx(self) -> tuple[int, int]: ... + @overload + def getstr(self) -> bytes: ... + @overload + def getstr(self, n: int) -> bytes: ... + @overload + def getstr(self, y: int, x: int) -> bytes: ... + @overload + def getstr(self, y: int, x: int, n: int) -> bytes: ... + def getyx(self) -> tuple[int, int]: ... + @overload + def hline(self, ch: _ChType, n: int) -> None: ... + @overload + def hline(self, y: int, x: int, ch: _ChType, n: int) -> None: ... + def idcok(self, flag: bool) -> None: ... + def idlok(self, yes: bool) -> None: ... + def immedok(self, flag: bool) -> None: ... + @overload + def inch(self) -> int: ... + @overload + def inch(self, y: int, x: int) -> int: ... + @overload + def insch(self, ch: _ChType, attr: int = ...) -> None: ... + @overload + def insch(self, y: int, x: int, ch: _ChType, attr: int = ...) -> None: ... + def insdelln(self, nlines: int) -> None: ... + def insertln(self) -> None: ... + @overload + def insnstr(self, str: str, n: int, attr: int = ...) -> None: ... + @overload + def insnstr(self, y: int, x: int, str: str, n: int, attr: int = ...) -> None: ... + @overload + def insstr(self, str: str, attr: int = ...) -> None: ... + @overload + def insstr(self, y: int, x: int, str: str, attr: int = ...) -> None: ... + @overload + def instr(self, n: int = ...) -> bytes: ... + @overload + def instr(self, y: int, x: int, n: int = ...) -> bytes: ... + def is_linetouched(self, line: int, /) -> bool: ... + def is_wintouched(self) -> bool: ... + def keypad(self, yes: bool) -> None: ... + def leaveok(self, yes: bool) -> None: ... + def move(self, new_y: int, new_x: int) -> None: ... + def mvderwin(self, y: int, x: int) -> None: ... + def mvwin(self, new_y: int, new_x: int) -> None: ... + def nodelay(self, yes: bool) -> None: ... + def notimeout(self, yes: bool) -> None: ... + @overload + def noutrefresh(self) -> None: ... + @overload + def noutrefresh(self, pminrow: int, pmincol: int, sminrow: int, smincol: int, smaxrow: int, smaxcol: int) -> None: ... + @overload + def overlay(self, destwin: _CursesWindow) -> None: ... + @overload + def overlay( + self, destwin: _CursesWindow, sminrow: int, smincol: int, dminrow: int, dmincol: int, dmaxrow: int, dmaxcol: int + ) -> None: ... + @overload + def overwrite(self, destwin: _CursesWindow) -> None: ... + @overload + def overwrite( + self, destwin: _CursesWindow, sminrow: int, smincol: int, dminrow: int, dmincol: int, dmaxrow: int, dmaxcol: int + ) -> None: ... + def putwin(self, file: IO[Any], /) -> None: ... + def redrawln(self, beg: int, num: int, /) -> None: ... + def redrawwin(self) -> None: ... + @overload + def refresh(self) -> None: ... + @overload + def refresh(self, pminrow: int, pmincol: int, sminrow: int, smincol: int, smaxrow: int, smaxcol: int) -> None: ... + def resize(self, nlines: int, ncols: int) -> None: ... + def scroll(self, lines: int = ...) -> None: ... + def scrollok(self, flag: bool) -> None: ... + def setscrreg(self, top: int, bottom: int, /) -> None: ... + def standend(self) -> None: ... + def standout(self) -> None: ... + @overload + def subpad(self, begin_y: int, begin_x: int) -> _CursesWindow: ... + @overload + def subpad(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... + @overload + def subwin(self, begin_y: int, begin_x: int) -> _CursesWindow: ... + @overload + def subwin(self, nlines: int, ncols: int, begin_y: int, begin_x: int) -> _CursesWindow: ... + def syncdown(self) -> None: ... + def syncok(self, flag: bool) -> None: ... + def syncup(self) -> None: ... + def timeout(self, delay: int) -> None: ... + def touchline(self, start: int, count: int, changed: bool = ...) -> None: ... + def touchwin(self) -> None: ... + def untouchwin(self) -> None: ... + @overload + def vline(self, ch: _ChType, n: int) -> None: ... + @overload + def vline(self, y: int, x: int, ch: _ChType, n: int) -> None: ... - class _ncurses_version(NamedTuple): - major: int - minor: int - patch: int +class _ncurses_version(NamedTuple): + major: int + minor: int + patch: int - ncurses_version: _ncurses_version - window = _CursesWindow # undocumented +ncurses_version: _ncurses_version +window = _CursesWindow # undocumented diff --git a/mypy/typeshed/stdlib/asyncio/streams.pyi b/mypy/typeshed/stdlib/asyncio/streams.pyi index 4dff8d28b616..c3cc7b8c9e5a 100644 --- a/mypy/typeshed/stdlib/asyncio/streams.pyi +++ b/mypy/typeshed/stdlib/asyncio/streams.pyi @@ -1,8 +1,8 @@ import ssl import sys -from _typeshed import StrPath -from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence -from typing import Any, SupportsIndex +from _typeshed import ReadableBuffer, StrPath +from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence, Sized +from typing import Any, Protocol, SupportsIndex from typing_extensions import Self, TypeAlias from . import events, protocols, transports @@ -23,6 +23,8 @@ else: _ClientConnectedCallback: TypeAlias = Callable[[StreamReader, StreamWriter], Awaitable[None] | None] +class _ReaduntilBuffer(ReadableBuffer, Sized, Protocol): ... + if sys.version_info >= (3, 10): async def open_connection( host: str | None = None, @@ -140,8 +142,11 @@ class StreamReader(AsyncIterator[bytes]): def at_eof(self) -> bool: ... def feed_data(self, data: Iterable[SupportsIndex]) -> None: ... async def readline(self) -> bytes: ... - # Can be any buffer that supports len(); consider changing to a Protocol if PEP 688 is accepted - async def readuntil(self, separator: bytes | bytearray | memoryview = b"\n") -> bytes: ... + if sys.version_info >= (3, 13): + async def readuntil(self, separator: _ReaduntilBuffer | tuple[_ReaduntilBuffer, ...] = b"\n") -> bytes: ... + else: + async def readuntil(self, separator: _ReaduntilBuffer = b"\n") -> bytes: ... + async def read(self, n: int = -1) -> bytes: ... async def readexactly(self, n: int) -> bytes: ... def __aiter__(self) -> Self: ... diff --git a/mypy/typeshed/stdlib/curses/__init__.pyi b/mypy/typeshed/stdlib/curses/__init__.pyi index 2a82ae9bda22..1df184dbaa60 100644 --- a/mypy/typeshed/stdlib/curses/__init__.pyi +++ b/mypy/typeshed/stdlib/curses/__init__.pyi @@ -1,21 +1,22 @@ -import sys +from _curses import * +from _curses import _CursesWindow as _CursesWindow from collections.abc import Callable from typing import TypeVar from typing_extensions import Concatenate, ParamSpec -if sys.platform != "win32": - from _curses import * - from _curses import _CursesWindow as _CursesWindow +# NOTE: The _curses module is ordinarily only available on Unix, but the +# windows-curses package makes it available on Windows as well with the same +# contents. - _T = TypeVar("_T") - _P = ParamSpec("_P") +_T = TypeVar("_T") +_P = ParamSpec("_P") - # available after calling `curses.initscr()` - LINES: int - COLS: int +# available after calling `curses.initscr()` +LINES: int +COLS: int - # available after calling `curses.start_color()` - COLORS: int - COLOR_PAIRS: int +# available after calling `curses.start_color()` +COLORS: int +COLOR_PAIRS: int - def wrapper(func: Callable[Concatenate[_CursesWindow, _P], _T], /, *arg: _P.args, **kwds: _P.kwargs) -> _T: ... +def wrapper(func: Callable[Concatenate[_CursesWindow, _P], _T], /, *arg: _P.args, **kwds: _P.kwargs) -> _T: ... diff --git a/mypy/typeshed/stdlib/curses/ascii.pyi b/mypy/typeshed/stdlib/curses/ascii.pyi index 25de8f605bda..66efbe36a7df 100644 --- a/mypy/typeshed/stdlib/curses/ascii.pyi +++ b/mypy/typeshed/stdlib/curses/ascii.pyi @@ -1,63 +1,62 @@ -import sys from typing import TypeVar -if sys.platform != "win32": - _CharT = TypeVar("_CharT", str, int) +_CharT = TypeVar("_CharT", str, int) - NUL: int - SOH: int - STX: int - ETX: int - EOT: int - ENQ: int - ACK: int - BEL: int - BS: int - TAB: int - HT: int - LF: int - NL: int - VT: int - FF: int - CR: int - SO: int - SI: int - DLE: int - DC1: int - DC2: int - DC3: int - DC4: int - NAK: int - SYN: int - ETB: int - CAN: int - EM: int - SUB: int - ESC: int - FS: int - GS: int - RS: int - US: int - SP: int - DEL: int +NUL: int +SOH: int +STX: int +ETX: int +EOT: int +ENQ: int +ACK: int +BEL: int +BS: int +TAB: int +HT: int +LF: int +NL: int +VT: int +FF: int +CR: int +SO: int +SI: int +DLE: int +DC1: int +DC2: int +DC3: int +DC4: int +NAK: int +SYN: int +ETB: int +CAN: int +EM: int +SUB: int +ESC: int +FS: int +GS: int +RS: int +US: int +SP: int +DEL: int - controlnames: list[int] - def isalnum(c: str | int) -> bool: ... - def isalpha(c: str | int) -> bool: ... - def isascii(c: str | int) -> bool: ... - def isblank(c: str | int) -> bool: ... - def iscntrl(c: str | int) -> bool: ... - def isdigit(c: str | int) -> bool: ... - def isgraph(c: str | int) -> bool: ... - def islower(c: str | int) -> bool: ... - def isprint(c: str | int) -> bool: ... - def ispunct(c: str | int) -> bool: ... - def isspace(c: str | int) -> bool: ... - def isupper(c: str | int) -> bool: ... - def isxdigit(c: str | int) -> bool: ... - def isctrl(c: str | int) -> bool: ... - def ismeta(c: str | int) -> bool: ... - def ascii(c: _CharT) -> _CharT: ... - def ctrl(c: _CharT) -> _CharT: ... - def alt(c: _CharT) -> _CharT: ... - def unctrl(c: str | int) -> str: ... +controlnames: list[int] + +def isalnum(c: str | int) -> bool: ... +def isalpha(c: str | int) -> bool: ... +def isascii(c: str | int) -> bool: ... +def isblank(c: str | int) -> bool: ... +def iscntrl(c: str | int) -> bool: ... +def isdigit(c: str | int) -> bool: ... +def isgraph(c: str | int) -> bool: ... +def islower(c: str | int) -> bool: ... +def isprint(c: str | int) -> bool: ... +def ispunct(c: str | int) -> bool: ... +def isspace(c: str | int) -> bool: ... +def isupper(c: str | int) -> bool: ... +def isxdigit(c: str | int) -> bool: ... +def isctrl(c: str | int) -> bool: ... +def ismeta(c: str | int) -> bool: ... +def ascii(c: _CharT) -> _CharT: ... +def ctrl(c: _CharT) -> _CharT: ... +def alt(c: _CharT) -> _CharT: ... +def unctrl(c: str | int) -> str: ... diff --git a/mypy/typeshed/stdlib/curses/has_key.pyi b/mypy/typeshed/stdlib/curses/has_key.pyi index ff728aedf84b..3811060b916a 100644 --- a/mypy/typeshed/stdlib/curses/has_key.pyi +++ b/mypy/typeshed/stdlib/curses/has_key.pyi @@ -1,4 +1 @@ -import sys - -if sys.platform != "win32": - def has_key(ch: int | str) -> bool: ... +def has_key(ch: int | str) -> bool: ... diff --git a/mypy/typeshed/stdlib/curses/panel.pyi b/mypy/typeshed/stdlib/curses/panel.pyi index 403ae9b50019..3d3448bd9584 100644 --- a/mypy/typeshed/stdlib/curses/panel.pyi +++ b/mypy/typeshed/stdlib/curses/panel.pyi @@ -1,25 +1,22 @@ -import sys +from _curses import _CursesWindow -if sys.platform != "win32": - from _curses import _CursesWindow +version: str - version: str +class _Curses_Panel: # type is (note the space in the class name) + def above(self) -> _Curses_Panel: ... + def below(self) -> _Curses_Panel: ... + def bottom(self) -> None: ... + def hidden(self) -> bool: ... + def hide(self) -> None: ... + def move(self, y: int, x: int) -> None: ... + def replace(self, win: _CursesWindow) -> None: ... + def set_userptr(self, obj: object) -> None: ... + def show(self) -> None: ... + def top(self) -> None: ... + def userptr(self) -> object: ... + def window(self) -> _CursesWindow: ... - class _Curses_Panel: # type is (note the space in the class name) - def above(self) -> _Curses_Panel: ... - def below(self) -> _Curses_Panel: ... - def bottom(self) -> None: ... - def hidden(self) -> bool: ... - def hide(self) -> None: ... - def move(self, y: int, x: int) -> None: ... - def replace(self, win: _CursesWindow) -> None: ... - def set_userptr(self, obj: object) -> None: ... - def show(self) -> None: ... - def top(self) -> None: ... - def userptr(self) -> object: ... - def window(self) -> _CursesWindow: ... - - def bottom_panel() -> _Curses_Panel: ... - def new_panel(win: _CursesWindow, /) -> _Curses_Panel: ... - def top_panel() -> _Curses_Panel: ... - def update_panels() -> _Curses_Panel: ... +def bottom_panel() -> _Curses_Panel: ... +def new_panel(win: _CursesWindow, /) -> _Curses_Panel: ... +def top_panel() -> _Curses_Panel: ... +def update_panels() -> _Curses_Panel: ... diff --git a/mypy/typeshed/stdlib/curses/textpad.pyi b/mypy/typeshed/stdlib/curses/textpad.pyi index 4d28b4dfbcdc..ce6eed09b289 100644 --- a/mypy/typeshed/stdlib/curses/textpad.pyi +++ b/mypy/typeshed/stdlib/curses/textpad.pyi @@ -1,13 +1,11 @@ -import sys +from _curses import _CursesWindow from collections.abc import Callable -if sys.platform != "win32": - from _curses import _CursesWindow - def rectangle(win: _CursesWindow, uly: int, ulx: int, lry: int, lrx: int) -> None: ... +def rectangle(win: _CursesWindow, uly: int, ulx: int, lry: int, lrx: int) -> None: ... - class Textbox: - stripspaces: bool - def __init__(self, win: _CursesWindow, insert_mode: bool = False) -> None: ... - def edit(self, validate: Callable[[int], int] | None = None) -> str: ... - def do_command(self, ch: str | int) -> None: ... - def gather(self) -> str: ... +class Textbox: + stripspaces: bool + def __init__(self, win: _CursesWindow, insert_mode: bool = False) -> None: ... + def edit(self, validate: Callable[[int], int] | None = None) -> str: ... + def do_command(self, ch: str | int) -> None: ... + def gather(self) -> str: ... diff --git a/mypy/typeshed/stdlib/importlib/resources/simple.pyi b/mypy/typeshed/stdlib/importlib/resources/simple.pyi index c360da96d856..c4c758111c2d 100644 --- a/mypy/typeshed/stdlib/importlib/resources/simple.pyi +++ b/mypy/typeshed/stdlib/importlib/resources/simple.pyi @@ -1,6 +1,5 @@ import abc import sys -from _typeshed import Incomplete, OpenBinaryMode, OpenTextMode, Unused from collections.abc import Iterator from io import TextIOWrapper from typing import IO, Any, BinaryIO, Literal, NoReturn, overload @@ -28,11 +27,19 @@ if sys.version_info >= (3, 11): def is_file(self) -> Literal[True]: ... def is_dir(self) -> Literal[False]: ... @overload - def open(self, mode: OpenTextMode = "r", *args, **kwargs) -> TextIOWrapper: ... + def open( + self, + mode: Literal["r"] = "r", + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + line_buffering: bool = False, + write_through: bool = False, + ) -> TextIOWrapper: ... @overload - def open(self, mode: OpenBinaryMode, *args: Unused, **kwargs: Unused) -> BinaryIO: ... + def open(self, mode: Literal["rb"]) -> BinaryIO: ... @overload - def open(self, mode: str, *args: Incomplete, **kwargs) -> IO[Any]: ... + def open(self, mode: str) -> IO[Any]: ... def joinpath(self, name: Never) -> NoReturn: ... # type: ignore[override] class ResourceContainer(Traversable, metaclass=abc.ABCMeta): diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index e7ed1b0b5ee5..fdbbc8dddce9 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -179,11 +179,11 @@ class TextIOWrapper(TextIOBase, TextIO): # type: ignore[misc] # incompatible d def __init__( self, buffer: _WrappedBuffer, - encoding: str | None = ..., - errors: str | None = ..., - newline: str | None = ..., - line_buffering: bool = ..., - write_through: bool = ..., + encoding: str | None = None, + errors: str | None = None, + newline: str | None = None, + line_buffering: bool = False, + write_through: bool = False, ) -> None: ... # Equals the "buffer" argument passed in to the constructor. @property diff --git a/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi b/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi index 78ad79cf925f..61da7fdf1ceb 100644 --- a/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/resource_tracker.pyi @@ -6,8 +6,8 @@ __all__ = ["ensure_running", "register", "unregister"] class ResourceTracker: def getfd(self) -> int | None: ... def ensure_running(self) -> None: ... - def register(self, name: Sized, rtype) -> None: ... - def unregister(self, name: Sized, rtype) -> None: ... + def register(self, name: Sized, rtype: str) -> None: ... + def unregister(self, name: Sized, rtype: str) -> None: ... _resource_tracker: ResourceTracker ensure_running = _resource_tracker.ensure_running diff --git a/mypy/typeshed/stdlib/multiprocessing/util.pyi b/mypy/typeshed/stdlib/multiprocessing/util.pyi index 8b900996f9eb..790d6c7467f0 100644 --- a/mypy/typeshed/stdlib/multiprocessing/util.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/util.pyi @@ -2,7 +2,7 @@ import threading from _typeshed import ConvertibleToInt, Incomplete, Unused from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence from logging import Logger, _Level as _LoggingLevel -from typing import Any +from typing import Any, Generic, TypeVar, overload __all__ = [ "sub_debug", @@ -22,6 +22,9 @@ __all__ = [ "SUBWARNING", ] +_T = TypeVar("_T") +_R_co = TypeVar("_R_co", default=Any, covariant=True) + NOTSET: int SUBDEBUG: int DEBUG: int @@ -42,13 +45,29 @@ def is_abstract_socket_namespace(address: str | bytes | None) -> bool: ... abstract_sockets_supported: bool def get_temp_dir() -> str: ... -def register_after_fork(obj, func: Callable[[Incomplete], object]) -> None: ... +def register_after_fork(obj: _T, func: Callable[[_T], object]) -> None: ... -class Finalize: +class Finalize(Generic[_R_co]): + # "args" and "kwargs" are passed as arguments to "callback". + @overload + def __init__( + self, + obj: None, + callback: Callable[..., _R_co], + *, + args: Sequence[Any] = (), + kwargs: Mapping[str, Any] | None = None, + exitpriority: int, + ) -> None: ... + @overload + def __init__( + self, obj: None, callback: Callable[..., _R_co], args: Sequence[Any], kwargs: Mapping[str, Any] | None, exitpriority: int + ) -> None: ... + @overload def __init__( self, - obj: Incomplete | None, - callback: Callable[..., Incomplete], + obj: Any, + callback: Callable[..., _R_co], args: Sequence[Any] = (), kwargs: Mapping[str, Any] | None = None, exitpriority: int | None = None, @@ -59,7 +78,7 @@ class Finalize: _finalizer_registry: MutableMapping[Incomplete, Incomplete] = {}, sub_debug: Callable[..., object] = ..., getpid: Callable[[], int] = ..., - ): ... + ) -> _R_co: ... def cancel(self) -> None: ... def still_active(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index b2263df1337d..15d86372531a 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -366,6 +366,9 @@ class SSLSocket(socket.socket): def recvmsg(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] def recvmsg_into(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] def sendmsg(self, *args: Never, **kwargs: Never) -> Never: ... # type: ignore[override] + if sys.version_info >= (3, 13): + def get_verified_chain(self) -> list[bytes]: ... + def get_unverified_chain(self) -> list[bytes]: ... class TLSVersion(enum.IntEnum): MINIMUM_SUPPORTED: int @@ -476,6 +479,9 @@ class SSLObject: def version(self) -> str | None: ... def get_channel_binding(self, cb_type: str = "tls-unique") -> bytes | None: ... def verify_client_post_handshake(self) -> None: ... + if sys.version_info >= (3, 13): + def get_verified_chain(self) -> list[bytes]: ... + def get_unverified_chain(self) -> list[bytes]: ... @final class MemoryBIO: diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index a2294f2f579f..580322b653b4 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -170,7 +170,7 @@ class TypeVar: def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg): ... + def __typing_subst__(self, arg: Any) -> Any: ... # Used for an undocumented mypy feature. Does not exist at runtime. _promote = object() @@ -221,7 +221,7 @@ if sys.version_info >= (3, 11): def __init__(self, name: str) -> None: ... def __iter__(self) -> Any: ... def __typing_subst__(self, arg: Never) -> Never: ... - def __typing_prepare_subst__(self, alias, args): ... + def __typing_prepare_subst__(self, alias: Any, args: Any) -> tuple[Any, ...]: ... if sys.version_info >= (3, 10): @final @@ -270,8 +270,8 @@ if sys.version_info >= (3, 10): @property def kwargs(self) -> ParamSpecKwargs: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg): ... - def __typing_prepare_subst__(self, alias, args): ... + def __typing_subst__(self, arg: Any) -> Any: ... + def __typing_prepare_subst__(self, alias: Any, args: Any) -> tuple[Any, ...]: ... def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... @@ -290,7 +290,7 @@ if sys.version_info >= (3, 10): def __or__(self, other: Any) -> _SpecialForm: ... def __ror__(self, other: Any) -> _SpecialForm: ... - __supertype__: type + __supertype__: type | NewType else: def NewType(name: str, tp: Any) -> Any: ... diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index cb67eb612a71..48a398ba4095 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -374,7 +374,7 @@ else: class NewType: def __init__(self, name: str, tp: Any) -> None: ... def __call__(self, obj: _T, /) -> _T: ... - __supertype__: type + __supertype__: type | NewType if sys.version_info >= (3, 10): def __or__(self, other: Any) -> _SpecialForm: ... def __ror__(self, other: Any) -> _SpecialForm: ... @@ -413,7 +413,7 @@ class TypeVar: def __or__(self, right: Any) -> _SpecialForm: ... def __ror__(self, left: Any) -> _SpecialForm: ... if sys.version_info >= (3, 11): - def __typing_subst__(self, arg): ... + def __typing_subst__(self, arg: Any) -> Any: ... @final class ParamSpec: @@ -453,10 +453,10 @@ class TypeVarTuple: def __iter__(self) -> Any: ... # Unpack[Self] class deprecated: - message: str + message: LiteralString category: type[Warning] | None stacklevel: int - def __init__(self, message: str, /, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> None: ... + def __init__(self, message: LiteralString, /, *, category: type[Warning] | None = ..., stacklevel: int = 1) -> None: ... def __call__(self, arg: _T, /) -> _T: ... if sys.version_info >= (3, 12): diff --git a/mypy/typeshed/stdlib/winreg.pyi b/mypy/typeshed/stdlib/winreg.pyi index ffb0a4cb8094..d4d04817d7e0 100644 --- a/mypy/typeshed/stdlib/winreg.pyi +++ b/mypy/typeshed/stdlib/winreg.pyi @@ -1,6 +1,7 @@ import sys +from _typeshed import ReadableBuffer, Unused from types import TracebackType -from typing import Any, Literal, final +from typing import Any, Final, Literal, final, overload from typing_extensions import Self, TypeAlias if sys.platform == "win32": @@ -24,12 +25,40 @@ if sys.platform == "win32": def QueryValueEx(key: _KeyType, name: str, /) -> tuple[Any, int]: ... def SaveKey(key: _KeyType, file_name: str, /) -> None: ... def SetValue(key: _KeyType, sub_key: str, type: int, value: str, /) -> None: ... + @overload # type=REG_DWORD|REG_QWORD def SetValueEx( - key: _KeyType, value_name: str | None, reserved: Any, type: int, value: str | int, / - ) -> None: ... # reserved is ignored + key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[4, 5], value: int | None, / + ) -> None: ... + @overload # type=REG_SZ|REG_EXPAND_SZ + def SetValueEx( + key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[1, 2], value: str | None, / + ) -> None: ... + @overload # type=REG_MULTI_SZ + def SetValueEx( + key: _KeyType, value_name: str | None, reserved: Unused, type: Literal[7], value: list[str] | None, / + ) -> None: ... + @overload # type=REG_BINARY and everything else + def SetValueEx( + key: _KeyType, + value_name: str | None, + reserved: Unused, + type: Literal[0, 3, 8, 9, 10, 11], + value: ReadableBuffer | None, + /, + ) -> None: ... + @overload # Unknown or undocumented + def SetValueEx( + key: _KeyType, + value_name: str | None, + reserved: Unused, + type: int, + value: int | str | list[str] | ReadableBuffer | None, + /, + ) -> None: ... def DisableReflectionKey(key: _KeyType, /) -> None: ... def EnableReflectionKey(key: _KeyType, /) -> None: ... def QueryReflectionKey(key: _KeyType, /) -> bool: ... + HKEY_CLASSES_ROOT: int HKEY_CURRENT_USER: int HKEY_LOCAL_MACHINE: int @@ -38,52 +67,52 @@ if sys.platform == "win32": HKEY_CURRENT_CONFIG: int HKEY_DYN_DATA: int - KEY_ALL_ACCESS: Literal[983103] - KEY_WRITE: Literal[131078] - KEY_READ: Literal[131097] - KEY_EXECUTE: Literal[131097] - KEY_QUERY_VALUE: Literal[1] - KEY_SET_VALUE: Literal[2] - KEY_CREATE_SUB_KEY: Literal[4] - KEY_ENUMERATE_SUB_KEYS: Literal[8] - KEY_NOTIFY: Literal[16] - KEY_CREATE_LINK: Literal[32] + KEY_ALL_ACCESS: Final = 983103 + KEY_WRITE: Final = 131078 + KEY_READ: Final = 131097 + KEY_EXECUTE: Final = 131097 + KEY_QUERY_VALUE: Final = 1 + KEY_SET_VALUE: Final = 2 + KEY_CREATE_SUB_KEY: Final = 4 + KEY_ENUMERATE_SUB_KEYS: Final = 8 + KEY_NOTIFY: Final = 16 + KEY_CREATE_LINK: Final = 32 - KEY_WOW64_64KEY: Literal[256] - KEY_WOW64_32KEY: Literal[512] + KEY_WOW64_64KEY: Final = 256 + KEY_WOW64_32KEY: Final = 512 - REG_BINARY: Literal[3] - REG_DWORD: Literal[4] - REG_DWORD_LITTLE_ENDIAN: Literal[4] - REG_DWORD_BIG_ENDIAN: Literal[5] - REG_EXPAND_SZ: Literal[2] - REG_LINK: Literal[6] - REG_MULTI_SZ: Literal[7] - REG_NONE: Literal[0] - REG_QWORD: Literal[11] - REG_QWORD_LITTLE_ENDIAN: Literal[11] - REG_RESOURCE_LIST: Literal[8] - REG_FULL_RESOURCE_DESCRIPTOR: Literal[9] - REG_RESOURCE_REQUIREMENTS_LIST: Literal[10] - REG_SZ: Literal[1] + REG_BINARY: Final = 3 + REG_DWORD: Final = 4 + REG_DWORD_LITTLE_ENDIAN: Final = 4 + REG_DWORD_BIG_ENDIAN: Final = 5 + REG_EXPAND_SZ: Final = 2 + REG_LINK: Final = 6 + REG_MULTI_SZ: Final = 7 + REG_NONE: Final = 0 + REG_QWORD: Final = 11 + REG_QWORD_LITTLE_ENDIAN: Final = 11 + REG_RESOURCE_LIST: Final = 8 + REG_FULL_RESOURCE_DESCRIPTOR: Final = 9 + REG_RESOURCE_REQUIREMENTS_LIST: Final = 10 + REG_SZ: Final = 1 - REG_CREATED_NEW_KEY: int # undocumented - REG_LEGAL_CHANGE_FILTER: int # undocumented - REG_LEGAL_OPTION: int # undocumented - REG_NOTIFY_CHANGE_ATTRIBUTES: int # undocumented - REG_NOTIFY_CHANGE_LAST_SET: int # undocumented - REG_NOTIFY_CHANGE_NAME: int # undocumented - REG_NOTIFY_CHANGE_SECURITY: int # undocumented - REG_NO_LAZY_FLUSH: int # undocumented - REG_OPENED_EXISTING_KEY: int # undocumented - REG_OPTION_BACKUP_RESTORE: int # undocumented - REG_OPTION_CREATE_LINK: int # undocumented - REG_OPTION_NON_VOLATILE: int # undocumented - REG_OPTION_OPEN_LINK: int # undocumented - REG_OPTION_RESERVED: int # undocumented - REG_OPTION_VOLATILE: int # undocumented - REG_REFRESH_HIVE: int # undocumented - REG_WHOLE_HIVE_VOLATILE: int # undocumented + REG_CREATED_NEW_KEY: Final = 1 # undocumented + REG_LEGAL_CHANGE_FILTER: Final = 268435471 # undocumented + REG_LEGAL_OPTION: Final = 31 # undocumented + REG_NOTIFY_CHANGE_ATTRIBUTES: Final = 2 # undocumented + REG_NOTIFY_CHANGE_LAST_SET: Final = 4 # undocumented + REG_NOTIFY_CHANGE_NAME: Final = 1 # undocumented + REG_NOTIFY_CHANGE_SECURITY: Final = 8 # undocumented + REG_NO_LAZY_FLUSH: Final = 4 # undocumented + REG_OPENED_EXISTING_KEY: Final = 2 # undocumented + REG_OPTION_BACKUP_RESTORE: Final = 4 # undocumented + REG_OPTION_CREATE_LINK: Final = 2 # undocumented + REG_OPTION_NON_VOLATILE: Final = 0 # undocumented + REG_OPTION_OPEN_LINK: Final = 8 # undocumented + REG_OPTION_RESERVED: Final = 0 # undocumented + REG_OPTION_VOLATILE: Final = 1 # undocumented + REG_REFRESH_HIVE: Final = 2 # undocumented + REG_WHOLE_HIVE_VOLATILE: Final = 1 # undocumented error = OSError diff --git a/mypy/typeshed/stdlib/xml/dom/minidom.pyi b/mypy/typeshed/stdlib/xml/dom/minidom.pyi index 28bfa1b36924..fae2c4d98714 100644 --- a/mypy/typeshed/stdlib/xml/dom/minidom.pyi +++ b/mypy/typeshed/stdlib/xml/dom/minidom.pyi @@ -256,9 +256,9 @@ class Text(CharacterData): nodeName: str attributes: Incomplete data: Incomplete - def splitText(self, offset): ... + def splitText(self, offset: int) -> Self: ... def writexml(self, writer: SupportsWrite[str], indent: str = "", addindent: str = "", newl: str = "") -> None: ... - def replaceWholeText(self, content): ... + def replaceWholeText(self, content) -> Self | None: ... @property def isWhitespaceInElementContent(self) -> bool: ... @property diff --git a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi index 62ca7dd9fc45..ab76d362e23f 100644 --- a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi +++ b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi @@ -60,7 +60,7 @@ class DOMBuilder: def supportsFeature(self, name: str) -> bool: ... def canSetFeature(self, name: str, state: int) -> bool: ... # getFeature could return any attribute from an instance of `Options` - def getFeature(self, name: str): ... + def getFeature(self, name: str) -> Any: ... def parseURI(self, uri: str) -> ExpatBuilder | ExpatBuilderNS: ... def parse(self, input: DOMInputSource) -> ExpatBuilder | ExpatBuilderNS: ... # `input` and `cnode` argtypes for `parseWithContext` are unknowable From d6d9d8cd4f27c52edac1f537e236ec48a01e54cb Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Mon, 15 Apr 2024 19:39:02 +0100 Subject: [PATCH 150/172] Bump version to 1.11.0+dev (#17129) The release branch has been cut: https://github.com/python/mypy/tree/release-1.10 Increase the dev version. --- mypy/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypy/version.py b/mypy/version.py index 93ab6463c573..f2615b77109d 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.10.0+dev" +__version__ = "1.11.0+dev" base_version = __version__ mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) From 0570f71f000489c94021d956662ab3373f7296bc Mon Sep 17 00:00:00 2001 From: Matthieu Devlin Date: Mon, 15 Apr 2024 21:16:51 -0700 Subject: [PATCH 151/172] fix: incorrect returned type of access descriptors on unions of types (#16604) Fixes https://github.com/python/mypy/issues/16603 This change maps over union types when determining the types of access descriptors. Previously, the because [this conditional](https://github.com/md384/mypy/blob/c2a55afcef32ecb11a4c76c4c79539f6ba36d55c/mypy/checkmember.py#L697-L701) would fall through to the `else` case because instance type was not a singular `TypeType` (it was a Union), so we'd end up with an instance value being passed to `__get__` instead of `None`. --- mypy/checkmember.py | 13 +++++++++++ test-data/unit/check-unions.test | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index afa8f37ff7d5..64d6733f5309 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -123,6 +123,7 @@ def copy_modified( messages: MessageBuilder | None = None, self_type: Type | None = None, is_lvalue: bool | None = None, + original_type: Type | None = None, ) -> MemberContext: mx = MemberContext( self.is_lvalue, @@ -142,6 +143,8 @@ def copy_modified( mx.self_type = self_type if is_lvalue is not None: mx.is_lvalue = is_lvalue + if original_type is not None: + mx.original_type = original_type return mx @@ -644,6 +647,16 @@ def analyze_descriptor_access(descriptor_type: Type, mx: MemberContext) -> Type: return make_simplified_union( [analyze_descriptor_access(typ, mx) for typ in descriptor_type.items] ) + elif isinstance(instance_type, UnionType): + # map over the instance types + return make_simplified_union( + [ + analyze_descriptor_access( + descriptor_type, mx.copy_modified(original_type=original_type) + ) + for original_type in instance_type.items + ] + ) elif not isinstance(descriptor_type, Instance): return orig_descriptor_type diff --git a/test-data/unit/check-unions.test b/test-data/unit/check-unions.test index d79ab14184c6..2e69a96f0c78 100644 --- a/test-data/unit/check-unions.test +++ b/test-data/unit/check-unions.test @@ -1220,3 +1220,41 @@ nc: Union[Container[str], int] 'x' in nc # E: Unsupported right operand type for in ("Union[Container[str], int]") [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] + +[case testDescriptorAccessForUnionOfTypes] +from typing import overload, Generic, Any, TypeVar, List, Optional, Union, Type + +_T_co = TypeVar("_T_co", bound=Any, covariant=True) + +class Mapped(Generic[_T_co]): + def __init__(self, value: _T_co): + self.value = value + + @overload + def __get__( + self, instance: None, owner: Any + ) -> List[_T_co]: + ... + + @overload + def __get__(self, instance: object, owner: Any) -> _T_co: + ... + + def __get__( + self, instance: Optional[object], owner: Any + ) -> Union[List[_T_co], _T_co]: + return self.value + +class A: + field_1: Mapped[int] = Mapped(1) + field_2: Mapped[str] = Mapped('1') + +class B: + field_1: Mapped[int] = Mapped(2) + field_2: Mapped[str] = Mapped('2') + +mix: Union[Type[A], Type[B]] = A +reveal_type(mix) # N: Revealed type is "Union[Type[__main__.A], Type[__main__.B]]" +reveal_type(mix.field_1) # N: Revealed type is "builtins.list[builtins.int]" +reveal_type(mix().field_1) # N: Revealed type is "builtins.int" +[builtins fixtures/list.pyi] From df35dcf020b3b03a8e3280edf8ada8c6ad8e0da5 Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 17 Apr 2024 02:27:55 -0700 Subject: [PATCH 152/172] Error for assignment of functional Enum to variable of different name (#16805) Relates to discussion in https://discuss.python.org/t/draft-of-typing-spec-chapter-for-enums/43496/11 --- mypy/semanal_enum.py | 19 ++++++--- test-data/unit/check-enum.test | 72 +++++++++++++--------------------- 2 files changed, 42 insertions(+), 49 deletions(-) diff --git a/mypy/semanal_enum.py b/mypy/semanal_enum.py index 21576ab47a84..30e0bd56c312 100644 --- a/mypy/semanal_enum.py +++ b/mypy/semanal_enum.py @@ -103,7 +103,10 @@ class A(enum.Enum): fullname = callee.fullname if fullname not in ENUM_BASES: return None - items, values, ok = self.parse_enum_call_args(call, fullname.split(".")[-1]) + + new_class_name, items, values, ok = self.parse_enum_call_args( + call, fullname.split(".")[-1] + ) if not ok: # Error. Construct dummy return value. name = var_name @@ -111,6 +114,10 @@ class A(enum.Enum): name += "@" + str(call.line) info = self.build_enum_call_typeinfo(name, [], fullname, node.line) else: + if new_class_name != var_name: + msg = f'String argument 1 "{new_class_name}" to {fullname}(...) does not match variable name "{var_name}"' + self.fail(msg, call) + name = cast(StrExpr, call.args[0]).value if name != var_name or is_func_scope: # Give it a unique name derived from the line number. @@ -142,7 +149,7 @@ def build_enum_call_typeinfo( def parse_enum_call_args( self, call: CallExpr, class_name: str - ) -> tuple[list[str], list[Expression | None], bool]: + ) -> tuple[str, list[str], list[Expression | None], bool]: """Parse arguments of an Enum call. Return a tuple of fields, values, was there an error. @@ -172,6 +179,8 @@ def parse_enum_call_args( return self.fail_enum_call_arg( f"{class_name}() expects a string literal as the first argument", call ) + new_class_name = value.value + items = [] values: list[Expression | None] = [] if isinstance(names, StrExpr): @@ -239,13 +248,13 @@ def parse_enum_call_args( if not values: values = [None] * len(items) assert len(items) == len(values) - return items, values, True + return new_class_name, items, values, True def fail_enum_call_arg( self, message: str, context: Context - ) -> tuple[list[str], list[Expression | None], bool]: + ) -> tuple[str, list[str], list[Expression | None], bool]: self.fail(message, context) - return [], [], False + return "", [], [], False # Helpers diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index 6779ae266454..b4e8795859c3 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -452,55 +452,39 @@ from enum import Enum, IntEnum PictureSize = Enum('PictureSize', 'P0 P1 P2 P3 P4 P5 P6 P7 P8', type=str, module=__name__) fake_enum1 = Enum('fake_enum1', ['a', 'b']) -fake_enum2 = Enum('fake_enum1', names=['a', 'b']) -fake_enum3 = Enum(value='fake_enum1', names=['a', 'b']) -fake_enum4 = Enum(value='fake_enum1', names=['a', 'b'] , module=__name__) +fake_enum2 = Enum('fake_enum2', names=['a', 'b']) +fake_enum3 = Enum(value='fake_enum3', names=['a', 'b']) +fake_enum4 = Enum(value='fake_enum4', names=['a', 'b'] , module=__name__) [case testFunctionalEnumErrors] from enum import Enum, IntEnum -A = Enum('A') -B = Enum('B', 42) -C = Enum('C', 'a b', 'x', 'y', 'z', 'p', 'q') -D = Enum('D', foo) +A = Enum('A') # E: Too few arguments for Enum() +B = Enum('B', 42) # E: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members +C = Enum('C', 'a b', 'x', 'y', 'z', 'p', 'q') # E: Too many arguments for Enum() +D = Enum('D', foo) # E: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members \ + # E: Name "foo" is not defined bar = 'x y z' -E = Enum('E', bar) -I = IntEnum('I') -J = IntEnum('I', 42) -K = IntEnum('I', 'p q', 'x', 'y', 'z', 'p', 'q') -L = Enum('L', ' ') -M = Enum('M', ()) -N = IntEnum('M', []) -P = Enum('P', [42]) -Q = Enum('Q', [('a', 42, 0)]) -R = IntEnum('R', [[0, 42]]) -S = Enum('S', {1: 1}) -T = Enum('T', keyword='a b') -U = Enum('U', *['a']) -V = Enum('U', **{'a': 1}) +E = Enum('E', bar) # E: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members +I = IntEnum('I') # E: Too few arguments for IntEnum() +J = IntEnum('I', 42) # E: Second argument of IntEnum() must be string, tuple, list or dict literal for mypy to determine Enum members +K = IntEnum('I', 'p q', 'x', 'y', 'z', 'p', 'q') # E: Too many arguments for IntEnum() +L = Enum('L', ' ') # E: Enum() needs at least one item +M = Enum('M', ()) # E: Enum() needs at least one item +N = IntEnum('M', []) # E: IntEnum() needs at least one item +P = Enum('P', [42]) # E: Enum() with tuple or list expects strings or (name, value) pairs +Q = Enum('Q', [('a', 42, 0)]) # E: Enum() with tuple or list expects strings or (name, value) pairs +R = IntEnum('R', [[0, 42]]) # E: IntEnum() with tuple or list expects strings or (name, value) pairs +S = Enum('S', {1: 1}) # E: Enum() with dict literal requires string literals +T = Enum('T', keyword='a b') # E: Unexpected keyword argument "keyword" +U = Enum('U', *['a']) # E: Unexpected arguments to Enum() +V = Enum('U', **{'a': 1}) # E: Unexpected arguments to Enum() W = Enum('W', 'a b') -W.c +W.c # E: "Type[W]" has no attribute "c" +X = Enum('Something', 'a b') # E: String argument 1 "Something" to enum.Enum(...) does not match variable name "X" +reveal_type(X.a) # N: Revealed type is "Literal[__main__.Something@23.a]?" +X.asdf # E: "Type[Something@23]" has no attribute "asdf" + [typing fixtures/typing-medium.pyi] -[out] -main:2: error: Too few arguments for Enum() -main:3: error: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members -main:4: error: Too many arguments for Enum() -main:5: error: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members -main:5: error: Name "foo" is not defined -main:7: error: Second argument of Enum() must be string, tuple, list or dict literal for mypy to determine Enum members -main:8: error: Too few arguments for IntEnum() -main:9: error: Second argument of IntEnum() must be string, tuple, list or dict literal for mypy to determine Enum members -main:10: error: Too many arguments for IntEnum() -main:11: error: Enum() needs at least one item -main:12: error: Enum() needs at least one item -main:13: error: IntEnum() needs at least one item -main:14: error: Enum() with tuple or list expects strings or (name, value) pairs -main:15: error: Enum() with tuple or list expects strings or (name, value) pairs -main:16: error: IntEnum() with tuple or list expects strings or (name, value) pairs -main:17: error: Enum() with dict literal requires string literals -main:18: error: Unexpected keyword argument "keyword" -main:19: error: Unexpected arguments to Enum() -main:20: error: Unexpected arguments to Enum() -main:22: error: "Type[W]" has no attribute "c" [case testFunctionalEnumFlag] from enum import Flag, IntFlag @@ -1117,7 +1101,7 @@ from enum import Enum class A: def __init__(self) -> None: - self.b = Enum("x", [("foo", "bar")]) # E: Enum type as attribute is not supported + self.b = Enum("b", [("foo", "bar")]) # E: Enum type as attribute is not supported reveal_type(A().b) # N: Revealed type is "Any" From 1072c78ad375b7f0511549287f54432050396717 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sun, 21 Apr 2024 19:31:46 -0700 Subject: [PATCH 153/172] Fix Literal strings containing pipe characters (#17148) Fixes #16367 During semantic analysis, we try to parse all strings as types, including those inside Literal[]. Previously, we preserved the original string in the `UnboundType.original_str_expr` attribute, but if a type is parsed as a Union, we didn't have a place to put the value. This PR instead always wraps string types in a RawExpressionType node, which now optionally includes a `.node` attribute containing the parsed type. This way, we don't need to worry about preserving the original string as a custom attribute on different kinds of types that can appear in this context. The downside is that more code needs to be aware of RawExpressionType. --- mypy/fastparse.py | 11 +-- mypy/semanal.py | 31 ++++---- mypy/server/astmerge.py | 3 +- mypy/stubutil.py | 16 +++- mypy/type_visitor.py | 4 + mypy/typeanal.py | 21 ++---- mypy/types.py | 75 ++++++++----------- mypy/typetraverser.py | 3 +- mypyc/irbuild/classdef.py | 9 +-- test-data/unit/check-final.test | 2 + test-data/unit/check-literal.test | 4 + test-data/unit/check-namedtuple.test | 8 +- .../unit/check-parameter-specification.test | 23 +++++- test-data/unit/check-typeguard.test | 11 +++ test-data/unit/check-typeis.test | 11 +++ 15 files changed, 142 insertions(+), 90 deletions(-) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index a155187992ec..e208e4d0b7d9 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -319,14 +319,7 @@ def parse_type_string( """ try: _, 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 - return node - elif isinstance(node, UnionType): - return node - else: - return RawExpressionType(expr_string, expr_fallback_name, line, column) + return RawExpressionType(expr_string, expr_fallback_name, line, column, node=node) except (SyntaxError, ValueError): # Note: the parser will raise a `ValueError` instead of a SyntaxError if # the string happens to contain things like \x00. @@ -1034,6 +1027,8 @@ def set_type_optional(self, type: Type | None, initializer: Expression | None) - return # Indicate that type should be wrapped in an Optional if arg is initialized to None. optional = isinstance(initializer, NameExpr) and initializer.name == "None" + if isinstance(type, RawExpressionType) and type.node is not None: + type = type.node if isinstance(type, UnboundType): type.optional = optional diff --git a/mypy/semanal.py b/mypy/semanal.py index 6832e767c3a4..1fc58a6c11f1 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -3231,10 +3231,10 @@ def analyze_typeddict_assign(self, s: AssignmentStmt) -> bool: def analyze_lvalues(self, s: AssignmentStmt) -> None: # We cannot use s.type, because analyze_simple_literal_type() will set it. explicit = s.unanalyzed_type is not None - if self.is_final_type(s.unanalyzed_type): + final_type = self.unwrap_final_type(s.unanalyzed_type) + if final_type is not None: # We need to exclude bare Final. - assert isinstance(s.unanalyzed_type, UnboundType) - if not s.unanalyzed_type.args: + if not final_type.args: explicit = False if s.rvalue: @@ -3300,19 +3300,19 @@ def unwrap_final(self, s: AssignmentStmt) -> bool: Returns True if Final[...] was present. """ - if not s.unanalyzed_type or not self.is_final_type(s.unanalyzed_type): + final_type = self.unwrap_final_type(s.unanalyzed_type) + if final_type is None: return False - assert isinstance(s.unanalyzed_type, UnboundType) - if len(s.unanalyzed_type.args) > 1: - self.fail("Final[...] takes at most one type argument", s.unanalyzed_type) + if len(final_type.args) > 1: + self.fail("Final[...] takes at most one type argument", final_type) invalid_bare_final = False - if not s.unanalyzed_type.args: + if not final_type.args: s.type = None if isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs: invalid_bare_final = True self.fail("Type in Final[...] can only be omitted if there is an initializer", s) else: - s.type = s.unanalyzed_type.args[0] + s.type = final_type.args[0] if s.type is not None and self.is_classvar(s.type): self.fail("Variable should not be annotated with both ClassVar and Final", s) @@ -4713,13 +4713,18 @@ def is_classvar(self, typ: Type) -> bool: return False return sym.node.fullname == "typing.ClassVar" - def is_final_type(self, typ: Type | None) -> bool: + def unwrap_final_type(self, typ: Type | None) -> UnboundType | None: + if typ is None: + return None + typ = typ.resolve_string_annotation() if not isinstance(typ, UnboundType): - return False + return None sym = self.lookup_qualified(typ.name, typ) if not sym or not sym.node: - return False - return sym.node.fullname in FINAL_TYPE_NAMES + return None + if sym.node.fullname in FINAL_TYPE_NAMES: + return typ + return None def fail_invalid_classvar(self, context: Context) -> None: self.fail(message_registry.CLASS_VAR_OUTSIDE_OF_CLASS, context) diff --git a/mypy/server/astmerge.py b/mypy/server/astmerge.py index 174c2922c767..e6648fbb4be7 100644 --- a/mypy/server/astmerge.py +++ b/mypy/server/astmerge.py @@ -507,7 +507,8 @@ def visit_typeddict_type(self, typ: TypedDictType) -> None: typ.fallback.accept(self) def visit_raw_expression_type(self, t: RawExpressionType) -> None: - pass + if t.node is not None: + t.node.accept(self) def visit_literal_type(self, typ: LiteralType) -> None: typ.fallback.accept(self) diff --git a/mypy/stubutil.py b/mypy/stubutil.py index 410672f89d09..8e41d6862531 100644 --- a/mypy/stubutil.py +++ b/mypy/stubutil.py @@ -17,7 +17,16 @@ from mypy.modulefinder import ModuleNotFoundReason from mypy.moduleinspect import InspectError, ModuleInspect from mypy.stubdoc import ArgSig, FunctionSig -from mypy.types import AnyType, NoneType, Type, TypeList, TypeStrVisitor, UnboundType, UnionType +from mypy.types import ( + AnyType, + NoneType, + RawExpressionType, + Type, + TypeList, + TypeStrVisitor, + UnboundType, + UnionType, +) # Modules that may fail when imported, or that may have side effects (fully qualified). NOT_IMPORTABLE_MODULES = () @@ -291,12 +300,11 @@ def args_str(self, args: Iterable[Type]) -> str: The main difference from list_str is the preservation of quotes for string arguments """ - types = ["builtins.bytes", "builtins.str"] res = [] for arg in args: arg_str = arg.accept(self) - if isinstance(arg, UnboundType) and arg.original_str_fallback in types: - res.append(f"'{arg_str}'") + if isinstance(arg, RawExpressionType): + res.append(repr(arg.literal_value)) else: res.append(arg_str) return ", ".join(res) diff --git a/mypy/type_visitor.py b/mypy/type_visitor.py index 1860a43eb14f..a6ae77832ceb 100644 --- a/mypy/type_visitor.py +++ b/mypy/type_visitor.py @@ -376,6 +376,8 @@ def visit_typeddict_type(self, t: TypedDictType) -> T: return self.query_types(t.items.values()) def visit_raw_expression_type(self, t: RawExpressionType) -> T: + if t.node is not None: + return t.node.accept(self) return self.strategy([]) def visit_literal_type(self, t: LiteralType) -> T: @@ -516,6 +518,8 @@ def visit_typeddict_type(self, t: TypedDictType) -> bool: return self.query_types(list(t.items.values())) def visit_raw_expression_type(self, t: RawExpressionType) -> bool: + if t.node is not None: + return t.node.accept(self) return self.default def visit_literal_type(self, t: LiteralType) -> bool: diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 3f4b86185f2d..c2c578045297 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -1070,6 +1070,7 @@ def visit_callable_type(self, t: CallableType, nested: bool = True) -> Type: return ret def anal_type_guard(self, t: Type) -> Type | None: + t = t.resolve_string_annotation() if isinstance(t, UnboundType): sym = self.lookup_qualified(t.name, t) if sym is not None and sym.node is not None: @@ -1088,6 +1089,7 @@ def anal_type_guard_arg(self, t: UnboundType, fullname: str) -> Type | None: return None def anal_type_is(self, t: Type) -> Type | None: + t = t.resolve_string_annotation() if isinstance(t, UnboundType): sym = self.lookup_qualified(t.name, t) if sym is not None and sym.node is not None: @@ -1105,6 +1107,7 @@ def anal_type_is_arg(self, t: UnboundType, fullname: str) -> Type | None: def anal_star_arg_type(self, t: Type, kind: ArgKind, nested: bool) -> Type: """Analyze signature argument type for *args and **kwargs argument.""" + t = t.resolve_string_annotation() if isinstance(t, UnboundType) and t.name and "." in t.name and not t.args: components = t.name.split(".") tvar_name = ".".join(components[:-1]) @@ -1195,6 +1198,8 @@ def visit_raw_expression_type(self, t: RawExpressionType) -> Type: # make signatures like "foo(x: 20) -> None" legal, we can change # this method so it generates and returns an actual LiteralType # instead. + if t.node is not None: + return t.node.accept(self) if self.report_invalid_types: if t.base_type_name in ("builtins.int", "builtins.bool"): @@ -1455,6 +1460,7 @@ def analyze_callable_args( invalid_unpacks: list[Type] = [] second_unpack_last = False for i, arg in enumerate(arglist.items): + arg = arg.resolve_string_annotation() if isinstance(arg, CallableArgument): args.append(arg.typ) names.append(arg.name) @@ -1535,18 +1541,6 @@ def analyze_literal_type(self, t: UnboundType) -> Type: return UnionType.make_union(output, line=t.line) def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> list[Type] | None: - # This UnboundType was originally defined as a string. - if isinstance(arg, UnboundType) and arg.original_str_expr is not None: - assert arg.original_str_fallback is not None - return [ - LiteralType( - value=arg.original_str_expr, - fallback=self.named_type(arg.original_str_fallback), - line=arg.line, - column=arg.column, - ) - ] - # If arg is an UnboundType that was *not* originally defined as # a string, try expanding it in case it's a type alias or something. if isinstance(arg, UnboundType): @@ -2528,7 +2522,8 @@ 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 + if t.node is not None: + t.node.accept(self) def visit_literal_type(self, t: LiteralType) -> None: pass diff --git a/mypy/types.py b/mypy/types.py index b4209e9debf4..5573dc9efe0e 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -271,6 +271,9 @@ def can_be_true_default(self) -> bool: def can_be_false_default(self) -> bool: return True + def resolve_string_annotation(self) -> Type: + return self + def accept(self, visitor: TypeVisitor[T]) -> T: raise RuntimeError("Not implemented", type(self)) @@ -900,14 +903,7 @@ def copy_modified( class UnboundType(ProperType): """Instance type that has not been bound during semantic analysis.""" - __slots__ = ( - "name", - "args", - "optional", - "empty_tuple_index", - "original_str_expr", - "original_str_fallback", - ) + __slots__ = ("name", "args", "optional", "empty_tuple_index") def __init__( self, @@ -917,8 +913,6 @@ def __init__( column: int = -1, optional: bool = False, empty_tuple_index: bool = False, - original_str_expr: str | None = None, - original_str_fallback: str | None = None, ) -> None: super().__init__(line, column) if not args: @@ -930,21 +924,6 @@ def __init__( self.optional = optional # Special case for X[()] self.empty_tuple_index = empty_tuple_index - # If this UnboundType was originally defined as a str or bytes, keep track of - # the original contents of that string-like thing. This way, if this UnboundExpr - # ever shows up inside of a LiteralType, we can determine whether that - # Literal[...] is valid or not. E.g. Literal[foo] is most likely invalid - # (unless 'foo' is an alias for another literal or something) and - # Literal["foo"] most likely is. - # - # We keep track of the entire string instead of just using a boolean flag - # so we can distinguish between things like Literal["foo"] vs - # Literal[" foo "]. - # - # We also keep track of what the original base fallback type was supposed to be - # so we don't have to try and recompute it later - self.original_str_expr = original_str_expr - self.original_str_fallback = original_str_fallback def copy_modified(self, args: Bogus[Sequence[Type] | None] = _dummy) -> UnboundType: if args is _dummy: @@ -956,25 +935,19 @@ def copy_modified(self, args: Bogus[Sequence[Type] | None] = _dummy) -> UnboundT column=self.column, optional=self.optional, empty_tuple_index=self.empty_tuple_index, - original_str_expr=self.original_str_expr, - original_str_fallback=self.original_str_fallback, ) def accept(self, visitor: TypeVisitor[T]) -> T: return visitor.visit_unbound_type(self) def __hash__(self) -> int: - return hash((self.name, self.optional, tuple(self.args), self.original_str_expr)) + return hash((self.name, self.optional, tuple(self.args))) def __eq__(self, other: object) -> bool: if not isinstance(other, UnboundType): return NotImplemented return ( - self.name == other.name - and self.optional == other.optional - and self.args == other.args - and self.original_str_expr == other.original_str_expr - and self.original_str_fallback == other.original_str_fallback + self.name == other.name and self.optional == other.optional and self.args == other.args ) def serialize(self) -> JsonDict: @@ -982,19 +955,12 @@ def serialize(self) -> JsonDict: ".class": "UnboundType", "name": self.name, "args": [a.serialize() for a in self.args], - "expr": self.original_str_expr, - "expr_fallback": self.original_str_fallback, } @classmethod def deserialize(cls, data: JsonDict) -> UnboundType: assert data[".class"] == "UnboundType" - return UnboundType( - data["name"], - [deserialize_type(a) for a in data["args"]], - original_str_expr=data["expr"], - original_str_fallback=data["expr_fallback"], - ) + return UnboundType(data["name"], [deserialize_type(a) for a in data["args"]]) class CallableArgument(ProperType): @@ -2646,7 +2612,7 @@ class RawExpressionType(ProperType): This synthetic type is only used at the beginning stages of semantic analysis and should be completely removing during the process for mapping UnboundTypes to - actual types: we either turn it into a LiteralType or an AnyType. + actual types: we turn it into its "node" argument, a LiteralType, or an AnyType. For example, suppose `Foo[1]` is initially represented as the following: @@ -2684,7 +2650,7 @@ class RawExpressionType(ProperType): ) """ - __slots__ = ("literal_value", "base_type_name", "note") + __slots__ = ("literal_value", "base_type_name", "note", "node") def __init__( self, @@ -2693,11 +2659,13 @@ def __init__( line: int = -1, column: int = -1, note: str | None = None, + node: Type | None = None, ) -> None: super().__init__(line, column) self.literal_value = literal_value self.base_type_name = base_type_name self.note = note + self.node = node def simple_name(self) -> str: return self.base_type_name.replace("builtins.", "") @@ -2707,6 +2675,21 @@ def accept(self, visitor: TypeVisitor[T]) -> T: ret: T = visitor.visit_raw_expression_type(self) return ret + def copy_modified(self, node: Type | None) -> RawExpressionType: + return RawExpressionType( + literal_value=self.literal_value, + base_type_name=self.base_type_name, + line=self.line, + column=self.column, + note=self.note, + node=node, + ) + + def resolve_string_annotation(self) -> Type: + if self.node is not None: + return self.node.resolve_string_annotation() + return self + def serialize(self) -> JsonDict: assert False, "Synthetic types don't serialize" @@ -2718,6 +2701,7 @@ def __eq__(self, other: object) -> bool: return ( self.base_type_name == other.base_type_name and self.literal_value == other.literal_value + and self.node == other.node ) else: return NotImplemented @@ -3386,6 +3370,8 @@ def item_str(name: str, typ: str) -> str: return f"TypedDict({prefix}{s})" def visit_raw_expression_type(self, t: RawExpressionType) -> str: + if t.node is not None: + return t.node.accept(self) return repr(t.literal_value) def visit_literal_type(self, t: LiteralType) -> str: @@ -3449,6 +3435,9 @@ def visit_ellipsis_type(self, t: EllipsisType) -> Type: return t def visit_raw_expression_type(self, t: RawExpressionType) -> Type: + if t.node is not None: + node = t.node.accept(self) + return t.copy_modified(node=node) return t def visit_type_list(self, t: TypeList) -> Type: diff --git a/mypy/typetraverser.py b/mypy/typetraverser.py index a28bbf422b61..4d740a802b55 100644 --- a/mypy/typetraverser.py +++ b/mypy/typetraverser.py @@ -130,7 +130,8 @@ def visit_partial_type(self, t: PartialType) -> None: pass def visit_raw_expression_type(self, t: RawExpressionType) -> None: - pass + if t.node is not None: + t.node.accept(self) def visit_type_alias_type(self, t: TypeAliasType) -> None: # TODO: sometimes we want to traverse target as well diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py index fc2bb4a1fc2f..3f6ec0f33822 100644 --- a/mypyc/irbuild/classdef.py +++ b/mypyc/irbuild/classdef.py @@ -24,7 +24,7 @@ TypeInfo, is_class_var, ) -from mypy.types import ENUM_REMOVED_PROPS, Instance, UnboundType, get_proper_type +from mypy.types import ENUM_REMOVED_PROPS, Instance, RawExpressionType, get_proper_type from mypyc.common import PROPSET_PREFIX from mypyc.ir.class_ir import ClassIR, NonExtClassInfo from mypyc.ir.func_ir import FuncDecl, FuncSignature @@ -601,16 +601,15 @@ def add_non_ext_class_attr_ann( if typ is None: # FIXME: if get_type_info is not provided, don't fall back to stmt.type? ann_type = get_proper_type(stmt.type) - if ( - isinstance(stmt.unanalyzed_type, UnboundType) - and stmt.unanalyzed_type.original_str_expr is not None + if isinstance(stmt.unanalyzed_type, RawExpressionType) and isinstance( + stmt.unanalyzed_type.literal_value, str ): # Annotation is a forward reference, so don't attempt to load the actual # type and load the string instead. # # TODO: is it possible to determine whether a non-string annotation is # actually a forward reference due to the __annotations__ future? - typ = builder.load_str(stmt.unanalyzed_type.original_str_expr) + typ = builder.load_str(stmt.unanalyzed_type.literal_value) elif isinstance(ann_type, Instance): typ = load_type(builder, ann_type.type, stmt.line) else: diff --git a/test-data/unit/check-final.test b/test-data/unit/check-final.test index b1378a47b1b1..26a0d0782503 100644 --- a/test-data/unit/check-final.test +++ b/test-data/unit/check-final.test @@ -6,11 +6,13 @@ [case testFinalDefiningModuleVar] from typing import Final +w: 'Final' = int() x: Final = int() y: Final[float] = int() z: Final[int] = int() bad: Final[str] = int() # E: Incompatible types in assignment (expression has type "int", variable has type "str") +reveal_type(w) # N: Revealed type is "builtins.int" reveal_type(x) # N: Revealed type is "builtins.int" reveal_type(y) # N: Revealed type is "builtins.float" reveal_type(z) # N: Revealed type is "builtins.int" diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index 5604cc4b5893..3cf6e8ff17e9 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -12,8 +12,12 @@ reveal_type(g1) # N: Revealed type is "def (x: Literal['A['])" def f2(x: 'A B') -> None: pass # E: Invalid type comment or annotation def g2(x: Literal['A B']) -> None: pass +def h2(x: 'A|int') -> None: pass # E: Name "A" is not defined +def i2(x: Literal['A|B']) -> None: pass reveal_type(f2) # N: Revealed type is "def (x: Any)" reveal_type(g2) # N: Revealed type is "def (x: Literal['A B'])" +reveal_type(h2) # N: Revealed type is "def (x: Union[Any, builtins.int])" +reveal_type(i2) # N: Revealed type is "def (x: Literal['A|B'])" [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-namedtuple.test b/test-data/unit/check-namedtuple.test index 0ce8630e51d9..23e109e1af78 100644 --- a/test-data/unit/check-namedtuple.test +++ b/test-data/unit/check-namedtuple.test @@ -802,14 +802,20 @@ class Fraction(Real): [builtins fixtures/tuple.pyi] [case testForwardReferenceInNamedTuple] -from typing import NamedTuple +from typing import List, NamedTuple class A(NamedTuple): b: 'B' x: int + y: List['B'] class B: pass + +def f(a: A): + reveal_type(a.b) # N: Revealed type is "__main__.B" + reveal_type(a.x) # N: Revealed type is "builtins.int" + reveal_type(a.y) # N: Revealed type is "builtins.list[__main__.B]" [builtins fixtures/tuple.pyi] [case testTypeNamedTupleClassmethod] diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index 8fd9abcb9752..cab7d2bf6819 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -1193,7 +1193,28 @@ def func(callback: Callable[P, str]) -> Callable[P, str]: return inner [builtins fixtures/paramspec.pyi] -[case testParamSpecArgsAndKwargsMissmatch] +[case testParamSpecArgsAndKwargsStringified] +from typing import Callable +from typing_extensions import ParamSpec + +P1 = ParamSpec("P1") + +def func(callback: Callable[P1, str]) -> Callable[P1, str]: + def inner(*args: "P1.args", **kwargs: "P1.kwargs") -> str: + return "foo" + return inner + +@func +def outer(a: int) -> str: + return "" + +outer(1) # OK +outer("x") # E: Argument 1 to "outer" has incompatible type "str"; expected "int" +outer(a=1) # OK +outer(b=1) # E: Unexpected keyword argument "b" for "outer" +[builtins fixtures/paramspec.pyi] + +[case testParamSpecArgsAndKwargsMismatch] from typing import Callable from typing_extensions import ParamSpec diff --git a/test-data/unit/check-typeguard.test b/test-data/unit/check-typeguard.test index 27b88553fb43..e1b7a86aba63 100644 --- a/test-data/unit/check-typeguard.test +++ b/test-data/unit/check-typeguard.test @@ -9,6 +9,17 @@ def main(a: object) -> None: reveal_type(a) # N: Revealed type is "builtins.object" [builtins fixtures/tuple.pyi] +[case testTypeGuardStringified] +from typing_extensions import TypeGuard +class Point: pass +def is_point(a: object) -> "TypeGuard[Point]": pass +def main(a: object) -> None: + if is_point(a): + reveal_type(a) # N: Revealed type is "__main__.Point" + else: + reveal_type(a) # N: Revealed type is "builtins.object" +[builtins fixtures/tuple.pyi] + [case testTypeGuardTypeArgsNone] from typing_extensions import TypeGuard def foo(a: object) -> TypeGuard: # E: TypeGuard must have exactly one type argument diff --git a/test-data/unit/check-typeis.test b/test-data/unit/check-typeis.test index 6b96845504ab..83467d5e3683 100644 --- a/test-data/unit/check-typeis.test +++ b/test-data/unit/check-typeis.test @@ -9,6 +9,17 @@ def main(a: object) -> None: reveal_type(a) # N: Revealed type is "builtins.object" [builtins fixtures/tuple.pyi] +[case testTypeIsStringified] +from typing_extensions import TypeIs +class Point: pass +def is_point(a: object) -> "TypeIs[Point]": pass +def main(a: object) -> None: + if is_point(a): + reveal_type(a) # N: Revealed type is "__main__.Point" + else: + reveal_type(a) # N: Revealed type is "builtins.object" +[builtins fixtures/tuple.pyi] + [case testTypeIsElif] from typing_extensions import TypeIs from typing import Union From f7687d30440564e0582755194872f7fa1b915fdd Mon Sep 17 00:00:00 2001 From: GiorgosPapoutsakis <116210016+GiorgosPapoutsakis@users.noreply.github.com> Date: Mon, 22 Apr 2024 08:58:49 +0300 Subject: [PATCH 154/172] Update CONTRIBUTING.md to include commands for Windows (#17142) Add command about how to activate virtual environment on Windows. --- CONTRIBUTING.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 46292c301406..a5d339330a75 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,17 +30,23 @@ cd mypy #### (3) Create then activate a virtual environment ```bash -# On Windows, the commands may be slightly different. For more details, see -# https://docs.python.org/3/library/venv.html#creating-virtual-environments python3 -m venv venv source venv/bin/activate ``` +```bash +# For Windows use +python -m venv venv +. venv/Scripts/activate + +# For more details, see https://docs.python.org/3/library/venv.html#creating-virtual-environments +``` + #### (4) Install the test requirements and the project ```bash -python3 -m pip install -r test-requirements.txt -python3 -m pip install -e . +python -m pip install -r test-requirements.txt +python -m pip install -e . hash -r # This resets shell PATH cache, not necessary on Windows ``` From 810a019c535ec0366cf9b2359129dec884b06a3e Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Mon, 22 Apr 2024 14:45:56 +0100 Subject: [PATCH 155/172] Update CHANGELOG.md with draft for release 1.10 (#17150) Initial pass at blog post for Release 1.10. Still need to add some information about the major changes. Pulled up 3 commits that seemed like we might want to write something about (under TODO), but they can move them to "Other Notable Changes and Fixes" if that's not the case. --- CHANGELOG.md | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bd537d46e9c..66b7cea86fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,111 @@ # Mypy Release Notes +## Next release + + + +## Mypy 1.10 (Unreleased) + +We’ve just uploaded mypy 1.10 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). + +**TODO** +- Implement TypeIs (PEP 742) (Jelle Zijlstra, PR [16898](https://github.com/python/mypy/pull/16898)) +- Error handling for recursive TypeVar defaults (PEP 696) (Marc Mueller, PR [16925](https://github.com/python/mypy/pull/16925)) +- Add basic support for recursive TypeVar defaults (PEP 696) (Marc Mueller, PR [16878](https://github.com/python/mypy/pull/16878)) + +#### Other Notable Changes and Fixes +- fix: incorrect returned type of access descriptors on unions of types (Matthieu Devlin, PR [16604](https://github.com/python/mypy/pull/16604)) +- Fix crash when expanding invalid Unpack in a `Callable` alias (Ali Hamdan, PR [17028](https://github.com/python/mypy/pull/17028)) +- Fix string formatting for string enums (roberfi, PR [16555](https://github.com/python/mypy/pull/16555)) +- Narrow individual items when matching a tuple to a sequence pattern (Loïc Simon, PR [16905](https://github.com/python/mypy/pull/16905)) +- Add TypeGuard and TypeIs traversing in TypeTraverserVisitor (Evgeniy Slobodkin, PR [17071](https://github.com/python/mypy/pull/17071)) +- Improve error message for bound typevar in TypeAliasType (Ali Hamdan, PR [17053](https://github.com/python/mypy/pull/17053)) +- Fix TypedDict init from Type with optional keys (Marc Mueller, PR [17068](https://github.com/python/mypy/pull/17068)) +- Improve yield from inference for unions of generators (Shantanu, PR [16717](https://github.com/python/mypy/pull/16717)) +- Support `TypeAliasType` in a class scope (Ali Hamdan, PR [17038](https://github.com/python/mypy/pull/17038)) +- attrs: Fix emulating hash method logic (Hashem, PR [17016](https://github.com/python/mypy/pull/17016)) +- Use lower-case generics more consistently in error messages (Jukka Lehtosalo, PR [17035](https://github.com/python/mypy/pull/17035)) +- Revert "Revert use of `ParamSpec` for `functools.wraps`" (Tamir Duberstein, PR [16942](https://github.com/python/mypy/pull/16942)) +- Support `TypeAliasType` (Ali Hamdan, PR [16926](https://github.com/python/mypy/pull/16926)) +- Fix type narrowing for types.EllipsisType (Shantanu, PR [17003](https://github.com/python/mypy/pull/17003)) +- Disallow all super calls to methods with trivial bodies (Shantanu, PR [16756](https://github.com/python/mypy/pull/16756)) +- Fix single item enum match type exhaustion (Oskari Lehto, PR [16966](https://github.com/python/mypy/pull/16966)) +- Fix inference with UninhabitedType (Marc Mueller, PR [16994](https://github.com/python/mypy/pull/16994)) +- Allow TypedDict initialization from Type (Marc Mueller, PR [16963](https://github.com/python/mypy/pull/16963)) +- Fix override checking for decorated property (Shantanu, PR [16856](https://github.com/python/mypy/pull/16856)) +- Fix duplicate word in protocols.rst (hesam, PR [16950](https://github.com/python/mypy/pull/16950)) +- Workaround parenthesised context manager issue (Shantanu, PR [16949](https://github.com/python/mypy/pull/16949)) +- Fix narrowing on match with function subject (Edward Paget, PR [16503](https://github.com/python/mypy/pull/16503)) +- Allow inferring +int to be a Literal (Spencer Brown, PR [16910](https://github.com/python/mypy/pull/16910)) + +#### Stubgen Improvements +- stubgen: Preserve empty tuple annotation (Ali Hamdan, PR [16907](https://github.com/python/mypy/pull/16907)) +- stubgen: Add support for PEP 570 positional-only parameters (Ali Hamdan, PR [16904](https://github.com/python/mypy/pull/16904)) +- stubgen: Replace obsolete typing aliases with builtin containers (Ali Hamdan, PR [16780](https://github.com/python/mypy/pull/16780)) +- stubgen: Fix generated dataclass `__init__` signature (Ali Hamdan, PR [16906](https://github.com/python/mypy/pull/16906)) + +#### Stubtest Improvements +- stubtest: correct type annotations in _Arguments (Sam Xifaras, PR [16897](https://github.com/python/mypy/pull/16897)) + +#### Mypyc Improvements +- [mypyc] Refactor: add two list primitive ops (Jukka Lehtosalo, PR [17058](https://github.com/python/mypy/pull/17058)) +- [mypyc] Refactor: use primitive op for initializing list item (Jukka Lehtosalo, PR [17056](https://github.com/python/mypy/pull/17056)) +- [mypyc] Refactor: move tagged int related code to mypyc.lower.int_ops (Jukka Lehtosalo, PR [17052](https://github.com/python/mypy/pull/17052)) +- [mypyc] Implement lowering for remaining tagged integer comparisons (Jukka Lehtosalo, PR [17040](https://github.com/python/mypy/pull/17040)) +- [mypyc] Implement lowering pass and add primitives for int (in)equality (Jukka Lehtosalo, PR [17027](https://github.com/python/mypy/pull/17027)) +- [mypyc] Optimize away some bool/bit registers (Jukka Lehtosalo, PR [17022](https://github.com/python/mypy/pull/17022)) +- [mypyc] Provide an easier way to define IR-to-IR transforms (Jukka Lehtosalo, PR [16998](https://github.com/python/mypy/pull/16998)) +- [mypyc] Remangle redefined names produced by async with (Richard Si, PR [16408](https://github.com/python/mypy/pull/16408)) +- [mypyc] Optimize TYPE_CHECKING to False at Runtime (Srinivas Lade, PR [16263](https://github.com/python/mypy/pull/16263)) +- [mypyc] Fix compilation of unreachable comprehensions (Richard Si, PR [15721](https://github.com/python/mypy/pull/15721)) +- [mypyc] Don't crash on non-inlinable final local reads (Richard Si, PR [15719](https://github.com/python/mypy/pull/15719)) + +#### Documentation Improvements +- Update running_mypy.rst add closing bracket (Roman Solomatin, PR [17046](https://github.com/python/mypy/pull/17046)) +- Docs: docstrings in checker.py, ast_helpers.py (Ihor, PR [16908](https://github.com/python/mypy/pull/16908)) +- docs: Add missing ClassVar import (youkaichao, PR [16962](https://github.com/python/mypy/pull/16962)) +- Docs: Update `TypedDict` import statements (Riccardo Di Maio, PR [16958](https://github.com/python/mypy/pull/16958)) +- Docs: adding missing `mutable-override` to section title (James Braza, PR [16886](https://github.com/python/mypy/pull/16886)) + +#### Acknowledgements +Thanks to all mypy contributors who contributed to this release: + +- Alex Waygood +- Ali Hamdan +- Edward Paget +- Evgeniy Slobodkin +- Hashem +- hesam +- Hugo van Kemenade +- Ihor +- James Braza +- Jelle Zijlstra +- jhance +- Jukka Lehtosalo +- Loïc Simon +- Marc Mueller +- Matthieu Devlin +- Michael R. Crusoe +- Nikita Sobolev +- Oskari Lehto +- Riccardo Di Maio +- Richard Si +- roberfi +- Roman Solomatin +- Sam Xifaras +- Shantanu +- Spencer Brown +- Srinivas Lade +- Tamir Duberstein +- youkaichao + +I’d also like to thank my employer, Dropbox, for supporting mypy development. + + ## Mypy 1.9 We’ve just uploaded mypy 1.9 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: From c1460f85e8db919a2f7c32c979d3b25aedc38a78 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Tue, 23 Apr 2024 17:32:11 +0100 Subject: [PATCH 156/172] Various updates to changelog for 1.10 (#17158) --- CHANGELOG.md | 159 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 108 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66b7cea86fb5..243d46946326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,64 +12,121 @@ We’ve just uploaded mypy 1.10 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). -**TODO** -- Implement TypeIs (PEP 742) (Jelle Zijlstra, PR [16898](https://github.com/python/mypy/pull/16898)) -- Error handling for recursive TypeVar defaults (PEP 696) (Marc Mueller, PR [16925](https://github.com/python/mypy/pull/16925)) -- Add basic support for recursive TypeVar defaults (PEP 696) (Marc Mueller, PR [16878](https://github.com/python/mypy/pull/16878)) +#### Support TypeIs (PEP 742) -#### Other Notable Changes and Fixes -- fix: incorrect returned type of access descriptors on unions of types (Matthieu Devlin, PR [16604](https://github.com/python/mypy/pull/16604)) -- Fix crash when expanding invalid Unpack in a `Callable` alias (Ali Hamdan, PR [17028](https://github.com/python/mypy/pull/17028)) -- Fix string formatting for string enums (roberfi, PR [16555](https://github.com/python/mypy/pull/16555)) -- Narrow individual items when matching a tuple to a sequence pattern (Loïc Simon, PR [16905](https://github.com/python/mypy/pull/16905)) -- Add TypeGuard and TypeIs traversing in TypeTraverserVisitor (Evgeniy Slobodkin, PR [17071](https://github.com/python/mypy/pull/17071)) -- Improve error message for bound typevar in TypeAliasType (Ali Hamdan, PR [17053](https://github.com/python/mypy/pull/17053)) -- Fix TypedDict init from Type with optional keys (Marc Mueller, PR [17068](https://github.com/python/mypy/pull/17068)) -- Improve yield from inference for unions of generators (Shantanu, PR [16717](https://github.com/python/mypy/pull/16717)) -- Support `TypeAliasType` in a class scope (Ali Hamdan, PR [17038](https://github.com/python/mypy/pull/17038)) -- attrs: Fix emulating hash method logic (Hashem, PR [17016](https://github.com/python/mypy/pull/17016)) -- Use lower-case generics more consistently in error messages (Jukka Lehtosalo, PR [17035](https://github.com/python/mypy/pull/17035)) -- Revert "Revert use of `ParamSpec` for `functools.wraps`" (Tamir Duberstein, PR [16942](https://github.com/python/mypy/pull/16942)) -- Support `TypeAliasType` (Ali Hamdan, PR [16926](https://github.com/python/mypy/pull/16926)) -- Fix type narrowing for types.EllipsisType (Shantanu, PR [17003](https://github.com/python/mypy/pull/17003)) -- Disallow all super calls to methods with trivial bodies (Shantanu, PR [16756](https://github.com/python/mypy/pull/16756)) -- Fix single item enum match type exhaustion (Oskari Lehto, PR [16966](https://github.com/python/mypy/pull/16966)) -- Fix inference with UninhabitedType (Marc Mueller, PR [16994](https://github.com/python/mypy/pull/16994)) -- Allow TypedDict initialization from Type (Marc Mueller, PR [16963](https://github.com/python/mypy/pull/16963)) -- Fix override checking for decorated property (Shantanu, PR [16856](https://github.com/python/mypy/pull/16856)) -- Fix duplicate word in protocols.rst (hesam, PR [16950](https://github.com/python/mypy/pull/16950)) -- Workaround parenthesised context manager issue (Shantanu, PR [16949](https://github.com/python/mypy/pull/16949)) -- Fix narrowing on match with function subject (Edward Paget, PR [16503](https://github.com/python/mypy/pull/16503)) -- Allow inferring +int to be a Literal (Spencer Brown, PR [16910](https://github.com/python/mypy/pull/16910)) +Mypy now supports `TypeIs` ([PEP 742](https://peps.python.org/pep-0742/)), which allows +functions to narrow the type of a value, similar to `isinstance()`. Unlike `TypeGuard`, +`TypeIs` can narrow in both the `if` and `else` branches of an if statement: -#### Stubgen Improvements -- stubgen: Preserve empty tuple annotation (Ali Hamdan, PR [16907](https://github.com/python/mypy/pull/16907)) -- stubgen: Add support for PEP 570 positional-only parameters (Ali Hamdan, PR [16904](https://github.com/python/mypy/pull/16904)) -- stubgen: Replace obsolete typing aliases with builtin containers (Ali Hamdan, PR [16780](https://github.com/python/mypy/pull/16780)) -- stubgen: Fix generated dataclass `__init__` signature (Ali Hamdan, PR [16906](https://github.com/python/mypy/pull/16906)) +```python +from typing_extensions import TypeIs -#### Stubtest Improvements -- stubtest: correct type annotations in _Arguments (Sam Xifaras, PR [16897](https://github.com/python/mypy/pull/16897)) +def is_str(s: object) -> TypeIs[str]: + return isinstance(s, str) + +def f(o: str | int) -> None: + if is_str(o): + # Type of o is 'str' + ... + else: + # Type of o is 'int' + ... +``` + +`TypeIs` will be added to the `typing` module in Python 3.13, but it +can be used on earlier Python versions by importing it from +`typing_extensions`. + +This feature was contributed by Jelle Zijlstra (PR [16898](https://github.com/python/mypy/pull/16898)). + +#### Support TypeVar Defaults (PEP 696) + +[PEP 696](https://peps.python.org/pep-0696/) adds support for type parameter defaults. +Example: + +```python +from typing import Generic +from typing_extensions import TypeVar + +T = TypeVar("T", default=int) + +class C(Generic[T]): + ... + +x: C = ... +y: C[str] = ... +reveal_type(x) # C[int], because of the default +reveal_type(y) # C[str] +``` + +TypeVar defaults will be added to the `typing` module in Python 3.13, but they +can be used with earlier Python releases by importing `TypeVar` from +`typing_extensions`. + +This feature was contributed by Marc Mueller (PR [16878](https://github.com/python/mypy/pull/16878) +and PR [16925](https://github.com/python/mypy/pull/16925)). + +#### Detect Additional Unsafe Uses of super() + +Mypy will reject unsafe uses of `super()` more consistently, when the target has a +trivial (empty) body. Example: + +```python +class Proto(Protocol): + def method(self) -> int: ... + +class Sub(Proto): + def method(self) -> int: + return super().meth() # Error (unsafe) +``` + +This feature was contributed by Shantanu (PR [16756](https://github.com/python/mypy/pull/16756)). + +#### Stubgen Improvements +- Preserve empty tuple annotation (Ali Hamdan, PR [16907](https://github.com/python/mypy/pull/16907)) +- Add support for PEP 570 positional-only parameters (Ali Hamdan, PR [16904](https://github.com/python/mypy/pull/16904)) +- Replace obsolete typing aliases with builtin containers (Ali Hamdan, PR [16780](https://github.com/python/mypy/pull/16780)) +- Fix generated dataclass `__init__` signature (Ali Hamdan, PR [16906](https://github.com/python/mypy/pull/16906)) #### Mypyc Improvements -- [mypyc] Refactor: add two list primitive ops (Jukka Lehtosalo, PR [17058](https://github.com/python/mypy/pull/17058)) -- [mypyc] Refactor: use primitive op for initializing list item (Jukka Lehtosalo, PR [17056](https://github.com/python/mypy/pull/17056)) -- [mypyc] Refactor: move tagged int related code to mypyc.lower.int_ops (Jukka Lehtosalo, PR [17052](https://github.com/python/mypy/pull/17052)) -- [mypyc] Implement lowering for remaining tagged integer comparisons (Jukka Lehtosalo, PR [17040](https://github.com/python/mypy/pull/17040)) -- [mypyc] Implement lowering pass and add primitives for int (in)equality (Jukka Lehtosalo, PR [17027](https://github.com/python/mypy/pull/17027)) -- [mypyc] Optimize away some bool/bit registers (Jukka Lehtosalo, PR [17022](https://github.com/python/mypy/pull/17022)) -- [mypyc] Provide an easier way to define IR-to-IR transforms (Jukka Lehtosalo, PR [16998](https://github.com/python/mypy/pull/16998)) -- [mypyc] Remangle redefined names produced by async with (Richard Si, PR [16408](https://github.com/python/mypy/pull/16408)) -- [mypyc] Optimize TYPE_CHECKING to False at Runtime (Srinivas Lade, PR [16263](https://github.com/python/mypy/pull/16263)) -- [mypyc] Fix compilation of unreachable comprehensions (Richard Si, PR [15721](https://github.com/python/mypy/pull/15721)) -- [mypyc] Don't crash on non-inlinable final local reads (Richard Si, PR [15719](https://github.com/python/mypy/pull/15719)) + +- Provide an easier way to define IR-to-IR transforms (Jukka Lehtosalo, PR [16998](https://github.com/python/mypy/pull/16998)) +- Implement lowering pass and add primitives for int (in)equality (Jukka Lehtosalo, PR [17027](https://github.com/python/mypy/pull/17027)) +- Implement lowering for remaining tagged integer comparisons (Jukka Lehtosalo, PR [17040](https://github.com/python/mypy/pull/17040)) +- Optimize away some bool/bit registers (Jukka Lehtosalo, PR [17022](https://github.com/python/mypy/pull/17022)) +- Remangle redefined names produced by async with (Richard Si, PR [16408](https://github.com/python/mypy/pull/16408)) +- Optimize TYPE_CHECKING to False at Runtime (Srinivas Lade, PR [16263](https://github.com/python/mypy/pull/16263)) +- Fix compilation of unreachable comprehensions (Richard Si, PR [15721](https://github.com/python/mypy/pull/15721)) +- Don't crash on non-inlinable final local reads (Richard Si, PR [15719](https://github.com/python/mypy/pull/15719)) +- Support `TypeAliasType` (Ali Hamdan, PR [16926](https://github.com/python/mypy/pull/16926)) #### Documentation Improvements -- Update running_mypy.rst add closing bracket (Roman Solomatin, PR [17046](https://github.com/python/mypy/pull/17046)) -- Docs: docstrings in checker.py, ast_helpers.py (Ihor, PR [16908](https://github.com/python/mypy/pull/16908)) -- docs: Add missing ClassVar import (youkaichao, PR [16962](https://github.com/python/mypy/pull/16962)) -- Docs: Update `TypedDict` import statements (Riccardo Di Maio, PR [16958](https://github.com/python/mypy/pull/16958)) -- Docs: adding missing `mutable-override` to section title (James Braza, PR [16886](https://github.com/python/mypy/pull/16886)) +- Import `TypedDict` from `typing` instead of `typing_extensions` (Riccardo Di Maio, PR [16958](https://github.com/python/mypy/pull/16958)) +- Add missing `mutable-override` to section title (James Braza, PR [16886](https://github.com/python/mypy/pull/16886)) + +#### Error Reporting Improvements + +- Improve error message for bound TypeVar in TypeAliasType (Ali Hamdan, PR [17053](https://github.com/python/mypy/pull/17053)) +- Use lower-case generics more consistently in error messages (Jukka Lehtosalo, PR [17035](https://github.com/python/mypy/pull/17035)) + +#### Other Notable Changes and Fixes +- Fix incorrect inferred type when accessing descriptor on union type (Matthieu Devlin, PR [16604](https://github.com/python/mypy/pull/16604)) +- Fix crash when expanding invalid `Unpack` in a `Callable` alias (Ali Hamdan, PR [17028](https://github.com/python/mypy/pull/17028)) +- Fix false positive when string formatting with string enum (roberfi, PR [16555](https://github.com/python/mypy/pull/16555)) +- Narrow individual items when matching a tuple to a sequence pattern (Loïc Simon, PR [16905](https://github.com/python/mypy/pull/16905)) +- Fix false positive from type variable within TypeGuard or TypeIs (Evgeniy Slobodkin, PR [17071](https://github.com/python/mypy/pull/17071)) +- Improve `yield from` inference for unions of generators (Shantanu, PR [16717](https://github.com/python/mypy/pull/16717)) +- Support `TypeAliasType` in a class scope (Ali Hamdan, PR [17038](https://github.com/python/mypy/pull/17038)) +- Fix emulating hash method logic in `attrs` classes (Hashem, PR [17016](https://github.com/python/mypy/pull/17016)) +- Add reverted typeshed commit that uses `ParamSpec` for `functools.wraps` (Tamir Duberstein, PR [16942](https://github.com/python/mypy/pull/16942)) +- Fix type narrowing for `types.EllipsisType` (Shantanu, PR [17003](https://github.com/python/mypy/pull/17003)) +- Fix single item enum match type exhaustion (Oskari Lehto, PR [16966](https://github.com/python/mypy/pull/16966)) +- Improve type inference with empty collections (Marc Mueller, PR [16994](https://github.com/python/mypy/pull/16994)) +- Fix override checking for decorated property (Shantanu, PR [16856](https://github.com/python/mypy/pull/16856)) +- Fix narrowing on match with function subject (Edward Paget, PR [16503](https://github.com/python/mypy/pull/16503)) +- Allow `+N` within `Literal[...]` (Spencer Brown, PR [16910](https://github.com/python/mypy/pull/16910)) +- Experimental: Support TypedDict within `type[...]` (Marc Mueller, PR [16963](https://github.com/python/mypy/pull/16963)) +- Experimtental: Fix issue with TypedDict with optional keys in `type[...]` (Marc Mueller, PR [17068](https://github.com/python/mypy/pull/17068)) #### Acknowledgements Thanks to all mypy contributors who contributed to this release: From 400eece0731772b8c584bc335f13b08eee4e3b61 Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:58:18 +0100 Subject: [PATCH 157/172] Update CHANGELOG.md (#17159) - add typeshed updates note - remove unreleased --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 243d46946326..a90997f6cc3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ -## Mypy 1.10 (Unreleased) +## Mypy 1.10 We’ve just uploaded mypy 1.10 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: @@ -128,6 +128,11 @@ This feature was contributed by Shantanu (PR [16756](https://github.com/python/m - Experimental: Support TypedDict within `type[...]` (Marc Mueller, PR [16963](https://github.com/python/mypy/pull/16963)) - Experimtental: Fix issue with TypedDict with optional keys in `type[...]` (Marc Mueller, PR [17068](https://github.com/python/mypy/pull/17068)) +#### Typeshed Updates + +Please see [git log](https://github.com/python/typeshed/commits/main?after=7c8e82fe483a40ec4cb0a2505cfdb0f3e7cc81d9+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: From 43e130b1bb2f912e7b51354570da041772d33767 Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Wed, 24 Apr 2024 14:26:48 +0100 Subject: [PATCH 158/172] Update CHANGELOG.md to point out PEP 695 initial support (#17164) --- CHANGELOG.md | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a90997f6cc3a..d0ea19866892 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,42 @@ can be used with earlier Python releases by importing `TypeVar` from This feature was contributed by Marc Mueller (PR [16878](https://github.com/python/mypy/pull/16878) and PR [16925](https://github.com/python/mypy/pull/16925)). +#### Support TypeAliasType (PEP 695) +As part of the initial steps towards implementing [PEP 695](https://peps.python.org/pep-0695/), mypy now supports `TypeAliasType`. +`TypeAliasType` provides a backport of the new `type` statement in Python 3.12. + +```python +type ListOrSet[T] = list[T] | set[T] +``` + +is equivalent to: + +```python +T = TypeVar("T") +ListOrSet = TypeAliasType("ListOrSet", list[T] | set[T], type_params=(T,)) +``` + +Example of use in mypy: + +```python +from typing_extensions import TypeAliasType, TypeVar + +NewUnionType = TypeAliasType("NewUnionType", int | str) +x: NewUnionType = 42 +y: NewUnionType = 'a' +z: NewUnionType = object() # error: Incompatible types in assignment (expression has type "object", variable has type "int | str") [assignment] + +T = TypeVar("T") +ListOrSet = TypeAliasType("ListOrSet", list[T] | set[T], type_params=(T,)) +a: ListOrSet[int] = [1, 2] +b: ListOrSet[str] = {'a', 'b'} +c: ListOrSet[str] = 'test' # error: Incompatible types in assignment (expression has type "str", variable has type "list[str] | set[str]") [assignment] +``` + +`TypeAliasType` was added to the `typing` module in Python 3.12, but it can be used with earlier Python releases by importing from `typing_extensions`. + +This feature was contributed by Ali Hamdan (PR [16926](https://github.com/python/mypy/pull/16926), PR [17038](https://github.com/python/mypy/pull/17038) and PR [17053](https://github.com/python/mypy/pull/17053)) + #### Detect Additional Unsafe Uses of super() Mypy will reject unsafe uses of `super()` more consistently, when the target has a @@ -98,7 +134,6 @@ This feature was contributed by Shantanu (PR [16756](https://github.com/python/m - Optimize TYPE_CHECKING to False at Runtime (Srinivas Lade, PR [16263](https://github.com/python/mypy/pull/16263)) - Fix compilation of unreachable comprehensions (Richard Si, PR [15721](https://github.com/python/mypy/pull/15721)) - Don't crash on non-inlinable final local reads (Richard Si, PR [15719](https://github.com/python/mypy/pull/15719)) -- Support `TypeAliasType` (Ali Hamdan, PR [16926](https://github.com/python/mypy/pull/16926)) #### Documentation Improvements - Import `TypedDict` from `typing` instead of `typing_extensions` (Riccardo Di Maio, PR [16958](https://github.com/python/mypy/pull/16958)) @@ -106,7 +141,6 @@ This feature was contributed by Shantanu (PR [16756](https://github.com/python/m #### Error Reporting Improvements -- Improve error message for bound TypeVar in TypeAliasType (Ali Hamdan, PR [17053](https://github.com/python/mypy/pull/17053)) - Use lower-case generics more consistently in error messages (Jukka Lehtosalo, PR [17035](https://github.com/python/mypy/pull/17035)) #### Other Notable Changes and Fixes @@ -116,7 +150,6 @@ This feature was contributed by Shantanu (PR [16756](https://github.com/python/m - Narrow individual items when matching a tuple to a sequence pattern (Loïc Simon, PR [16905](https://github.com/python/mypy/pull/16905)) - Fix false positive from type variable within TypeGuard or TypeIs (Evgeniy Slobodkin, PR [17071](https://github.com/python/mypy/pull/17071)) - Improve `yield from` inference for unions of generators (Shantanu, PR [16717](https://github.com/python/mypy/pull/16717)) -- Support `TypeAliasType` in a class scope (Ali Hamdan, PR [17038](https://github.com/python/mypy/pull/17038)) - Fix emulating hash method logic in `attrs` classes (Hashem, PR [17016](https://github.com/python/mypy/pull/17016)) - Add reverted typeshed commit that uses `ParamSpec` for `functools.wraps` (Tamir Duberstein, PR [16942](https://github.com/python/mypy/pull/16942)) - Fix type narrowing for `types.EllipsisType` (Shantanu, PR [17003](https://github.com/python/mypy/pull/17003)) From 82ebd866830cd79e25bf9d59e9f9474bd280c4f5 Mon Sep 17 00:00:00 2001 From: "Michael R. Crusoe" <1330696+mr-c@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:17:59 +0200 Subject: [PATCH 159/172] docs: remove six from the intersphinx mappings (#17165) 002f77cedc9a5c772ebcfb0c5d245a98044c8b21 removed the last reference to six, so there is no need to pull down the six docs inventory --- docs/source/conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 683b2a6785b3..fa76734054ac 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -266,7 +266,6 @@ intersphinx_mapping = { "python": ("https://docs.python.org/3", None), - "six": ("https://six.readthedocs.io", None), "attrs": ("https://www.attrs.org/en/stable/", None), "cython": ("https://docs.cython.org/en/latest", None), "monkeytype": ("https://monkeytype.readthedocs.io/en/latest", None), From 6ebce43143c898db3de83f31b2b9e5f34e3000fa Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 26 Apr 2024 23:02:17 +0900 Subject: [PATCH 160/172] docs: Use lower-case generics (#17176) Use lower-case `list`, `tuple`, `type` instead of `List`, `Tuple`, `Type` in documentation. --- docs/source/common_issues.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index 4a1d1b437153..cfe82e19e77b 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -41,7 +41,7 @@ once you add annotations: def foo(a: str) -> str: return '(' + a.split() + ')' - # error: Unsupported operand types for + ("str" and List[str]) + # error: Unsupported operand types for + ("str" and "list[str]") If you don't know what types to add, you can use ``Any``, but beware: @@ -226,7 +226,7 @@ dict to a new variable, as mentioned earlier: .. code-block:: python - a: List[int] = [] + a: list[int] = [] Without the annotation mypy can't always figure out the precise type of ``a``. @@ -238,7 +238,7 @@ modification operation in the same scope (such as ``append`` for a list): .. code-block:: python - a = [] # Okay because followed by append, inferred type List[int] + a = [] # Okay because followed by append, inferred type list[int] for i in range(n): a.append(i * i) @@ -276,7 +276,7 @@ not support ``sort()``) as a list and sort it in-place: def f(x: Sequence[int]) -> None: # Type of x is Sequence[int] here; we don't know the concrete type. x = list(x) - # Type of x is List[int] here. + # Type of x is list[int] here. x.sort() # Okay! See :ref:`type-narrowing` for more information. @@ -296,8 +296,8 @@ unexpected errors when combined with type inference. For example: class A: ... class B(A): ... - lst = [A(), A()] # Inferred type is List[A] - new_lst = [B(), B()] # inferred type is List[B] + lst = [A(), A()] # Inferred type is list[A] + new_lst = [B(), B()] # inferred type is list[B] lst = new_lst # mypy will complain about this, because List is invariant Possible strategies in such situations are: @@ -306,7 +306,7 @@ Possible strategies in such situations are: .. code-block:: python - new_lst: List[A] = [B(), B()] + new_lst: list[A] = [B(), B()] lst = new_lst # OK * Make a copy of the right hand side: @@ -319,7 +319,7 @@ Possible strategies in such situations are: .. code-block:: python - def f_bad(x: List[A]) -> A: + def f_bad(x: list[A]) -> A: return x[0] f_bad(new_lst) # Fails @@ -489,7 +489,7 @@ understand how mypy handles a particular piece of code. Example: .. code-block:: python - reveal_type((1, 'hello')) # Revealed type is "Tuple[builtins.int, builtins.str]" + reveal_type((1, 'hello')) # Revealed type is "tuple[builtins.int, builtins.str]" You can also use ``reveal_locals()`` at any line in a file to see the types of all local variables at once. Example: @@ -622,16 +622,16 @@ instructions at the `mypyc wheels repo 0.5: tp = A else: From a1900c2c94aebc0a23a1238fde078d5c4020c954 Mon Sep 17 00:00:00 2001 From: dexterkennedy <104945997+dexterkennedy@users.noreply.github.com> Date: Sat, 27 Apr 2024 05:35:55 -0400 Subject: [PATCH 161/172] Log full path to config file in verbose output (#17180) Contributes to #6544 --- mypy/build.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mypy/build.py b/mypy/build.py index 65a06211c87e..84c85e66bd49 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -2850,10 +2850,14 @@ def skipping_ancestor(manager: BuildManager, id: str, path: str, ancestor_for: S def log_configuration(manager: BuildManager, sources: list[BuildSource]) -> None: """Output useful configuration information to LOG and TRACE""" + config_file = manager.options.config_file + if config_file: + config_file = os.path.abspath(config_file) + manager.log() configuration_vars = [ ("Mypy Version", __version__), - ("Config File", (manager.options.config_file or "Default")), + ("Config File", (config_file or "Default")), ("Configured Executable", manager.options.python_executable or "None"), ("Current Executable", sys.executable), ("Cache Dir", manager.options.cache_dir), From 8bc79660734aa06572f51ba71da97f1b38f9efbf Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 28 Apr 2024 00:06:15 +0300 Subject: [PATCH 162/172] Pin MacOS version in GH actions (#17183) Fix failing MacOS tests in CI Python 3.9 is not available on the latest MacOS images https://github.com/actions/setup-python/issues/850 --------- Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com> --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4e44c671287..4593e79e728c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -74,7 +74,8 @@ jobs: - name: mypyc runtime tests with py39-macos python: '3.9.18' arch: x64 - os: macos-latest + # TODO: macos-13 is the last one to support Python 3.9, change it to macos-latest when updating the Python version + os: macos-13 toxenv: py tox_extra_args: "-n 2 mypyc/test/test_run.py mypyc/test/test_external.py" - name: mypyc runtime tests with py38-debug-build-ubuntu From ba6febc903776491ea445cef2ef5375b95e178cd Mon Sep 17 00:00:00 2001 From: Ali Hamdan Date: Sun, 28 Apr 2024 00:46:32 +0300 Subject: [PATCH 163/172] Enum private attributes are not enum members (#17182) Fixes #17098 --- mypy/checkmember.py | 4 ++-- mypy/semanal.py | 7 ++++++- mypy/typeanal.py | 7 ++++++- mypy/typeops.py | 3 +++ test-data/unit/check-enum.test | 33 +++++++++++++++++++++++++++++++ test-data/unit/check-literal.test | 4 +++- 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 64d6733f5309..5824b00a37f6 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -1139,8 +1139,8 @@ def analyze_enum_class_attribute_access( # Skip these since Enum will remove it if name in ENUM_REMOVED_PROPS: return report_missing_attribute(mx.original_type, itype, name, mx) - # For other names surrendered by underscores, we don't make them Enum members - if name.startswith("__") and name.endswith("__") and name.replace("_", "") != "": + # Dunders and private names are not Enum members + if name.startswith("__") and name.replace("_", "") != "": return None enum_literal = LiteralType(name, fallback=itype) diff --git a/mypy/semanal.py b/mypy/semanal.py index 1fc58a6c11f1..91a6b1808987 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -3979,7 +3979,12 @@ def analyze_name_lvalue( existing = names.get(name) outer = self.is_global_or_nonlocal(name) - if kind == MDEF and isinstance(self.type, TypeInfo) and self.type.is_enum: + if ( + kind == MDEF + and isinstance(self.type, TypeInfo) + and self.type.is_enum + and not name.startswith("__") + ): # Special case: we need to be sure that `Enum` keys are unique. if existing is not None and not isinstance(existing.node, PlaceholderNode): self.fail( diff --git a/mypy/typeanal.py b/mypy/typeanal.py index c2c578045297..5cde7da721ec 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -868,7 +868,12 @@ def analyze_unbound_type_without_type_info( # If, in the distant future, we decide to permit things like # `def foo(x: Color.RED) -> None: ...`, we can remove that # check entirely. - if isinstance(sym.node, Var) and sym.node.info and sym.node.info.is_enum: + if ( + isinstance(sym.node, Var) + and sym.node.info + and sym.node.info.is_enum + and not sym.node.name.startswith("__") + ): value = sym.node.name base_enum_short_name = sym.node.info.name if not defining_literal: diff --git a/mypy/typeops.py b/mypy/typeops.py index 5b396308d955..a59bd3739562 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -885,6 +885,9 @@ class Status(Enum): # Skip these since Enum will remove it if name in ENUM_REMOVED_PROPS: continue + # Skip private attributes + if name.startswith("__"): + continue new_items.append(LiteralType(name, typ)) return make_simplified_union(new_items, contract_literals=False) elif typ.type.fullname == "builtins.bool": diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index b4e8795859c3..e8e65f464eaf 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -1425,6 +1425,10 @@ from enum import Enum class Correct(Enum): x = 'y' y = 'x' +class Correct2(Enum): + x = 'y' + __z = 'y' + __z = 'x' class Foo(Enum): A = 1 A = 'a' # E: Attempted to reuse member name "A" in Enum definition "Foo" \ @@ -2105,3 +2109,32 @@ class AllPartialList(Enum): def check(self) -> None: reveal_type(self.value) # N: Revealed type is "builtins.list[Any]" + +[case testEnumPrivateAttributeNotMember] +from enum import Enum + +class MyEnum(Enum): + A = 1 + B = 2 + __my_dict = {A: "ham", B: "spam"} + +# TODO: change the next line to use MyEnum._MyEnum__my_dict when mypy implements name mangling +x: MyEnum = MyEnum.__my_dict # E: Incompatible types in assignment (expression has type "Dict[int, str]", variable has type "MyEnum") + +[case testEnumWithPrivateAttributeReachability] +# flags: --warn-unreachable +from enum import Enum + +class MyEnum(Enum): + A = 1 + B = 2 + __my_dict = {A: "ham", B: "spam"} + +e: MyEnum +if e == MyEnum.A: + reveal_type(e) # N: Revealed type is "Literal[__main__.MyEnum.A]" +elif e == MyEnum.B: + reveal_type(e) # N: Revealed type is "Literal[__main__.MyEnum.B]" +else: + reveal_type(e) # E: Statement is unreachable +[builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index 3cf6e8ff17e9..423ba74eba72 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -2503,7 +2503,7 @@ class Color(Enum): RED = 1 GREEN = 2 BLUE = 3 - + __ROUGE = RED def func(self) -> int: pass r: Literal[Color.RED] @@ -2512,6 +2512,8 @@ b: Literal[Color.BLUE] bad1: Literal[Color] # E: Parameter 1 of Literal[...] is invalid bad2: Literal[Color.func] # E: Parameter 1 of Literal[...] is invalid bad3: Literal[Color.func()] # E: Invalid type: Literal[...] cannot contain arbitrary expressions +# TODO: change the next line to use Color._Color__ROUGE when mypy implements name mangling +bad4: Literal[Color.__ROUGE] # E: Parameter 1 of Literal[...] is invalid def expects_color(x: Color) -> None: pass def expects_red(x: Literal[Color.RED]) -> None: pass From cd895ce3d356acba5c88c67c853d3671768f0c8d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Apr 2024 18:13:42 -0700 Subject: [PATCH 164/172] Sync typeshed (#17201) Source commit: https://github.com/python/typeshed/commit/f244be921e4a3dfb8f7d84ae404e1515815df2ce --- mypy/typeshed/stdlib/_typeshed/__init__.pyi | 22 ++- mypy/typeshed/stdlib/asyncio/constants.pyi | 6 +- mypy/typeshed/stdlib/asyncio/coroutines.pyi | 4 +- mypy/typeshed/stdlib/asyncio/futures.pyi | 4 +- mypy/typeshed/stdlib/asyncio/locks.pyi | 8 +- mypy/typeshed/stdlib/asyncio/sslproto.pyi | 18 +- mypy/typeshed/stdlib/audioop.pyi | 54 +++--- mypy/typeshed/stdlib/builtins.pyi | 21 ++- mypy/typeshed/stdlib/cgi.pyi | 4 +- mypy/typeshed/stdlib/collections/__init__.pyi | 31 +++- mypy/typeshed/stdlib/contextlib.pyi | 49 +++--- mypy/typeshed/stdlib/email/message.pyi | 53 +++--- mypy/typeshed/stdlib/email/parser.pyi | 40 +++-- mypy/typeshed/stdlib/http/__init__.pyi | 136 +++++++-------- mypy/typeshed/stdlib/http/client.pyi | 28 +-- mypy/typeshed/stdlib/inspect.pyi | 86 +++++----- mypy/typeshed/stdlib/logging/__init__.pyi | 2 +- .../stdlib/multiprocessing/context.pyi | 13 +- .../stdlib/multiprocessing/synchronize.pyi | 4 +- mypy/typeshed/stdlib/os/__init__.pyi | 4 +- mypy/typeshed/stdlib/plistlib.pyi | 4 +- mypy/typeshed/stdlib/pstats.pyi | 18 +- mypy/typeshed/stdlib/py_compile.pyi | 6 +- mypy/typeshed/stdlib/signal.pyi | 92 +++++----- mypy/typeshed/stdlib/socket.pyi | 150 ++++++++-------- mypy/typeshed/stdlib/ssl.pyi | 162 +++++++++--------- mypy/typeshed/stdlib/tkinter/__init__.pyi | 76 ++++---- mypy/typeshed/stdlib/typing.pyi | 36 ++-- mypy/typeshed/stdlib/unittest/mock.pyi | 4 +- mypy/typeshed/stdlib/uuid.pyi | 6 +- mypy/typeshed/stdlib/weakref.pyi | 11 +- 31 files changed, 608 insertions(+), 544 deletions(-) diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 9469081ae5d6..6937d97b87ea 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -47,10 +47,15 @@ AnyStr_co = TypeVar("AnyStr_co", str, bytes, covariant=True) # noqa: Y001 # isn't possible or a type is already partially known. In cases like these, # use Incomplete instead of Any as a marker. For example, use # "Incomplete | None" instead of "Any | None". -Incomplete: TypeAlias = Any +Incomplete: TypeAlias = Any # stable # To describe a function parameter that is unused and will work with anything. -Unused: TypeAlias = object +Unused: TypeAlias = object # stable + +# Marker for return types that include None, but where forcing the user to +# check for None can be detrimental. Sometimes called "the Any trick". See +# CONTRIBUTING.md for more information. +MaybeNone: TypeAlias = Any # stable # Used to mark arguments that default to a sentinel value. This prevents # stubtest from complaining about the default value not matching. @@ -146,13 +151,22 @@ class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]): def keys(self) -> Iterable[_KT]: ... def __getitem__(self, key: _KT, /) -> _VT_co: ... -# stable +# This protocol is currently under discussion. Use SupportsContainsAndGetItem +# instead, if you require the __contains__ method. +# See https://github.com/python/typeshed/issues/11822. class SupportsGetItem(Protocol[_KT_contra, _VT_co]): def __contains__(self, x: Any, /) -> bool: ... def __getitem__(self, key: _KT_contra, /) -> _VT_co: ... # stable -class SupportsItemAccess(SupportsGetItem[_KT_contra, _VT], Protocol[_KT_contra, _VT]): +class SupportsContainsAndGetItem(Protocol[_KT_contra, _VT_co]): + def __contains__(self, x: Any, /) -> bool: ... + def __getitem__(self, key: _KT_contra, /) -> _VT_co: ... + +# stable +class SupportsItemAccess(Protocol[_KT_contra, _VT]): + def __contains__(self, x: Any, /) -> bool: ... + def __getitem__(self, key: _KT_contra, /) -> _VT: ... def __setitem__(self, key: _KT_contra, value: _VT, /) -> None: ... def __delitem__(self, key: _KT_contra, /) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/constants.pyi b/mypy/typeshed/stdlib/asyncio/constants.pyi index 559cc02a0faa..7759a2844953 100644 --- a/mypy/typeshed/stdlib/asyncio/constants.pyi +++ b/mypy/typeshed/stdlib/asyncio/constants.pyi @@ -15,6 +15,6 @@ if sys.version_info >= (3, 12): THREAD_JOIN_TIMEOUT: Literal[300] class _SendfileMode(enum.Enum): - UNSUPPORTED: int - TRY_NATIVE: int - FALLBACK: int + UNSUPPORTED = 1 + TRY_NATIVE = 2 + FALLBACK = 3 diff --git a/mypy/typeshed/stdlib/asyncio/coroutines.pyi b/mypy/typeshed/stdlib/asyncio/coroutines.pyi index e92b150875f6..bc797de7fd51 100644 --- a/mypy/typeshed/stdlib/asyncio/coroutines.pyi +++ b/mypy/typeshed/stdlib/asyncio/coroutines.pyi @@ -1,7 +1,7 @@ import sys from collections.abc import Awaitable, Callable, Coroutine from typing import Any, TypeVar, overload -from typing_extensions import ParamSpec, TypeGuard +from typing_extensions import ParamSpec, TypeGuard, TypeIs if sys.version_info >= (3, 11): __all__ = ("iscoroutinefunction", "iscoroutine") @@ -23,4 +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]]]: ... -def iscoroutine(obj: object) -> TypeGuard[Coroutine[Any, Any, Any]]: ... +def iscoroutine(obj: object) -> TypeIs[Coroutine[Any, Any, Any]]: ... diff --git a/mypy/typeshed/stdlib/asyncio/futures.pyi b/mypy/typeshed/stdlib/asyncio/futures.pyi index 560dcc1d5712..a3953cdaf8c7 100644 --- a/mypy/typeshed/stdlib/asyncio/futures.pyi +++ b/mypy/typeshed/stdlib/asyncio/futures.pyi @@ -3,7 +3,7 @@ from collections.abc import Awaitable, Callable, Generator, Iterable 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 typing_extensions import Self, TypeIs from .events import AbstractEventLoop @@ -17,7 +17,7 @@ _T = TypeVar("_T") # asyncio defines 'isfuture()' in base_futures.py and re-imports it in futures.py # but it leads to circular import error in pytype tool. # That's why the import order is reversed. -def isfuture(obj: object) -> TypeGuard[Future[Any]]: ... +def isfuture(obj: object) -> TypeIs[Future[Any]]: ... class Future(Awaitable[_T], Iterable[_T]): _state: str diff --git a/mypy/typeshed/stdlib/asyncio/locks.pyi b/mypy/typeshed/stdlib/asyncio/locks.pyi index 3aac34b6934f..0114aeb23329 100644 --- a/mypy/typeshed/stdlib/asyncio/locks.pyi +++ b/mypy/typeshed/stdlib/asyncio/locks.pyi @@ -101,10 +101,10 @@ class BoundedSemaphore(Semaphore): ... if sys.version_info >= (3, 11): class _BarrierState(enum.Enum): # undocumented - FILLING: str - DRAINING: str - RESETTING: str - BROKEN: str + FILLING = "filling" + DRAINING = "draining" + RESETTING = "resetting" + BROKEN = "broken" class Barrier(_LoopBoundMixin): def __init__(self, parties: int) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/sslproto.pyi b/mypy/typeshed/stdlib/asyncio/sslproto.pyi index 04197c8d2978..e904d7395cdc 100644 --- a/mypy/typeshed/stdlib/asyncio/sslproto.pyi +++ b/mypy/typeshed/stdlib/asyncio/sslproto.pyi @@ -14,17 +14,17 @@ if sys.version_info >= (3, 11): SSLAgainErrors: tuple[type[ssl.SSLWantReadError], type[ssl.SSLSyscallError]] class SSLProtocolState(Enum): - UNWRAPPED: str - DO_HANDSHAKE: str - WRAPPED: str - FLUSHING: str - SHUTDOWN: str + UNWRAPPED = "UNWRAPPED" + DO_HANDSHAKE = "DO_HANDSHAKE" + WRAPPED = "WRAPPED" + FLUSHING = "FLUSHING" + SHUTDOWN = "SHUTDOWN" class AppProtocolState(Enum): - STATE_INIT: str - STATE_CON_MADE: str - STATE_EOF: str - STATE_CON_LOST: str + STATE_INIT = "STATE_INIT" + STATE_CON_MADE = "STATE_CON_MADE" + STATE_EOF = "STATE_EOF" + STATE_CON_LOST = "STATE_CON_LOST" def add_flowcontrol_defaults(high: int | None, low: int | None, kb: int) -> tuple[int, int]: ... diff --git a/mypy/typeshed/stdlib/audioop.pyi b/mypy/typeshed/stdlib/audioop.pyi index 830d6f83a273..f3ce78ccb7fa 100644 --- a/mypy/typeshed/stdlib/audioop.pyi +++ b/mypy/typeshed/stdlib/audioop.pyi @@ -1,32 +1,32 @@ -from typing_extensions import TypeAlias +from typing_extensions import Buffer, TypeAlias _AdpcmState: TypeAlias = tuple[int, int] _RatecvState: TypeAlias = tuple[int, tuple[tuple[int, int], ...]] class error(Exception): ... -def add(fragment1: bytes, fragment2: bytes, width: int, /) -> bytes: ... -def adpcm2lin(fragment: bytes, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... -def alaw2lin(fragment: bytes, width: int, /) -> bytes: ... -def avg(fragment: bytes, width: int, /) -> int: ... -def avgpp(fragment: bytes, width: int, /) -> int: ... -def bias(fragment: bytes, width: int, bias: int, /) -> bytes: ... -def byteswap(fragment: bytes, width: int, /) -> bytes: ... -def cross(fragment: bytes, width: int, /) -> int: ... -def findfactor(fragment: bytes, reference: bytes, /) -> float: ... -def findfit(fragment: bytes, reference: bytes, /) -> tuple[int, float]: ... -def findmax(fragment: bytes, length: int, /) -> int: ... -def getsample(fragment: bytes, width: int, index: int, /) -> int: ... -def lin2adpcm(fragment: bytes, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... -def lin2alaw(fragment: bytes, width: int, /) -> bytes: ... -def lin2lin(fragment: bytes, width: int, newwidth: int, /) -> bytes: ... -def lin2ulaw(fragment: bytes, width: int, /) -> bytes: ... -def max(fragment: bytes, width: int, /) -> int: ... -def maxpp(fragment: bytes, width: int, /) -> int: ... -def minmax(fragment: bytes, width: int, /) -> tuple[int, int]: ... -def mul(fragment: bytes, width: int, factor: float, /) -> bytes: ... +def add(fragment1: Buffer, fragment2: Buffer, width: int, /) -> bytes: ... +def adpcm2lin(fragment: Buffer, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... +def alaw2lin(fragment: Buffer, width: int, /) -> bytes: ... +def avg(fragment: Buffer, width: int, /) -> int: ... +def avgpp(fragment: Buffer, width: int, /) -> int: ... +def bias(fragment: Buffer, width: int, bias: int, /) -> bytes: ... +def byteswap(fragment: Buffer, width: int, /) -> bytes: ... +def cross(fragment: Buffer, width: int, /) -> int: ... +def findfactor(fragment: Buffer, reference: Buffer, /) -> float: ... +def findfit(fragment: Buffer, reference: Buffer, /) -> tuple[int, float]: ... +def findmax(fragment: Buffer, length: int, /) -> int: ... +def getsample(fragment: Buffer, width: int, index: int, /) -> int: ... +def lin2adpcm(fragment: Buffer, width: int, state: _AdpcmState | None, /) -> tuple[bytes, _AdpcmState]: ... +def lin2alaw(fragment: Buffer, width: int, /) -> bytes: ... +def lin2lin(fragment: Buffer, width: int, newwidth: int, /) -> bytes: ... +def lin2ulaw(fragment: Buffer, width: int, /) -> bytes: ... +def max(fragment: Buffer, width: int, /) -> int: ... +def maxpp(fragment: Buffer, width: int, /) -> int: ... +def minmax(fragment: Buffer, width: int, /) -> tuple[int, int]: ... +def mul(fragment: Buffer, width: int, factor: float, /) -> bytes: ... def ratecv( - fragment: bytes, + fragment: Buffer, width: int, nchannels: int, inrate: int, @@ -36,8 +36,8 @@ def ratecv( weightB: int = 0, /, ) -> tuple[bytes, _RatecvState]: ... -def reverse(fragment: bytes, width: int, /) -> bytes: ... -def rms(fragment: bytes, width: int, /) -> int: ... -def tomono(fragment: bytes, width: int, lfactor: float, rfactor: float, /) -> bytes: ... -def tostereo(fragment: bytes, width: int, lfactor: float, rfactor: float, /) -> bytes: ... -def ulaw2lin(fragment: bytes, width: int, /) -> bytes: ... +def reverse(fragment: Buffer, width: int, /) -> bytes: ... +def rms(fragment: Buffer, width: int, /) -> int: ... +def tomono(fragment: Buffer, width: int, lfactor: float, rfactor: float, /) -> bytes: ... +def tostereo(fragment: Buffer, width: int, lfactor: float, rfactor: float, /) -> bytes: ... +def ulaw2lin(fragment: Buffer, width: int, /) -> bytes: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 47dddcadf36d..9e56c5430c52 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -65,6 +65,7 @@ from typing_extensions import ( # noqa: Y023 Self, TypeAlias, TypeGuard, + TypeIs, TypeVarTuple, deprecated, ) @@ -943,15 +944,25 @@ class dict(MutableMapping[_KT, _VT]): @overload def __init__(self) -> None: ... @overload - def __init__(self: dict[str, _VT], **kwargs: _VT) -> None: ... + def __init__(self: dict[str, _VT], **kwargs: _VT) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 @overload def __init__(self, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload - def __init__(self: dict[str, _VT], map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... + def __init__( + self: dict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + map: SupportsKeysAndGetItem[str, _VT], + /, + **kwargs: _VT, + ) -> None: ... @overload def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload - def __init__(self: dict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... + def __init__( + self: dict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + iterable: Iterable[tuple[str, _VT]], + /, + **kwargs: _VT, + ) -> None: ... # Next two overloads are for dict(string.split(sep) for string in iterable) # Cannot be Iterable[Sequence[_T]] or otherwise dict(["foo", "bar", "baz"]) is not an error @overload @@ -1143,7 +1154,7 @@ def any(iterable: Iterable[object], /) -> bool: ... def ascii(obj: object, /) -> str: ... def bin(number: int | SupportsIndex, /) -> str: ... def breakpoint(*args: Any, **kws: Any) -> None: ... -def callable(obj: object, /) -> TypeGuard[Callable[..., object]]: ... +def callable(obj: object, /) -> TypeIs[Callable[..., object]]: ... def chr(i: int, /) -> str: ... # We define this here instead of using os.PathLike to avoid import cycle issues. @@ -1253,6 +1264,8 @@ class filter(Iterator[_T]): @overload def __new__(cls, function: Callable[[_S], TypeGuard[_T]], iterable: Iterable[_S], /) -> Self: ... @overload + def __new__(cls, function: Callable[[_S], TypeIs[_T]], iterable: Iterable[_S], /) -> Self: ... + @overload def __new__(cls, function: Callable[[_T], Any], iterable: Iterable[_T], /) -> Self: ... def __iter__(self) -> Self: ... def __next__(self) -> _T: ... diff --git a/mypy/typeshed/stdlib/cgi.pyi b/mypy/typeshed/stdlib/cgi.pyi index d20be33e3d76..3a2e2a91b241 100644 --- a/mypy/typeshed/stdlib/cgi.pyi +++ b/mypy/typeshed/stdlib/cgi.pyi @@ -1,4 +1,4 @@ -from _typeshed import SupportsGetItem, SupportsItemAccess, Unused +from _typeshed import SupportsContainsAndGetItem, SupportsGetItem, SupportsItemAccess, Unused from builtins import list as _list, type as _type from collections.abc import Iterable, Iterator, Mapping from email.message import Message @@ -85,7 +85,7 @@ class FieldStorage: fp: IO[Any] | None = None, headers: Mapping[str, str] | Message | None = None, outerboundary: bytes = b"", - environ: SupportsGetItem[str, str] = ..., + environ: SupportsContainsAndGetItem[str, str] = ..., keep_blank_values: int = 0, strict_parsing: int = 0, limit: int | None = None, diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index 1d23ecd66a8d..71e3c564dd57 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -51,15 +51,27 @@ class UserDict(MutableMapping[_KT, _VT]): @overload def __init__(self, dict: None = None, /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], dict: None = None, /, **kwargs: _VT) -> None: ... + def __init__( + self: UserDict[str, _VT], dict: None = None, /, **kwargs: _VT # pyright: ignore[reportInvalidTypeVarUse] #11780 + ) -> None: ... @overload def __init__(self, dict: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], dict: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... + def __init__( + self: UserDict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + dict: SupportsKeysAndGetItem[str, _VT], + /, + **kwargs: _VT, + ) -> None: ... @overload def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload - def __init__(self: UserDict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... + def __init__( + self: UserDict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + iterable: Iterable[tuple[str, _VT]], + /, + **kwargs: _VT, + ) -> None: ... @overload def __init__(self: UserDict[str, str], iterable: Iterable[list[str]], /) -> None: ... @overload @@ -389,16 +401,21 @@ class defaultdict(dict[_KT, _VT]): @overload def __init__(self) -> None: ... @overload - def __init__(self: defaultdict[str, _VT], **kwargs: _VT) -> None: ... + def __init__(self: defaultdict[str, _VT], **kwargs: _VT) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 @overload def __init__(self, default_factory: Callable[[], _VT] | None, /) -> None: ... @overload - def __init__(self: defaultdict[str, _VT], default_factory: Callable[[], _VT] | None, /, **kwargs: _VT) -> None: ... + def __init__( + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + default_factory: Callable[[], _VT] | None, + /, + **kwargs: _VT, + ) -> None: ... @overload def __init__(self, default_factory: Callable[[], _VT] | None, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... @overload def __init__( - self: defaultdict[str, _VT], + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 default_factory: Callable[[], _VT] | None, map: SupportsKeysAndGetItem[str, _VT], /, @@ -408,7 +425,7 @@ class defaultdict(dict[_KT, _VT]): def __init__(self, default_factory: Callable[[], _VT] | None, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... @overload def __init__( - self: defaultdict[str, _VT], + self: defaultdict[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 default_factory: Callable[[], _VT] | None, iterable: Iterable[tuple[str, _VT]], /, diff --git a/mypy/typeshed/stdlib/contextlib.pyi b/mypy/typeshed/stdlib/contextlib.pyi index f82bb4b7b6ad..29ac7cde561a 100644 --- a/mypy/typeshed/stdlib/contextlib.pyi +++ b/mypy/typeshed/stdlib/contextlib.pyi @@ -31,32 +31,33 @@ if sys.version_info >= (3, 11): _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) _T_io = TypeVar("_T_io", bound=IO[str] | None) +_ExitT_co = TypeVar("_ExitT_co", covariant=True, bound=bool | None, default=bool | None) _F = TypeVar("_F", bound=Callable[..., Any]) _P = ParamSpec("_P") _ExitFunc: TypeAlias = Callable[[type[BaseException] | None, BaseException | None, TracebackType | None], bool | None] -_CM_EF = TypeVar("_CM_EF", bound=AbstractContextManager[Any] | _ExitFunc) +_CM_EF = TypeVar("_CM_EF", bound=AbstractContextManager[Any, Any] | _ExitFunc) @runtime_checkable -class AbstractContextManager(Protocol[_T_co]): +class AbstractContextManager(Protocol[_T_co, _ExitT_co]): def __enter__(self) -> _T_co: ... @abstractmethod def __exit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / - ) -> bool | None: ... + ) -> _ExitT_co: ... @runtime_checkable -class AbstractAsyncContextManager(Protocol[_T_co]): +class AbstractAsyncContextManager(Protocol[_T_co, _ExitT_co]): async def __aenter__(self) -> _T_co: ... @abstractmethod async def __aexit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / - ) -> bool | None: ... + ) -> _ExitT_co: ... class ContextDecorator: def __call__(self, func: _F) -> _F: ... -class _GeneratorContextManager(AbstractContextManager[_T_co], ContextDecorator): +class _GeneratorContextManager(AbstractContextManager[_T_co, bool | None], ContextDecorator): # __init__ and all instance attributes are actually inherited from _GeneratorContextManagerBase # _GeneratorContextManagerBase is more trouble than it's worth to include in the stub; see #6676 def __init__(self, func: Callable[..., Iterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ... @@ -81,7 +82,7 @@ if sys.version_info >= (3, 10): class AsyncContextDecorator: def __call__(self, func: _AF) -> _AF: ... - class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co], AsyncContextDecorator): + class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co, bool | None], AsyncContextDecorator): # __init__ and these attributes are actually defined in the base class _GeneratorContextManagerBase, # which is more trouble than it's worth to include in the stub (see #6676) def __init__(self, func: Callable[..., AsyncIterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ... @@ -94,7 +95,7 @@ if sys.version_info >= (3, 10): ) -> bool | None: ... else: - class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co]): + class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co, bool | None]): def __init__(self, func: Callable[..., AsyncIterator[_T_co]], args: tuple[Any, ...], kwds: dict[str, Any]) -> None: ... gen: AsyncGenerator[_T_co, Any] func: Callable[..., AsyncGenerator[_T_co, Any]] @@ -111,7 +112,7 @@ class _SupportsClose(Protocol): _SupportsCloseT = TypeVar("_SupportsCloseT", bound=_SupportsClose) -class closing(AbstractContextManager[_SupportsCloseT]): +class closing(AbstractContextManager[_SupportsCloseT, None]): def __init__(self, thing: _SupportsCloseT) -> None: ... def __exit__(self, *exc_info: Unused) -> None: ... @@ -121,17 +122,17 @@ if sys.version_info >= (3, 10): _SupportsAcloseT = TypeVar("_SupportsAcloseT", bound=_SupportsAclose) - class aclosing(AbstractAsyncContextManager[_SupportsAcloseT]): + class aclosing(AbstractAsyncContextManager[_SupportsAcloseT, None]): def __init__(self, thing: _SupportsAcloseT) -> None: ... async def __aexit__(self, *exc_info: Unused) -> None: ... -class suppress(AbstractContextManager[None]): +class suppress(AbstractContextManager[None, bool]): def __init__(self, *exceptions: type[BaseException]) -> None: ... def __exit__( self, exctype: type[BaseException] | None, excinst: BaseException | None, exctb: TracebackType | None ) -> bool: ... -class _RedirectStream(AbstractContextManager[_T_io]): +class _RedirectStream(AbstractContextManager[_T_io, None]): def __init__(self, new_target: _T_io) -> None: ... def __exit__( self, exctype: type[BaseException] | None, excinst: BaseException | None, exctb: TracebackType | None @@ -142,8 +143,8 @@ class redirect_stderr(_RedirectStream[_T_io]): ... # In reality this is a subclass of `AbstractContextManager`; # see #7961 for why we don't do that in the stub -class ExitStack(metaclass=abc.ABCMeta): - def enter_context(self, cm: AbstractContextManager[_T]) -> _T: ... +class ExitStack(Generic[_ExitT_co], metaclass=abc.ABCMeta): + def enter_context(self, cm: AbstractContextManager[_T, _ExitT_co]) -> _T: ... def push(self, exit: _CM_EF) -> _CM_EF: ... def callback(self, callback: Callable[_P, _T], /, *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... def pop_all(self) -> Self: ... @@ -151,18 +152,18 @@ class ExitStack(metaclass=abc.ABCMeta): def __enter__(self) -> Self: ... def __exit__( self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None, / - ) -> bool: ... + ) -> _ExitT_co: ... _ExitCoroFunc: TypeAlias = Callable[ [type[BaseException] | None, BaseException | None, TracebackType | None], Awaitable[bool | None] ] -_ACM_EF = TypeVar("_ACM_EF", bound=AbstractAsyncContextManager[Any] | _ExitCoroFunc) +_ACM_EF = TypeVar("_ACM_EF", bound=AbstractAsyncContextManager[Any, Any] | _ExitCoroFunc) # In reality this is a subclass of `AbstractAsyncContextManager`; # see #7961 for why we don't do that in the stub -class AsyncExitStack(metaclass=abc.ABCMeta): - def enter_context(self, cm: AbstractContextManager[_T]) -> _T: ... - async def enter_async_context(self, cm: AbstractAsyncContextManager[_T]) -> _T: ... +class AsyncExitStack(Generic[_ExitT_co], metaclass=abc.ABCMeta): + def enter_context(self, cm: AbstractContextManager[_T, _ExitT_co]) -> _T: ... + async def enter_async_context(self, cm: AbstractAsyncContextManager[_T, _ExitT_co]) -> _T: ... def push(self, exit: _CM_EF) -> _CM_EF: ... def push_async_exit(self, exit: _ACM_EF) -> _ACM_EF: ... def callback(self, callback: Callable[_P, _T], /, *args: _P.args, **kwds: _P.kwargs) -> Callable[_P, _T]: ... @@ -177,31 +178,31 @@ class AsyncExitStack(metaclass=abc.ABCMeta): ) -> bool: ... if sys.version_info >= (3, 10): - class nullcontext(AbstractContextManager[_T], AbstractAsyncContextManager[_T]): + class nullcontext(AbstractContextManager[_T, None], AbstractAsyncContextManager[_T, None]): enter_result: _T @overload def __init__(self: nullcontext[None], enter_result: None = None) -> None: ... @overload - def __init__(self: nullcontext[_T], enter_result: _T) -> None: ... + def __init__(self: nullcontext[_T], enter_result: _T) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 def __enter__(self) -> _T: ... def __exit__(self, *exctype: Unused) -> None: ... async def __aenter__(self) -> _T: ... async def __aexit__(self, *exctype: Unused) -> None: ... else: - class nullcontext(AbstractContextManager[_T]): + class nullcontext(AbstractContextManager[_T, None]): enter_result: _T @overload def __init__(self: nullcontext[None], enter_result: None = None) -> None: ... @overload - def __init__(self: nullcontext[_T], enter_result: _T) -> None: ... + def __init__(self: nullcontext[_T], enter_result: _T) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 def __enter__(self) -> _T: ... def __exit__(self, *exctype: Unused) -> None: ... if sys.version_info >= (3, 11): _T_fd_or_any_path = TypeVar("_T_fd_or_any_path", bound=FileDescriptorOrPath) - class chdir(AbstractContextManager[None], Generic[_T_fd_or_any_path]): + class chdir(AbstractContextManager[None, None], Generic[_T_fd_or_any_path]): path: _T_fd_or_any_path def __init__(self, path: _T_fd_or_any_path) -> None: ... def __enter__(self) -> None: ... diff --git a/mypy/typeshed/stdlib/email/message.pyi b/mypy/typeshed/stdlib/email/message.pyi index d7d7e8c8e908..4032bc6136d4 100644 --- a/mypy/typeshed/stdlib/email/message.pyi +++ b/mypy/typeshed/stdlib/email/message.pyi @@ -3,22 +3,25 @@ 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, Literal, Protocol, TypeVar, overload +from typing import Any, Generic, Literal, Protocol, TypeVar, overload from typing_extensions import Self, TypeAlias __all__ = ["Message", "EmailMessage"] _T = TypeVar("_T") +# Type returned by Policy.header_fetch_parse, often str or Header. +_HeaderT = TypeVar("_HeaderT", default=str) +_HeaderParamT = TypeVar("_HeaderParamT", default=str) +# Represents headers constructed by HeaderRegistry. Those are sub-classes +# of BaseHeader and another header type. +_HeaderRegistryT = TypeVar("_HeaderRegistryT", default=Any) +_HeaderRegistryParamT = TypeVar("_HeaderRegistryParamT", default=Any) + _PayloadType: TypeAlias = Message | str _EncodedPayloadType: TypeAlias = Message | bytes _MultipartPayloadType: TypeAlias = list[_PayloadType] _CharsetType: TypeAlias = Charset | str | None -# Type returned by Policy.header_fetch_parse, often str or Header. -_HeaderType: TypeAlias = Any -# Type accepted by Policy.header_store_parse. -_HeaderTypeParam: TypeAlias = str | Header | Any class _SupportsEncodeToPayload(Protocol): def encode(self, encoding: str, /) -> _PayloadType | _MultipartPayloadType | _SupportsDecodeToPayload: ... @@ -26,10 +29,7 @@ class _SupportsEncodeToPayload(Protocol): class _SupportsDecodeToPayload(Protocol): def decode(self, encoding: str, errors: str, /) -> _PayloadType | _MultipartPayloadType: ... -# TODO: This class should be generic over the header policy and/or the header -# value types allowed by the policy. This depends on PEP 696 support -# (https://github.com/python/typeshed/issues/11422). -class Message: +class Message(Generic[_HeaderT, _HeaderParamT]): policy: Policy # undocumented preamble: str | None epilogue: str | None @@ -70,24 +70,23 @@ class Message: # 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: _HeaderTypeParam) -> None: ... + # so using "the Any trick" instead. + def __getitem__(self, name: str) -> _HeaderT | Any: ... + def __setitem__(self, name: str, val: _HeaderParamT) -> None: ... def __delitem__(self, name: str) -> None: ... def keys(self) -> list[str]: ... - def values(self) -> list[_HeaderType]: ... - def items(self) -> list[tuple[str, _HeaderType]]: ... + def values(self) -> list[_HeaderT]: ... + def items(self) -> list[tuple[str, _HeaderT]]: ... @overload - def get(self, name: str, failobj: None = None) -> _HeaderType | None: ... + def get(self, name: str, failobj: None = None) -> _HeaderT | None: ... @overload - def get(self, name: str, failobj: _T) -> _HeaderType | _T: ... + def get(self, name: str, failobj: _T) -> _HeaderT | _T: ... @overload - def get_all(self, name: str, failobj: None = None) -> list[_HeaderType] | None: ... + def get_all(self, name: str, failobj: None = None) -> list[_HeaderT] | None: ... @overload - def get_all(self, name: str, failobj: _T) -> list[_HeaderType] | _T: ... + def get_all(self, name: str, failobj: _T) -> list[_HeaderT] | _T: ... def add_header(self, _name: str, _value: str, **_params: _ParamsType) -> None: ... - def replace_header(self, _name: str, _value: _HeaderTypeParam) -> None: ... + def replace_header(self, _name: str, _value: _HeaderParamT) -> None: ... def get_content_type(self) -> str: ... def get_content_maintype(self) -> str: ... def get_content_subtype(self) -> str: ... @@ -141,14 +140,14 @@ 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: _HeaderTypeParam) -> None: ... - def raw_items(self) -> Iterator[tuple[str, _HeaderType]]: ... + def set_raw(self, name: str, value: _HeaderParamT) -> None: ... + def raw_items(self) -> Iterator[tuple[str, _HeaderT]]: ... -class MIMEPart(Message): +class MIMEPart(Message[_HeaderRegistryT, _HeaderRegistryParamT]): def __init__(self, policy: Policy | None = None) -> None: ... - def get_body(self, preferencelist: Sequence[str] = ("related", "html", "plain")) -> Message | None: ... - def iter_attachments(self) -> Iterator[Message]: ... - def iter_parts(self) -> Iterator[Message]: ... + def get_body(self, preferencelist: Sequence[str] = ("related", "html", "plain")) -> MIMEPart[_HeaderRegistryT] | None: ... + def iter_attachments(self) -> Iterator[MIMEPart[_HeaderRegistryT]]: ... + def iter_parts(self) -> Iterator[MIMEPart[_HeaderRegistryT]]: ... def get_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> Any: ... def set_content(self, *args: Any, content_manager: ContentManager | None = None, **kw: Any) -> None: ... def make_related(self, boundary: str | None = None) -> None: ... diff --git a/mypy/typeshed/stdlib/email/parser.pyi b/mypy/typeshed/stdlib/email/parser.pyi index 28b6aca856ca..fecb29d90b2e 100644 --- a/mypy/typeshed/stdlib/email/parser.pyi +++ b/mypy/typeshed/stdlib/email/parser.pyi @@ -3,24 +3,34 @@ from collections.abc import Callable from email.feedparser import BytesFeedParser as BytesFeedParser, FeedParser as FeedParser from email.message import Message from email.policy import Policy -from typing import IO +from io import _WrappedBuffer +from typing import Generic, TypeVar, overload __all__ = ["Parser", "HeaderParser", "BytesParser", "BytesHeaderParser", "FeedParser", "BytesFeedParser"] -class Parser: - def __init__(self, _class: Callable[[], Message] | None = None, *, policy: Policy = ...) -> None: ... - def parse(self, fp: SupportsRead[str], headersonly: bool = False) -> Message: ... - def parsestr(self, text: str, headersonly: bool = False) -> Message: ... +_MessageT = TypeVar("_MessageT", bound=Message, default=Message) -class HeaderParser(Parser): - def parse(self, fp: SupportsRead[str], headersonly: bool = True) -> Message: ... - def parsestr(self, text: str, headersonly: bool = True) -> Message: ... +class Parser(Generic[_MessageT]): + @overload + def __init__(self: Parser[Message[str, str]], _class: None = None, *, policy: Policy = ...) -> None: ... + @overload + def __init__(self, _class: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... + def parse(self, fp: SupportsRead[str], headersonly: bool = False) -> _MessageT: ... + def parsestr(self, text: str, headersonly: bool = False) -> _MessageT: ... -class BytesParser: - def __init__(self, _class: Callable[[], Message] = ..., *, policy: Policy = ...) -> None: ... - def parse(self, fp: IO[bytes], headersonly: bool = False) -> Message: ... - def parsebytes(self, text: bytes | bytearray, headersonly: bool = False) -> Message: ... +class HeaderParser(Parser[_MessageT]): + def parse(self, fp: SupportsRead[str], headersonly: bool = True) -> _MessageT: ... + def parsestr(self, text: str, headersonly: bool = True) -> _MessageT: ... -class BytesHeaderParser(BytesParser): - def parse(self, fp: IO[bytes], headersonly: bool = True) -> Message: ... - def parsebytes(self, text: bytes | bytearray, headersonly: bool = True) -> Message: ... +class BytesParser(Generic[_MessageT]): + parser: Parser[_MessageT] + @overload + def __init__(self: BytesParser[Message[str, str]], _class: None = None, *, policy: Policy = ...) -> None: ... + @overload + def __init__(self, _class: Callable[[], _MessageT], *, policy: Policy = ...) -> None: ... + def parse(self, fp: _WrappedBuffer, headersonly: bool = False) -> _MessageT: ... + def parsebytes(self, text: bytes | bytearray, headersonly: bool = False) -> _MessageT: ... + +class BytesHeaderParser(BytesParser[_MessageT]): + def parse(self, fp: _WrappedBuffer, headersonly: bool = True) -> _MessageT: ... + def parsebytes(self, text: bytes | bytearray, headersonly: bool = True) -> _MessageT: ... diff --git a/mypy/typeshed/stdlib/http/__init__.pyi b/mypy/typeshed/stdlib/http/__init__.pyi index 2eee06fdaaa9..bb5737cc0481 100644 --- a/mypy/typeshed/stdlib/http/__init__.pyi +++ b/mypy/typeshed/stdlib/http/__init__.pyi @@ -15,65 +15,65 @@ class HTTPStatus(IntEnum): def phrase(self) -> str: ... @property def description(self) -> str: ... - CONTINUE: int - SWITCHING_PROTOCOLS: int - PROCESSING: int - OK: int - CREATED: int - ACCEPTED: int - NON_AUTHORITATIVE_INFORMATION: int - NO_CONTENT: int - RESET_CONTENT: int - PARTIAL_CONTENT: int - MULTI_STATUS: int - ALREADY_REPORTED: int - IM_USED: int - MULTIPLE_CHOICES: int - MOVED_PERMANENTLY: int - FOUND: int - SEE_OTHER: int - NOT_MODIFIED: int - USE_PROXY: int - TEMPORARY_REDIRECT: int - PERMANENT_REDIRECT: int - BAD_REQUEST: int - UNAUTHORIZED: int - PAYMENT_REQUIRED: int - FORBIDDEN: int - NOT_FOUND: int - METHOD_NOT_ALLOWED: int - NOT_ACCEPTABLE: int - PROXY_AUTHENTICATION_REQUIRED: int - REQUEST_TIMEOUT: int - CONFLICT: int - GONE: int - LENGTH_REQUIRED: int - PRECONDITION_FAILED: int - REQUEST_ENTITY_TOO_LARGE: int - REQUEST_URI_TOO_LONG: int - UNSUPPORTED_MEDIA_TYPE: int - REQUESTED_RANGE_NOT_SATISFIABLE: int - EXPECTATION_FAILED: int - UNPROCESSABLE_ENTITY: int - LOCKED: int - FAILED_DEPENDENCY: int - UPGRADE_REQUIRED: int - PRECONDITION_REQUIRED: int - TOO_MANY_REQUESTS: int - REQUEST_HEADER_FIELDS_TOO_LARGE: int - INTERNAL_SERVER_ERROR: int - NOT_IMPLEMENTED: int - BAD_GATEWAY: int - SERVICE_UNAVAILABLE: int - GATEWAY_TIMEOUT: int - HTTP_VERSION_NOT_SUPPORTED: int - VARIANT_ALSO_NEGOTIATES: int - INSUFFICIENT_STORAGE: int - LOOP_DETECTED: int - NOT_EXTENDED: int - NETWORK_AUTHENTICATION_REQUIRED: int - MISDIRECTED_REQUEST: int - UNAVAILABLE_FOR_LEGAL_REASONS: int + CONTINUE = 100 + SWITCHING_PROTOCOLS = 101 + PROCESSING = 102 + OK = 200 + CREATED = 201 + ACCEPTED = 202 + NON_AUTHORITATIVE_INFORMATION = 203 + NO_CONTENT = 204 + RESET_CONTENT = 205 + PARTIAL_CONTENT = 206 + MULTI_STATUS = 207 + ALREADY_REPORTED = 208 + IM_USED = 226 + MULTIPLE_CHOICES = 300 + MOVED_PERMANENTLY = 301 + FOUND = 302 + SEE_OTHER = 303 + NOT_MODIFIED = 304 + USE_PROXY = 305 + TEMPORARY_REDIRECT = 307 + PERMANENT_REDIRECT = 308 + BAD_REQUEST = 400 + UNAUTHORIZED = 401 + PAYMENT_REQUIRED = 402 + FORBIDDEN = 403 + NOT_FOUND = 404 + METHOD_NOT_ALLOWED = 405 + NOT_ACCEPTABLE = 406 + PROXY_AUTHENTICATION_REQUIRED = 407 + REQUEST_TIMEOUT = 408 + CONFLICT = 409 + GONE = 410 + LENGTH_REQUIRED = 411 + PRECONDITION_FAILED = 412 + REQUEST_ENTITY_TOO_LARGE = 413 + REQUEST_URI_TOO_LONG = 414 + UNSUPPORTED_MEDIA_TYPE = 415 + REQUESTED_RANGE_NOT_SATISFIABLE = 416 + EXPECTATION_FAILED = 417 + UNPROCESSABLE_ENTITY = 422 + LOCKED = 423 + FAILED_DEPENDENCY = 424 + UPGRADE_REQUIRED = 426 + PRECONDITION_REQUIRED = 428 + TOO_MANY_REQUESTS = 429 + REQUEST_HEADER_FIELDS_TOO_LARGE = 431 + INTERNAL_SERVER_ERROR = 500 + NOT_IMPLEMENTED = 501 + BAD_GATEWAY = 502 + SERVICE_UNAVAILABLE = 503 + GATEWAY_TIMEOUT = 504 + HTTP_VERSION_NOT_SUPPORTED = 505 + VARIANT_ALSO_NEGOTIATES = 506 + INSUFFICIENT_STORAGE = 507 + LOOP_DETECTED = 508 + NOT_EXTENDED = 510 + NETWORK_AUTHENTICATION_REQUIRED = 511 + MISDIRECTED_REQUEST = 421 + UNAVAILABLE_FOR_LEGAL_REASONS = 451 if sys.version_info >= (3, 9): EARLY_HINTS: Literal[103] IM_A_TEAPOT: Literal[418] @@ -94,12 +94,12 @@ if sys.version_info >= (3, 11): class HTTPMethod(StrEnum): @property def description(self) -> str: ... - CONNECT: str - DELETE: str - GET: str - HEAD: str - OPTIONS: str - PATCH: str - POST: str - PUT: str - TRACE: str + CONNECT = "CONNECT" + DELETE = "DELETE" + GET = "GET" + HEAD = "HEAD" + OPTIONS = "OPTIONS" + PATCH = "PATCH" + POST = "POST" + PUT = "PUT" + TRACE = "TRACE" diff --git a/mypy/typeshed/stdlib/http/client.pyi b/mypy/typeshed/stdlib/http/client.pyi index fb5450730f60..f68d9d0ca7d7 100644 --- a/mypy/typeshed/stdlib/http/client.pyi +++ b/mypy/typeshed/stdlib/http/client.pyi @@ -3,7 +3,7 @@ import io import ssl import sys import types -from _typeshed import ReadableBuffer, SupportsRead, WriteableBuffer +from _typeshed import ReadableBuffer, SupportsRead, SupportsReadline, WriteableBuffer from collections.abc import Callable, Iterable, Iterator, Mapping from socket import socket from typing import Any, BinaryIO, TypeVar, overload @@ -33,6 +33,7 @@ __all__ = [ _DataType: TypeAlias = SupportsRead[bytes] | Iterable[ReadableBuffer] | ReadableBuffer _T = TypeVar("_T") +_MessageT = TypeVar("_MessageT", bound=email.message.Message) HTTP_PORT: int HTTPS_PORT: int @@ -97,28 +98,13 @@ NETWORK_AUTHENTICATION_REQUIRED: int responses: dict[int, str] -class HTTPMessage(email.message.Message): +class HTTPMessage(email.message.Message[str, str]): 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: ... +@overload +def parse_headers(fp: SupportsReadline[bytes], _class: Callable[[], _MessageT]) -> _MessageT: ... +@overload +def parse_headers(fp: SupportsReadline[bytes]) -> HTTPMessage: ... class HTTPResponse(io.BufferedIOBase, BinaryIO): # type: ignore[misc] # incompatible method definitions in the base classes msg: HTTPMessage diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index bb5ddc37c603..0abf16d9d0ab 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -26,7 +26,7 @@ from types import ( WrapperDescriptorType, ) from typing import Any, ClassVar, Literal, NamedTuple, Protocol, TypeVar, overload -from typing_extensions import ParamSpec, Self, TypeAlias, TypeGuard +from typing_extensions import ParamSpec, Self, TypeAlias, TypeGuard, TypeIs if sys.version_info >= (3, 11): __all__ = [ @@ -192,10 +192,10 @@ if sys.version_info >= (3, 11): def getmembers_static(object: object, predicate: _GetMembersPredicate | None = None) -> _GetMembersReturn: ... def getmodulename(path: StrPath) -> str | None: ... -def ismodule(object: object) -> TypeGuard[ModuleType]: ... -def isclass(object: object) -> TypeGuard[type[Any]]: ... -def ismethod(object: object) -> TypeGuard[MethodType]: ... -def isfunction(object: object) -> TypeGuard[FunctionType]: ... +def ismodule(object: object) -> TypeIs[ModuleType]: ... +def isclass(object: object) -> TypeIs[type[Any]]: ... +def ismethod(object: object) -> TypeIs[MethodType]: ... +def isfunction(object: object) -> TypeIs[FunctionType]: ... if sys.version_info >= (3, 12): def markcoroutinefunction(func: _F) -> _F: ... @@ -214,9 +214,9 @@ def iscoroutinefunction(obj: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable[ 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]]: ... +def isgenerator(object: object) -> TypeIs[GeneratorType[Any, Any, Any]]: ... +def iscoroutine(object: object) -> TypeIs[CoroutineType[Any, Any, Any]]: ... +def isawaitable(object: object) -> TypeIs[Awaitable[Any]]: ... @overload def isasyncgenfunction(obj: Callable[..., AsyncGenerator[Any, Any]]) -> bool: ... @overload @@ -230,18 +230,18 @@ class _SupportsSet(Protocol[_T_cont, _V_cont]): class _SupportsDelete(Protocol[_T_cont]): def __delete__(self, instance: _T_cont, /) -> None: ... -def isasyncgen(object: object) -> TypeGuard[AsyncGeneratorType[Any, Any]]: ... -def istraceback(object: object) -> TypeGuard[TracebackType]: ... -def isframe(object: object) -> TypeGuard[FrameType]: ... -def iscode(object: object) -> TypeGuard[CodeType]: ... -def isbuiltin(object: object) -> TypeGuard[BuiltinFunctionType]: ... +def isasyncgen(object: object) -> TypeIs[AsyncGeneratorType[Any, Any]]: ... +def istraceback(object: object) -> TypeIs[TracebackType]: ... +def isframe(object: object) -> TypeIs[FrameType]: ... +def iscode(object: object) -> TypeIs[CodeType]: ... +def isbuiltin(object: object) -> TypeIs[BuiltinFunctionType]: ... if sys.version_info >= (3, 11): - def ismethodwrapper(object: object) -> TypeGuard[MethodWrapperType]: ... + def ismethodwrapper(object: object) -> TypeIs[MethodWrapperType]: ... def isroutine( object: object, -) -> TypeGuard[ +) -> TypeIs[ FunctionType | LambdaType | MethodType @@ -251,11 +251,11 @@ def isroutine( | MethodDescriptorType | ClassMethodDescriptorType ]: ... -def ismethoddescriptor(object: object) -> TypeGuard[MethodDescriptorType]: ... -def ismemberdescriptor(object: object) -> TypeGuard[MemberDescriptorType]: ... +def ismethoddescriptor(object: object) -> TypeIs[MethodDescriptorType]: ... +def ismemberdescriptor(object: object) -> TypeIs[MemberDescriptorType]: ... def isabstract(object: object) -> bool: ... -def isgetsetdescriptor(object: object) -> TypeGuard[GetSetDescriptorType]: ... -def isdatadescriptor(object: object) -> TypeGuard[_SupportsSet[Any, Any] | _SupportsDelete[Any]]: ... +def isgetsetdescriptor(object: object) -> TypeIs[GetSetDescriptorType]: ... +def isdatadescriptor(object: object) -> TypeIs[_SupportsSet[Any, Any] | _SupportsDelete[Any]]: ... # # Retrieving source code @@ -347,11 +347,11 @@ if sys.version_info >= (3, 10): # The name is the same as the enum's name in CPython class _ParameterKind(enum.IntEnum): - POSITIONAL_ONLY: int - POSITIONAL_OR_KEYWORD: int - VAR_POSITIONAL: int - KEYWORD_ONLY: int - VAR_KEYWORD: int + POSITIONAL_ONLY = 0 + POSITIONAL_OR_KEYWORD = 1 + VAR_POSITIONAL = 2 + KEYWORD_ONLY = 3 + VAR_KEYWORD = 4 @property def description(self) -> str: ... @@ -611,22 +611,22 @@ if sys.version_info >= (3, 9): if sys.version_info >= (3, 12): class BufferFlags(enum.IntFlag): - SIMPLE: int - WRITABLE: int - FORMAT: int - ND: int - STRIDES: int - C_CONTIGUOUS: int - F_CONTIGUOUS: int - ANY_CONTIGUOUS: int - INDIRECT: int - CONTIG: int - CONTIG_RO: int - STRIDED: int - STRIDED_RO: int - RECORDS: int - RECORDS_RO: int - FULL: int - FULL_RO: int - READ: int - WRITE: int + SIMPLE = 0 + WRITABLE = 1 + FORMAT = 4 + ND = 8 + STRIDES = 24 + C_CONTIGUOUS = 56 + F_CONTIGUOUS = 88 + ANY_CONTIGUOUS = 152 + INDIRECT = 280 + CONTIG = 9 + CONTIG_RO = 8 + STRIDED = 25 + STRIDED_RO = 24 + RECORDS = 29 + RECORDS_RO = 28 + FULL = 285 + FULL_RO = 284 + READ = 256 + WRITE = 512 diff --git a/mypy/typeshed/stdlib/logging/__init__.pyi b/mypy/typeshed/stdlib/logging/__init__.pyi index a62d0674df4c..f5f7f91ece61 100644 --- a/mypy/typeshed/stdlib/logging/__init__.pyi +++ b/mypy/typeshed/stdlib/logging/__init__.pyi @@ -597,7 +597,7 @@ class StreamHandler(Handler, Generic[_StreamT]): @overload def __init__(self: StreamHandler[TextIO], stream: None = None) -> None: ... @overload - def __init__(self: StreamHandler[_StreamT], stream: _StreamT) -> None: ... + def __init__(self: StreamHandler[_StreamT], stream: _StreamT) -> None: ... # pyright: ignore[reportInvalidTypeVarUse] #11780 def setStream(self, stream: _StreamT) -> _StreamT | None: ... if sys.version_info >= (3, 11): def __class_getitem__(cls, item: Any) -> GenericAlias: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/context.pyi b/mypy/typeshed/stdlib/multiprocessing/context.pyi index a3edaa463818..9a45a81559c0 100644 --- a/mypy/typeshed/stdlib/multiprocessing/context.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/context.pyi @@ -1,13 +1,13 @@ import ctypes import sys from collections.abc import Callable, Iterable, Sequence -from ctypes import _CData +from ctypes import _CData, _SimpleCData, c_char from logging import Logger, _Level as _LoggingLevel from multiprocessing import popen_fork, popen_forkserver, popen_spawn_posix, popen_spawn_win32, queues, synchronize from multiprocessing.managers import SyncManager from multiprocessing.pool import Pool as _Pool from multiprocessing.process import BaseProcess -from multiprocessing.sharedctypes import Synchronized, SynchronizedArray +from multiprocessing.sharedctypes import Synchronized, SynchronizedArray, SynchronizedString from typing import Any, ClassVar, Literal, TypeVar, overload from typing_extensions import TypeAlias @@ -19,6 +19,7 @@ else: __all__ = () _LockLike: TypeAlias = synchronize.Lock | synchronize.RLock +_T = TypeVar("_T") _CT = TypeVar("_CT", bound=_CData) class ProcessError(Exception): ... @@ -79,6 +80,10 @@ class BaseContext: @overload def RawArray(self, typecode_or_type: str, size_or_initializer: int | Sequence[Any]) -> Any: ... @overload + def Value( + self, typecode_or_type: type[_SimpleCData[_T]], *args: Any, lock: Literal[True] | _LockLike = True + ) -> Synchronized[_T]: ... + @overload def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[False]) -> Synchronized[_CT]: ... @overload def Value(self, typecode_or_type: type[_CT], *args: Any, lock: Literal[True] | _LockLike = True) -> Synchronized[_CT]: ... @@ -87,6 +92,10 @@ class BaseContext: @overload def Value(self, typecode_or_type: str | type[_CData], *args: Any, lock: bool | _LockLike = True) -> Any: ... @overload + def Array( + self, typecode_or_type: type[c_char], size_or_initializer: int | Sequence[Any], *, lock: Literal[True] | _LockLike = True + ) -> SynchronizedString: ... + @overload def Array( self, typecode_or_type: type[_CT], size_or_initializer: int | Sequence[Any], *, lock: Literal[False] ) -> SynchronizedArray[_CT]: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi index 048c6fe8d891..b417925fb17b 100644 --- a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi @@ -14,7 +14,7 @@ class Barrier(threading.Barrier): self, parties: int, action: Callable[[], object] | None = None, timeout: float | None = None, *ctx: BaseContext ) -> None: ... -class Condition(AbstractContextManager[bool]): +class Condition(AbstractContextManager[bool, None]): def __init__(self, lock: _LockLike | None = None, *, ctx: BaseContext) -> None: ... def notify(self, n: int = 1) -> None: ... def notify_all(self) -> None: ... @@ -34,7 +34,7 @@ class Event: def wait(self, timeout: float | None = None) -> bool: ... # Not part of public API -class SemLock(AbstractContextManager[bool]): +class SemLock(AbstractContextManager[bool, None]): def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... def release(self) -> None: ... def __exit__( diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index 89d906d4edfc..e1c7855c0bb6 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -747,7 +747,7 @@ if sys.platform != "win32": def getcwd() -> str: ... def getcwdb() -> bytes: ... -def chmod(path: FileDescriptorOrPath, mode: int, *, dir_fd: int | None = None, follow_symlinks: bool = True) -> None: ... +def chmod(path: FileDescriptorOrPath, mode: int, *, dir_fd: int | None = None, follow_symlinks: bool = ...) -> None: ... if sys.platform != "win32" and sys.platform != "linux": def chflags(path: StrOrBytesPath, flags: int, follow_symlinks: bool = True) -> None: ... # some flavors of Unix @@ -794,7 +794,7 @@ def replace( ) -> None: ... def rmdir(path: StrOrBytesPath, *, dir_fd: int | None = None) -> None: ... -class _ScandirIterator(Iterator[DirEntry[AnyStr]], AbstractContextManager[_ScandirIterator[AnyStr]]): +class _ScandirIterator(Iterator[DirEntry[AnyStr]], AbstractContextManager[_ScandirIterator[AnyStr], None]): def __next__(self) -> DirEntry[AnyStr]: ... def __exit__(self, *args: Unused) -> None: ... def close(self) -> None: ... diff --git a/mypy/typeshed/stdlib/plistlib.pyi b/mypy/typeshed/stdlib/plistlib.pyi index f7912a784987..09637673ce21 100644 --- a/mypy/typeshed/stdlib/plistlib.pyi +++ b/mypy/typeshed/stdlib/plistlib.pyi @@ -11,8 +11,8 @@ if sys.version_info < (3, 9): __all__ += ["readPlist", "writePlist", "readPlistFromBytes", "writePlistToBytes", "Data"] class PlistFormat(Enum): - FMT_XML: int - FMT_BINARY: int + FMT_XML = 1 + FMT_BINARY = 2 FMT_XML = PlistFormat.FMT_XML FMT_BINARY = PlistFormat.FMT_BINARY diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index d1571fd94be5..83256b433035 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -14,15 +14,15 @@ else: _Selector: TypeAlias = str | float | int class SortKey(StrEnum): - CALLS: str - CUMULATIVE: str - FILENAME: str - LINE: str - NAME: str - NFL: str - PCALLS: str - STDNAME: str - TIME: str + CALLS = "calls" + CUMULATIVE = "cumulative" + FILENAME = "filename" + LINE = "line" + NAME = "name" + NFL = "nfl" + PCALLS = "pcalls" + STDNAME = "stdname" + TIME = "time" if sys.version_info >= (3, 9): from dataclasses import dataclass diff --git a/mypy/typeshed/stdlib/py_compile.pyi b/mypy/typeshed/stdlib/py_compile.pyi index 81561a202883..334ce79b5dd0 100644 --- a/mypy/typeshed/stdlib/py_compile.pyi +++ b/mypy/typeshed/stdlib/py_compile.pyi @@ -12,9 +12,9 @@ class PyCompileError(Exception): def __init__(self, exc_type: type[BaseException], exc_value: BaseException, file: str, msg: str = "") -> None: ... class PycInvalidationMode(enum.Enum): - TIMESTAMP: int - CHECKED_HASH: int - UNCHECKED_HASH: int + TIMESTAMP = 1 + CHECKED_HASH = 2 + UNCHECKED_HASH = 3 def _get_default_invalidation_mode() -> PycInvalidationMode: ... def compile( diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index 663ee2fe7430..cbb7440b9147 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -9,57 +9,57 @@ from typing_extensions import Never, TypeAlias NSIG: int class Signals(IntEnum): - SIGABRT: int - SIGFPE: int - SIGILL: int - SIGINT: int - SIGSEGV: int - SIGTERM: int + SIGABRT = 6 + SIGFPE = 8 + SIGILL = 4 + SIGINT = 2 + SIGSEGV = 11 + SIGTERM = 15 if sys.platform == "win32": - SIGBREAK: int - CTRL_C_EVENT: int - CTRL_BREAK_EVENT: int + SIGBREAK = 21 + CTRL_C_EVENT = 0 + CTRL_BREAK_EVENT = 1 else: - SIGALRM: int - SIGBUS: int - SIGCHLD: int - SIGCONT: int - SIGHUP: int - SIGIO: int - SIGIOT: int - SIGKILL: int - SIGPIPE: int - SIGPROF: int - SIGQUIT: int - SIGSTOP: int - SIGSYS: int - SIGTRAP: int - SIGTSTP: int - SIGTTIN: int - SIGTTOU: int - SIGURG: int - SIGUSR1: int - SIGUSR2: int - SIGVTALRM: int - SIGWINCH: int - SIGXCPU: int - SIGXFSZ: int + SIGALRM = 14 + SIGBUS = 7 + SIGCHLD = 17 + SIGCONT = 18 + SIGHUP = 1 + SIGIO = 29 + SIGIOT = 6 + SIGKILL = 9 + SIGPIPE = 13 + SIGPROF = 27 + SIGQUIT = 3 + SIGSTOP = 19 + SIGSYS = 31 + SIGTRAP = 5 + SIGTSTP = 20 + SIGTTIN = 21 + SIGTTOU = 22 + SIGURG = 23 + SIGUSR1 = 10 + SIGUSR2 = 12 + SIGVTALRM = 26 + SIGWINCH = 28 + SIGXCPU = 24 + SIGXFSZ = 25 if sys.platform != "linux": - SIGEMT: int - SIGINFO: int + SIGEMT = 7 + SIGINFO = 29 if sys.platform != "darwin": - SIGCLD: int - SIGPOLL: int - SIGPWR: int - SIGRTMAX: int - SIGRTMIN: int + SIGCLD = 17 + SIGPOLL = 29 + SIGPWR = 30 + SIGRTMAX = 64 + SIGRTMIN = 34 if sys.version_info >= (3, 11): - SIGSTKFLT: int + SIGSTKFLT = 16 class Handlers(IntEnum): - SIG_DFL: int - SIG_IGN: int + SIG_DFL = 0 + SIG_IGN = 1 SIG_DFL: Handlers SIG_IGN: Handlers @@ -123,9 +123,9 @@ else: ITIMER_VIRTUAL: int class Sigmasks(IntEnum): - SIG_BLOCK: int - SIG_UNBLOCK: int - SIG_SETMASK: int + SIG_BLOCK = 0 + SIG_UNBLOCK = 1 + SIG_SETMASK = 2 SIG_BLOCK = Sigmasks.SIG_BLOCK SIG_UNBLOCK = Sigmasks.SIG_UNBLOCK diff --git a/mypy/typeshed/stdlib/socket.pyi b/mypy/typeshed/stdlib/socket.pyi index cdbd70533714..a309bac9370a 100644 --- a/mypy/typeshed/stdlib/socket.pyi +++ b/mypy/typeshed/stdlib/socket.pyi @@ -480,51 +480,51 @@ EAGAIN: int EWOULDBLOCK: int class AddressFamily(IntEnum): - AF_INET: int - AF_INET6: int - AF_APPLETALK: int - AF_DECnet: int - AF_IPX: int - AF_SNA: int - AF_UNSPEC: int + AF_INET = 2 + AF_INET6 = 10 + AF_APPLETALK = 5 + AF_DECnet = ... + AF_IPX = 4 + AF_SNA = 22 + AF_UNSPEC = 0 if sys.platform != "darwin": - AF_IRDA: int + AF_IRDA = 23 if sys.platform != "win32": - AF_ROUTE: int - AF_SYSTEM: int - AF_UNIX: int + AF_ROUTE = 16 + AF_SYSTEM = 32 + AF_UNIX = 1 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 + AF_AAL5 = ... + AF_ASH = 18 + AF_ATMPVC = 8 + AF_ATMSVC = 20 + AF_AX25 = 3 + AF_BRIDGE = 7 + AF_ECONET = 19 + AF_KEY = 15 + AF_LLC = 26 + AF_NETBEUI = 13 + AF_NETROM = 6 + AF_PPPOX = 24 + AF_ROSE = 11 + AF_SECURITY = 14 + AF_WANPIPE = 25 + AF_X25 = 9 if sys.platform == "linux": - AF_CAN: int - AF_PACKET: int - AF_RDS: int - AF_TIPC: int - AF_ALG: int - AF_NETLINK: int - AF_VSOCK: int - AF_QIPCRTR: int + AF_CAN = 29 + AF_PACKET = 17 + AF_RDS = 21 + AF_TIPC = 30 + AF_ALG = 38 + AF_NETLINK = 16 + AF_VSOCK = 40 + AF_QIPCRTR = 42 if sys.platform != "win32" or sys.version_info >= (3, 9): - AF_LINK: int + AF_LINK = 33 if sys.platform != "darwin": - AF_BLUETOOTH: int + AF_BLUETOOTH = 32 if sys.platform == "win32" and sys.version_info >= (3, 12): - AF_HYPERV: int + AF_HYPERV = 34 AF_INET = AddressFamily.AF_INET AF_INET6 = AddressFamily.AF_INET6 @@ -579,14 +579,14 @@ if sys.platform == "win32" and sys.version_info >= (3, 12): AF_HYPERV = AddressFamily.AF_HYPERV class SocketKind(IntEnum): - SOCK_STREAM: int - SOCK_DGRAM: int - SOCK_RAW: int - SOCK_RDM: int - SOCK_SEQPACKET: int + SOCK_STREAM = 1 + SOCK_DGRAM = 2 + SOCK_RAW = 3 + SOCK_RDM = 4 + SOCK_SEQPACKET = 5 if sys.platform == "linux": - SOCK_CLOEXEC: int - SOCK_NONBLOCK: int + SOCK_CLOEXEC = 524288 + SOCK_NONBLOCK = 2048 SOCK_STREAM = SocketKind.SOCK_STREAM SOCK_DGRAM = SocketKind.SOCK_DGRAM @@ -598,32 +598,32 @@ if sys.platform == "linux": SOCK_NONBLOCK = SocketKind.SOCK_NONBLOCK class MsgFlag(IntFlag): - MSG_CTRUNC: int - MSG_DONTROUTE: int - MSG_OOB: int - MSG_PEEK: int - MSG_TRUNC: int - MSG_WAITALL: int + MSG_CTRUNC = 8 + MSG_DONTROUTE = 4 + MSG_OOB = 1 + MSG_PEEK = 2 + MSG_TRUNC = 32 + MSG_WAITALL = 256 if sys.platform != "darwin": - MSG_BCAST: int - MSG_MCAST: int - MSG_ERRQUEUE: int + MSG_BCAST = 1024 + MSG_MCAST = 2048 + MSG_ERRQUEUE = 8192 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 + MSG_BTAG = ... + MSG_CMSG_CLOEXEC = 1073741821 + MSG_CONFIRM = 2048 + MSG_ETAG = ... + MSG_FASTOPEN = 536870912 + MSG_MORE = 32768 + MSG_NOTIFICATION = ... if sys.platform != "win32": - MSG_DONTWAIT: int - MSG_EOF: int - MSG_EOR: int - MSG_NOSIGNAL: int # sometimes this exists on darwin, sometimes not + MSG_DONTWAIT = 64 + MSG_EOF = 256 + MSG_EOR = 128 + MSG_NOSIGNAL = 16384 # sometimes this exists on darwin, sometimes not MSG_CTRUNC = MsgFlag.MSG_CTRUNC MSG_DONTROUTE = MsgFlag.MSG_DONTROUTE @@ -653,17 +653,17 @@ if sys.platform != "win32" and sys.platform != "darwin": MSG_NOTIFICATION = MsgFlag.MSG_NOTIFICATION class AddressInfo(IntFlag): - AI_ADDRCONFIG: int - AI_ALL: int - AI_CANONNAME: int - AI_NUMERICHOST: int - AI_NUMERICSERV: int - AI_PASSIVE: int - AI_V4MAPPED: int + AI_ADDRCONFIG = 32 + AI_ALL = 16 + AI_CANONNAME = 2 + AI_NUMERICHOST = 4 + AI_NUMERICSERV = 1024 + AI_PASSIVE = 1 + AI_V4MAPPED = 8 if sys.platform != "win32": - AI_DEFAULT: int - AI_MASK: int - AI_V4MAPPED_CFG: int + AI_DEFAULT = 1536 + AI_MASK = 5127 + AI_V4MAPPED_CFG = 512 AI_ADDRCONFIG = AddressInfo.AI_ADDRCONFIG AI_ALL = AddressInfo.AI_ALL diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index 15d86372531a..81c68c69ec4e 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -138,23 +138,23 @@ if sys.platform == "win32": def enum_crls(store_name: str) -> _EnumRetType: ... class VerifyMode(enum.IntEnum): - CERT_NONE: int - CERT_OPTIONAL: int - CERT_REQUIRED: int + CERT_NONE = 0 + CERT_OPTIONAL = 1 + CERT_REQUIRED = 2 CERT_NONE: VerifyMode CERT_OPTIONAL: VerifyMode CERT_REQUIRED: VerifyMode class VerifyFlags(enum.IntFlag): - VERIFY_DEFAULT: int - VERIFY_CRL_CHECK_LEAF: int - VERIFY_CRL_CHECK_CHAIN: int - VERIFY_X509_STRICT: int - VERIFY_X509_TRUSTED_FIRST: int + VERIFY_DEFAULT = 0 + VERIFY_CRL_CHECK_LEAF = 4 + VERIFY_CRL_CHECK_CHAIN = 12 + VERIFY_X509_STRICT = 32 + VERIFY_X509_TRUSTED_FIRST = 32768 if sys.version_info >= (3, 10): - VERIFY_ALLOW_PROXY_CERTS: int - VERIFY_X509_PARTIAL_CHAIN: int + VERIFY_ALLOW_PROXY_CERTS = 64 + VERIFY_X509_PARTIAL_CHAIN = 524288 VERIFY_DEFAULT: VerifyFlags VERIFY_CRL_CHECK_LEAF: VerifyFlags @@ -167,15 +167,15 @@ if sys.version_info >= (3, 10): VERIFY_X509_PARTIAL_CHAIN: VerifyFlags class _SSLMethod(enum.IntEnum): - PROTOCOL_SSLv23: int - PROTOCOL_SSLv2: int - PROTOCOL_SSLv3: int - PROTOCOL_TLSv1: int - PROTOCOL_TLSv1_1: int - PROTOCOL_TLSv1_2: int - PROTOCOL_TLS: int - PROTOCOL_TLS_CLIENT: int - PROTOCOL_TLS_SERVER: int + PROTOCOL_SSLv23 = 2 + PROTOCOL_SSLv2 = ... + PROTOCOL_SSLv3 = ... + PROTOCOL_TLSv1 = 3 + PROTOCOL_TLSv1_1 = 4 + PROTOCOL_TLSv1_2 = 5 + PROTOCOL_TLS = 2 + PROTOCOL_TLS_CLIENT = 16 + PROTOCOL_TLS_SERVER = 17 PROTOCOL_SSLv23: _SSLMethod PROTOCOL_SSLv2: _SSLMethod @@ -188,25 +188,25 @@ PROTOCOL_TLS_CLIENT: _SSLMethod PROTOCOL_TLS_SERVER: _SSLMethod class Options(enum.IntFlag): - OP_ALL: int - OP_NO_SSLv2: int - OP_NO_SSLv3: int - OP_NO_TLSv1: int - OP_NO_TLSv1_1: int - OP_NO_TLSv1_2: int - OP_NO_TLSv1_3: int - OP_CIPHER_SERVER_PREFERENCE: int - OP_SINGLE_DH_USE: int - OP_SINGLE_ECDH_USE: int - OP_NO_COMPRESSION: int - OP_NO_TICKET: int - OP_NO_RENEGOTIATION: int - OP_ENABLE_MIDDLEBOX_COMPAT: int + OP_ALL = 2147483728 + OP_NO_SSLv2 = 0 + OP_NO_SSLv3 = 33554432 + OP_NO_TLSv1 = 67108864 + OP_NO_TLSv1_1 = 268435456 + OP_NO_TLSv1_2 = 134217728 + OP_NO_TLSv1_3 = 536870912 + OP_CIPHER_SERVER_PREFERENCE = 4194304 + OP_SINGLE_DH_USE = 0 + OP_SINGLE_ECDH_USE = 0 + OP_NO_COMPRESSION = 131072 + OP_NO_TICKET = 16384 + OP_NO_RENEGOTIATION = 1073741824 + OP_ENABLE_MIDDLEBOX_COMPAT = 1048576 if sys.version_info >= (3, 12): - OP_LEGACY_SERVER_CONNECT: int - OP_ENABLE_KTLS: int + OP_LEGACY_SERVER_CONNECT = 4 + OP_ENABLE_KTLS = 8 if sys.version_info >= (3, 11) or sys.platform == "linux": - OP_IGNORE_UNEXPECTED_EOF: int + OP_IGNORE_UNEXPECTED_EOF = 128 OP_ALL: Options OP_NO_SSLv2: Options @@ -246,33 +246,33 @@ OPENSSL_VERSION_INFO: tuple[int, int, int, int, int] OPENSSL_VERSION_NUMBER: int class AlertDescription(enum.IntEnum): - ALERT_DESCRIPTION_ACCESS_DENIED: int - ALERT_DESCRIPTION_BAD_CERTIFICATE: int - ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE: int - ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE: int - ALERT_DESCRIPTION_BAD_RECORD_MAC: int - ALERT_DESCRIPTION_CERTIFICATE_EXPIRED: int - ALERT_DESCRIPTION_CERTIFICATE_REVOKED: int - ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN: int - ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE: int - ALERT_DESCRIPTION_CLOSE_NOTIFY: int - ALERT_DESCRIPTION_DECODE_ERROR: int - ALERT_DESCRIPTION_DECOMPRESSION_FAILURE: int - ALERT_DESCRIPTION_DECRYPT_ERROR: int - ALERT_DESCRIPTION_HANDSHAKE_FAILURE: int - ALERT_DESCRIPTION_ILLEGAL_PARAMETER: int - ALERT_DESCRIPTION_INSUFFICIENT_SECURITY: int - ALERT_DESCRIPTION_INTERNAL_ERROR: int - ALERT_DESCRIPTION_NO_RENEGOTIATION: int - ALERT_DESCRIPTION_PROTOCOL_VERSION: int - ALERT_DESCRIPTION_RECORD_OVERFLOW: int - ALERT_DESCRIPTION_UNEXPECTED_MESSAGE: int - ALERT_DESCRIPTION_UNKNOWN_CA: int - ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY: int - ALERT_DESCRIPTION_UNRECOGNIZED_NAME: int - ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE: int - ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION: int - ALERT_DESCRIPTION_USER_CANCELLED: int + ALERT_DESCRIPTION_ACCESS_DENIED = 49 + ALERT_DESCRIPTION_BAD_CERTIFICATE = 42 + ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE = 114 + ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE = 113 + ALERT_DESCRIPTION_BAD_RECORD_MAC = 20 + ALERT_DESCRIPTION_CERTIFICATE_EXPIRED = 45 + ALERT_DESCRIPTION_CERTIFICATE_REVOKED = 44 + ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN = 46 + ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE = 111 + ALERT_DESCRIPTION_CLOSE_NOTIFY = 0 + ALERT_DESCRIPTION_DECODE_ERROR = 50 + ALERT_DESCRIPTION_DECOMPRESSION_FAILURE = 30 + ALERT_DESCRIPTION_DECRYPT_ERROR = 51 + ALERT_DESCRIPTION_HANDSHAKE_FAILURE = 40 + ALERT_DESCRIPTION_ILLEGAL_PARAMETER = 47 + ALERT_DESCRIPTION_INSUFFICIENT_SECURITY = 71 + ALERT_DESCRIPTION_INTERNAL_ERROR = 80 + ALERT_DESCRIPTION_NO_RENEGOTIATION = 100 + ALERT_DESCRIPTION_PROTOCOL_VERSION = 70 + ALERT_DESCRIPTION_RECORD_OVERFLOW = 22 + ALERT_DESCRIPTION_UNEXPECTED_MESSAGE = 10 + ALERT_DESCRIPTION_UNKNOWN_CA = 48 + ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY = 115 + ALERT_DESCRIPTION_UNRECOGNIZED_NAME = 112 + ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE = 43 + ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION = 110 + ALERT_DESCRIPTION_USER_CANCELLED = 90 ALERT_DESCRIPTION_HANDSHAKE_FAILURE: AlertDescription ALERT_DESCRIPTION_INTERNAL_ERROR: AlertDescription @@ -316,8 +316,8 @@ class _ASN1Object(_ASN1ObjectBase): def fromname(cls, name: str) -> Self: ... class Purpose(_ASN1Object, enum.Enum): - SERVER_AUTH: _ASN1Object - CLIENT_AUTH: _ASN1Object + SERVER_AUTH = (129, "serverAuth", "TLS Web Server Authentication", "1.3.6.1.5.5.7.3.2") # pyright: ignore[reportCallIssue] + CLIENT_AUTH = (130, "clientAuth", "TLS Web Client Authentication", "1.3.6.1.5.5.7.3.1") # pyright: ignore[reportCallIssue] class SSLSocket(socket.socket): context: SSLContext @@ -371,13 +371,13 @@ class SSLSocket(socket.socket): def get_unverified_chain(self) -> list[bytes]: ... class TLSVersion(enum.IntEnum): - MINIMUM_SUPPORTED: int - MAXIMUM_SUPPORTED: int - SSLv3: int - TLSv1: int - TLSv1_1: int - TLSv1_2: int - TLSv1_3: int + MINIMUM_SUPPORTED = -2 + MAXIMUM_SUPPORTED = -1 + SSLv3 = 768 + TLSv1 = 769 + TLSv1_1 = 770 + TLSv1_2 = 771 + TLSv1_3 = 772 class SSLContext: check_hostname: bool @@ -506,15 +506,15 @@ class SSLSession: def __eq__(self, value: object, /) -> bool: ... class SSLErrorNumber(enum.IntEnum): - SSL_ERROR_EOF: int - SSL_ERROR_INVALID_ERROR_CODE: int - SSL_ERROR_SSL: int - SSL_ERROR_SYSCALL: int - SSL_ERROR_WANT_CONNECT: int - SSL_ERROR_WANT_READ: int - SSL_ERROR_WANT_WRITE: int - SSL_ERROR_WANT_X509_LOOKUP: int - SSL_ERROR_ZERO_RETURN: int + SSL_ERROR_EOF = 8 + SSL_ERROR_INVALID_ERROR_CODE = 10 + SSL_ERROR_SSL = 1 + SSL_ERROR_SYSCALL = 5 + SSL_ERROR_WANT_CONNECT = 7 + SSL_ERROR_WANT_READ = 2 + SSL_ERROR_WANT_WRITE = 3 + SSL_ERROR_WANT_X509_LOOKUP = 4 + SSL_ERROR_ZERO_RETURN = 6 SSL_ERROR_EOF: SSLErrorNumber # undocumented SSL_ERROR_INVALID_ERROR_CODE: SSLErrorNumber # undocumented diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index 80bc56ef53f3..d8ce17535eab 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -194,45 +194,45 @@ if sys.version_info >= (3, 11): serial: int class EventType(StrEnum): - Activate: str - ButtonPress: str + Activate = "36" + ButtonPress = "4" Button = ButtonPress - ButtonRelease: str - Circulate: str - CirculateRequest: str - ClientMessage: str - Colormap: str - Configure: str - ConfigureRequest: str - Create: str - Deactivate: str - Destroy: str - Enter: str - Expose: str - FocusIn: str - FocusOut: str - GraphicsExpose: str - Gravity: str - KeyPress: str - Key = KeyPress - KeyRelease: str - Keymap: str - Leave: str - Map: str - MapRequest: str - Mapping: str - Motion: str - MouseWheel: str - NoExpose: str - Property: str - Reparent: str - ResizeRequest: str - Selection: str - SelectionClear: str - SelectionRequest: str - Unmap: str - VirtualEvent: str - Visibility: str + ButtonRelease = "5" + Circulate = "26" + CirculateRequest = "27" + ClientMessage = "33" + Colormap = "32" + Configure = "22" + ConfigureRequest = "23" + Create = "16" + Deactivate = "37" + Destroy = "17" + Enter = "7" + Expose = "12" + FocusIn = "9" + FocusOut = "10" + GraphicsExpose = "13" + Gravity = "24" + KeyPress = "2" + Key = "2" + KeyRelease = "3" + Keymap = "11" + Leave = "8" + Map = "19" + MapRequest = "20" + Mapping = "34" + Motion = "6" + MouseWheel = "38" + NoExpose = "14" + Property = "28" + Reparent = "21" + ResizeRequest = "25" + Selection = "31" + SelectionClear = "29" + SelectionRequest = "30" + Unmap = "18" + VirtualEvent = "35" + Visibility = "15" _W = TypeVar("_W", bound=Misc) # Events considered covariant because you should never assign to event.widget. diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 580322b653b4..4b80397bdd7a 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -129,12 +129,6 @@ if sys.version_info >= (3, 11): if sys.version_info >= (3, 12): __all__ += ["TypeAliasType", "override"] -ContextManager = AbstractContextManager -AsyncContextManager = AbstractAsyncContextManager - -# This itself is only available during type checking -def type_check_only(func_or_cls: _F) -> _F: ... - Any = object() def final(f: _T) -> _T: ... @@ -183,12 +177,6 @@ class _SpecialForm: def __or__(self, other: Any) -> _SpecialForm: ... def __ror__(self, other: Any) -> _SpecialForm: ... -_F = TypeVar("_F", bound=Callable[..., Any]) -_P = _ParamSpec("_P") -_T = TypeVar("_T") - -def overload(func: _F) -> _F: ... - Union: _SpecialForm Generic: _SpecialForm # Protocol is only present in 3.8 and later, but mypy needs it unconditionally @@ -295,6 +283,10 @@ if sys.version_info >= (3, 10): else: def NewType(name: str, tp: Any) -> Any: ... +_F = TypeVar("_F", bound=Callable[..., Any]) +_P = _ParamSpec("_P") +_T = TypeVar("_T") + # These type variables are used by the container types. _S = TypeVar("_S") _KT = TypeVar("_KT") # Key type. @@ -304,9 +296,13 @@ _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]) +def overload(func: _F) -> _F: ... def no_type_check(arg: _F) -> _F: ... def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... +# This itself is only available during type checking +def type_check_only(func_or_cls: _F) -> _F: ... + # Type aliases and type constructors class _Alias: @@ -432,10 +428,22 @@ class Generator(Iterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra, _Return @property def gi_yieldfrom(self) -> Generator[Any, Any, Any] | None: ... +# NOTE: Technically we would like this to be able to accept a second parameter as well, just +# like it's counterpart in contextlib, however `typing._SpecialGenericAlias` enforces the +# correct number of arguments at runtime, so we would be hiding runtime errors. +@runtime_checkable +class ContextManager(AbstractContextManager[_T_co, bool | None], Protocol[_T_co]): ... + +# NOTE: Technically we would like this to be able to accept a second parameter as well, just +# like it's counterpart in contextlib, however `typing._SpecialGenericAlias` enforces the +# correct number of arguments at runtime, so we would be hiding runtime errors. +@runtime_checkable +class AsyncContextManager(AbstractAsyncContextManager[_T_co, bool | None], Protocol[_T_co]): ... + @runtime_checkable class Awaitable(Protocol[_T_co]): @abstractmethod - def __await__(self) -> Generator[Any, None, _T_co]: ... + def __await__(self) -> Generator[Any, Any, _T_co]: ... class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _ReturnT_co]): __name__: str @@ -445,7 +453,7 @@ class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _Retu @property def cr_code(self) -> CodeType: ... @property - def cr_frame(self) -> FrameType: ... + def cr_frame(self) -> FrameType | None: ... @property def cr_running(self) -> bool: ... @abstractmethod diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index 6e64e7a85560..dd61b83a658a 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -188,7 +188,7 @@ class _patch(Generic[_T]): # but that's impossible with the current type system. if sys.version_info >= (3, 10): def __init__( - self: _patch[_T], + self: _patch[_T], # pyright: ignore[reportInvalidTypeVarUse] #11780 getter: Callable[[], Any], attribute: str, new: _T, @@ -203,7 +203,7 @@ class _patch(Generic[_T]): ) -> None: ... else: def __init__( - self: _patch[_T], + self: _patch[_T], # pyright: ignore[reportInvalidTypeVarUse] #11780 getter: Callable[[], Any], attribute: str, new: _T, diff --git a/mypy/typeshed/stdlib/uuid.pyi b/mypy/typeshed/stdlib/uuid.pyi index e1ea424f9680..1be7a5ef009f 100644 --- a/mypy/typeshed/stdlib/uuid.pyi +++ b/mypy/typeshed/stdlib/uuid.pyi @@ -7,9 +7,9 @@ from typing_extensions import TypeAlias _FieldsType: TypeAlias = tuple[int, int, int, int, int, int] class SafeUUID(Enum): - safe: int - unsafe: int - unknown: None + safe = 0 + unsafe = -1 + unknown = None class UUID: def __init__( diff --git a/mypy/typeshed/stdlib/weakref.pyi b/mypy/typeshed/stdlib/weakref.pyi index 8f3ad0631c10..e345124237da 100644 --- a/mypy/typeshed/stdlib/weakref.pyi +++ b/mypy/typeshed/stdlib/weakref.pyi @@ -51,10 +51,17 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): @overload def __init__(self) -> None: ... @overload - def __init__(self: WeakValueDictionary[_KT, _VT], other: Mapping[_KT, _VT] | Iterable[tuple[_KT, _VT]], /) -> None: ... + def __init__( + self: WeakValueDictionary[_KT, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + other: Mapping[_KT, _VT] | Iterable[tuple[_KT, _VT]], + /, + ) -> None: ... @overload def __init__( - self: WeakValueDictionary[str, _VT], other: Mapping[str, _VT] | Iterable[tuple[str, _VT]] = (), /, **kwargs: _VT + self: WeakValueDictionary[str, _VT], # pyright: ignore[reportInvalidTypeVarUse] #11780 + other: Mapping[str, _VT] | Iterable[tuple[str, _VT]] = (), + /, + **kwargs: _VT, ) -> None: ... def __len__(self) -> int: ... def __getitem__(self, key: _KT) -> _VT: ... From fb31409b392c5533b25173705d62ed385ee39cfb Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Wed, 1 May 2024 03:15:32 -0700 Subject: [PATCH 165/172] Run more tests in parallel (#17185) At some point, Github Actions runners started having more cores: https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories --- .github/workflows/test.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4593e79e728c..98a737a78b3b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,39 +36,39 @@ jobs: arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" test_mypyc: true - name: Test suite with py38-windows-64 python: '3.8' arch: x64 os: windows-latest toxenv: py38 - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" - name: Test suite with py39-ubuntu python: '3.9' arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" - name: Test suite with py310-ubuntu python: '3.10' arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" - name: Test suite with py311-ubuntu, mypyc-compiled python: '3.11' arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" test_mypyc: true - name: Test suite with py312-ubuntu, mypyc-compiled python: '3.12' arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2" + tox_extra_args: "-n 4" test_mypyc: true - name: mypyc runtime tests with py39-macos @@ -77,13 +77,13 @@ jobs: # TODO: macos-13 is the last one to support Python 3.9, change it to macos-latest when updating the Python version os: macos-13 toxenv: py - tox_extra_args: "-n 2 mypyc/test/test_run.py mypyc/test/test_external.py" + tox_extra_args: "-n 3 mypyc/test/test_run.py mypyc/test/test_external.py" - name: mypyc runtime tests with py38-debug-build-ubuntu python: '3.8.17' arch: x64 os: ubuntu-latest toxenv: py - tox_extra_args: "-n 2 mypyc/test/test_run.py mypyc/test/test_external.py" + tox_extra_args: "-n 4 mypyc/test/test_run.py mypyc/test/test_external.py" debug_build: true - name: Type check our own code (py38-ubuntu) @@ -141,7 +141,9 @@ jobs: pip install -r test-requirements.txt CC=clang MYPYC_OPT_LEVEL=0 MYPY_USE_MYPYC=1 pip install -e . - name: Setup tox environment - run: tox run -e ${{ matrix.toxenv }} --notest + run: | + tox run -e ${{ matrix.toxenv }} --notest + python -c 'import os; print("os.cpu_count", os.cpu_count(), "os.sched_getaffinity", len(getattr(os, "sched_getaffinity", lambda *args: [])(0)))' - name: Test run: tox run -e ${{ matrix.toxenv }} --skip-pkg-install -- ${{ matrix.tox_extra_args }} @@ -190,4 +192,4 @@ jobs: - name: Setup tox environment run: tox run -e py --notest - name: Test - run: tox run -e py --skip-pkg-install -- -n 2 mypyc/test/ + run: tox run -e py --skip-pkg-install -- -n 4 mypyc/test/ From 35fbd2a852be2c47e8006429afe9b3ad4b1bfac2 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Sat, 11 May 2024 05:11:02 +0530 Subject: [PATCH 166/172] Add Error format support, and JSON output option (#11396) ### Description Resolves #10816 The changes this PR makes are relatively small. It currently: - Adds an `--output` option to mypy CLI - Adds a `ErrorFormatter` abstract base class, which can be subclassed to create new output formats - Adds a `MypyError` class that represents the external format of a mypy error. - Adds a check for `--output` being `'json'`, in which case the `JSONFormatter` is used to produce the reported output. #### Demo: ```console $ mypy mytest.py mytest.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int") mytest.py:3: error: Name "z" is not defined Found 2 errors in 1 file (checked 1 source file) $ mypy mytest.py --output=json {"file": "mytest.py", "line": 2, "column": 4, "severity": "error", "message": "Incompatible types in assignment (expression has type \"str\", variable has type \"int\")", "code": "assignment"} {"file": "mytest.py", "line": 3, "column": 4, "severity": "error", "message": "Name \"z\" is not defined", "code": "name-defined"} ``` --- A few notes regarding the changes: - I chose to re-use the intermediate `ErrorTuple`s created during error reporting, instead of using the more general `ErrorInfo` class, because a lot of machinery already exists in mypy for sorting and removing duplicate error reports, which produces `ErrorTuple`s at the end. The error sorting and duplicate removal logic could perhaps be separated out from the rest of the code, to be able to use `ErrorInfo` objects more freely. - `ErrorFormatter` doesn't really need to be an abstract class, but I think it would be better this way. If there's a different method that would be preferred, I'd be happy to know. - The `--output` CLI option is, most probably, not added in the correct place. Any help in how to do it properly would be appreciated, the mypy option parsing code seems very complex. - The ability to add custom output formats can be simply added by subclassing the `ErrorFormatter` class inside a mypy plugin, and adding a `name` field to the formatters. The mypy runtime can then check through the `__subclasses__` of the formatter and determine if such a formatter is present. The "checking for the `name` field" part of this code might be appropriate to add within this PR itself, instead of hard-coding `JSONFormatter`. Does that sound like a good idea? --------- Co-authored-by: Tushar Sadhwani <86737547+tushar-deepsource@users.noreply.github.com> Co-authored-by: Tushar Sadhwani --- mypy/build.py | 11 ++--- mypy/error_formatter.py | 37 +++++++++++++++++ mypy/errors.py | 75 ++++++++++++++++++++++++++++++---- mypy/main.py | 17 +++++++- mypy/options.py | 4 +- mypy/test/testoutput.py | 58 ++++++++++++++++++++++++++ mypy/util.py | 9 +++- test-data/unit/outputjson.test | 44 ++++++++++++++++++++ 8 files changed, 239 insertions(+), 16 deletions(-) create mode 100644 mypy/error_formatter.py create mode 100644 mypy/test/testoutput.py create mode 100644 test-data/unit/outputjson.test diff --git a/mypy/build.py b/mypy/build.py index 84c85e66bd49..3ceb473f0948 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -44,6 +44,7 @@ import mypy.semanal_main from mypy.checker import TypeChecker +from mypy.error_formatter import OUTPUT_CHOICES, ErrorFormatter from mypy.errors import CompileError, ErrorInfo, Errors, report_internal_error from mypy.graph_utils import prepare_sccs, strongly_connected_components, topsort from mypy.indirection import TypeIndirectionVisitor @@ -253,6 +254,7 @@ def _build( plugin=plugin, plugins_snapshot=snapshot, errors=errors, + error_formatter=None if options.output is None else OUTPUT_CHOICES.get(options.output), flush_errors=flush_errors, fscache=fscache, stdout=stdout, @@ -607,6 +609,7 @@ def __init__( fscache: FileSystemCache, stdout: TextIO, stderr: TextIO, + error_formatter: ErrorFormatter | None = None, ) -> None: self.stats: dict[str, Any] = {} # Values are ints or floats self.stdout = stdout @@ -615,6 +618,7 @@ def __init__( self.data_dir = data_dir self.errors = errors self.errors.set_ignore_prefix(ignore_prefix) + self.error_formatter = error_formatter self.search_paths = search_paths self.source_set = source_set self.reports = reports @@ -3463,11 +3467,8 @@ def process_stale_scc(graph: Graph, scc: list[str], manager: BuildManager) -> No for id in stale: graph[id].transitive_error = True for id in stale: - manager.flush_errors( - manager.errors.simplify_path(graph[id].xpath), - manager.errors.file_messages(graph[id].xpath), - False, - ) + errors = manager.errors.file_messages(graph[id].xpath, formatter=manager.error_formatter) + manager.flush_errors(manager.errors.simplify_path(graph[id].xpath), errors, False) graph[id].write_cache() graph[id].mark_as_rechecked() diff --git a/mypy/error_formatter.py b/mypy/error_formatter.py new file mode 100644 index 000000000000..ffc6b6747596 --- /dev/null +++ b/mypy/error_formatter.py @@ -0,0 +1,37 @@ +"""Defines the different custom formats in which mypy can output.""" + +import json +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mypy.errors import MypyError + + +class ErrorFormatter(ABC): + """Base class to define how errors are formatted before being printed.""" + + @abstractmethod + def report_error(self, error: "MypyError") -> str: + raise NotImplementedError + + +class JSONFormatter(ErrorFormatter): + """Formatter for basic JSON output format.""" + + def report_error(self, error: "MypyError") -> str: + """Prints out the errors as simple, static JSON lines.""" + return json.dumps( + { + "file": error.file_path, + "line": error.line, + "column": error.column, + "message": error.message, + "hint": None if len(error.hints) == 0 else "\n".join(error.hints), + "code": None if error.errorcode is None else error.errorcode.code, + "severity": error.severity, + } + ) + + +OUTPUT_CHOICES = {"json": JSONFormatter()} diff --git a/mypy/errors.py b/mypy/errors.py index eabe96a2dc73..7a937da39c20 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -8,6 +8,7 @@ from typing_extensions import Literal, TypeAlias as _TypeAlias from mypy import errorcodes as codes +from mypy.error_formatter import ErrorFormatter from mypy.errorcodes import IMPORT, IMPORT_NOT_FOUND, IMPORT_UNTYPED, ErrorCode, mypy_error_codes from mypy.message_registry import ErrorMessage from mypy.options import Options @@ -834,7 +835,7 @@ def raise_error(self, use_stdout: bool = True) -> NoReturn: ) def format_messages( - self, error_info: list[ErrorInfo], source_lines: list[str] | None + self, error_tuples: list[ErrorTuple], source_lines: list[str] | None ) -> list[str]: """Return a string list that represents the error messages. @@ -843,9 +844,6 @@ def format_messages( severity 'error'). """ a: list[str] = [] - error_info = [info for info in error_info if not info.hidden] - errors = self.render_messages(self.sort_messages(error_info)) - errors = self.remove_duplicates(errors) for ( file, line, @@ -856,7 +854,7 @@ def format_messages( message, allow_dups, code, - ) in errors: + ) in error_tuples: s = "" if file is not None: if self.options.show_column_numbers and line >= 0 and column >= 0: @@ -901,18 +899,28 @@ def format_messages( a.append(" " * (DEFAULT_SOURCE_OFFSET + column) + marker) return a - def file_messages(self, path: str) -> list[str]: + def file_messages(self, path: str, formatter: ErrorFormatter | None = None) -> list[str]: """Return a string list of new error messages from a given file. Use a form suitable for displaying to the user. """ if path not in self.error_info_map: return [] + + error_info = self.error_info_map[path] + error_info = [info for info in error_info if not info.hidden] + error_tuples = self.render_messages(self.sort_messages(error_info)) + error_tuples = self.remove_duplicates(error_tuples) + + if formatter is not None: + errors = create_errors(error_tuples) + return [formatter.report_error(err) for err in errors] + self.flushed_files.add(path) source_lines = None if self.options.pretty and self.read_source: source_lines = self.read_source(path) - return self.format_messages(self.error_info_map[path], source_lines) + return self.format_messages(error_tuples, source_lines) def new_messages(self) -> list[str]: """Return a string list of new error messages. @@ -1278,3 +1286,56 @@ def report_internal_error( # Exit. The caller has nothing more to say. # We use exit code 2 to signal that this is no ordinary error. raise SystemExit(2) + + +class MypyError: + def __init__( + self, + file_path: str, + line: int, + column: int, + message: str, + errorcode: ErrorCode | None, + severity: Literal["error", "note"], + ) -> None: + self.file_path = file_path + self.line = line + self.column = column + self.message = message + self.errorcode = errorcode + self.severity = severity + self.hints: list[str] = [] + + +# (file_path, line, column) +_ErrorLocation = Tuple[str, int, int] + + +def create_errors(error_tuples: list[ErrorTuple]) -> list[MypyError]: + errors: list[MypyError] = [] + latest_error_at_location: dict[_ErrorLocation, MypyError] = {} + + for error_tuple in error_tuples: + file_path, line, column, _, _, severity, message, _, errorcode = error_tuple + if file_path is None: + continue + + assert severity in ("error", "note") + if severity == "note": + error_location = (file_path, line, column) + error = latest_error_at_location.get(error_location) + if error is None: + # This is purely a note, with no error correlated to it + error = MypyError(file_path, line, column, message, errorcode, severity="note") + errors.append(error) + continue + + error.hints.append(message) + + else: + error = MypyError(file_path, line, column, message, errorcode, severity="error") + errors.append(error) + error_location = (file_path, line, column) + latest_error_at_location[error_location] = error + + return errors diff --git a/mypy/main.py b/mypy/main.py index c2df79d51e83..489ef8fd9a7b 100644 --- a/mypy/main.py +++ b/mypy/main.py @@ -18,6 +18,7 @@ parse_version, validate_package_allow_list, ) +from mypy.error_formatter import OUTPUT_CHOICES from mypy.errorcodes import error_codes from mypy.errors import CompileError from mypy.find_sources import InvalidSourceList, create_source_list @@ -72,7 +73,9 @@ def main( if clean_exit: options.fast_exit = False - formatter = util.FancyFormatter(stdout, stderr, options.hide_error_codes) + formatter = util.FancyFormatter( + stdout, stderr, options.hide_error_codes, hide_success=bool(options.output) + ) if options.install_types and (stdout is not sys.stdout or stderr is not sys.stderr): # Since --install-types performs user input, we want regular stdout and stderr. @@ -156,7 +159,9 @@ def run_build( stdout: TextIO, stderr: TextIO, ) -> tuple[build.BuildResult | None, list[str], bool]: - formatter = util.FancyFormatter(stdout, stderr, options.hide_error_codes) + formatter = util.FancyFormatter( + stdout, stderr, options.hide_error_codes, hide_success=bool(options.output) + ) messages = [] messages_by_file = defaultdict(list) @@ -525,6 +530,14 @@ def add_invertible_flag( stdout=stdout, ) + general_group.add_argument( + "-O", + "--output", + metavar="FORMAT", + help="Set a custom output format", + choices=OUTPUT_CHOICES, + ) + config_group = parser.add_argument_group( title="Config file", description="Use a config file instead of command line arguments. " diff --git a/mypy/options.py b/mypy/options.py index bf9c09f1bf4b..91639828801e 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -376,10 +376,12 @@ def __init__(self) -> None: self.disable_bytearray_promotion = False self.disable_memoryview_promotion = False - self.force_uppercase_builtins = False self.force_union_syntax = False + # Sets custom output format + self.output: str | None = None + def use_lowercase_names(self) -> bool: if self.python_version >= (3, 9): return not self.force_uppercase_builtins diff --git a/mypy/test/testoutput.py b/mypy/test/testoutput.py new file mode 100644 index 000000000000..41f6881658c8 --- /dev/null +++ b/mypy/test/testoutput.py @@ -0,0 +1,58 @@ +"""Test cases for `--output=json`. + +These cannot be run by the usual unit test runner because of the backslashes in +the output, which get normalized to forward slashes by the test suite on Windows. +""" + +from __future__ import annotations + +import os +import os.path + +from mypy import api +from mypy.defaults import PYTHON3_VERSION +from mypy.test.config import test_temp_dir +from mypy.test.data import DataDrivenTestCase, DataSuite + + +class OutputJSONsuite(DataSuite): + files = ["outputjson.test"] + + def run_case(self, testcase: DataDrivenTestCase) -> None: + test_output_json(testcase) + + +def test_output_json(testcase: DataDrivenTestCase) -> None: + """Runs Mypy in a subprocess, and ensures that `--output=json` works as intended.""" + mypy_cmdline = ["--output=json"] + mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}") + + # Write the program to a file. + program_path = os.path.join(test_temp_dir, "main") + mypy_cmdline.append(program_path) + with open(program_path, "w", encoding="utf8") as file: + for s in testcase.input: + file.write(f"{s}\n") + + output = [] + # Type check the program. + out, err, returncode = api.run(mypy_cmdline) + # split lines, remove newlines, and remove directory of test case + for line in (out + err).rstrip("\n").splitlines(): + if line.startswith(test_temp_dir + os.sep): + output.append(line[len(test_temp_dir + os.sep) :].rstrip("\r\n")) + else: + output.append(line.rstrip("\r\n")) + + if returncode > 1: + output.append("!!! Mypy crashed !!!") + + # Remove temp file. + os.remove(program_path) + + # JSON encodes every `\` character into `\\`, so we need to remove `\\` from windows paths + # and `/` from POSIX paths + json_os_separator = os.sep.replace("\\", "\\\\") + normalized_output = [line.replace(test_temp_dir + json_os_separator, "") for line in output] + + assert normalized_output == testcase.output diff --git a/mypy/util.py b/mypy/util.py index bbb5a8610f7f..4b1b918b92e6 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -563,8 +563,12 @@ class FancyFormatter: This currently only works on Linux and Mac. """ - def __init__(self, f_out: IO[str], f_err: IO[str], hide_error_codes: bool) -> None: + def __init__( + self, f_out: IO[str], f_err: IO[str], hide_error_codes: bool, hide_success: bool = False + ) -> None: self.hide_error_codes = hide_error_codes + self.hide_success = hide_success + # Check if we are in a human-facing terminal on a supported platform. if sys.platform not in ("linux", "darwin", "win32", "emscripten"): self.dummy_term = True @@ -793,6 +797,9 @@ def format_success(self, n_sources: int, use_color: bool = True) -> str: n_sources is total number of files passed directly on command line, i.e. excluding stubs and followed imports. """ + if self.hide_success: + return "" + msg = f"Success: no issues found in {n_sources} source file{plural_s(n_sources)}" if not use_color: return msg diff --git a/test-data/unit/outputjson.test b/test-data/unit/outputjson.test new file mode 100644 index 000000000000..43649b7b781d --- /dev/null +++ b/test-data/unit/outputjson.test @@ -0,0 +1,44 @@ +-- Test cases for `--output=json`. +-- These cannot be run by the usual unit test runner because of the backslashes +-- in the output, which get normalized to forward slashes by the test suite on +-- Windows. + +[case testOutputJsonNoIssues] +# flags: --output=json +def foo() -> None: + pass + +foo() +[out] + +[case testOutputJsonSimple] +# flags: --output=json +def foo() -> None: + pass + +foo(1) +[out] +{"file": "main", "line": 5, "column": 0, "message": "Too many arguments for \"foo\"", "hint": null, "code": "call-arg", "severity": "error"} + +[case testOutputJsonWithHint] +# flags: --output=json +from typing import Optional, overload + +@overload +def foo() -> None: ... +@overload +def foo(x: int) -> None: ... + +def foo(x: Optional[int] = None) -> None: + ... + +reveal_type(foo) + +foo('42') + +def bar() -> None: ... +bar('42') +[out] +{"file": "main", "line": 12, "column": 12, "message": "Revealed type is \"Overload(def (), def (x: builtins.int))\"", "hint": null, "code": "misc", "severity": "note"} +{"file": "main", "line": 14, "column": 0, "message": "No overload variant of \"foo\" matches argument type \"str\"", "hint": "Possible overload variants:\n def foo() -> None\n def foo(x: int) -> None", "code": "call-overload", "severity": "error"} +{"file": "main", "line": 17, "column": 0, "message": "Too many arguments for \"bar\"", "hint": null, "code": "call-arg", "severity": "error"} From b4f98698d83d2601b97cbead4503066e492bf8a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 May 2024 21:11:50 -0400 Subject: [PATCH 167/172] Sync typeshed (#17246) Source commit: https://github.com/python/typeshed/commit/a9d7e861f7a46ae7acd56569326adef302e10f29 --- .../test_cases/asyncio/check_coroutines.py | 25 ++ .../@tests/test_cases/asyncio/check_gather.py | 38 ++ .../@tests/test_cases/asyncio/check_task.py | 28 ++ .../test_cases/builtins/check_dict-py39.py | 67 +++ .../@tests/test_cases/builtins/check_dict.py | 58 +++ .../builtins/check_exception_group-py311.py | 323 ++++++++++++++ .../test_cases/builtins/check_iteration.py | 16 + .../@tests/test_cases/builtins/check_list.py | 21 + .../test_cases/builtins/check_object.py | 13 + .../@tests/test_cases/builtins/check_pow.py | 91 ++++ .../test_cases/builtins/check_reversed.py | 34 ++ .../@tests/test_cases/builtins/check_round.py | 68 +++ .../@tests/test_cases/builtins/check_sum.py | 55 +++ .../@tests/test_cases/builtins/check_tuple.py | 13 + .../stdlib/@tests/test_cases/check_codecs.py | 13 + .../test_cases/check_concurrent_futures.py | 30 ++ .../@tests/test_cases/check_contextlib.py | 20 + .../@tests/test_cases/check_dataclasses.py | 101 +++++ .../stdlib/@tests/test_cases/check_enum.py | 38 ++ .../@tests/test_cases/check_functools.py | 67 +++ .../@tests/test_cases/check_importlib.py | 47 ++ .../test_cases/check_importlib_metadata.py | 33 ++ .../stdlib/@tests/test_cases/check_io.py | 6 + .../stdlib/@tests/test_cases/check_logging.py | 30 ++ .../test_cases/check_multiprocessing.py | 14 + .../stdlib/@tests/test_cases/check_pathlib.py | 20 + .../stdlib/@tests/test_cases/check_re.py | 26 ++ .../stdlib/@tests/test_cases/check_sqlite3.py | 26 ++ .../stdlib/@tests/test_cases/check_tarfile.py | 13 + .../@tests/test_cases/check_tempfile.py | 31 ++ .../@tests/test_cases/check_threading.py | 14 + .../stdlib/@tests/test_cases/check_tkinter.py | 30 ++ .../@tests/test_cases/check_unittest.py | 173 ++++++++ .../stdlib/@tests/test_cases/check_xml.py | 35 ++ .../collections/check_defaultdict-py39.py | 69 +++ .../@tests/test_cases/email/check_message.py | 6 + .../itertools/check_itertools_recipes.py | 410 ++++++++++++++++++ .../test_cases/typing/check_MutableMapping.py | 18 + .../@tests/test_cases/typing/check_all.py | 14 + .../typing/check_regression_issue_9296.py | 16 + .../test_cases/typing/check_typing_io.py | 21 + mypy/typeshed/stdlib/_typeshed/importlib.pyi | 18 + mypy/typeshed/stdlib/ast.pyi | 230 +++++++--- mypy/typeshed/stdlib/builtins.pyi | 8 +- mypy/typeshed/stdlib/dbm/__init__.pyi | 11 +- mypy/typeshed/stdlib/dbm/dumb.pyi | 8 +- mypy/typeshed/stdlib/dbm/gnu.pyi | 7 +- mypy/typeshed/stdlib/dbm/ndbm.pyi | 7 +- mypy/typeshed/stdlib/importlib/abc.pyi | 4 +- mypy/typeshed/stdlib/importlib/util.pyi | 5 +- mypy/typeshed/stdlib/logging/__init__.pyi | 2 +- mypy/typeshed/stdlib/pathlib.pyi | 8 +- mypy/typeshed/stdlib/pkgutil.pyi | 12 +- mypy/typeshed/stdlib/shelve.pyi | 17 +- mypy/typeshed/stdlib/socket.pyi | 13 + mypy/typeshed/stdlib/sys/__init__.pyi | 13 +- mypy/typeshed/stdlib/tempfile.pyi | 6 +- mypy/typeshed/stdlib/types.pyi | 29 +- mypy/typeshed/stdlib/typing.pyi | 43 +- 59 files changed, 2469 insertions(+), 143 deletions(-) create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_enum.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_functools.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_io.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_logging.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_re.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_threading.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_xml.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py create mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py create mode 100644 mypy/typeshed/stdlib/_typeshed/importlib.pyi diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py new file mode 100644 index 000000000000..160bd896469e --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from asyncio import iscoroutinefunction +from collections.abc import Awaitable, Callable, Coroutine +from typing import Any +from typing_extensions import assert_type + + +def test_iscoroutinefunction( + x: Callable[[str, int], Coroutine[str, int, bytes]], + y: Callable[[str, int], Awaitable[bytes]], + z: Callable[[str, int], str | Awaitable[bytes]], + xx: object, +) -> None: + if iscoroutinefunction(x): + assert_type(x, Callable[[str, int], Coroutine[str, int, bytes]]) + + if iscoroutinefunction(y): + assert_type(y, Callable[[str, int], Coroutine[Any, Any, bytes]]) + + if iscoroutinefunction(z): + assert_type(z, Callable[[str, int], Coroutine[Any, Any, Any]]) + + if iscoroutinefunction(xx): + assert_type(xx, Callable[..., Coroutine[Any, Any, Any]]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py new file mode 100644 index 000000000000..02a01e39731a --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import asyncio +from typing import Awaitable, List, Tuple, Union +from typing_extensions import assert_type + + +async def coro1() -> int: + return 42 + + +async def coro2() -> str: + return "spam" + + +async def test_gather(awaitable1: Awaitable[int], awaitable2: Awaitable[str]) -> None: + a = await asyncio.gather(awaitable1) + assert_type(a, Tuple[int]) + + b = await asyncio.gather(awaitable1, awaitable2, return_exceptions=True) + assert_type(b, Tuple[Union[int, BaseException], Union[str, BaseException]]) + + c = await asyncio.gather(awaitable1, awaitable2, awaitable1, awaitable1, awaitable1, awaitable1) + assert_type(c, Tuple[int, str, int, int, int, int]) + + d = await asyncio.gather(awaitable1, awaitable1, awaitable1, awaitable1, awaitable1, awaitable1, awaitable1) + assert_type(d, List[int]) + + awaitables_list: list[Awaitable[int]] = [awaitable1] + e = await asyncio.gather(*awaitables_list) + assert_type(e, List[int]) + + # this case isn't reliable between typecheckers, no one would ever call it with no args anyway + # f = await asyncio.gather() + # assert_type(f, list[Any]) + + +asyncio.run(test_gather(coro1(), coro2())) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py new file mode 100644 index 000000000000..69bcf8f782aa --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +import asyncio + + +class Waiter: + def __init__(self) -> None: + self.tasks: list[asyncio.Task[object]] = [] + + def add(self, t: asyncio.Task[object]) -> None: + self.tasks.append(t) + + async def join(self) -> None: + await asyncio.wait(self.tasks) + + +async def foo() -> int: + return 42 + + +async def main() -> None: + # asyncio.Task is covariant in its type argument, which is unusual since its parent class + # asyncio.Future is invariant in its type argument. This is only sound because asyncio.Task + # is not actually Liskov substitutable for asyncio.Future: it does not implement set_result. + w = Waiter() + t: asyncio.Task[int] = asyncio.create_task(foo()) + w.add(t) + await w.join() diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py new file mode 100644 index 000000000000..d707cfed222e --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py @@ -0,0 +1,67 @@ +""" +Tests for `dict.__(r)or__`. + +`dict.__or__` and `dict.__ror__` were only added in py39, +hence why these are in a separate file to the other test cases for `dict`. +""" + +from __future__ import annotations + +import os +import sys +from typing import Mapping, TypeVar, Union +from typing_extensions import Self, assert_type + +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + +if sys.version_info >= (3, 9): + + class CustomDictSubclass(dict[_KT, _VT]): + pass + + class CustomMappingWithDunderOr(Mapping[_KT, _VT]): + def __or__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: + return {} + + def __ror__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: + return {} + + def __ior__(self, other: Mapping[_KT, _VT]) -> Self: + return self + + def test_dict_dot_or( + a: dict[int, int], + b: CustomDictSubclass[int, int], + c: dict[str, str], + d: Mapping[int, int], + e: CustomMappingWithDunderOr[str, str], + ) -> None: + # dict.__(r)or__ always returns a dict, even if called on a subclass of dict: + assert_type(a | b, dict[int, int]) + assert_type(b | a, dict[int, int]) + + assert_type(a | c, dict[Union[int, str], Union[int, str]]) + + # arbitrary mappings are not accepted by `dict.__or__`; + # it has to be a subclass of `dict` + a | d # type: ignore + + # but Mappings such as `os._Environ` or `CustomMappingWithDunderOr`, + # which define `__ror__` methods that accept `dict`, are fine: + assert_type(a | os.environ, dict[Union[str, int], Union[str, int]]) + assert_type(os.environ | a, dict[Union[str, int], Union[str, int]]) + + assert_type(c | os.environ, dict[str, str]) + assert_type(c | e, dict[str, str]) + + assert_type(os.environ | c, dict[str, str]) + assert_type(e | c, dict[str, str]) + + e |= c + e |= a # type: ignore + + # TODO: this test passes mypy, but fails pyright for some reason: + # c |= e + + c |= a # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py new file mode 100644 index 000000000000..aa920d045cbc --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from typing import Dict, Generic, Iterable, TypeVar +from typing_extensions import assert_type + +# These do follow `__init__` overloads order: +# mypy and pyright have different opinions about this one: +# mypy raises: 'Need type annotation for "bad"' +# pyright is fine with it. +# bad = dict() +good: dict[str, str] = dict() +assert_type(good, Dict[str, str]) + +assert_type(dict(arg=1), Dict[str, int]) + +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + + +class KeysAndGetItem(Generic[_KT, _VT]): + data: dict[_KT, _VT] + + def __init__(self, data: dict[_KT, _VT]) -> None: + self.data = data + + def keys(self) -> Iterable[_KT]: + return self.data.keys() + + def __getitem__(self, __k: _KT) -> _VT: + return self.data[__k] + + +kt1: KeysAndGetItem[int, str] = KeysAndGetItem({0: ""}) +assert_type(dict(kt1), Dict[int, str]) +dict(kt1, arg="a") # type: ignore + +kt2: KeysAndGetItem[str, int] = KeysAndGetItem({"": 0}) +assert_type(dict(kt2, arg=1), Dict[str, int]) + + +def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str]: + return dict(x) + + +i1: Iterable[tuple[int, str]] = [(1, "a"), (2, "b")] +test_iterable_tuple_overload(i1) +dict(i1, arg="a") # type: ignore + +i2: Iterable[tuple[str, int]] = [("a", 1), ("b", 2)] +assert_type(dict(i2, arg=1), Dict[str, int]) + +i3: Iterable[str] = ["a.b"] +i4: Iterable[bytes] = [b"a.b"] +assert_type(dict(string.split(".") for string in i3), Dict[str, str]) +assert_type(dict(string.split(b".") for string in i4), Dict[bytes, bytes]) + +dict(["foo", "bar", "baz"]) # type: ignore +dict([b"foo", b"bar", b"baz"]) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py new file mode 100644 index 000000000000..e53cd12288a4 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py @@ -0,0 +1,323 @@ +from __future__ import annotations + +import sys +from typing import TypeVar +from typing_extensions import assert_type + +if sys.version_info >= (3, 11): + # This can be removed later, but right now Flake8 does not know + # about these two classes: + from builtins import BaseExceptionGroup, ExceptionGroup + + # BaseExceptionGroup + # ================== + # `BaseExceptionGroup` can work with `BaseException`: + beg = BaseExceptionGroup("x", [SystemExit(), SystemExit()]) + assert_type(beg, BaseExceptionGroup[SystemExit]) + assert_type(beg.exceptions, tuple[SystemExit | BaseExceptionGroup[SystemExit], ...]) + + # Covariance works: + _beg1: BaseExceptionGroup[BaseException] = beg + + # `BaseExceptionGroup` can work with `Exception`: + beg2 = BaseExceptionGroup("x", [ValueError()]) + # FIXME: this is not right, runtime returns `ExceptionGroup` instance instead, + # but I am unable to represent this with types right now. + assert_type(beg2, BaseExceptionGroup[ValueError]) + + # .subgroup() + # ----------- + + assert_type(beg.subgroup(KeyboardInterrupt), BaseExceptionGroup[KeyboardInterrupt] | None) + assert_type(beg.subgroup((KeyboardInterrupt,)), BaseExceptionGroup[KeyboardInterrupt] | None) + + def is_base_exc(exc: BaseException) -> bool: + return isinstance(exc, BaseException) + + def is_specific(exc: SystemExit | BaseExceptionGroup[SystemExit]) -> bool: + return isinstance(exc, SystemExit) + + # This one does not have `BaseExceptionGroup` part, + # this is why we treat as an error. + def is_system_exit(exc: SystemExit) -> bool: + return isinstance(exc, SystemExit) + + def unrelated_subgroup(exc: KeyboardInterrupt) -> bool: + return False + + assert_type(beg.subgroup(is_base_exc), BaseExceptionGroup[SystemExit] | None) + assert_type(beg.subgroup(is_specific), BaseExceptionGroup[SystemExit] | None) + beg.subgroup(is_system_exit) # type: ignore + beg.subgroup(unrelated_subgroup) # type: ignore + + # `Exception`` subgroup returns `ExceptionGroup`: + assert_type(beg.subgroup(ValueError), ExceptionGroup[ValueError] | None) + assert_type(beg.subgroup((ValueError,)), ExceptionGroup[ValueError] | None) + + # Callable are harder, we don't support cast to `ExceptionGroup` here. + # Because callables might return `True` the first time. And `BaseExceptionGroup` + # will stick, no matter what arguments are. + + def is_exception(exc: Exception) -> bool: + return isinstance(exc, Exception) + + def is_exception_or_beg(exc: Exception | BaseExceptionGroup[SystemExit]) -> bool: + return isinstance(exc, Exception) + + # This is an error because of the `Exception` argument type, + # while `SystemExit` is needed instead. + beg.subgroup(is_exception_or_beg) # type: ignore + + # This is an error, because `BaseExceptionGroup` is not an `Exception` + # subclass. It is required. + beg.subgroup(is_exception) # type: ignore + + # .split() + # -------- + + assert_type( + beg.split(KeyboardInterrupt), tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None] + ) + assert_type( + beg.split((KeyboardInterrupt,)), + tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None], + ) + assert_type( + beg.split(ValueError), # there are no `ValueError` items in there, but anyway + tuple[ExceptionGroup[ValueError] | None, BaseExceptionGroup[SystemExit] | None], + ) + + excs_to_split: list[ValueError | KeyError | SystemExit] = [ValueError(), KeyError(), SystemExit()] + to_split = BaseExceptionGroup("x", excs_to_split) + assert_type(to_split, BaseExceptionGroup[ValueError | KeyError | SystemExit]) + + # Ideally the first part should be `ExceptionGroup[ValueError]` (done) + # and the second part should be `BaseExceptionGroup[KeyError | SystemExit]`, + # but we cannot subtract type from a union. + # We also cannot change `BaseExceptionGroup` to `ExceptionGroup` even if needed + # in the second part here because of that. + assert_type( + to_split.split(ValueError), + tuple[ExceptionGroup[ValueError] | None, BaseExceptionGroup[ValueError | KeyError | SystemExit] | None], + ) + + def split_callable1(exc: ValueError | KeyError | SystemExit | BaseExceptionGroup[ValueError | KeyError | SystemExit]) -> bool: + return True + + assert_type( + to_split.split(split_callable1), # Concrete type is ok + tuple[ + BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, + BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, + ], + ) + assert_type( + to_split.split(is_base_exc), # Base class is ok + tuple[ + BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, + BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, + ], + ) + # `Exception` cannot be used: `BaseExceptionGroup` is not a subtype of it. + to_split.split(is_exception) # type: ignore + + # .derive() + # --------- + + assert_type(beg.derive([ValueError()]), ExceptionGroup[ValueError]) + assert_type(beg.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) + + # ExceptionGroup + # ============== + + # `ExceptionGroup` can work with `Exception`: + excs: list[ValueError | KeyError] = [ValueError(), KeyError()] + eg = ExceptionGroup("x", excs) + assert_type(eg, ExceptionGroup[ValueError | KeyError]) + assert_type(eg.exceptions, tuple[ValueError | KeyError | ExceptionGroup[ValueError | KeyError], ...]) + + # Covariance works: + _eg1: ExceptionGroup[Exception] = eg + + # `ExceptionGroup` cannot work with `BaseException`: + ExceptionGroup("x", [SystemExit()]) # type: ignore + + # .subgroup() + # ----------- + + # Our decision is to ban cases like:: + # + # >>> eg = ExceptionGroup('x', [ValueError()]) + # >>> eg.subgroup(BaseException) + # ExceptionGroup('e', [ValueError()]) + # + # are possible in runtime. + # We do it because, it does not make sense for all other base exception types. + # Supporting just `BaseException` looks like an overkill. + eg.subgroup(BaseException) # type: ignore + eg.subgroup((KeyboardInterrupt, SystemExit)) # type: ignore + + assert_type(eg.subgroup(Exception), ExceptionGroup[Exception] | None) + assert_type(eg.subgroup(ValueError), ExceptionGroup[ValueError] | None) + assert_type(eg.subgroup((ValueError,)), ExceptionGroup[ValueError] | None) + + def subgroup_eg1(exc: ValueError | KeyError | ExceptionGroup[ValueError | KeyError]) -> bool: + return True + + def subgroup_eg2(exc: ValueError | KeyError) -> bool: + return True + + assert_type(eg.subgroup(subgroup_eg1), ExceptionGroup[ValueError | KeyError] | None) + assert_type(eg.subgroup(is_exception), ExceptionGroup[ValueError | KeyError] | None) + assert_type(eg.subgroup(is_base_exc), ExceptionGroup[ValueError | KeyError] | None) + assert_type(eg.subgroup(is_base_exc), ExceptionGroup[ValueError | KeyError] | None) + + # Does not have `ExceptionGroup` part: + eg.subgroup(subgroup_eg2) # type: ignore + + # .split() + # -------- + + assert_type(eg.split(TypeError), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError | KeyError] | None]) + assert_type(eg.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError | KeyError] | None]) + assert_type( + eg.split(is_exception), tuple[ExceptionGroup[ValueError | KeyError] | None, ExceptionGroup[ValueError | KeyError] | None] + ) + assert_type( + eg.split(is_base_exc), + # is not converted, because `ExceptionGroup` cannot have + # direct `BaseException` subclasses inside. + tuple[ExceptionGroup[ValueError | KeyError] | None, ExceptionGroup[ValueError | KeyError] | None], + ) + + # It does not include `ExceptionGroup` itself, so it will fail: + def value_or_key_error(exc: ValueError | KeyError) -> bool: + return isinstance(exc, (ValueError, KeyError)) + + eg.split(value_or_key_error) # type: ignore + + # `ExceptionGroup` cannot have direct `BaseException` subclasses inside. + eg.split(BaseException) # type: ignore + eg.split((SystemExit, GeneratorExit)) # type: ignore + + # .derive() + # --------- + + assert_type(eg.derive([ValueError()]), ExceptionGroup[ValueError]) + assert_type(eg.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) + + # BaseExceptionGroup Custom Subclass + # ================================== + # In some cases `Self` type can be preserved in runtime, + # but it is impossible to express. That's why we always fallback to + # `BaseExceptionGroup` and `ExceptionGroup`. + + _BE = TypeVar("_BE", bound=BaseException) + + class CustomBaseGroup(BaseExceptionGroup[_BE]): ... + + cb1 = CustomBaseGroup("x", [SystemExit()]) + assert_type(cb1, CustomBaseGroup[SystemExit]) + cb2 = CustomBaseGroup("x", [ValueError()]) + assert_type(cb2, CustomBaseGroup[ValueError]) + + # .subgroup() + # ----------- + + assert_type(cb1.subgroup(KeyboardInterrupt), BaseExceptionGroup[KeyboardInterrupt] | None) + assert_type(cb2.subgroup((KeyboardInterrupt,)), BaseExceptionGroup[KeyboardInterrupt] | None) + + assert_type(cb1.subgroup(ValueError), ExceptionGroup[ValueError] | None) + assert_type(cb2.subgroup((KeyError,)), ExceptionGroup[KeyError] | None) + + def cb_subgroup1(exc: SystemExit | CustomBaseGroup[SystemExit]) -> bool: + return True + + def cb_subgroup2(exc: ValueError | CustomBaseGroup[ValueError]) -> bool: + return True + + assert_type(cb1.subgroup(cb_subgroup1), BaseExceptionGroup[SystemExit] | None) + assert_type(cb2.subgroup(cb_subgroup2), BaseExceptionGroup[ValueError] | None) + cb1.subgroup(cb_subgroup2) # type: ignore + cb2.subgroup(cb_subgroup1) # type: ignore + + # .split() + # -------- + + assert_type( + cb1.split(KeyboardInterrupt), tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None] + ) + assert_type(cb1.split(TypeError), tuple[ExceptionGroup[TypeError] | None, BaseExceptionGroup[SystemExit] | None]) + assert_type(cb2.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, BaseExceptionGroup[ValueError] | None]) + + def cb_split1(exc: SystemExit | CustomBaseGroup[SystemExit]) -> bool: + return True + + def cb_split2(exc: ValueError | CustomBaseGroup[ValueError]) -> bool: + return True + + assert_type(cb1.split(cb_split1), tuple[BaseExceptionGroup[SystemExit] | None, BaseExceptionGroup[SystemExit] | None]) + assert_type(cb2.split(cb_split2), tuple[BaseExceptionGroup[ValueError] | None, BaseExceptionGroup[ValueError] | None]) + cb1.split(cb_split2) # type: ignore + cb2.split(cb_split1) # type: ignore + + # .derive() + # --------- + + # Note, that `Self` type is not preserved in runtime. + assert_type(cb1.derive([ValueError()]), ExceptionGroup[ValueError]) + assert_type(cb1.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) + assert_type(cb2.derive([ValueError()]), ExceptionGroup[ValueError]) + assert_type(cb2.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) + + # ExceptionGroup Custom Subclass + # ============================== + + _E = TypeVar("_E", bound=Exception) + + class CustomGroup(ExceptionGroup[_E]): ... + + CustomGroup("x", [SystemExit()]) # type: ignore + cg1 = CustomGroup("x", [ValueError()]) + assert_type(cg1, CustomGroup[ValueError]) + + # .subgroup() + # ----------- + + cg1.subgroup(BaseException) # type: ignore + cg1.subgroup((KeyboardInterrupt, SystemExit)) # type: ignore + + assert_type(cg1.subgroup(ValueError), ExceptionGroup[ValueError] | None) + assert_type(cg1.subgroup((KeyError,)), ExceptionGroup[KeyError] | None) + + def cg_subgroup1(exc: ValueError | CustomGroup[ValueError]) -> bool: + return True + + def cg_subgroup2(exc: ValueError) -> bool: + return True + + assert_type(cg1.subgroup(cg_subgroup1), ExceptionGroup[ValueError] | None) + cg1.subgroup(cb_subgroup2) # type: ignore + + # .split() + # -------- + + assert_type(cg1.split(TypeError), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError] | None]) + assert_type(cg1.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError] | None]) + cg1.split(BaseException) # type: ignore + + def cg_split1(exc: ValueError | CustomGroup[ValueError]) -> bool: + return True + + def cg_split2(exc: ValueError) -> bool: + return True + + assert_type(cg1.split(cg_split1), tuple[ExceptionGroup[ValueError] | None, ExceptionGroup[ValueError] | None]) + cg1.split(cg_split2) # type: ignore + + # .derive() + # --------- + + # Note, that `Self` type is not preserved in runtime. + assert_type(cg1.derive([ValueError()]), ExceptionGroup[ValueError]) + assert_type(cg1.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py new file mode 100644 index 000000000000..3d609635377e --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +from typing import Iterator +from typing_extensions import assert_type + + +class OldStyleIter: + def __getitem__(self, index: int) -> str: + return str(index) + + +for x in iter(OldStyleIter()): + assert_type(x, str) + +assert_type(iter(OldStyleIter()), Iterator[str]) +assert_type(next(iter(OldStyleIter())), str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py new file mode 100644 index 000000000000..4113f5c66182 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from typing import List, Union +from typing_extensions import assert_type + + +# list.__add__ example from #8292 +class Foo: + def asd(self) -> int: + return 1 + + +class Bar: + def asd(self) -> int: + return 2 + + +combined = [Foo()] + [Bar()] +assert_type(combined, List[Union[Foo, Bar]]) +for item in combined: + assert_type(item.asd(), int) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py new file mode 100644 index 000000000000..60df1143f727 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import Any + + +# The following should pass without error (see #6661): +class Diagnostic: + def __reduce__(self) -> str | tuple[Any, ...]: + res = super().__reduce__() + if isinstance(res, tuple) and len(res) >= 3: + res[2]["_info"] = 42 + + return res diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py new file mode 100644 index 000000000000..1f38710d6bea --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +from decimal import Decimal +from fractions import Fraction +from typing import Any, Literal +from typing_extensions import assert_type + +# See #7163 +assert_type(pow(1, 0), Literal[1]) +assert_type(1**0, Literal[1]) +assert_type(pow(1, 0, None), Literal[1]) + +# TODO: We don't have a good way of expressing the fact +# that passing 0 for the third argument will lead to an exception being raised +# (see discussion in #8566) +# +# assert_type(pow(2, 4, 0), NoReturn) + +assert_type(pow(2, 4), int) +assert_type(2**4, int) +assert_type(pow(4, 6, None), int) + +assert_type(pow(5, -7), float) +assert_type(5**-7, float) + +assert_type(pow(2, 4, 5), int) # pow(, , ) +assert_type(pow(2, 35, 3), int) # pow(, , ) + +assert_type(pow(2, 8.5), float) +assert_type(2**8.6, float) +assert_type(pow(2, 8.6, None), float) + +# TODO: Why does this pass pyright but not mypy?? +# assert_type((-2) ** 0.5, complex) + +assert_type(pow((-5), 8.42, None), complex) + +assert_type(pow(4.6, 8), float) +assert_type(4.6**8, float) +assert_type(pow(5.1, 4, None), float) + +assert_type(pow(complex(6), 6.2), complex) +assert_type(complex(6) ** 6.2, complex) +assert_type(pow(complex(9), 7.3, None), complex) + +assert_type(pow(Fraction(), 4, None), Fraction) +assert_type(Fraction() ** 4, Fraction) + +assert_type(pow(Fraction(3, 7), complex(1, 8)), complex) +assert_type(Fraction(3, 7) ** complex(1, 8), complex) + +assert_type(pow(complex(4, -8), Fraction(2, 3)), complex) +assert_type(complex(4, -8) ** Fraction(2, 3), complex) + +assert_type(pow(Decimal("1.0"), Decimal("1.6")), Decimal) +assert_type(Decimal("1.0") ** Decimal("1.6"), Decimal) + +assert_type(pow(Decimal("1.0"), Decimal("1.0"), Decimal("1.0")), Decimal) +assert_type(pow(Decimal("4.6"), 7, None), Decimal) +assert_type(Decimal("4.6") ** 7, Decimal) + +# These would ideally be more precise, but `Any` is acceptable +# They have to be `Any` due to the fact that type-checkers can't distinguish +# between positive and negative numbers for the second argument to `pow()` +# +# int for positive 2nd-arg, float otherwise +assert_type(pow(4, 65), Any) +assert_type(pow(2, -45), Any) +assert_type(pow(3, 57, None), Any) +assert_type(pow(67, 0.98, None), Any) +assert_type(87**7.32, Any) +# pow(, ) -> float +# pow(, ) -> complex +assert_type(pow(4.7, 7.4), Any) +assert_type(pow(-9.8, 8.3), Any) +assert_type(pow(-9.3, -88.2), Any) +assert_type(pow(8.2, -9.8), Any) +assert_type(pow(4.7, 9.2, None), Any) +# See #7046 -- float for a positive 1st arg, complex otherwise +assert_type((-95) ** 8.42, Any) + +# All of the following cases should fail a type-checker. +pow(1.9, 4, 6) # type: ignore +pow(4, 7, 4.32) # type: ignore +pow(6.2, 5.9, 73) # type: ignore +pow(complex(6), 6.2, 7) # type: ignore +pow(Fraction(), 5, 8) # type: ignore +Decimal("8.7") ** 3.14 # type: ignore + +# TODO: This fails at runtime, but currently passes mypy and pyright: +pow(Decimal("8.5"), 3.21) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py new file mode 100644 index 000000000000..2a43a57deb4e --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from collections.abc import Iterator +from typing import Generic, TypeVar +from typing_extensions import assert_type + +x: list[int] = [] +assert_type(list(reversed(x)), "list[int]") + + +class MyReversible: + def __iter__(self) -> Iterator[str]: + yield "blah" + + def __reversed__(self) -> Iterator[str]: + yield "blah" + + +assert_type(list(reversed(MyReversible())), "list[str]") + + +_T = TypeVar("_T") + + +class MyLenAndGetItem(Generic[_T]): + def __len__(self) -> int: + return 0 + + def __getitem__(self, item: int) -> _T: + raise KeyError + + +len_and_get_item: MyLenAndGetItem[int] = MyLenAndGetItem() +assert_type(list(reversed(len_and_get_item)), "list[int]") diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py new file mode 100644 index 000000000000..84081f3665b9 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py @@ -0,0 +1,68 @@ +from __future__ import annotations + +from typing import overload +from typing_extensions import assert_type + + +class CustomIndex: + def __index__(self) -> int: + return 1 + + +# float: + +assert_type(round(5.5), int) +assert_type(round(5.5, None), int) +assert_type(round(5.5, 0), float) +assert_type(round(5.5, 1), float) +assert_type(round(5.5, 5), float) +assert_type(round(5.5, CustomIndex()), float) + +# int: + +assert_type(round(1), int) +assert_type(round(1, 1), int) +assert_type(round(1, None), int) +assert_type(round(1, CustomIndex()), int) + +# Protocols: + + +class WithCustomRound1: + def __round__(self) -> str: + return "a" + + +assert_type(round(WithCustomRound1()), str) +assert_type(round(WithCustomRound1(), None), str) +# Errors: +round(WithCustomRound1(), 1) # type: ignore +round(WithCustomRound1(), CustomIndex()) # type: ignore + + +class WithCustomRound2: + def __round__(self, digits: int) -> str: + return "a" + + +assert_type(round(WithCustomRound2(), 1), str) +assert_type(round(WithCustomRound2(), CustomIndex()), str) +# Errors: +round(WithCustomRound2(), None) # type: ignore +round(WithCustomRound2()) # type: ignore + + +class WithOverloadedRound: + @overload + def __round__(self, ndigits: None = ...) -> str: ... + + @overload + def __round__(self, ndigits: int) -> bytes: ... + + def __round__(self, ndigits: int | None = None) -> str | bytes: + return b"" if ndigits is None else "" + + +assert_type(round(WithOverloadedRound()), str) +assert_type(round(WithOverloadedRound(), None), str) +assert_type(round(WithOverloadedRound(), 1), bytes) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py new file mode 100644 index 000000000000..cda7eadbbe41 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from typing import Any, List, Literal, Union +from typing_extensions import assert_type + + +class Foo: + def __add__(self, other: Any) -> Foo: + return Foo() + + +class Bar: + def __radd__(self, other: Any) -> Bar: + return Bar() + + +class Baz: + def __add__(self, other: Any) -> Baz: + return Baz() + + def __radd__(self, other: Any) -> Baz: + return Baz() + + +literal_list: list[Literal[0, 1]] = [0, 1, 1] + +assert_type(sum([2, 4]), int) +assert_type(sum([3, 5], 4), int) + +assert_type(sum([True, False]), int) +assert_type(sum([True, False], True), int) +assert_type(sum(literal_list), int) + +assert_type(sum([["foo"], ["bar"]], ["baz"]), List[str]) + +assert_type(sum([Foo(), Foo()], Foo()), Foo) +assert_type(sum([Baz(), Baz()]), Union[Baz, Literal[0]]) + +# mypy and pyright infer the types differently for these, so we can't use assert_type +# Just test that no error is emitted for any of these +sum([("foo",), ("bar", "baz")], ()) # mypy: `tuple[str, ...]`; pyright: `tuple[()] | tuple[str] | tuple[str, str]` +sum([5.6, 3.2]) # mypy: `float`; pyright: `float | Literal[0]` +sum([2.5, 5.8], 5) # mypy: `float`; pyright: `float | int` + +# These all fail at runtime +sum("abcde") # type: ignore +sum([["foo"], ["bar"]]) # type: ignore +sum([("foo",), ("bar", "baz")]) # type: ignore +sum([Foo(), Foo()]) # type: ignore +sum([Bar(), Bar()], Bar()) # type: ignore +sum([Bar(), Bar()]) # type: ignore + +# TODO: these pass pyright with the current stubs, but mypy erroneously emits an error: +# sum([3, Fraction(7, 22), complex(8, 0), 9.83]) +# sum([3, Decimal('0.98')]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py new file mode 100644 index 000000000000..bc0d8db28389 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import Tuple +from typing_extensions import assert_type + + +# Empty tuples, see #8275 +class TupleSub(Tuple[int, ...]): + pass + + +assert_type(TupleSub(), TupleSub) +assert_type(TupleSub([1, 2, 3]), TupleSub) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py b/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py new file mode 100644 index 000000000000..19e663ceeaaf --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +import codecs +from typing_extensions import assert_type + +assert_type(codecs.decode("x", "unicode-escape"), str) +assert_type(codecs.decode(b"x", "unicode-escape"), str) + +assert_type(codecs.decode(b"x", "utf-8"), str) +codecs.decode("x", "utf-8") # type: ignore + +assert_type(codecs.decode("ab", "hex"), bytes) +assert_type(codecs.decode(b"ab", "hex"), bytes) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py b/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py new file mode 100644 index 000000000000..962ec23c6b48 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +from collections.abc import Callable, Iterator +from concurrent.futures import Future, ThreadPoolExecutor, as_completed +from typing_extensions import assert_type + + +class Parent: ... + + +class Child(Parent): ... + + +def check_as_completed_covariance() -> None: + with ThreadPoolExecutor() as executor: + f1 = executor.submit(lambda: Parent()) + f2 = executor.submit(lambda: Child()) + fs: list[Future[Parent] | Future[Child]] = [f1, f2] + assert_type(as_completed(fs), Iterator[Future[Parent]]) + for future in as_completed(fs): + assert_type(future.result(), Parent) + + +def check_future_invariance() -> None: + def execute_callback(callback: Callable[[], Parent], future: Future[Parent]) -> None: + future.set_result(callback()) + + fut: Future[Child] = Future() + execute_callback(lambda: Parent(), fut) # type: ignore + assert isinstance(fut.result(), Child) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py new file mode 100644 index 000000000000..648661bca856 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from contextlib import ExitStack +from typing_extensions import assert_type + + +# See issue #7961 +class Thing(ExitStack): + pass + + +stack = ExitStack() +thing = Thing() +assert_type(stack.enter_context(Thing()), Thing) +assert_type(thing.enter_context(ExitStack()), ExitStack) + +with stack as cm: + assert_type(cm, ExitStack) +with thing as cm2: + assert_type(cm2, Thing) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py b/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py new file mode 100644 index 000000000000..76ce8e1bd260 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import dataclasses as dc +from typing import TYPE_CHECKING, Any, Dict, FrozenSet, Tuple, Type, Union +from typing_extensions import Annotated, assert_type + +if TYPE_CHECKING: + from _typeshed import DataclassInstance + + +@dc.dataclass +class Foo: + attr: str + + +assert_type(dc.fields(Foo), Tuple[dc.Field[Any], ...]) + +# Mypy correctly emits errors on these +# due to the fact it's a dataclass class, not an instance. +# Pyright, however, handles ClassVar members in protocols differently. +# See https://github.com/microsoft/pyright/issues/4339 +# +# dc.asdict(Foo) +# dc.astuple(Foo) +# dc.replace(Foo) + +# See #9723 for why we can't make this assertion +# if dc.is_dataclass(Foo): +# assert_type(Foo, Type[Foo]) + +f = Foo(attr="attr") + +assert_type(dc.fields(f), Tuple[dc.Field[Any], ...]) +assert_type(dc.asdict(f), Dict[str, Any]) +assert_type(dc.astuple(f), Tuple[Any, ...]) +assert_type(dc.replace(f, attr="new"), Foo) + +if dc.is_dataclass(f): + # The inferred type doesn't change + # if it's already known to be a subtype of _DataclassInstance + assert_type(f, Foo) + + +def check_other_isdataclass_overloads(x: type, y: object) -> None: + # TODO: pyright correctly emits an error on this, but mypy does not -- why? + # dc.fields(x) + + dc.fields(y) # type: ignore + + dc.asdict(x) # type: ignore + dc.asdict(y) # type: ignore + + dc.astuple(x) # type: ignore + dc.astuple(y) # type: ignore + + dc.replace(x) # type: ignore + dc.replace(y) # type: ignore + + if dc.is_dataclass(x): + assert_type(x, Type["DataclassInstance"]) + assert_type(dc.fields(x), Tuple[dc.Field[Any], ...]) + + # Mypy correctly emits an error on these due to the fact + # that it's a dataclass class, not a dataclass instance. + # Pyright, however, handles ClassVar members in protocols differently. + # See https://github.com/microsoft/pyright/issues/4339 + # + # dc.asdict(x) + # dc.astuple(x) + # dc.replace(x) + + if dc.is_dataclass(y): + assert_type(y, Union["DataclassInstance", Type["DataclassInstance"]]) + assert_type(dc.fields(y), Tuple[dc.Field[Any], ...]) + + # Mypy correctly emits an error on these due to the fact we don't know + # whether it's a dataclass class or a dataclass instance. + # Pyright, however, handles ClassVar members in protocols differently. + # See https://github.com/microsoft/pyright/issues/4339 + # + # dc.asdict(y) + # dc.astuple(y) + # dc.replace(y) + + if dc.is_dataclass(y) and not isinstance(y, type): + assert_type(y, "DataclassInstance") + assert_type(dc.fields(y), Tuple[dc.Field[Any], ...]) + assert_type(dc.asdict(y), Dict[str, Any]) + assert_type(dc.astuple(y), Tuple[Any, ...]) + dc.replace(y) + + +# Regression test for #11653 +D = dc.make_dataclass( + "D", [("a", Union[int, None]), "y", ("z", Annotated[FrozenSet[bytes], "metadata"], dc.field(default=frozenset({b"foo"})))] +) +# Check that it's inferred by the type checker as a class object of some kind +# (but don't assert the exact type that `D` is inferred as, +# in case a type checker decides to add some special-casing for +# `make_dataclass` in the future) +assert_type(D.__mro__, Tuple[type, ...]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py b/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py new file mode 100644 index 000000000000..4ea4947c811d --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import enum +import sys +from typing import Literal, Type +from typing_extensions import assert_type + +A = enum.Enum("A", "spam eggs bacon") +B = enum.Enum("B", ["spam", "eggs", "bacon"]) +C = enum.Enum("Bar", [("spam", 1), ("eggs", 2), ("bacon", 3)]) +D = enum.Enum("Bar", {"spam": 1, "eggs": 2}) + +assert_type(A, Type[A]) +assert_type(B, Type[B]) +assert_type(C, Type[C]) +assert_type(D, Type[D]) + + +class EnumOfTuples(enum.Enum): + X = 1, 2, 3 + Y = 4, 5, 6 + + +assert_type(EnumOfTuples((1, 2, 3)), EnumOfTuples) + +# TODO: ideally this test would pass: +# +# if sys.version_info >= (3, 12): +# assert_type(EnumOfTuples(1, 2, 3), EnumOfTuples) + + +if sys.version_info >= (3, 11): + + class Foo(enum.StrEnum): + X = enum.auto() + + assert_type(Foo.X, Literal[Foo.X]) + assert_type(Foo.X.value, str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py b/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py new file mode 100644 index 000000000000..dca572683f8d --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +from functools import cached_property, wraps +from typing import Callable, TypeVar +from typing_extensions import ParamSpec, assert_type + +P = ParamSpec("P") +T_co = TypeVar("T_co", covariant=True) + + +def my_decorator(func: Callable[P, T_co]) -> Callable[P, T_co]: + @wraps(func) + def wrapper(*args: P.args, **kwargs: P.kwargs) -> T_co: + print(args) + return func(*args, **kwargs) + + # verify that the wrapped function has all these attributes + wrapper.__annotations__ = func.__annotations__ + wrapper.__doc__ = func.__doc__ + wrapper.__module__ = func.__module__ + wrapper.__name__ = func.__name__ + wrapper.__qualname__ = func.__qualname__ + return wrapper + + +class A: + def __init__(self, x: int): + self.x = x + + @cached_property + def x(self) -> int: + return 0 + + +assert_type(A(x=1).x, int) + + +class B: + @cached_property + def x(self) -> int: + return 0 + + +def check_cached_property_settable(x: int) -> None: + b = B() + assert_type(b.x, int) + b.x = x + assert_type(b.x, int) + + +# https://github.com/python/typeshed/issues/10048 +class Parent: ... + + +class Child(Parent): ... + + +class X: + @cached_property + def some(self) -> Parent: + return Parent() + + +class Y(X): + @cached_property + def some(self) -> Child: # safe override + return Child() diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py new file mode 100644 index 000000000000..17eefdafc971 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py @@ -0,0 +1,47 @@ +from __future__ import annotations + +import importlib.abc +import importlib.util +import pathlib +import sys +import zipfile +from collections.abc import Sequence +from importlib.machinery import ModuleSpec +from types import ModuleType +from typing_extensions import Self + +# Assert that some Path classes are Traversable. +if sys.version_info >= (3, 9): + + def traverse(t: importlib.abc.Traversable) -> None: + pass + + traverse(pathlib.Path()) + traverse(zipfile.Path("")) + + +class MetaFinder: + @classmethod + def find_spec(cls, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None) -> ModuleSpec | None: + return None # simplified mock for demonstration purposes only + + +class PathFinder: + @classmethod + def path_hook(cls, path_entry: str) -> type[Self]: + return cls # simplified mock for demonstration purposes only + + @classmethod + def find_spec(cls, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: + return None # simplified mock for demonstration purposes only + + +class Loader: + @classmethod + def load_module(cls, fullname: str) -> ModuleType: + return ModuleType(fullname) + + +sys.meta_path.append(MetaFinder) +sys.path_hooks.append(PathFinder.path_hook) +importlib.util.spec_from_loader("xxxx42xxxx", Loader) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py new file mode 100644 index 000000000000..f1322e16c54f --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +import sys +from _typeshed import StrPath +from os import PathLike +from pathlib import Path +from typing import Any +from zipfile import Path as ZipPath + +if sys.version_info >= (3, 10): + from importlib.metadata._meta import SimplePath + + # Simplified version of zipfile.Path + class MyPath: + @property + def parent(self) -> PathLike[str]: ... # undocumented + + def read_text(self, encoding: str | None = ..., errors: str | None = ...) -> str: ... + def joinpath(self, *other: StrPath) -> MyPath: ... + def __truediv__(self, add: StrPath) -> MyPath: ... + + if sys.version_info >= (3, 12): + + def takes_simple_path(p: SimplePath[Any]) -> None: ... + + else: + + def takes_simple_path(p: SimplePath) -> None: ... + + takes_simple_path(Path()) + takes_simple_path(ZipPath("")) + takes_simple_path(MyPath()) + takes_simple_path("some string") # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_io.py b/mypy/typeshed/stdlib/@tests/test_cases/check_io.py new file mode 100644 index 000000000000..abf84dd5a103 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_io.py @@ -0,0 +1,6 @@ +from gzip import GzipFile +from io import FileIO, TextIOWrapper + +TextIOWrapper(FileIO("")) +TextIOWrapper(FileIO(13)) +TextIOWrapper(GzipFile("")) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py b/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py new file mode 100644 index 000000000000..fe3d8eb16fd0 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import logging +import logging.handlers +import multiprocessing +import queue +from typing import Any + +# This pattern comes from the logging docs, and should therefore pass a type checker +# See https://docs.python.org/3/library/logging.html#logrecord-objects + +old_factory = logging.getLogRecordFactory() + + +def record_factory(*args: Any, **kwargs: Any) -> logging.LogRecord: + record = old_factory(*args, **kwargs) + record.custom_attribute = 0xDECAFBAD + return record + + +logging.setLogRecordFactory(record_factory) + +# The logging docs say that QueueHandler and QueueListener can take "any queue-like object" +# We test that here (regression test for #10168) +logging.handlers.QueueHandler(queue.Queue()) +logging.handlers.QueueHandler(queue.SimpleQueue()) +logging.handlers.QueueHandler(multiprocessing.Queue()) +logging.handlers.QueueListener(queue.Queue()) +logging.handlers.QueueListener(queue.SimpleQueue()) +logging.handlers.QueueListener(multiprocessing.Queue()) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py b/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py new file mode 100644 index 000000000000..201f96c0c4c8 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +from ctypes import c_char, c_float +from multiprocessing import Array, Value +from multiprocessing.sharedctypes import Synchronized, SynchronizedString +from typing_extensions import assert_type + +string = Array(c_char, 12) +assert_type(string, SynchronizedString) +assert_type(string.value, bytes) + +field = Value(c_float, 0.0) +assert_type(field, Synchronized[float]) +field.value = 1.2 diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py new file mode 100644 index 000000000000..0b52c3669d07 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from pathlib import Path, PureWindowsPath + +if Path("asdf") == Path("asdf"): + ... + +# https://github.com/python/typeshed/issues/10661 +# Provide a true positive error when comparing Path to str +# mypy should report a comparison-overlap error with --strict-equality, +# and pyright should report a reportUnnecessaryComparison error +if Path("asdf") == "asdf": # type: ignore + ... + +# Errors on comparison here are technically false positives. However, this comparison is a little +# interesting: it can never hold true on Posix, but could hold true on Windows. We should experiment +# with more accurate __new__, such that we only get an error for such comparisons on platforms +# where they can never hold true. +if PureWindowsPath("asdf") == Path("asdf"): # type: ignore + ... diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_re.py b/mypy/typeshed/stdlib/@tests/test_cases/check_re.py new file mode 100644 index 000000000000..b6ab2b0d59d2 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_re.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import mmap +import re +import typing as t +from typing_extensions import assert_type + + +def check_search(str_pat: re.Pattern[str], bytes_pat: re.Pattern[bytes]) -> None: + assert_type(str_pat.search("x"), t.Optional[t.Match[str]]) + assert_type(bytes_pat.search(b"x"), t.Optional[t.Match[bytes]]) + assert_type(bytes_pat.search(bytearray(b"x")), t.Optional[t.Match[bytes]]) + assert_type(bytes_pat.search(mmap.mmap(0, 10)), t.Optional[t.Match[bytes]]) + + +def check_search_with_AnyStr(pattern: re.Pattern[t.AnyStr], string: t.AnyStr) -> re.Match[t.AnyStr]: + """See issue #9591""" + match = pattern.search(string) + if match is None: + raise ValueError(f"'{string!r}' does not match {pattern!r}") + return match + + +def check_no_ReadableBuffer_false_negatives() -> None: + re.compile("foo").search(bytearray(b"foo")) # type: ignore + re.compile("foo").search(mmap.mmap(0, 10)) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py b/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py new file mode 100644 index 000000000000..3ec47ceccb90 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import sqlite3 +from typing_extensions import assert_type + + +class MyConnection(sqlite3.Connection): + pass + + +# Default return-type is Connection. +assert_type(sqlite3.connect(":memory:"), sqlite3.Connection) + +# Providing an alternate factory changes the return-type. +assert_type(sqlite3.connect(":memory:", factory=MyConnection), MyConnection) + +# Provides a true positive error. When checking the connect() function, +# mypy should report an arg-type error for the factory argument. +with sqlite3.connect(":memory:", factory=None) as con: # type: ignore + pass + +# The Connection class also accepts a `factory` arg but it does not affect +# the return-type. This use case is not idiomatic--connections should be +# established using the `connect()` function, not directly (as shown here). +assert_type(sqlite3.Connection(":memory:", factory=None), sqlite3.Connection) +assert_type(sqlite3.Connection(":memory:", factory=MyConnection), sqlite3.Connection) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py new file mode 100644 index 000000000000..54510a3d7626 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py @@ -0,0 +1,13 @@ +import tarfile + +with tarfile.open("test.tar.xz", "w:xz") as tar: + pass + +# Test with valid preset values +tarfile.open("test.tar.xz", "w:xz", preset=0) +tarfile.open("test.tar.xz", "w:xz", preset=5) +tarfile.open("test.tar.xz", "w:xz", preset=9) + +# Test with invalid preset values +tarfile.open("test.tar.xz", "w:xz", preset=-1) # type: ignore +tarfile.open("test.tar.xz", "w:xz", preset=10) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py new file mode 100644 index 000000000000..c259c192a140 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import io +import sys +from tempfile import TemporaryFile, _TemporaryFileWrapper +from typing_extensions import assert_type + +if sys.platform == "win32": + assert_type(TemporaryFile(), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile("w+"), _TemporaryFileWrapper[str]) + assert_type(TemporaryFile("w+b"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile("wb"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile("rb"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile("wb", 0), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile(mode="w+"), _TemporaryFileWrapper[str]) + assert_type(TemporaryFile(mode="w+b"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile(mode="wb"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile(mode="rb"), _TemporaryFileWrapper[bytes]) + assert_type(TemporaryFile(buffering=0), _TemporaryFileWrapper[bytes]) +else: + assert_type(TemporaryFile(), io.BufferedRandom) + assert_type(TemporaryFile("w+"), io.TextIOWrapper) + assert_type(TemporaryFile("w+b"), io.BufferedRandom) + assert_type(TemporaryFile("wb"), io.BufferedWriter) + assert_type(TemporaryFile("rb"), io.BufferedReader) + assert_type(TemporaryFile("wb", 0), io.FileIO) + assert_type(TemporaryFile(mode="w+"), io.TextIOWrapper) + assert_type(TemporaryFile(mode="w+b"), io.BufferedRandom) + assert_type(TemporaryFile(mode="wb"), io.BufferedWriter) + assert_type(TemporaryFile(mode="rb"), io.BufferedReader) + assert_type(TemporaryFile(buffering=0), io.FileIO) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py b/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py new file mode 100644 index 000000000000..eddfc2549a64 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +import _threading_local +import threading + +loc = threading.local() +loc.foo = 42 +del loc.foo +loc.baz = ["spam", "eggs"] +del loc.baz + +l2 = _threading_local.local() +l2.asdfasdf = 56 +del l2.asdfasdf diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py new file mode 100644 index 000000000000..befac6697519 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import tkinter +import traceback +import types + + +def custom_handler(exc: type[BaseException], val: BaseException, tb: types.TracebackType | None) -> None: + print("oh no") + + +root = tkinter.Tk() +root.report_callback_exception = traceback.print_exception +root.report_callback_exception = custom_handler + + +def foo(x: int, y: str) -> None: + pass + + +root.after(1000, foo, 10, "lol") +root.after(1000, foo, 10, 10) # type: ignore + + +# Font size must be integer +label = tkinter.Label() +label.config(font=("", 12)) +label.config(font=("", 12.34)) # type: ignore +label.config(font=("", 12, "bold")) +label.config(font=("", 12.34, "bold")) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py b/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py new file mode 100644 index 000000000000..40c6efaa8ca0 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +import unittest +from collections.abc import Iterator, Mapping +from datetime import datetime, timedelta +from decimal import Decimal +from fractions import Fraction +from typing import TypedDict +from typing_extensions import assert_type +from unittest.mock import MagicMock, Mock, patch + +case = unittest.TestCase() + +### +# Tests for assertAlmostEqual +### + +case.assertAlmostEqual(1, 2.4) +case.assertAlmostEqual(2.4, 2.41) +case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) +case.assertAlmostEqual(3.14, complex(5, 6)) +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) +case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) +case.assertAlmostEqual(2.4, 2.41, places=8) +case.assertAlmostEqual(2.4, 2.41, delta=0.02) +case.assertAlmostEqual(2.4, 2.41, None, "foo", 0.02) + +case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore +case.assertAlmostEqual("foo", "bar") # type: ignore +case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore +case.assertAlmostEqual(Decimal("0.4"), Fraction(1, 2)) # type: ignore +case.assertAlmostEqual(complex(2, 3), Decimal("0.9")) # type: ignore + +### +# Tests for assertNotAlmostEqual +### + +case.assertAlmostEqual(1, 2.4) +case.assertNotAlmostEqual(Fraction(49, 50), Fraction(48, 50)) +case.assertAlmostEqual(3.14, complex(5, 6)) +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) + +case.assertNotAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore +case.assertNotAlmostEqual("foo", "bar") # type: ignore +case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore +case.assertNotAlmostEqual(Decimal("0.4"), Fraction(1, 2)) # type: ignore +case.assertNotAlmostEqual(complex(2, 3), Decimal("0.9")) # type: ignore + +### +# Tests for assertGreater +### + + +class Spam: + def __lt__(self, other: object) -> bool: + return True + + +class Eggs: + def __gt__(self, other: object) -> bool: + return True + + +class Ham: + def __lt__(self, other: Ham) -> bool: + if not isinstance(other, Ham): + return NotImplemented + return True + + +class Bacon: + def __gt__(self, other: Bacon) -> bool: + if not isinstance(other, Bacon): + return NotImplemented + return True + + +case.assertGreater(5.8, 3) +case.assertGreater(Decimal("4.5"), Fraction(3, 2)) +case.assertGreater(Fraction(3, 2), 0.9) +case.assertGreater(Eggs(), object()) +case.assertGreater(object(), Spam()) +case.assertGreater(Ham(), Ham()) +case.assertGreater(Bacon(), Bacon()) + +case.assertGreater(object(), object()) # type: ignore +case.assertGreater(datetime(1999, 1, 2), 1) # type: ignore +case.assertGreater(Spam(), Eggs()) # type: ignore +case.assertGreater(Ham(), Bacon()) # type: ignore +case.assertGreater(Bacon(), Ham()) # type: ignore + + +### +# Tests for assertDictEqual +### + + +class TD1(TypedDict): + x: int + y: str + + +class TD2(TypedDict): + a: bool + b: bool + + +class MyMapping(Mapping[str, int]): + def __getitem__(self, __key: str) -> int: + return 42 + + def __iter__(self) -> Iterator[str]: + return iter([]) + + def __len__(self) -> int: + return 0 + + +td1: TD1 = {"x": 1, "y": "foo"} +td2: TD2 = {"a": True, "b": False} +m = MyMapping() + +case.assertDictEqual({}, {}) +case.assertDictEqual({"x": 1, "y": 2}, {"x": 1, "y": 2}) +case.assertDictEqual({"x": 1, "y": "foo"}, {"y": "foo", "x": 1}) +case.assertDictEqual({"x": 1}, {}) +case.assertDictEqual({}, {"x": 1}) +case.assertDictEqual({1: "x"}, {"y": 222}) +case.assertDictEqual({1: "x"}, td1) +case.assertDictEqual(td1, {1: "x"}) +case.assertDictEqual(td1, td2) + +case.assertDictEqual(1, {}) # type: ignore +case.assertDictEqual({}, 1) # type: ignore + +# These should fail, but don't due to TypedDict limitations: +# case.assertDictEqual(m, {"": 0}) # xtype: ignore +# case.assertDictEqual({"": 0}, m) # xtype: ignore + +### +# Tests for mock.patch +### + + +@patch("sys.exit") +def f_default_new(i: int, mock: MagicMock) -> str: + return "asdf" + + +@patch("sys.exit", new=42) +def f_explicit_new(i: int) -> str: + return "asdf" + + +assert_type(f_default_new(1), str) +f_default_new("a") # Not an error due to ParamSpec limitations +assert_type(f_explicit_new(1), str) +f_explicit_new("a") # type: ignore[arg-type] + + +@patch("sys.exit", new=Mock()) +class TestXYZ(unittest.TestCase): + attr: int = 5 + + @staticmethod + def method() -> int: + return 123 + + +assert_type(TestXYZ.attr, int) +assert_type(TestXYZ.method(), int) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py b/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py new file mode 100644 index 000000000000..b485dac8dc29 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import sys +from typing_extensions import assert_type +from xml.dom.minidom import Document + +document = Document() + +assert_type(document.toxml(), str) +assert_type(document.toxml(encoding=None), str) +assert_type(document.toxml(encoding="UTF8"), bytes) +assert_type(document.toxml("UTF8"), bytes) +if sys.version_info >= (3, 9): + assert_type(document.toxml(standalone=True), str) + assert_type(document.toxml("UTF8", True), bytes) + assert_type(document.toxml(encoding="UTF8", standalone=True), bytes) + + +# Because toprettyxml can mix positional and keyword variants of the "encoding" argument, which +# determines the return type, the proper stub typing isn't immediately obvious. This is a basic +# brute-force sanity check. +# Test cases like toxml +assert_type(document.toprettyxml(), str) +assert_type(document.toprettyxml(encoding=None), str) +assert_type(document.toprettyxml(encoding="UTF8"), bytes) +if sys.version_info >= (3, 9): + assert_type(document.toprettyxml(standalone=True), str) + assert_type(document.toprettyxml(encoding="UTF8", standalone=True), bytes) +# Test cases unique to toprettyxml +assert_type(document.toprettyxml(" "), str) +assert_type(document.toprettyxml(" ", "\r\n"), str) +assert_type(document.toprettyxml(" ", "\r\n", "UTF8"), bytes) +if sys.version_info >= (3, 9): + assert_type(document.toprettyxml(" ", "\r\n", "UTF8", True), bytes) + assert_type(document.toprettyxml(" ", "\r\n", standalone=True), str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py b/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py new file mode 100644 index 000000000000..9fe5ec8076ce --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py @@ -0,0 +1,69 @@ +""" +Tests for `defaultdict.__or__` and `defaultdict.__ror__`. +These methods were only added in py39. +""" + +from __future__ import annotations + +import os +import sys +from collections import defaultdict +from typing import Mapping, TypeVar, Union +from typing_extensions import Self, assert_type + +_KT = TypeVar("_KT") +_VT = TypeVar("_VT") + + +if sys.version_info >= (3, 9): + + class CustomDefaultDictSubclass(defaultdict[_KT, _VT]): + pass + + class CustomMappingWithDunderOr(Mapping[_KT, _VT]): + def __or__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: + return {} + + def __ror__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: + return {} + + def __ior__(self, other: Mapping[_KT, _VT]) -> Self: + return self + + def test_defaultdict_dot_or( + a: defaultdict[int, int], + b: CustomDefaultDictSubclass[int, int], + c: defaultdict[str, str], + d: Mapping[int, int], + e: CustomMappingWithDunderOr[str, str], + ) -> None: + assert_type(a | b, defaultdict[int, int]) + + # In contrast to `dict.__or__`, `defaultdict.__or__` returns `Self` if called on a subclass of `defaultdict`: + assert_type(b | a, CustomDefaultDictSubclass[int, int]) + + assert_type(a | c, defaultdict[Union[int, str], Union[int, str]]) + + # arbitrary mappings are not accepted by `defaultdict.__or__`; + # it has to be a subclass of `dict` + a | d # type: ignore + + # but Mappings such as `os._Environ` or `CustomMappingWithDunderOr`, + # which define `__ror__` methods that accept `dict`, are fine + # (`os._Environ.__(r)or__` always returns `dict`, even if a `defaultdict` is passed): + assert_type(a | os.environ, dict[Union[str, int], Union[str, int]]) + assert_type(os.environ | a, dict[Union[str, int], Union[str, int]]) + + assert_type(c | os.environ, dict[str, str]) + assert_type(c | e, dict[str, str]) + + assert_type(os.environ | c, dict[str, str]) + assert_type(e | c, dict[str, str]) + + e |= c + e |= a # type: ignore + + # TODO: this test passes mypy, but fails pyright for some reason: + # c |= e + + c |= a # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py b/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py new file mode 100644 index 000000000000..a9b43e23fb27 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py @@ -0,0 +1,6 @@ +from email.headerregistry import Address +from email.message import EmailMessage + +msg = EmailMessage() +msg["To"] = "receiver@example.com" +msg["From"] = Address("Sender Name", "sender", "example.com") diff --git a/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py b/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py new file mode 100644 index 000000000000..c45ffee28cee --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py @@ -0,0 +1,410 @@ +"""Type-annotated versions of the recipes from the itertools docs. + +These are all meant to be examples of idiomatic itertools usage, +so they should all type-check without error. +""" + +from __future__ import annotations + +import collections +import math +import operator +import sys +from itertools import chain, combinations, count, cycle, filterfalse, groupby, islice, product, repeat, starmap, tee, zip_longest +from typing import ( + Any, + Callable, + Collection, + Hashable, + Iterable, + Iterator, + Literal, + Sequence, + Tuple, + Type, + TypeVar, + Union, + overload, +) +from typing_extensions import TypeAlias, TypeVarTuple, Unpack + +_T = TypeVar("_T") +_T1 = TypeVar("_T1") +_T2 = TypeVar("_T2") +_HashableT = TypeVar("_HashableT", bound=Hashable) +_Ts = TypeVarTuple("_Ts") + + +def take(n: int, iterable: Iterable[_T]) -> list[_T]: + "Return first n items of the iterable as a list" + return list(islice(iterable, n)) + + +# Note: the itertools docs uses the parameter name "iterator", +# but the function actually accepts any iterable +# as its second argument +def prepend(value: _T1, iterator: Iterable[_T2]) -> Iterator[_T1 | _T2]: + "Prepend a single value in front of an iterator" + # prepend(1, [2, 3, 4]) --> 1 2 3 4 + return chain([value], iterator) + + +def tabulate(function: Callable[[int], _T], start: int = 0) -> Iterator[_T]: + "Return function(0), function(1), ..." + return map(function, count(start)) + + +def repeatfunc(func: Callable[[Unpack[_Ts]], _T], times: int | None = None, *args: Unpack[_Ts]) -> Iterator[_T]: + """Repeat calls to func with specified arguments. + + Example: repeatfunc(random.random) + """ + if times is None: + return starmap(func, repeat(args)) + return starmap(func, repeat(args, times)) + + +def flatten(list_of_lists: Iterable[Iterable[_T]]) -> Iterator[_T]: + "Flatten one level of nesting" + return chain.from_iterable(list_of_lists) + + +def ncycles(iterable: Iterable[_T], n: int) -> Iterator[_T]: + "Returns the sequence elements n times" + return chain.from_iterable(repeat(tuple(iterable), n)) + + +def tail(n: int, iterable: Iterable[_T]) -> Iterator[_T]: + "Return an iterator over the last n items" + # tail(3, 'ABCDEFG') --> E F G + return iter(collections.deque(iterable, maxlen=n)) + + +# This function *accepts* any iterable, +# but it only *makes sense* to use it with an iterator +def consume(iterator: Iterator[object], n: int | None = None) -> None: + "Advance the iterator n-steps ahead. If n is None, consume entirely." + # Use functions that consume iterators at C speed. + if n is None: + # feed the entire iterator into a zero-length deque + collections.deque(iterator, maxlen=0) + else: + # advance to the empty slice starting at position n + next(islice(iterator, n, n), None) + + +@overload +def nth(iterable: Iterable[_T], n: int, default: None = None) -> _T | None: ... + + +@overload +def nth(iterable: Iterable[_T], n: int, default: _T1) -> _T | _T1: ... + + +def nth(iterable: Iterable[object], n: int, default: object = None) -> object: + "Returns the nth item or a default value" + return next(islice(iterable, n, None), default) + + +@overload +def quantify(iterable: Iterable[object]) -> int: ... + + +@overload +def quantify(iterable: Iterable[_T], pred: Callable[[_T], bool]) -> int: ... + + +def quantify(iterable: Iterable[object], pred: Callable[[Any], bool] = bool) -> int: + "Given a predicate that returns True or False, count the True results." + return sum(map(pred, iterable)) + + +@overload +def first_true( + iterable: Iterable[_T], default: Literal[False] = False, pred: Callable[[_T], bool] | None = None +) -> _T | Literal[False]: ... + + +@overload +def first_true(iterable: Iterable[_T], default: _T1, pred: Callable[[_T], bool] | None = None) -> _T | _T1: ... + + +def first_true(iterable: Iterable[object], default: object = False, pred: Callable[[Any], bool] | None = None) -> object: + """Returns the first true value in the iterable. + If no true value is found, returns *default* + If *pred* is not None, returns the first item + for which pred(item) is true. + """ + # first_true([a,b,c], x) --> a or b or c or x + # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x + return next(filter(pred, iterable), default) + + +_ExceptionOrExceptionTuple: TypeAlias = Union[Type[BaseException], Tuple[Type[BaseException], ...]] + + +@overload +def iter_except(func: Callable[[], _T], exception: _ExceptionOrExceptionTuple, first: None = None) -> Iterator[_T]: ... + + +@overload +def iter_except( + func: Callable[[], _T], exception: _ExceptionOrExceptionTuple, first: Callable[[], _T1] +) -> Iterator[_T | _T1]: ... + + +def iter_except( + func: Callable[[], object], exception: _ExceptionOrExceptionTuple, first: Callable[[], object] | None = None +) -> Iterator[object]: + """Call a function repeatedly until an exception is raised. + Converts a call-until-exception interface to an iterator interface. + Like builtins.iter(func, sentinel) but uses an exception instead + of a sentinel to end the loop. + Examples: + iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator + iter_except(d.popitem, KeyError) # non-blocking dict iterator + iter_except(d.popleft, IndexError) # non-blocking deque iterator + iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue + iter_except(s.pop, KeyError) # non-blocking set iterator + """ + try: + if first is not None: + yield first() # For database APIs needing an initial cast to db.first() + while True: + yield func() + except exception: + pass + + +def sliding_window(iterable: Iterable[_T], n: int) -> Iterator[tuple[_T, ...]]: + # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG + it = iter(iterable) + window = collections.deque(islice(it, n - 1), maxlen=n) + for x in it: + window.append(x) + yield tuple(window) + + +def roundrobin(*iterables: Iterable[_T]) -> Iterator[_T]: + "roundrobin('ABC', 'D', 'EF') --> A D E B F C" + # Recipe credited to George Sakkis + num_active = len(iterables) + nexts: Iterator[Callable[[], _T]] = cycle(iter(it).__next__ for it in iterables) + while num_active: + try: + for next in nexts: + yield next() + except StopIteration: + # Remove the iterator we just exhausted from the cycle. + num_active -= 1 + nexts = cycle(islice(nexts, num_active)) + + +def partition(pred: Callable[[_T], bool], iterable: Iterable[_T]) -> tuple[Iterator[_T], Iterator[_T]]: + """Partition entries into false entries and true entries. + If *pred* is slow, consider wrapping it with functools.lru_cache(). + """ + # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + t1, t2 = tee(iterable) + return filterfalse(pred, t1), filter(pred, t2) + + +def subslices(seq: Sequence[_T]) -> Iterator[Sequence[_T]]: + "Return all contiguous non-empty subslices of a sequence" + # subslices('ABCD') --> A AB ABC ABCD B BC BCD C CD D + slices = starmap(slice, combinations(range(len(seq) + 1), 2)) + return map(operator.getitem, repeat(seq), slices) + + +def before_and_after(predicate: Callable[[_T], bool], it: Iterable[_T]) -> tuple[Iterator[_T], Iterator[_T]]: + """Variant of takewhile() that allows complete + access to the remainder of the iterator. + >>> it = iter('ABCdEfGhI') + >>> all_upper, remainder = before_and_after(str.isupper, it) + >>> ''.join(all_upper) + 'ABC' + >>> ''.join(remainder) # takewhile() would lose the 'd' + 'dEfGhI' + Note that the first iterator must be fully + consumed before the second iterator can + generate valid results. + """ + it = iter(it) + transition: list[_T] = [] + + def true_iterator() -> Iterator[_T]: + for elem in it: + if predicate(elem): + yield elem + else: + transition.append(elem) + return + + def remainder_iterator() -> Iterator[_T]: + yield from transition + yield from it + + return true_iterator(), remainder_iterator() + + +@overload +def unique_everseen(iterable: Iterable[_HashableT], key: None = None) -> Iterator[_HashableT]: ... + + +@overload +def unique_everseen(iterable: Iterable[_T], key: Callable[[_T], Hashable]) -> Iterator[_T]: ... + + +def unique_everseen(iterable: Iterable[_T], key: Callable[[_T], Hashable] | None = None) -> Iterator[_T]: + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBcCAD', str.lower) --> A B c D + seen: set[Hashable] = set() + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen.add(element) + yield element + # For order preserving deduplication, + # a faster but non-lazy solution is: + # yield from dict.fromkeys(iterable) + else: + for element in iterable: + k = key(element) + if k not in seen: + seen.add(k) + yield element + # For use cases that allow the last matching element to be returned, + # a faster but non-lazy solution is: + # t1, t2 = tee(iterable) + # yield from dict(zip(map(key, t1), t2)).values() + + +# Slightly adapted from the docs recipe; a one-liner was a bit much for pyright +def unique_justseen(iterable: Iterable[_T], key: Callable[[_T], bool] | None = None) -> Iterator[_T]: + "List unique elements, preserving order. Remember only the element just seen." + # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B + # unique_justseen('ABBcCAD', str.lower) --> A B c A D + g: groupby[_T | bool, _T] = groupby(iterable, key) + return map(next, map(operator.itemgetter(1), g)) + + +def powerset(iterable: Iterable[_T]) -> Iterator[tuple[_T, ...]]: + "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) + + +def polynomial_derivative(coefficients: Sequence[float]) -> list[float]: + """Compute the first derivative of a polynomial. + f(x) = x³ -4x² -17x + 60 + f'(x) = 3x² -8x -17 + """ + # polynomial_derivative([1, -4, -17, 60]) -> [3, -8, -17] + n = len(coefficients) + powers = reversed(range(1, n)) + return list(map(operator.mul, coefficients, powers)) + + +def nth_combination(iterable: Iterable[_T], r: int, index: int) -> tuple[_T, ...]: + "Equivalent to list(combinations(iterable, r))[index]" + pool = tuple(iterable) + n = len(pool) + c = math.comb(n, r) + if index < 0: + index += c + if index < 0 or index >= c: + raise IndexError + result: list[_T] = [] + while r: + c, n, r = c * r // n, n - 1, r - 1 + while index >= c: + index -= c + c, n = c * (n - r) // n, n - 1 + result.append(pool[-1 - n]) + return tuple(result) + + +if sys.version_info >= (3, 10): + + @overload + def grouper( + iterable: Iterable[_T], n: int, *, incomplete: Literal["fill"] = "fill", fillvalue: None = None + ) -> Iterator[tuple[_T | None, ...]]: ... + + @overload + def grouper( + iterable: Iterable[_T], n: int, *, incomplete: Literal["fill"] = "fill", fillvalue: _T1 + ) -> Iterator[tuple[_T | _T1, ...]]: ... + + @overload + def grouper( + iterable: Iterable[_T], n: int, *, incomplete: Literal["strict", "ignore"], fillvalue: None = None + ) -> Iterator[tuple[_T, ...]]: ... + + def grouper( + iterable: Iterable[object], n: int, *, incomplete: Literal["fill", "strict", "ignore"] = "fill", fillvalue: object = None + ) -> Iterator[tuple[object, ...]]: + "Collect data into non-overlapping fixed-length chunks or blocks" + # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx + # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError + # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF + args = [iter(iterable)] * n + if incomplete == "fill": + return zip_longest(*args, fillvalue=fillvalue) + if incomplete == "strict": + return zip(*args, strict=True) + if incomplete == "ignore": + return zip(*args) + else: + raise ValueError("Expected fill, strict, or ignore") + + def transpose(it: Iterable[Iterable[_T]]) -> Iterator[tuple[_T, ...]]: + "Swap the rows and columns of the input." + # transpose([(1, 2, 3), (11, 22, 33)]) --> (1, 11) (2, 22) (3, 33) + return zip(*it, strict=True) + + +if sys.version_info >= (3, 12): + from itertools import batched + + def sum_of_squares(it: Iterable[float]) -> float: + "Add up the squares of the input values." + # sum_of_squares([10, 20, 30]) -> 1400 + return math.sumprod(*tee(it)) + + def convolve(signal: Iterable[float], kernel: Iterable[float]) -> Iterator[float]: + """Discrete linear convolution of two iterables. + The kernel is fully consumed before the calculations begin. + The signal is consumed lazily and can be infinite. + Convolutions are mathematically commutative. + If the signal and kernel are swapped, + the output will be the same. + Article: https://betterexplained.com/articles/intuitive-convolution/ + Video: https://www.youtube.com/watch?v=KuXjwB4LzSA + """ + # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) + # convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate + # convolve(data, [1, -2, 1]) --> 2nd derivative estimate + kernel = tuple(kernel)[::-1] + n = len(kernel) + padded_signal = chain(repeat(0, n - 1), signal, repeat(0, n - 1)) + windowed_signal = sliding_window(padded_signal, n) + return map(math.sumprod, repeat(kernel), windowed_signal) + + def polynomial_eval(coefficients: Sequence[float], x: float) -> float: + """Evaluate a polynomial at a specific value. + Computes with better numeric stability than Horner's method. + """ + # Evaluate x³ -4x² -17x + 60 at x = 2.5 + # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125 + n = len(coefficients) + if not n: + return type(x)(0) + powers = map(pow, repeat(x), reversed(range(n))) + return math.sumprod(coefficients, powers) + + def matmul(m1: Sequence[Collection[float]], m2: Sequence[Collection[float]]) -> Iterator[tuple[float, ...]]: + "Multiply two matrices." + # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) --> (49, 80), (41, 60) + n = len(m2[0]) + return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py new file mode 100644 index 000000000000..10a33ffb83d5 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +from typing import Any, Union +from typing_extensions import assert_type + + +def check_setdefault_method() -> None: + d: dict[int, str] = {} + d2: dict[int, str | None] = {} + d3: dict[int, Any] = {} + + d.setdefault(1) # type: ignore + assert_type(d.setdefault(1, "x"), str) + assert_type(d2.setdefault(1), Union[str, None]) + assert_type(d2.setdefault(1, None), Union[str, None]) + assert_type(d2.setdefault(1, "x"), Union[str, None]) + assert_type(d3.setdefault(1), Union[Any, None]) + assert_type(d3.setdefault(1, "x"), Any) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py new file mode 100644 index 000000000000..44eb548e04a9 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py @@ -0,0 +1,14 @@ +# pyright: reportWildcardImportFromLibrary=false +""" +This tests that star imports work when using "all += " syntax. +""" +from __future__ import annotations + +import sys +from typing import * +from zipfile import * + +if sys.version_info >= (3, 9): + x: Annotated[int, 42] + +p: Path diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py new file mode 100644 index 000000000000..34c5631aeb1a --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +import typing as t + +KT = t.TypeVar("KT") + + +class MyKeysView(t.KeysView[KT]): + pass + + +d: dict[t.Any, t.Any] = {} +dict_keys = type(d.keys()) + +# This should not cause an error like `Member "register" is unknown`: +MyKeysView.register(dict_keys) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py new file mode 100644 index 000000000000..67f16dc91765 --- /dev/null +++ b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +import mmap +from typing import IO, AnyStr + + +def check_write(io_bytes: IO[bytes], io_str: IO[str], io_anystr: IO[AnyStr], any_str: AnyStr, buf: mmap.mmap) -> None: + io_bytes.write(b"") + io_bytes.write(buf) + io_bytes.write("") # type: ignore + io_bytes.write(any_str) # type: ignore + + io_str.write(b"") # type: ignore + io_str.write(buf) # type: ignore + io_str.write("") + io_str.write(any_str) # type: ignore + + io_anystr.write(b"") # type: ignore + io_anystr.write(buf) # type: ignore + io_anystr.write("") # type: ignore + io_anystr.write(any_str) diff --git a/mypy/typeshed/stdlib/_typeshed/importlib.pyi b/mypy/typeshed/stdlib/_typeshed/importlib.pyi new file mode 100644 index 000000000000..a4e56cdaff62 --- /dev/null +++ b/mypy/typeshed/stdlib/_typeshed/importlib.pyi @@ -0,0 +1,18 @@ +# Implicit protocols used in importlib. +# We intentionally omit deprecated and optional methods. + +from collections.abc import Sequence +from importlib.machinery import ModuleSpec +from types import ModuleType +from typing import Protocol + +__all__ = ["LoaderProtocol", "MetaPathFinderProtocol", "PathEntryFinderProtocol"] + +class LoaderProtocol(Protocol): + def load_module(self, fullname: str, /) -> ModuleType: ... + +class MetaPathFinderProtocol(Protocol): + def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = ..., /) -> ModuleSpec | None: ... + +class PathEntryFinderProtocol(Protocol): + def find_spec(self, fullname: str, target: ModuleType | None = ..., /) -> ModuleSpec | None: ... diff --git a/mypy/typeshed/stdlib/ast.pyi b/mypy/typeshed/stdlib/ast.pyi index 4ab325b5baa7..2525c3642a6f 100644 --- a/mypy/typeshed/stdlib/ast.pyi +++ b/mypy/typeshed/stdlib/ast.pyi @@ -181,82 +181,172 @@ class NodeTransformer(NodeVisitor): _T = _TypeVar("_T", bound=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, 13): + @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, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> 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, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> 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, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> 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, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> Interactive: ... + @overload + def parse( + source: str | ReadableBuffer, + *, + mode: Literal["eval"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> Expression: ... + @overload + def parse( + source: str | ReadableBuffer, + *, + mode: Literal["func_type"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> FunctionType: ... + @overload + def parse( + source: str | ReadableBuffer, + *, + mode: Literal["single"], + type_comments: bool = False, + feature_version: None | int | tuple[int, int] = None, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> 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, + optimize: Literal[-1, 0, 1, 2] = -1, + ) -> AST: ... + +else: + @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: ... def copy_location(new_node: _T, old_node: AST) -> _T: ... -if sys.version_info >= (3, 9): +if sys.version_info >= (3, 13): + def dump( + node: AST, + annotate_fields: bool = True, + include_attributes: bool = False, + *, + indent: int | str | None = None, + show_empty: bool = False, + ) -> str: ... + +elif sys.version_info >= (3, 9): def dump( node: AST, annotate_fields: bool = True, include_attributes: bool = False, *, indent: int | str | None = None ) -> str: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 9e56c5430c52..4c47a0736e2e 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -31,7 +31,7 @@ from _typeshed import ( ) from collections.abc import Awaitable, Callable, Iterable, Iterator, MutableSet, Reversible, Set as AbstractSet, Sized from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from types import CodeType, TracebackType, _Cell +from types import CellType, CodeType, TracebackType # mypy crashes if any of {ByteString, Sequence, MutableSequence, Mapping, MutableMapping} are imported from collections.abc in builtins.pyi from typing import ( # noqa: Y022 @@ -863,7 +863,7 @@ class tuple(Sequence[_T_co]): class function: # Make sure this class definition stays roughly in line with `types.FunctionType` @property - def __closure__(self) -> tuple[_Cell, ...] | None: ... + def __closure__(self) -> tuple[CellType, ...] | None: ... __code__: CodeType __defaults__: tuple[Any, ...] | None __dict__: dict[str, Any] @@ -1245,7 +1245,7 @@ if sys.version_info >= (3, 11): locals: Mapping[str, object] | None = None, /, *, - closure: tuple[_Cell, ...] | None = None, + closure: tuple[CellType, ...] | None = None, ) -> None: ... else: @@ -1706,7 +1706,7 @@ def __import__( fromlist: Sequence[str] = (), level: int = 0, ) -> types.ModuleType: ... -def __build_class__(func: Callable[[], _Cell | Any], name: str, /, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... +def __build_class__(func: Callable[[], CellType | Any], name: str, /, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... if sys.version_info >= (3, 10): from types import EllipsisType diff --git a/mypy/typeshed/stdlib/dbm/__init__.pyi b/mypy/typeshed/stdlib/dbm/__init__.pyi index 9c6989a1c151..f414763e02a6 100644 --- a/mypy/typeshed/stdlib/dbm/__init__.pyi +++ b/mypy/typeshed/stdlib/dbm/__init__.pyi @@ -1,3 +1,5 @@ +import sys +from _typeshed import StrOrBytesPath from collections.abc import Iterator, MutableMapping from types import TracebackType from typing import Literal @@ -91,5 +93,10 @@ class _error(Exception): ... error: tuple[type[_error], type[OSError]] -def whichdb(filename: str) -> str | None: ... -def open(file: str, flag: _TFlags = "r", mode: int = 0o666) -> _Database: ... +if sys.version_info >= (3, 11): + def whichdb(filename: StrOrBytesPath) -> str | None: ... + def open(file: StrOrBytesPath, flag: _TFlags = "r", mode: int = 0o666) -> _Database: ... + +else: + def whichdb(filename: str) -> str | None: ... + def open(file: str, flag: _TFlags = "r", mode: int = 0o666) -> _Database: ... diff --git a/mypy/typeshed/stdlib/dbm/dumb.pyi b/mypy/typeshed/stdlib/dbm/dumb.pyi index 1fc68cf71f9d..1c0b7756f292 100644 --- a/mypy/typeshed/stdlib/dbm/dumb.pyi +++ b/mypy/typeshed/stdlib/dbm/dumb.pyi @@ -1,3 +1,5 @@ +import sys +from _typeshed import StrOrBytesPath from collections.abc import Iterator, MutableMapping from types import TracebackType from typing_extensions import Self, TypeAlias @@ -28,4 +30,8 @@ class _Database(MutableMapping[_KeyType, bytes]): self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> None: ... -def open(file: str, flag: str = "c", mode: int = 0o666) -> _Database: ... +if sys.version_info >= (3, 11): + def open(file: StrOrBytesPath, flag: str = "c", mode: int = 0o666) -> _Database: ... + +else: + def open(file: str, flag: str = "c", mode: int = 0o666) -> _Database: ... diff --git a/mypy/typeshed/stdlib/dbm/gnu.pyi b/mypy/typeshed/stdlib/dbm/gnu.pyi index 8b562019fcfb..e80441cbb25b 100644 --- a/mypy/typeshed/stdlib/dbm/gnu.pyi +++ b/mypy/typeshed/stdlib/dbm/gnu.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import ReadOnlyBuffer +from _typeshed import ReadOnlyBuffer, StrOrBytesPath from types import TracebackType from typing import TypeVar, overload from typing_extensions import Self, TypeAlias @@ -38,4 +38,7 @@ if sys.platform != "win32": __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] - def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _gdbm: ... + if sys.version_info >= (3, 11): + def open(filename: StrOrBytesPath, flags: str = "r", mode: int = 0o666, /) -> _gdbm: ... + else: + def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _gdbm: ... diff --git a/mypy/typeshed/stdlib/dbm/ndbm.pyi b/mypy/typeshed/stdlib/dbm/ndbm.pyi index 5eb84e6949fc..02bf23ec181c 100644 --- a/mypy/typeshed/stdlib/dbm/ndbm.pyi +++ b/mypy/typeshed/stdlib/dbm/ndbm.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import ReadOnlyBuffer +from _typeshed import ReadOnlyBuffer, StrOrBytesPath from types import TracebackType from typing import TypeVar, overload from typing_extensions import Self, TypeAlias @@ -34,4 +34,7 @@ if sys.platform != "win32": __new__: None # type: ignore[assignment] __init__: None # type: ignore[assignment] - def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _dbm: ... + if sys.version_info >= (3, 11): + def open(filename: StrOrBytesPath, flags: str = "r", mode: int = 0o666, /) -> _dbm: ... + else: + def open(filename: str, flags: str = "r", mode: int = 0o666, /) -> _dbm: ... diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index 75e78ed59172..3937481159dc 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -64,7 +64,7 @@ class SourceLoader(ResourceLoader, ExecutionLoader, metaclass=ABCMeta): # The base classes differ starting in 3.10: if sys.version_info >= (3, 10): - # Please keep in sync with sys._MetaPathFinder + # Please keep in sync with _typeshed.importlib.MetaPathFinderProtocol class MetaPathFinder(metaclass=ABCMeta): if sys.version_info < (3, 12): def find_module(self, fullname: str, path: Sequence[str] | None) -> Loader | None: ... @@ -85,7 +85,7 @@ if sys.version_info >= (3, 10): def find_spec(self, fullname: str, target: types.ModuleType | None = ...) -> ModuleSpec | None: ... else: - # Please keep in sync with sys._MetaPathFinder + # Please keep in sync with _typeshed.importlib.MetaPathFinderProtocol class MetaPathFinder(Finder): def find_module(self, fullname: str, path: Sequence[str] | None) -> Loader | None: ... def invalidate_caches(self) -> None: ... diff --git a/mypy/typeshed/stdlib/importlib/util.pyi b/mypy/typeshed/stdlib/importlib/util.pyi index 6608f70d4469..2492c76d5c6c 100644 --- a/mypy/typeshed/stdlib/importlib/util.pyi +++ b/mypy/typeshed/stdlib/importlib/util.pyi @@ -3,6 +3,7 @@ import importlib.machinery import sys import types from _typeshed import ReadableBuffer, StrOrBytesPath +from _typeshed.importlib import LoaderProtocol from collections.abc import Callable from typing import Any from typing_extensions import ParamSpec @@ -23,13 +24,13 @@ def source_from_cache(path: str) -> str: ... def decode_source(source_bytes: ReadableBuffer) -> str: ... def find_spec(name: str, package: str | None = None) -> importlib.machinery.ModuleSpec | None: ... def spec_from_loader( - name: str, loader: importlib.abc.Loader | None, *, origin: str | None = None, is_package: bool | None = None + name: str, loader: LoaderProtocol | None, *, origin: str | None = None, is_package: bool | None = None ) -> importlib.machinery.ModuleSpec | None: ... def spec_from_file_location( name: str, location: StrOrBytesPath | None = None, *, - loader: importlib.abc.Loader | None = None, + loader: LoaderProtocol | None = None, submodule_search_locations: list[str] | None = ..., ) -> importlib.machinery.ModuleSpec | None: ... def module_from_spec(spec: importlib.machinery.ModuleSpec) -> types.ModuleType: ... diff --git a/mypy/typeshed/stdlib/logging/__init__.pyi b/mypy/typeshed/stdlib/logging/__init__.pyi index f5f7f91ece61..7ceddfa7ff28 100644 --- a/mypy/typeshed/stdlib/logging/__init__.pyi +++ b/mypy/typeshed/stdlib/logging/__init__.pyi @@ -587,7 +587,7 @@ def setLoggerClass(klass: type[Logger]) -> None: ... def captureWarnings(capture: bool) -> None: ... def setLogRecordFactory(factory: Callable[..., LogRecord]) -> None: ... -lastResort: StreamHandler[Any] | None +lastResort: Handler | None _StreamT = TypeVar("_StreamT", bound=SupportsWrite[str]) diff --git a/mypy/typeshed/stdlib/pathlib.pyi b/mypy/typeshed/stdlib/pathlib.pyi index 5ea025095f68..0013e221f2e1 100644 --- a/mypy/typeshed/stdlib/pathlib.pyi +++ b/mypy/typeshed/stdlib/pathlib.pyi @@ -15,7 +15,7 @@ from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWra from os import PathLike, stat_result from types import TracebackType from typing import IO, Any, BinaryIO, Literal, overload -from typing_extensions import Self +from typing_extensions import Self, deprecated if sys.version_info >= (3, 9): from types import GenericAlias @@ -222,7 +222,11 @@ class Path(PurePath): else: def write_text(self, data: str, encoding: str | None = None, errors: str | None = None) -> int: ... if sys.version_info < (3, 12): - def link_to(self, target: StrOrBytesPath) -> None: ... + if sys.version_info >= (3, 10): + @deprecated("Deprecated as of Python 3.10 and removed in Python 3.12. Use hardlink_to() instead.") + def link_to(self, target: StrOrBytesPath) -> None: ... + else: + def link_to(self, target: StrOrBytesPath) -> None: ... if sys.version_info >= (3, 12): def walk( self, top_down: bool = ..., on_error: Callable[[OSError], object] | None = ..., follow_symlinks: bool = ... diff --git a/mypy/typeshed/stdlib/pkgutil.pyi b/mypy/typeshed/stdlib/pkgutil.pyi index 4a0c8d101b7a..7e7fa4fda9a1 100644 --- a/mypy/typeshed/stdlib/pkgutil.pyi +++ b/mypy/typeshed/stdlib/pkgutil.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import SupportsRead +from _typeshed.importlib import LoaderProtocol, MetaPathFinderProtocol, PathEntryFinderProtocol from collections.abc import Callable, Iterable, Iterator -from importlib.abc import Loader, MetaPathFinder, PathEntryFinder from typing import IO, Any, NamedTuple, TypeVar from typing_extensions import deprecated @@ -23,7 +23,7 @@ if sys.version_info < (3, 12): _PathT = TypeVar("_PathT", bound=Iterable[str]) class ModuleInfo(NamedTuple): - module_finder: MetaPathFinder | PathEntryFinder + module_finder: MetaPathFinderProtocol | PathEntryFinderProtocol name: str ispkg: bool @@ -37,11 +37,11 @@ if sys.version_info < (3, 12): def __init__(self, fullname: str, file: IO[str], filename: str, etc: tuple[str, str, int]) -> None: ... @deprecated("Use importlib.util.find_spec() instead. Will be removed in Python 3.14.") -def find_loader(fullname: str) -> Loader | None: ... -def get_importer(path_item: str) -> PathEntryFinder | None: ... +def find_loader(fullname: str) -> LoaderProtocol | None: ... +def get_importer(path_item: str) -> PathEntryFinderProtocol | None: ... @deprecated("Use importlib.util.find_spec() instead. Will be removed in Python 3.14.") -def get_loader(module_or_name: str) -> Loader | None: ... -def iter_importers(fullname: str = "") -> Iterator[MetaPathFinder | PathEntryFinder]: ... +def get_loader(module_or_name: str) -> LoaderProtocol | None: ... +def iter_importers(fullname: str = "") -> Iterator[MetaPathFinderProtocol | PathEntryFinderProtocol]: ... def iter_modules(path: Iterable[str] | None = None, prefix: str = "") -> Iterator[ModuleInfo]: ... def read_code(stream: SupportsRead[bytes]) -> Any: ... # undocumented def walk_packages( diff --git a/mypy/typeshed/stdlib/shelve.pyi b/mypy/typeshed/stdlib/shelve.pyi index 59abeafe6fca..654c2ea097f7 100644 --- a/mypy/typeshed/stdlib/shelve.pyi +++ b/mypy/typeshed/stdlib/shelve.pyi @@ -1,3 +1,5 @@ +import sys +from _typeshed import StrOrBytesPath from collections.abc import Iterator, MutableMapping from dbm import _TFlags from types import TracebackType @@ -41,6 +43,17 @@ class BsdDbShelf(Shelf[_VT]): def last(self) -> tuple[str, _VT]: ... class DbfilenameShelf(Shelf[_VT]): - def __init__(self, filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> None: ... + if sys.version_info >= (3, 11): + def __init__( + self, filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + ) -> None: ... + else: + def __init__(self, filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> None: ... -def open(filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> Shelf[Any]: ... +if sys.version_info >= (3, 11): + def open( + filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + ) -> Shelf[Any]: ... + +else: + def open(filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> Shelf[Any]: ... diff --git a/mypy/typeshed/stdlib/socket.pyi b/mypy/typeshed/stdlib/socket.pyi index a309bac9370a..b626409d2dde 100644 --- a/mypy/typeshed/stdlib/socket.pyi +++ b/mypy/typeshed/stdlib/socket.pyi @@ -474,6 +474,13 @@ if sys.version_info >= (3, 12): ETHERTYPE_VLAN as ETHERTYPE_VLAN, ) + if sys.platform == "linux": + from _socket import ETH_P_ALL as ETH_P_ALL + + if sys.platform != "linux" and sys.platform != "win32" and sys.platform != "darwin": + # FreeBSD >= 14.0 + from _socket import PF_DIVERT as PF_DIVERT + # Re-exported from errno EBADF: int EAGAIN: int @@ -525,6 +532,9 @@ class AddressFamily(IntEnum): AF_BLUETOOTH = 32 if sys.platform == "win32" and sys.version_info >= (3, 12): AF_HYPERV = 34 + if sys.platform != "linux" and sys.platform != "win32" and sys.platform != "darwin" and sys.version_info >= (3, 12): + # FreeBSD >= 14.0 + AF_DIVERT = 44 AF_INET = AddressFamily.AF_INET AF_INET6 = AddressFamily.AF_INET6 @@ -577,6 +587,9 @@ if sys.platform != "win32" or sys.version_info >= (3, 9): if sys.platform == "win32" and sys.version_info >= (3, 12): AF_HYPERV = AddressFamily.AF_HYPERV +if sys.platform != "linux" and sys.platform != "win32" and sys.platform != "darwin" and sys.version_info >= (3, 12): + # FreeBSD >= 14.0 + AF_DIVERT = AddressFamily.AF_DIVERT class SocketKind(IntEnum): SOCK_STREAM = 1 diff --git a/mypy/typeshed/stdlib/sys/__init__.pyi b/mypy/typeshed/stdlib/sys/__init__.pyi index 353e20c4b2e1..5867c9a9d510 100644 --- a/mypy/typeshed/stdlib/sys/__init__.pyi +++ b/mypy/typeshed/stdlib/sys/__init__.pyi @@ -1,9 +1,8 @@ import sys from _typeshed import OptExcInfo, ProfileFunction, TraceFunction, structseq +from _typeshed.importlib import MetaPathFinderProtocol, PathEntryFinderProtocol from builtins import object as _object 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, Final, Literal, NoReturn, Protocol, TextIO, TypeVar, final @@ -15,10 +14,6 @@ _T = TypeVar("_T") _ExitCode: TypeAlias = str | int | None _OptExcInfo: TypeAlias = OptExcInfo # noqa: Y047 # TODO: obsolete, remove fall 2022 or later -# Intentionally omits one deprecated and one optional method of `importlib.abc.MetaPathFinder` -class _MetaPathFinder(Protocol): - def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = ..., /) -> ModuleSpec | None: ... - # ----- sys variables ----- if sys.platform != "win32": abiflags: str @@ -44,13 +39,13 @@ if sys.version_info >= (3, 12): last_exc: BaseException # or undefined. maxsize: int maxunicode: int -meta_path: list[_MetaPathFinder] +meta_path: list[MetaPathFinderProtocol] modules: dict[str, ModuleType] if sys.version_info >= (3, 10): orig_argv: list[str] path: list[str] -path_hooks: list[Callable[[str], PathEntryFinder]] -path_importer_cache: dict[str, PathEntryFinder | None] +path_hooks: list[Callable[[str], PathEntryFinderProtocol]] +path_importer_cache: dict[str, PathEntryFinderProtocol | None] platform: str if sys.version_info >= (3, 9): platlibdir: str diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index ce8f2f1f5929..b66369926404 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -374,7 +374,11 @@ class SpooledTemporaryFile(IO[AnyStr], _SpooledTemporaryFileBase): def readlines(self, hint: int = ..., /) -> list[AnyStr]: ... # type: ignore[override] def seek(self, offset: int, whence: int = ...) -> int: ... def tell(self) -> int: ... - def truncate(self, size: int | None = None) -> None: ... # type: ignore[override] + if sys.version_info >= (3, 11): + def truncate(self, size: int | None = None) -> int: ... + else: + def truncate(self, size: int | None = None) -> None: ... # type: ignore[override] + @overload def write(self: SpooledTemporaryFile[str], s: str) -> int: ... @overload diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index f2d79b7f3ade..38940b4345c8 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -1,5 +1,6 @@ import sys from _typeshed import SupportsKeysAndGetItem +from _typeshed.importlib import LoaderProtocol from collections.abc import ( AsyncGenerator, Awaitable, @@ -16,7 +17,7 @@ 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, Literal, Mapping, Protocol, TypeVar, final, overload # noqa: Y022 +from typing import Any, ClassVar, Literal, Mapping, TypeVar, final, overload # noqa: Y022 from typing_extensions import ParamSpec, Self, TypeVarTuple, deprecated __all__ = [ @@ -64,18 +65,11 @@ _T2 = TypeVar("_T2") _KT = TypeVar("_KT") _VT_co = TypeVar("_VT_co", covariant=True) -@final -class _Cell: - def __new__(cls, contents: object = ..., /) -> Self: ... - def __eq__(self, value: object, /) -> bool: ... - __hash__: ClassVar[None] # type: ignore[assignment] - cell_contents: Any - # Make sure this class definition stays roughly in line with `builtins.function` @final class FunctionType: @property - def __closure__(self) -> tuple[_Cell, ...] | None: ... + def __closure__(self) -> tuple[CellType, ...] | None: ... __code__: CodeType __defaults__: tuple[Any, ...] | None __dict__: dict[str, Any] @@ -98,7 +92,7 @@ class FunctionType: globals: dict[str, Any], name: str | None = ..., argdefs: tuple[object, ...] | None = ..., - closure: tuple[_Cell, ...] | None = ..., + closure: tuple[CellType, ...] | None = ..., ) -> Self: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... @overload @@ -318,15 +312,12 @@ class SimpleNamespace: def __setattr__(self, name: str, value: Any, /) -> None: ... def __delattr__(self, name: str, /) -> None: ... -class _LoaderProtocol(Protocol): - def load_module(self, fullname: str, /) -> ModuleType: ... - class ModuleType: __name__: str __file__: str | None @property def __dict__(self) -> dict[str, Any]: ... # type: ignore[override] - __loader__: _LoaderProtocol | None + __loader__: LoaderProtocol | None __package__: str | None __path__: MutableSequence[str] __spec__: ModuleSpec | None @@ -336,6 +327,12 @@ class ModuleType: # using `builtins.__import__` or `importlib.import_module` less painful def __getattr__(self, name: str) -> Any: ... +@final +class CellType: + def __new__(cls, contents: object = ..., /) -> Self: ... + __hash__: ClassVar[None] # type: ignore[assignment] + cell_contents: Any + _YieldT_co = TypeVar("_YieldT_co", covariant=True) _SendT_contra = TypeVar("_SendT_contra", contravariant=True) _ReturnT_co = TypeVar("_ReturnT_co", covariant=True) @@ -405,7 +402,7 @@ class CoroutineType(Coroutine[_YieldT_co, _SendT_contra, _ReturnT_co]): @final class MethodType: @property - def __closure__(self) -> tuple[_Cell, ...] | None: ... # inherited from the added function + def __closure__(self) -> tuple[CellType, ...] | None: ... # inherited from the added function @property def __defaults__(self) -> tuple[Any, ...] | None: ... # inherited from the added function @property @@ -570,8 +567,6 @@ def coroutine(func: Callable[_P, Generator[Any, Any, _R]]) -> Callable[_P, Await @overload def coroutine(func: _Fn) -> _Fn: ... -CellType = _Cell - if sys.version_info >= (3, 9): class GenericAlias: @property diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 4b80397bdd7a..d047f1c87621 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -8,7 +8,6 @@ import typing_extensions from _collections_abc import dict_items, dict_keys, dict_values from _typeshed import IdentityFunction, ReadableBuffer, SupportsKeysAndGetItem from abc import ABCMeta, abstractmethod -from contextlib import AbstractAsyncContextManager, AbstractContextManager from re import Match as Match, Pattern as Pattern from types import ( BuiltinFunctionType, @@ -24,10 +23,10 @@ from types import ( ) from typing_extensions import Never as _Never, ParamSpec as _ParamSpec -if sys.version_info >= (3, 10): - from types import UnionType if sys.version_info >= (3, 9): from types import GenericAlias +if sys.version_info >= (3, 10): + from types import UnionType __all__ = [ "AbstractSet", @@ -402,8 +401,8 @@ class Reversible(Iterable[_T_co], Protocol[_T_co]): def __reversed__(self) -> Iterator[_T_co]: ... _YieldT_co = TypeVar("_YieldT_co", covariant=True) -_SendT_contra = TypeVar("_SendT_contra", contravariant=True) -_ReturnT_co = TypeVar("_ReturnT_co", covariant=True) +_SendT_contra = TypeVar("_SendT_contra", contravariant=True, default=None) +_ReturnT_co = TypeVar("_ReturnT_co", covariant=True, default=None) class Generator(Iterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra, _ReturnT_co]): def __next__(self) -> _YieldT_co: ... @@ -428,24 +427,28 @@ class Generator(Iterator[_YieldT_co], Generic[_YieldT_co, _SendT_contra, _Return @property def gi_yieldfrom(self) -> Generator[Any, Any, Any] | None: ... -# NOTE: Technically we would like this to be able to accept a second parameter as well, just -# like it's counterpart in contextlib, however `typing._SpecialGenericAlias` enforces the -# correct number of arguments at runtime, so we would be hiding runtime errors. -@runtime_checkable -class ContextManager(AbstractContextManager[_T_co, bool | None], Protocol[_T_co]): ... +# NOTE: Prior to Python 3.13 these aliases are lacking the second _ExitT_co parameter +if sys.version_info >= (3, 13): + from contextlib import AbstractAsyncContextManager as AsyncContextManager, AbstractContextManager as ContextManager +else: + from contextlib import AbstractAsyncContextManager, AbstractContextManager -# NOTE: Technically we would like this to be able to accept a second parameter as well, just -# like it's counterpart in contextlib, however `typing._SpecialGenericAlias` enforces the -# correct number of arguments at runtime, so we would be hiding runtime errors. -@runtime_checkable -class AsyncContextManager(AbstractAsyncContextManager[_T_co, bool | None], Protocol[_T_co]): ... + @runtime_checkable + class ContextManager(AbstractContextManager[_T_co, bool | None], Protocol[_T_co]): ... + + @runtime_checkable + class AsyncContextManager(AbstractAsyncContextManager[_T_co, bool | None], Protocol[_T_co]): ... @runtime_checkable class Awaitable(Protocol[_T_co]): @abstractmethod def __await__(self) -> Generator[Any, Any, _T_co]: ... -class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _ReturnT_co]): +# Non-default variations to accommodate couroutines, and `AwaitableGenerator` having a 4th type parameter. +_SendT_contra_nd = TypeVar("_SendT_contra_nd", contravariant=True) +_ReturnT_co_nd = TypeVar("_ReturnT_co_nd", covariant=True) + +class Coroutine(Awaitable[_ReturnT_co_nd], Generic[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd]): __name__: str __qualname__: str @property @@ -457,7 +460,7 @@ class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _Retu @property def cr_running(self) -> bool: ... @abstractmethod - def send(self, value: _SendT_contra, /) -> _YieldT_co: ... + def send(self, value: _SendT_contra_nd, /) -> _YieldT_co: ... @overload @abstractmethod def throw( @@ -473,9 +476,9 @@ class Coroutine(Awaitable[_ReturnT_co], Generic[_YieldT_co, _SendT_contra, _Retu # The parameters correspond to Generator, but the 4th is the original type. @type_check_only class AwaitableGenerator( - Awaitable[_ReturnT_co], - Generator[_YieldT_co, _SendT_contra, _ReturnT_co], - Generic[_YieldT_co, _SendT_contra, _ReturnT_co, _S], + Awaitable[_ReturnT_co_nd], + Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + Generic[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd, _S], metaclass=ABCMeta, ): ... From 0a2225b0754d7bd0714291820d56833d5284b2a4 Mon Sep 17 00:00:00 2001 From: Valentin Stanciu <250871+svalentin@users.noreply.github.com> Date: Wed, 15 May 2024 10:48:15 +0100 Subject: [PATCH 168/172] [dmypy] sort list of files for update by extension (#17245) dmypy receives the list of updated files via `--update` flag. If this list contains both `foo.py` and `foo.pyi`, the order matters. It seems to process the first file in the list first. But if we have a `.pyi` file, we want this to be processed first since this one contains the typing information. Let's reverse sort the list of updated files by the extension. This should be a simple enough fix to resolve this. Though there might be some edge cases where the list of files to update contains just pyi files, but we might need to recheck the equivalent py files even if not explicitly updated. --- mypy/dmypy_server.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mypy/dmypy_server.py b/mypy/dmypy_server.py index 3d337eedbf1c..f8a0f91f87d9 100644 --- a/mypy/dmypy_server.py +++ b/mypy/dmypy_server.py @@ -383,6 +383,9 @@ def cmd_recheck( removals = set(remove) sources = [s for s in sources if s.path and s.path not in removals] if update: + # Sort list of file updates by extension, so *.pyi files are first. + update.sort(key=lambda f: os.path.splitext(f)[1], reverse=True) + known = {s.path for s in sources if s.path} added = [p for p in update if p not in known] try: From cdc956bd209285b43cfca712902be2da04d133f9 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 15 May 2024 14:14:41 +0200 Subject: [PATCH 169/172] Ignore typeshed test files (#17249) During the last typehed update, we included the `@tests` folder which is unnecessary for mypy. Update the `sync-typeshed.py` script to exclude it in the future. Refs: - #17246 - https://github.com/python/typeshed/issues/11762 --------- Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: AlexWaygood --- misc/sync-typeshed.py | 4 +- .../test_cases/asyncio/check_coroutines.py | 25 -- .../@tests/test_cases/asyncio/check_gather.py | 38 -- .../@tests/test_cases/asyncio/check_task.py | 28 -- .../test_cases/builtins/check_dict-py39.py | 67 --- .../@tests/test_cases/builtins/check_dict.py | 58 --- .../builtins/check_exception_group-py311.py | 323 -------------- .../test_cases/builtins/check_iteration.py | 16 - .../@tests/test_cases/builtins/check_list.py | 21 - .../test_cases/builtins/check_object.py | 13 - .../@tests/test_cases/builtins/check_pow.py | 91 ---- .../test_cases/builtins/check_reversed.py | 34 -- .../@tests/test_cases/builtins/check_round.py | 68 --- .../@tests/test_cases/builtins/check_sum.py | 55 --- .../@tests/test_cases/builtins/check_tuple.py | 13 - .../stdlib/@tests/test_cases/check_codecs.py | 13 - .../test_cases/check_concurrent_futures.py | 30 -- .../@tests/test_cases/check_contextlib.py | 20 - .../@tests/test_cases/check_dataclasses.py | 101 ----- .../stdlib/@tests/test_cases/check_enum.py | 38 -- .../@tests/test_cases/check_functools.py | 67 --- .../@tests/test_cases/check_importlib.py | 47 -- .../test_cases/check_importlib_metadata.py | 33 -- .../stdlib/@tests/test_cases/check_io.py | 6 - .../stdlib/@tests/test_cases/check_logging.py | 30 -- .../test_cases/check_multiprocessing.py | 14 - .../stdlib/@tests/test_cases/check_pathlib.py | 20 - .../stdlib/@tests/test_cases/check_re.py | 26 -- .../stdlib/@tests/test_cases/check_sqlite3.py | 26 -- .../stdlib/@tests/test_cases/check_tarfile.py | 13 - .../@tests/test_cases/check_tempfile.py | 31 -- .../@tests/test_cases/check_threading.py | 14 - .../stdlib/@tests/test_cases/check_tkinter.py | 30 -- .../@tests/test_cases/check_unittest.py | 173 -------- .../stdlib/@tests/test_cases/check_xml.py | 35 -- .../collections/check_defaultdict-py39.py | 69 --- .../@tests/test_cases/email/check_message.py | 6 - .../itertools/check_itertools_recipes.py | 410 ------------------ .../test_cases/typing/check_MutableMapping.py | 18 - .../@tests/test_cases/typing/check_all.py | 14 - .../typing/check_regression_issue_9296.py | 16 - .../test_cases/typing/check_typing_io.py | 21 - 42 files changed, 3 insertions(+), 2172 deletions(-) delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_enum.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_functools.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_io.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_logging.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_re.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_threading.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/check_xml.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py delete mode 100644 mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py diff --git a/misc/sync-typeshed.py b/misc/sync-typeshed.py index 3101b4bfa72a..22023234710e 100644 --- a/misc/sync-typeshed.py +++ b/misc/sync-typeshed.py @@ -51,7 +51,9 @@ def update_typeshed(typeshed_dir: str, commit: str | None) -> str: # Remove existing stubs. shutil.rmtree(stdlib_dir) # Copy new stdlib stubs. - shutil.copytree(os.path.join(typeshed_dir, "stdlib"), stdlib_dir) + shutil.copytree( + os.path.join(typeshed_dir, "stdlib"), stdlib_dir, ignore=shutil.ignore_patterns("@tests") + ) shutil.copy(os.path.join(typeshed_dir, "LICENSE"), os.path.join("mypy", "typeshed")) return commit diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py deleted file mode 100644 index 160bd896469e..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_coroutines.py +++ /dev/null @@ -1,25 +0,0 @@ -from __future__ import annotations - -from asyncio import iscoroutinefunction -from collections.abc import Awaitable, Callable, Coroutine -from typing import Any -from typing_extensions import assert_type - - -def test_iscoroutinefunction( - x: Callable[[str, int], Coroutine[str, int, bytes]], - y: Callable[[str, int], Awaitable[bytes]], - z: Callable[[str, int], str | Awaitable[bytes]], - xx: object, -) -> None: - if iscoroutinefunction(x): - assert_type(x, Callable[[str, int], Coroutine[str, int, bytes]]) - - if iscoroutinefunction(y): - assert_type(y, Callable[[str, int], Coroutine[Any, Any, bytes]]) - - if iscoroutinefunction(z): - assert_type(z, Callable[[str, int], Coroutine[Any, Any, Any]]) - - if iscoroutinefunction(xx): - assert_type(xx, Callable[..., Coroutine[Any, Any, Any]]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py deleted file mode 100644 index 02a01e39731a..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_gather.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations - -import asyncio -from typing import Awaitable, List, Tuple, Union -from typing_extensions import assert_type - - -async def coro1() -> int: - return 42 - - -async def coro2() -> str: - return "spam" - - -async def test_gather(awaitable1: Awaitable[int], awaitable2: Awaitable[str]) -> None: - a = await asyncio.gather(awaitable1) - assert_type(a, Tuple[int]) - - b = await asyncio.gather(awaitable1, awaitable2, return_exceptions=True) - assert_type(b, Tuple[Union[int, BaseException], Union[str, BaseException]]) - - c = await asyncio.gather(awaitable1, awaitable2, awaitable1, awaitable1, awaitable1, awaitable1) - assert_type(c, Tuple[int, str, int, int, int, int]) - - d = await asyncio.gather(awaitable1, awaitable1, awaitable1, awaitable1, awaitable1, awaitable1, awaitable1) - assert_type(d, List[int]) - - awaitables_list: list[Awaitable[int]] = [awaitable1] - e = await asyncio.gather(*awaitables_list) - assert_type(e, List[int]) - - # this case isn't reliable between typecheckers, no one would ever call it with no args anyway - # f = await asyncio.gather() - # assert_type(f, list[Any]) - - -asyncio.run(test_gather(coro1(), coro2())) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py b/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py deleted file mode 100644 index 69bcf8f782aa..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/asyncio/check_task.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import annotations - -import asyncio - - -class Waiter: - def __init__(self) -> None: - self.tasks: list[asyncio.Task[object]] = [] - - def add(self, t: asyncio.Task[object]) -> None: - self.tasks.append(t) - - async def join(self) -> None: - await asyncio.wait(self.tasks) - - -async def foo() -> int: - return 42 - - -async def main() -> None: - # asyncio.Task is covariant in its type argument, which is unusual since its parent class - # asyncio.Future is invariant in its type argument. This is only sound because asyncio.Task - # is not actually Liskov substitutable for asyncio.Future: it does not implement set_result. - w = Waiter() - t: asyncio.Task[int] = asyncio.create_task(foo()) - w.add(t) - await w.join() diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py deleted file mode 100644 index d707cfed222e..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict-py39.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Tests for `dict.__(r)or__`. - -`dict.__or__` and `dict.__ror__` were only added in py39, -hence why these are in a separate file to the other test cases for `dict`. -""" - -from __future__ import annotations - -import os -import sys -from typing import Mapping, TypeVar, Union -from typing_extensions import Self, assert_type - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - -if sys.version_info >= (3, 9): - - class CustomDictSubclass(dict[_KT, _VT]): - pass - - class CustomMappingWithDunderOr(Mapping[_KT, _VT]): - def __or__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: - return {} - - def __ror__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: - return {} - - def __ior__(self, other: Mapping[_KT, _VT]) -> Self: - return self - - def test_dict_dot_or( - a: dict[int, int], - b: CustomDictSubclass[int, int], - c: dict[str, str], - d: Mapping[int, int], - e: CustomMappingWithDunderOr[str, str], - ) -> None: - # dict.__(r)or__ always returns a dict, even if called on a subclass of dict: - assert_type(a | b, dict[int, int]) - assert_type(b | a, dict[int, int]) - - assert_type(a | c, dict[Union[int, str], Union[int, str]]) - - # arbitrary mappings are not accepted by `dict.__or__`; - # it has to be a subclass of `dict` - a | d # type: ignore - - # but Mappings such as `os._Environ` or `CustomMappingWithDunderOr`, - # which define `__ror__` methods that accept `dict`, are fine: - assert_type(a | os.environ, dict[Union[str, int], Union[str, int]]) - assert_type(os.environ | a, dict[Union[str, int], Union[str, int]]) - - assert_type(c | os.environ, dict[str, str]) - assert_type(c | e, dict[str, str]) - - assert_type(os.environ | c, dict[str, str]) - assert_type(e | c, dict[str, str]) - - e |= c - e |= a # type: ignore - - # TODO: this test passes mypy, but fails pyright for some reason: - # c |= e - - c |= a # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py deleted file mode 100644 index aa920d045cbc..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_dict.py +++ /dev/null @@ -1,58 +0,0 @@ -from __future__ import annotations - -from typing import Dict, Generic, Iterable, TypeVar -from typing_extensions import assert_type - -# These do follow `__init__` overloads order: -# mypy and pyright have different opinions about this one: -# mypy raises: 'Need type annotation for "bad"' -# pyright is fine with it. -# bad = dict() -good: dict[str, str] = dict() -assert_type(good, Dict[str, str]) - -assert_type(dict(arg=1), Dict[str, int]) - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - - -class KeysAndGetItem(Generic[_KT, _VT]): - data: dict[_KT, _VT] - - def __init__(self, data: dict[_KT, _VT]) -> None: - self.data = data - - def keys(self) -> Iterable[_KT]: - return self.data.keys() - - def __getitem__(self, __k: _KT) -> _VT: - return self.data[__k] - - -kt1: KeysAndGetItem[int, str] = KeysAndGetItem({0: ""}) -assert_type(dict(kt1), Dict[int, str]) -dict(kt1, arg="a") # type: ignore - -kt2: KeysAndGetItem[str, int] = KeysAndGetItem({"": 0}) -assert_type(dict(kt2, arg=1), Dict[str, int]) - - -def test_iterable_tuple_overload(x: Iterable[tuple[int, str]]) -> dict[int, str]: - return dict(x) - - -i1: Iterable[tuple[int, str]] = [(1, "a"), (2, "b")] -test_iterable_tuple_overload(i1) -dict(i1, arg="a") # type: ignore - -i2: Iterable[tuple[str, int]] = [("a", 1), ("b", 2)] -assert_type(dict(i2, arg=1), Dict[str, int]) - -i3: Iterable[str] = ["a.b"] -i4: Iterable[bytes] = [b"a.b"] -assert_type(dict(string.split(".") for string in i3), Dict[str, str]) -assert_type(dict(string.split(b".") for string in i4), Dict[bytes, bytes]) - -dict(["foo", "bar", "baz"]) # type: ignore -dict([b"foo", b"bar", b"baz"]) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py deleted file mode 100644 index e53cd12288a4..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_exception_group-py311.py +++ /dev/null @@ -1,323 +0,0 @@ -from __future__ import annotations - -import sys -from typing import TypeVar -from typing_extensions import assert_type - -if sys.version_info >= (3, 11): - # This can be removed later, but right now Flake8 does not know - # about these two classes: - from builtins import BaseExceptionGroup, ExceptionGroup - - # BaseExceptionGroup - # ================== - # `BaseExceptionGroup` can work with `BaseException`: - beg = BaseExceptionGroup("x", [SystemExit(), SystemExit()]) - assert_type(beg, BaseExceptionGroup[SystemExit]) - assert_type(beg.exceptions, tuple[SystemExit | BaseExceptionGroup[SystemExit], ...]) - - # Covariance works: - _beg1: BaseExceptionGroup[BaseException] = beg - - # `BaseExceptionGroup` can work with `Exception`: - beg2 = BaseExceptionGroup("x", [ValueError()]) - # FIXME: this is not right, runtime returns `ExceptionGroup` instance instead, - # but I am unable to represent this with types right now. - assert_type(beg2, BaseExceptionGroup[ValueError]) - - # .subgroup() - # ----------- - - assert_type(beg.subgroup(KeyboardInterrupt), BaseExceptionGroup[KeyboardInterrupt] | None) - assert_type(beg.subgroup((KeyboardInterrupt,)), BaseExceptionGroup[KeyboardInterrupt] | None) - - def is_base_exc(exc: BaseException) -> bool: - return isinstance(exc, BaseException) - - def is_specific(exc: SystemExit | BaseExceptionGroup[SystemExit]) -> bool: - return isinstance(exc, SystemExit) - - # This one does not have `BaseExceptionGroup` part, - # this is why we treat as an error. - def is_system_exit(exc: SystemExit) -> bool: - return isinstance(exc, SystemExit) - - def unrelated_subgroup(exc: KeyboardInterrupt) -> bool: - return False - - assert_type(beg.subgroup(is_base_exc), BaseExceptionGroup[SystemExit] | None) - assert_type(beg.subgroup(is_specific), BaseExceptionGroup[SystemExit] | None) - beg.subgroup(is_system_exit) # type: ignore - beg.subgroup(unrelated_subgroup) # type: ignore - - # `Exception`` subgroup returns `ExceptionGroup`: - assert_type(beg.subgroup(ValueError), ExceptionGroup[ValueError] | None) - assert_type(beg.subgroup((ValueError,)), ExceptionGroup[ValueError] | None) - - # Callable are harder, we don't support cast to `ExceptionGroup` here. - # Because callables might return `True` the first time. And `BaseExceptionGroup` - # will stick, no matter what arguments are. - - def is_exception(exc: Exception) -> bool: - return isinstance(exc, Exception) - - def is_exception_or_beg(exc: Exception | BaseExceptionGroup[SystemExit]) -> bool: - return isinstance(exc, Exception) - - # This is an error because of the `Exception` argument type, - # while `SystemExit` is needed instead. - beg.subgroup(is_exception_or_beg) # type: ignore - - # This is an error, because `BaseExceptionGroup` is not an `Exception` - # subclass. It is required. - beg.subgroup(is_exception) # type: ignore - - # .split() - # -------- - - assert_type( - beg.split(KeyboardInterrupt), tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None] - ) - assert_type( - beg.split((KeyboardInterrupt,)), - tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None], - ) - assert_type( - beg.split(ValueError), # there are no `ValueError` items in there, but anyway - tuple[ExceptionGroup[ValueError] | None, BaseExceptionGroup[SystemExit] | None], - ) - - excs_to_split: list[ValueError | KeyError | SystemExit] = [ValueError(), KeyError(), SystemExit()] - to_split = BaseExceptionGroup("x", excs_to_split) - assert_type(to_split, BaseExceptionGroup[ValueError | KeyError | SystemExit]) - - # Ideally the first part should be `ExceptionGroup[ValueError]` (done) - # and the second part should be `BaseExceptionGroup[KeyError | SystemExit]`, - # but we cannot subtract type from a union. - # We also cannot change `BaseExceptionGroup` to `ExceptionGroup` even if needed - # in the second part here because of that. - assert_type( - to_split.split(ValueError), - tuple[ExceptionGroup[ValueError] | None, BaseExceptionGroup[ValueError | KeyError | SystemExit] | None], - ) - - def split_callable1(exc: ValueError | KeyError | SystemExit | BaseExceptionGroup[ValueError | KeyError | SystemExit]) -> bool: - return True - - assert_type( - to_split.split(split_callable1), # Concrete type is ok - tuple[ - BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, - BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, - ], - ) - assert_type( - to_split.split(is_base_exc), # Base class is ok - tuple[ - BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, - BaseExceptionGroup[ValueError | KeyError | SystemExit] | None, - ], - ) - # `Exception` cannot be used: `BaseExceptionGroup` is not a subtype of it. - to_split.split(is_exception) # type: ignore - - # .derive() - # --------- - - assert_type(beg.derive([ValueError()]), ExceptionGroup[ValueError]) - assert_type(beg.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) - - # ExceptionGroup - # ============== - - # `ExceptionGroup` can work with `Exception`: - excs: list[ValueError | KeyError] = [ValueError(), KeyError()] - eg = ExceptionGroup("x", excs) - assert_type(eg, ExceptionGroup[ValueError | KeyError]) - assert_type(eg.exceptions, tuple[ValueError | KeyError | ExceptionGroup[ValueError | KeyError], ...]) - - # Covariance works: - _eg1: ExceptionGroup[Exception] = eg - - # `ExceptionGroup` cannot work with `BaseException`: - ExceptionGroup("x", [SystemExit()]) # type: ignore - - # .subgroup() - # ----------- - - # Our decision is to ban cases like:: - # - # >>> eg = ExceptionGroup('x', [ValueError()]) - # >>> eg.subgroup(BaseException) - # ExceptionGroup('e', [ValueError()]) - # - # are possible in runtime. - # We do it because, it does not make sense for all other base exception types. - # Supporting just `BaseException` looks like an overkill. - eg.subgroup(BaseException) # type: ignore - eg.subgroup((KeyboardInterrupt, SystemExit)) # type: ignore - - assert_type(eg.subgroup(Exception), ExceptionGroup[Exception] | None) - assert_type(eg.subgroup(ValueError), ExceptionGroup[ValueError] | None) - assert_type(eg.subgroup((ValueError,)), ExceptionGroup[ValueError] | None) - - def subgroup_eg1(exc: ValueError | KeyError | ExceptionGroup[ValueError | KeyError]) -> bool: - return True - - def subgroup_eg2(exc: ValueError | KeyError) -> bool: - return True - - assert_type(eg.subgroup(subgroup_eg1), ExceptionGroup[ValueError | KeyError] | None) - assert_type(eg.subgroup(is_exception), ExceptionGroup[ValueError | KeyError] | None) - assert_type(eg.subgroup(is_base_exc), ExceptionGroup[ValueError | KeyError] | None) - assert_type(eg.subgroup(is_base_exc), ExceptionGroup[ValueError | KeyError] | None) - - # Does not have `ExceptionGroup` part: - eg.subgroup(subgroup_eg2) # type: ignore - - # .split() - # -------- - - assert_type(eg.split(TypeError), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError | KeyError] | None]) - assert_type(eg.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError | KeyError] | None]) - assert_type( - eg.split(is_exception), tuple[ExceptionGroup[ValueError | KeyError] | None, ExceptionGroup[ValueError | KeyError] | None] - ) - assert_type( - eg.split(is_base_exc), - # is not converted, because `ExceptionGroup` cannot have - # direct `BaseException` subclasses inside. - tuple[ExceptionGroup[ValueError | KeyError] | None, ExceptionGroup[ValueError | KeyError] | None], - ) - - # It does not include `ExceptionGroup` itself, so it will fail: - def value_or_key_error(exc: ValueError | KeyError) -> bool: - return isinstance(exc, (ValueError, KeyError)) - - eg.split(value_or_key_error) # type: ignore - - # `ExceptionGroup` cannot have direct `BaseException` subclasses inside. - eg.split(BaseException) # type: ignore - eg.split((SystemExit, GeneratorExit)) # type: ignore - - # .derive() - # --------- - - assert_type(eg.derive([ValueError()]), ExceptionGroup[ValueError]) - assert_type(eg.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) - - # BaseExceptionGroup Custom Subclass - # ================================== - # In some cases `Self` type can be preserved in runtime, - # but it is impossible to express. That's why we always fallback to - # `BaseExceptionGroup` and `ExceptionGroup`. - - _BE = TypeVar("_BE", bound=BaseException) - - class CustomBaseGroup(BaseExceptionGroup[_BE]): ... - - cb1 = CustomBaseGroup("x", [SystemExit()]) - assert_type(cb1, CustomBaseGroup[SystemExit]) - cb2 = CustomBaseGroup("x", [ValueError()]) - assert_type(cb2, CustomBaseGroup[ValueError]) - - # .subgroup() - # ----------- - - assert_type(cb1.subgroup(KeyboardInterrupt), BaseExceptionGroup[KeyboardInterrupt] | None) - assert_type(cb2.subgroup((KeyboardInterrupt,)), BaseExceptionGroup[KeyboardInterrupt] | None) - - assert_type(cb1.subgroup(ValueError), ExceptionGroup[ValueError] | None) - assert_type(cb2.subgroup((KeyError,)), ExceptionGroup[KeyError] | None) - - def cb_subgroup1(exc: SystemExit | CustomBaseGroup[SystemExit]) -> bool: - return True - - def cb_subgroup2(exc: ValueError | CustomBaseGroup[ValueError]) -> bool: - return True - - assert_type(cb1.subgroup(cb_subgroup1), BaseExceptionGroup[SystemExit] | None) - assert_type(cb2.subgroup(cb_subgroup2), BaseExceptionGroup[ValueError] | None) - cb1.subgroup(cb_subgroup2) # type: ignore - cb2.subgroup(cb_subgroup1) # type: ignore - - # .split() - # -------- - - assert_type( - cb1.split(KeyboardInterrupt), tuple[BaseExceptionGroup[KeyboardInterrupt] | None, BaseExceptionGroup[SystemExit] | None] - ) - assert_type(cb1.split(TypeError), tuple[ExceptionGroup[TypeError] | None, BaseExceptionGroup[SystemExit] | None]) - assert_type(cb2.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, BaseExceptionGroup[ValueError] | None]) - - def cb_split1(exc: SystemExit | CustomBaseGroup[SystemExit]) -> bool: - return True - - def cb_split2(exc: ValueError | CustomBaseGroup[ValueError]) -> bool: - return True - - assert_type(cb1.split(cb_split1), tuple[BaseExceptionGroup[SystemExit] | None, BaseExceptionGroup[SystemExit] | None]) - assert_type(cb2.split(cb_split2), tuple[BaseExceptionGroup[ValueError] | None, BaseExceptionGroup[ValueError] | None]) - cb1.split(cb_split2) # type: ignore - cb2.split(cb_split1) # type: ignore - - # .derive() - # --------- - - # Note, that `Self` type is not preserved in runtime. - assert_type(cb1.derive([ValueError()]), ExceptionGroup[ValueError]) - assert_type(cb1.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) - assert_type(cb2.derive([ValueError()]), ExceptionGroup[ValueError]) - assert_type(cb2.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) - - # ExceptionGroup Custom Subclass - # ============================== - - _E = TypeVar("_E", bound=Exception) - - class CustomGroup(ExceptionGroup[_E]): ... - - CustomGroup("x", [SystemExit()]) # type: ignore - cg1 = CustomGroup("x", [ValueError()]) - assert_type(cg1, CustomGroup[ValueError]) - - # .subgroup() - # ----------- - - cg1.subgroup(BaseException) # type: ignore - cg1.subgroup((KeyboardInterrupt, SystemExit)) # type: ignore - - assert_type(cg1.subgroup(ValueError), ExceptionGroup[ValueError] | None) - assert_type(cg1.subgroup((KeyError,)), ExceptionGroup[KeyError] | None) - - def cg_subgroup1(exc: ValueError | CustomGroup[ValueError]) -> bool: - return True - - def cg_subgroup2(exc: ValueError) -> bool: - return True - - assert_type(cg1.subgroup(cg_subgroup1), ExceptionGroup[ValueError] | None) - cg1.subgroup(cb_subgroup2) # type: ignore - - # .split() - # -------- - - assert_type(cg1.split(TypeError), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError] | None]) - assert_type(cg1.split((TypeError,)), tuple[ExceptionGroup[TypeError] | None, ExceptionGroup[ValueError] | None]) - cg1.split(BaseException) # type: ignore - - def cg_split1(exc: ValueError | CustomGroup[ValueError]) -> bool: - return True - - def cg_split2(exc: ValueError) -> bool: - return True - - assert_type(cg1.split(cg_split1), tuple[ExceptionGroup[ValueError] | None, ExceptionGroup[ValueError] | None]) - cg1.split(cg_split2) # type: ignore - - # .derive() - # --------- - - # Note, that `Self` type is not preserved in runtime. - assert_type(cg1.derive([ValueError()]), ExceptionGroup[ValueError]) - assert_type(cg1.derive([KeyboardInterrupt()]), BaseExceptionGroup[KeyboardInterrupt]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py deleted file mode 100644 index 3d609635377e..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_iteration.py +++ /dev/null @@ -1,16 +0,0 @@ -from __future__ import annotations - -from typing import Iterator -from typing_extensions import assert_type - - -class OldStyleIter: - def __getitem__(self, index: int) -> str: - return str(index) - - -for x in iter(OldStyleIter()): - assert_type(x, str) - -assert_type(iter(OldStyleIter()), Iterator[str]) -assert_type(next(iter(OldStyleIter())), str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py deleted file mode 100644 index 4113f5c66182..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_list.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import annotations - -from typing import List, Union -from typing_extensions import assert_type - - -# list.__add__ example from #8292 -class Foo: - def asd(self) -> int: - return 1 - - -class Bar: - def asd(self) -> int: - return 2 - - -combined = [Foo()] + [Bar()] -assert_type(combined, List[Union[Foo, Bar]]) -for item in combined: - assert_type(item.asd(), int) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py deleted file mode 100644 index 60df1143f727..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_object.py +++ /dev/null @@ -1,13 +0,0 @@ -from __future__ import annotations - -from typing import Any - - -# The following should pass without error (see #6661): -class Diagnostic: - def __reduce__(self) -> str | tuple[Any, ...]: - res = super().__reduce__() - if isinstance(res, tuple) and len(res) >= 3: - res[2]["_info"] = 42 - - return res diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py deleted file mode 100644 index 1f38710d6bea..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_pow.py +++ /dev/null @@ -1,91 +0,0 @@ -from __future__ import annotations - -from decimal import Decimal -from fractions import Fraction -from typing import Any, Literal -from typing_extensions import assert_type - -# See #7163 -assert_type(pow(1, 0), Literal[1]) -assert_type(1**0, Literal[1]) -assert_type(pow(1, 0, None), Literal[1]) - -# TODO: We don't have a good way of expressing the fact -# that passing 0 for the third argument will lead to an exception being raised -# (see discussion in #8566) -# -# assert_type(pow(2, 4, 0), NoReturn) - -assert_type(pow(2, 4), int) -assert_type(2**4, int) -assert_type(pow(4, 6, None), int) - -assert_type(pow(5, -7), float) -assert_type(5**-7, float) - -assert_type(pow(2, 4, 5), int) # pow(, , ) -assert_type(pow(2, 35, 3), int) # pow(, , ) - -assert_type(pow(2, 8.5), float) -assert_type(2**8.6, float) -assert_type(pow(2, 8.6, None), float) - -# TODO: Why does this pass pyright but not mypy?? -# assert_type((-2) ** 0.5, complex) - -assert_type(pow((-5), 8.42, None), complex) - -assert_type(pow(4.6, 8), float) -assert_type(4.6**8, float) -assert_type(pow(5.1, 4, None), float) - -assert_type(pow(complex(6), 6.2), complex) -assert_type(complex(6) ** 6.2, complex) -assert_type(pow(complex(9), 7.3, None), complex) - -assert_type(pow(Fraction(), 4, None), Fraction) -assert_type(Fraction() ** 4, Fraction) - -assert_type(pow(Fraction(3, 7), complex(1, 8)), complex) -assert_type(Fraction(3, 7) ** complex(1, 8), complex) - -assert_type(pow(complex(4, -8), Fraction(2, 3)), complex) -assert_type(complex(4, -8) ** Fraction(2, 3), complex) - -assert_type(pow(Decimal("1.0"), Decimal("1.6")), Decimal) -assert_type(Decimal("1.0") ** Decimal("1.6"), Decimal) - -assert_type(pow(Decimal("1.0"), Decimal("1.0"), Decimal("1.0")), Decimal) -assert_type(pow(Decimal("4.6"), 7, None), Decimal) -assert_type(Decimal("4.6") ** 7, Decimal) - -# These would ideally be more precise, but `Any` is acceptable -# They have to be `Any` due to the fact that type-checkers can't distinguish -# between positive and negative numbers for the second argument to `pow()` -# -# int for positive 2nd-arg, float otherwise -assert_type(pow(4, 65), Any) -assert_type(pow(2, -45), Any) -assert_type(pow(3, 57, None), Any) -assert_type(pow(67, 0.98, None), Any) -assert_type(87**7.32, Any) -# pow(, ) -> float -# pow(, ) -> complex -assert_type(pow(4.7, 7.4), Any) -assert_type(pow(-9.8, 8.3), Any) -assert_type(pow(-9.3, -88.2), Any) -assert_type(pow(8.2, -9.8), Any) -assert_type(pow(4.7, 9.2, None), Any) -# See #7046 -- float for a positive 1st arg, complex otherwise -assert_type((-95) ** 8.42, Any) - -# All of the following cases should fail a type-checker. -pow(1.9, 4, 6) # type: ignore -pow(4, 7, 4.32) # type: ignore -pow(6.2, 5.9, 73) # type: ignore -pow(complex(6), 6.2, 7) # type: ignore -pow(Fraction(), 5, 8) # type: ignore -Decimal("8.7") ** 3.14 # type: ignore - -# TODO: This fails at runtime, but currently passes mypy and pyright: -pow(Decimal("8.5"), 3.21) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py deleted file mode 100644 index 2a43a57deb4e..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_reversed.py +++ /dev/null @@ -1,34 +0,0 @@ -from __future__ import annotations - -from collections.abc import Iterator -from typing import Generic, TypeVar -from typing_extensions import assert_type - -x: list[int] = [] -assert_type(list(reversed(x)), "list[int]") - - -class MyReversible: - def __iter__(self) -> Iterator[str]: - yield "blah" - - def __reversed__(self) -> Iterator[str]: - yield "blah" - - -assert_type(list(reversed(MyReversible())), "list[str]") - - -_T = TypeVar("_T") - - -class MyLenAndGetItem(Generic[_T]): - def __len__(self) -> int: - return 0 - - def __getitem__(self, item: int) -> _T: - raise KeyError - - -len_and_get_item: MyLenAndGetItem[int] = MyLenAndGetItem() -assert_type(list(reversed(len_and_get_item)), "list[int]") diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py deleted file mode 100644 index 84081f3665b9..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_round.py +++ /dev/null @@ -1,68 +0,0 @@ -from __future__ import annotations - -from typing import overload -from typing_extensions import assert_type - - -class CustomIndex: - def __index__(self) -> int: - return 1 - - -# float: - -assert_type(round(5.5), int) -assert_type(round(5.5, None), int) -assert_type(round(5.5, 0), float) -assert_type(round(5.5, 1), float) -assert_type(round(5.5, 5), float) -assert_type(round(5.5, CustomIndex()), float) - -# int: - -assert_type(round(1), int) -assert_type(round(1, 1), int) -assert_type(round(1, None), int) -assert_type(round(1, CustomIndex()), int) - -# Protocols: - - -class WithCustomRound1: - def __round__(self) -> str: - return "a" - - -assert_type(round(WithCustomRound1()), str) -assert_type(round(WithCustomRound1(), None), str) -# Errors: -round(WithCustomRound1(), 1) # type: ignore -round(WithCustomRound1(), CustomIndex()) # type: ignore - - -class WithCustomRound2: - def __round__(self, digits: int) -> str: - return "a" - - -assert_type(round(WithCustomRound2(), 1), str) -assert_type(round(WithCustomRound2(), CustomIndex()), str) -# Errors: -round(WithCustomRound2(), None) # type: ignore -round(WithCustomRound2()) # type: ignore - - -class WithOverloadedRound: - @overload - def __round__(self, ndigits: None = ...) -> str: ... - - @overload - def __round__(self, ndigits: int) -> bytes: ... - - def __round__(self, ndigits: int | None = None) -> str | bytes: - return b"" if ndigits is None else "" - - -assert_type(round(WithOverloadedRound()), str) -assert_type(round(WithOverloadedRound(), None), str) -assert_type(round(WithOverloadedRound(), 1), bytes) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py deleted file mode 100644 index cda7eadbbe41..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_sum.py +++ /dev/null @@ -1,55 +0,0 @@ -from __future__ import annotations - -from typing import Any, List, Literal, Union -from typing_extensions import assert_type - - -class Foo: - def __add__(self, other: Any) -> Foo: - return Foo() - - -class Bar: - def __radd__(self, other: Any) -> Bar: - return Bar() - - -class Baz: - def __add__(self, other: Any) -> Baz: - return Baz() - - def __radd__(self, other: Any) -> Baz: - return Baz() - - -literal_list: list[Literal[0, 1]] = [0, 1, 1] - -assert_type(sum([2, 4]), int) -assert_type(sum([3, 5], 4), int) - -assert_type(sum([True, False]), int) -assert_type(sum([True, False], True), int) -assert_type(sum(literal_list), int) - -assert_type(sum([["foo"], ["bar"]], ["baz"]), List[str]) - -assert_type(sum([Foo(), Foo()], Foo()), Foo) -assert_type(sum([Baz(), Baz()]), Union[Baz, Literal[0]]) - -# mypy and pyright infer the types differently for these, so we can't use assert_type -# Just test that no error is emitted for any of these -sum([("foo",), ("bar", "baz")], ()) # mypy: `tuple[str, ...]`; pyright: `tuple[()] | tuple[str] | tuple[str, str]` -sum([5.6, 3.2]) # mypy: `float`; pyright: `float | Literal[0]` -sum([2.5, 5.8], 5) # mypy: `float`; pyright: `float | int` - -# These all fail at runtime -sum("abcde") # type: ignore -sum([["foo"], ["bar"]]) # type: ignore -sum([("foo",), ("bar", "baz")]) # type: ignore -sum([Foo(), Foo()]) # type: ignore -sum([Bar(), Bar()], Bar()) # type: ignore -sum([Bar(), Bar()]) # type: ignore - -# TODO: these pass pyright with the current stubs, but mypy erroneously emits an error: -# sum([3, Fraction(7, 22), complex(8, 0), 9.83]) -# sum([3, Decimal('0.98')]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py b/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py deleted file mode 100644 index bc0d8db28389..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/builtins/check_tuple.py +++ /dev/null @@ -1,13 +0,0 @@ -from __future__ import annotations - -from typing import Tuple -from typing_extensions import assert_type - - -# Empty tuples, see #8275 -class TupleSub(Tuple[int, ...]): - pass - - -assert_type(TupleSub(), TupleSub) -assert_type(TupleSub([1, 2, 3]), TupleSub) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py b/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py deleted file mode 100644 index 19e663ceeaaf..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_codecs.py +++ /dev/null @@ -1,13 +0,0 @@ -from __future__ import annotations - -import codecs -from typing_extensions import assert_type - -assert_type(codecs.decode("x", "unicode-escape"), str) -assert_type(codecs.decode(b"x", "unicode-escape"), str) - -assert_type(codecs.decode(b"x", "utf-8"), str) -codecs.decode("x", "utf-8") # type: ignore - -assert_type(codecs.decode("ab", "hex"), bytes) -assert_type(codecs.decode(b"ab", "hex"), bytes) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py b/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py deleted file mode 100644 index 962ec23c6b48..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_concurrent_futures.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import annotations - -from collections.abc import Callable, Iterator -from concurrent.futures import Future, ThreadPoolExecutor, as_completed -from typing_extensions import assert_type - - -class Parent: ... - - -class Child(Parent): ... - - -def check_as_completed_covariance() -> None: - with ThreadPoolExecutor() as executor: - f1 = executor.submit(lambda: Parent()) - f2 = executor.submit(lambda: Child()) - fs: list[Future[Parent] | Future[Child]] = [f1, f2] - assert_type(as_completed(fs), Iterator[Future[Parent]]) - for future in as_completed(fs): - assert_type(future.result(), Parent) - - -def check_future_invariance() -> None: - def execute_callback(callback: Callable[[], Parent], future: Future[Parent]) -> None: - future.set_result(callback()) - - fut: Future[Child] = Future() - execute_callback(lambda: Parent(), fut) # type: ignore - assert isinstance(fut.result(), Child) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py deleted file mode 100644 index 648661bca856..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_contextlib.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import annotations - -from contextlib import ExitStack -from typing_extensions import assert_type - - -# See issue #7961 -class Thing(ExitStack): - pass - - -stack = ExitStack() -thing = Thing() -assert_type(stack.enter_context(Thing()), Thing) -assert_type(thing.enter_context(ExitStack()), ExitStack) - -with stack as cm: - assert_type(cm, ExitStack) -with thing as cm2: - assert_type(cm2, Thing) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py b/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py deleted file mode 100644 index 76ce8e1bd260..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_dataclasses.py +++ /dev/null @@ -1,101 +0,0 @@ -from __future__ import annotations - -import dataclasses as dc -from typing import TYPE_CHECKING, Any, Dict, FrozenSet, Tuple, Type, Union -from typing_extensions import Annotated, assert_type - -if TYPE_CHECKING: - from _typeshed import DataclassInstance - - -@dc.dataclass -class Foo: - attr: str - - -assert_type(dc.fields(Foo), Tuple[dc.Field[Any], ...]) - -# Mypy correctly emits errors on these -# due to the fact it's a dataclass class, not an instance. -# Pyright, however, handles ClassVar members in protocols differently. -# See https://github.com/microsoft/pyright/issues/4339 -# -# dc.asdict(Foo) -# dc.astuple(Foo) -# dc.replace(Foo) - -# See #9723 for why we can't make this assertion -# if dc.is_dataclass(Foo): -# assert_type(Foo, Type[Foo]) - -f = Foo(attr="attr") - -assert_type(dc.fields(f), Tuple[dc.Field[Any], ...]) -assert_type(dc.asdict(f), Dict[str, Any]) -assert_type(dc.astuple(f), Tuple[Any, ...]) -assert_type(dc.replace(f, attr="new"), Foo) - -if dc.is_dataclass(f): - # The inferred type doesn't change - # if it's already known to be a subtype of _DataclassInstance - assert_type(f, Foo) - - -def check_other_isdataclass_overloads(x: type, y: object) -> None: - # TODO: pyright correctly emits an error on this, but mypy does not -- why? - # dc.fields(x) - - dc.fields(y) # type: ignore - - dc.asdict(x) # type: ignore - dc.asdict(y) # type: ignore - - dc.astuple(x) # type: ignore - dc.astuple(y) # type: ignore - - dc.replace(x) # type: ignore - dc.replace(y) # type: ignore - - if dc.is_dataclass(x): - assert_type(x, Type["DataclassInstance"]) - assert_type(dc.fields(x), Tuple[dc.Field[Any], ...]) - - # Mypy correctly emits an error on these due to the fact - # that it's a dataclass class, not a dataclass instance. - # Pyright, however, handles ClassVar members in protocols differently. - # See https://github.com/microsoft/pyright/issues/4339 - # - # dc.asdict(x) - # dc.astuple(x) - # dc.replace(x) - - if dc.is_dataclass(y): - assert_type(y, Union["DataclassInstance", Type["DataclassInstance"]]) - assert_type(dc.fields(y), Tuple[dc.Field[Any], ...]) - - # Mypy correctly emits an error on these due to the fact we don't know - # whether it's a dataclass class or a dataclass instance. - # Pyright, however, handles ClassVar members in protocols differently. - # See https://github.com/microsoft/pyright/issues/4339 - # - # dc.asdict(y) - # dc.astuple(y) - # dc.replace(y) - - if dc.is_dataclass(y) and not isinstance(y, type): - assert_type(y, "DataclassInstance") - assert_type(dc.fields(y), Tuple[dc.Field[Any], ...]) - assert_type(dc.asdict(y), Dict[str, Any]) - assert_type(dc.astuple(y), Tuple[Any, ...]) - dc.replace(y) - - -# Regression test for #11653 -D = dc.make_dataclass( - "D", [("a", Union[int, None]), "y", ("z", Annotated[FrozenSet[bytes], "metadata"], dc.field(default=frozenset({b"foo"})))] -) -# Check that it's inferred by the type checker as a class object of some kind -# (but don't assert the exact type that `D` is inferred as, -# in case a type checker decides to add some special-casing for -# `make_dataclass` in the future) -assert_type(D.__mro__, Tuple[type, ...]) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py b/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py deleted file mode 100644 index 4ea4947c811d..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_enum.py +++ /dev/null @@ -1,38 +0,0 @@ -from __future__ import annotations - -import enum -import sys -from typing import Literal, Type -from typing_extensions import assert_type - -A = enum.Enum("A", "spam eggs bacon") -B = enum.Enum("B", ["spam", "eggs", "bacon"]) -C = enum.Enum("Bar", [("spam", 1), ("eggs", 2), ("bacon", 3)]) -D = enum.Enum("Bar", {"spam": 1, "eggs": 2}) - -assert_type(A, Type[A]) -assert_type(B, Type[B]) -assert_type(C, Type[C]) -assert_type(D, Type[D]) - - -class EnumOfTuples(enum.Enum): - X = 1, 2, 3 - Y = 4, 5, 6 - - -assert_type(EnumOfTuples((1, 2, 3)), EnumOfTuples) - -# TODO: ideally this test would pass: -# -# if sys.version_info >= (3, 12): -# assert_type(EnumOfTuples(1, 2, 3), EnumOfTuples) - - -if sys.version_info >= (3, 11): - - class Foo(enum.StrEnum): - X = enum.auto() - - assert_type(Foo.X, Literal[Foo.X]) - assert_type(Foo.X.value, str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py b/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py deleted file mode 100644 index dca572683f8d..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_functools.py +++ /dev/null @@ -1,67 +0,0 @@ -from __future__ import annotations - -from functools import cached_property, wraps -from typing import Callable, TypeVar -from typing_extensions import ParamSpec, assert_type - -P = ParamSpec("P") -T_co = TypeVar("T_co", covariant=True) - - -def my_decorator(func: Callable[P, T_co]) -> Callable[P, T_co]: - @wraps(func) - def wrapper(*args: P.args, **kwargs: P.kwargs) -> T_co: - print(args) - return func(*args, **kwargs) - - # verify that the wrapped function has all these attributes - wrapper.__annotations__ = func.__annotations__ - wrapper.__doc__ = func.__doc__ - wrapper.__module__ = func.__module__ - wrapper.__name__ = func.__name__ - wrapper.__qualname__ = func.__qualname__ - return wrapper - - -class A: - def __init__(self, x: int): - self.x = x - - @cached_property - def x(self) -> int: - return 0 - - -assert_type(A(x=1).x, int) - - -class B: - @cached_property - def x(self) -> int: - return 0 - - -def check_cached_property_settable(x: int) -> None: - b = B() - assert_type(b.x, int) - b.x = x - assert_type(b.x, int) - - -# https://github.com/python/typeshed/issues/10048 -class Parent: ... - - -class Child(Parent): ... - - -class X: - @cached_property - def some(self) -> Parent: - return Parent() - - -class Y(X): - @cached_property - def some(self) -> Child: # safe override - return Child() diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py deleted file mode 100644 index 17eefdafc971..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import annotations - -import importlib.abc -import importlib.util -import pathlib -import sys -import zipfile -from collections.abc import Sequence -from importlib.machinery import ModuleSpec -from types import ModuleType -from typing_extensions import Self - -# Assert that some Path classes are Traversable. -if sys.version_info >= (3, 9): - - def traverse(t: importlib.abc.Traversable) -> None: - pass - - traverse(pathlib.Path()) - traverse(zipfile.Path("")) - - -class MetaFinder: - @classmethod - def find_spec(cls, fullname: str, path: Sequence[str] | None, target: ModuleType | None = None) -> ModuleSpec | None: - return None # simplified mock for demonstration purposes only - - -class PathFinder: - @classmethod - def path_hook(cls, path_entry: str) -> type[Self]: - return cls # simplified mock for demonstration purposes only - - @classmethod - def find_spec(cls, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: - return None # simplified mock for demonstration purposes only - - -class Loader: - @classmethod - def load_module(cls, fullname: str) -> ModuleType: - return ModuleType(fullname) - - -sys.meta_path.append(MetaFinder) -sys.path_hooks.append(PathFinder.path_hook) -importlib.util.spec_from_loader("xxxx42xxxx", Loader) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py b/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py deleted file mode 100644 index f1322e16c54f..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_importlib_metadata.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import annotations - -import sys -from _typeshed import StrPath -from os import PathLike -from pathlib import Path -from typing import Any -from zipfile import Path as ZipPath - -if sys.version_info >= (3, 10): - from importlib.metadata._meta import SimplePath - - # Simplified version of zipfile.Path - class MyPath: - @property - def parent(self) -> PathLike[str]: ... # undocumented - - def read_text(self, encoding: str | None = ..., errors: str | None = ...) -> str: ... - def joinpath(self, *other: StrPath) -> MyPath: ... - def __truediv__(self, add: StrPath) -> MyPath: ... - - if sys.version_info >= (3, 12): - - def takes_simple_path(p: SimplePath[Any]) -> None: ... - - else: - - def takes_simple_path(p: SimplePath) -> None: ... - - takes_simple_path(Path()) - takes_simple_path(ZipPath("")) - takes_simple_path(MyPath()) - takes_simple_path("some string") # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_io.py b/mypy/typeshed/stdlib/@tests/test_cases/check_io.py deleted file mode 100644 index abf84dd5a103..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_io.py +++ /dev/null @@ -1,6 +0,0 @@ -from gzip import GzipFile -from io import FileIO, TextIOWrapper - -TextIOWrapper(FileIO("")) -TextIOWrapper(FileIO(13)) -TextIOWrapper(GzipFile("")) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py b/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py deleted file mode 100644 index fe3d8eb16fd0..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_logging.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import annotations - -import logging -import logging.handlers -import multiprocessing -import queue -from typing import Any - -# This pattern comes from the logging docs, and should therefore pass a type checker -# See https://docs.python.org/3/library/logging.html#logrecord-objects - -old_factory = logging.getLogRecordFactory() - - -def record_factory(*args: Any, **kwargs: Any) -> logging.LogRecord: - record = old_factory(*args, **kwargs) - record.custom_attribute = 0xDECAFBAD - return record - - -logging.setLogRecordFactory(record_factory) - -# The logging docs say that QueueHandler and QueueListener can take "any queue-like object" -# We test that here (regression test for #10168) -logging.handlers.QueueHandler(queue.Queue()) -logging.handlers.QueueHandler(queue.SimpleQueue()) -logging.handlers.QueueHandler(multiprocessing.Queue()) -logging.handlers.QueueListener(queue.Queue()) -logging.handlers.QueueListener(queue.SimpleQueue()) -logging.handlers.QueueListener(multiprocessing.Queue()) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py b/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py deleted file mode 100644 index 201f96c0c4c8..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_multiprocessing.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import annotations - -from ctypes import c_char, c_float -from multiprocessing import Array, Value -from multiprocessing.sharedctypes import Synchronized, SynchronizedString -from typing_extensions import assert_type - -string = Array(c_char, 12) -assert_type(string, SynchronizedString) -assert_type(string.value, bytes) - -field = Value(c_float, 0.0) -assert_type(field, Synchronized[float]) -field.value = 1.2 diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py b/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py deleted file mode 100644 index 0b52c3669d07..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_pathlib.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import annotations - -from pathlib import Path, PureWindowsPath - -if Path("asdf") == Path("asdf"): - ... - -# https://github.com/python/typeshed/issues/10661 -# Provide a true positive error when comparing Path to str -# mypy should report a comparison-overlap error with --strict-equality, -# and pyright should report a reportUnnecessaryComparison error -if Path("asdf") == "asdf": # type: ignore - ... - -# Errors on comparison here are technically false positives. However, this comparison is a little -# interesting: it can never hold true on Posix, but could hold true on Windows. We should experiment -# with more accurate __new__, such that we only get an error for such comparisons on platforms -# where they can never hold true. -if PureWindowsPath("asdf") == Path("asdf"): # type: ignore - ... diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_re.py b/mypy/typeshed/stdlib/@tests/test_cases/check_re.py deleted file mode 100644 index b6ab2b0d59d2..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_re.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import annotations - -import mmap -import re -import typing as t -from typing_extensions import assert_type - - -def check_search(str_pat: re.Pattern[str], bytes_pat: re.Pattern[bytes]) -> None: - assert_type(str_pat.search("x"), t.Optional[t.Match[str]]) - assert_type(bytes_pat.search(b"x"), t.Optional[t.Match[bytes]]) - assert_type(bytes_pat.search(bytearray(b"x")), t.Optional[t.Match[bytes]]) - assert_type(bytes_pat.search(mmap.mmap(0, 10)), t.Optional[t.Match[bytes]]) - - -def check_search_with_AnyStr(pattern: re.Pattern[t.AnyStr], string: t.AnyStr) -> re.Match[t.AnyStr]: - """See issue #9591""" - match = pattern.search(string) - if match is None: - raise ValueError(f"'{string!r}' does not match {pattern!r}") - return match - - -def check_no_ReadableBuffer_false_negatives() -> None: - re.compile("foo").search(bytearray(b"foo")) # type: ignore - re.compile("foo").search(mmap.mmap(0, 10)) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py b/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py deleted file mode 100644 index 3ec47ceccb90..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_sqlite3.py +++ /dev/null @@ -1,26 +0,0 @@ -from __future__ import annotations - -import sqlite3 -from typing_extensions import assert_type - - -class MyConnection(sqlite3.Connection): - pass - - -# Default return-type is Connection. -assert_type(sqlite3.connect(":memory:"), sqlite3.Connection) - -# Providing an alternate factory changes the return-type. -assert_type(sqlite3.connect(":memory:", factory=MyConnection), MyConnection) - -# Provides a true positive error. When checking the connect() function, -# mypy should report an arg-type error for the factory argument. -with sqlite3.connect(":memory:", factory=None) as con: # type: ignore - pass - -# The Connection class also accepts a `factory` arg but it does not affect -# the return-type. This use case is not idiomatic--connections should be -# established using the `connect()` function, not directly (as shown here). -assert_type(sqlite3.Connection(":memory:", factory=None), sqlite3.Connection) -assert_type(sqlite3.Connection(":memory:", factory=MyConnection), sqlite3.Connection) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py deleted file mode 100644 index 54510a3d7626..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_tarfile.py +++ /dev/null @@ -1,13 +0,0 @@ -import tarfile - -with tarfile.open("test.tar.xz", "w:xz") as tar: - pass - -# Test with valid preset values -tarfile.open("test.tar.xz", "w:xz", preset=0) -tarfile.open("test.tar.xz", "w:xz", preset=5) -tarfile.open("test.tar.xz", "w:xz", preset=9) - -# Test with invalid preset values -tarfile.open("test.tar.xz", "w:xz", preset=-1) # type: ignore -tarfile.open("test.tar.xz", "w:xz", preset=10) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py deleted file mode 100644 index c259c192a140..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_tempfile.py +++ /dev/null @@ -1,31 +0,0 @@ -from __future__ import annotations - -import io -import sys -from tempfile import TemporaryFile, _TemporaryFileWrapper -from typing_extensions import assert_type - -if sys.platform == "win32": - assert_type(TemporaryFile(), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile("w+"), _TemporaryFileWrapper[str]) - assert_type(TemporaryFile("w+b"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile("wb"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile("rb"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile("wb", 0), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile(mode="w+"), _TemporaryFileWrapper[str]) - assert_type(TemporaryFile(mode="w+b"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile(mode="wb"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile(mode="rb"), _TemporaryFileWrapper[bytes]) - assert_type(TemporaryFile(buffering=0), _TemporaryFileWrapper[bytes]) -else: - assert_type(TemporaryFile(), io.BufferedRandom) - assert_type(TemporaryFile("w+"), io.TextIOWrapper) - assert_type(TemporaryFile("w+b"), io.BufferedRandom) - assert_type(TemporaryFile("wb"), io.BufferedWriter) - assert_type(TemporaryFile("rb"), io.BufferedReader) - assert_type(TemporaryFile("wb", 0), io.FileIO) - assert_type(TemporaryFile(mode="w+"), io.TextIOWrapper) - assert_type(TemporaryFile(mode="w+b"), io.BufferedRandom) - assert_type(TemporaryFile(mode="wb"), io.BufferedWriter) - assert_type(TemporaryFile(mode="rb"), io.BufferedReader) - assert_type(TemporaryFile(buffering=0), io.FileIO) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py b/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py deleted file mode 100644 index eddfc2549a64..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_threading.py +++ /dev/null @@ -1,14 +0,0 @@ -from __future__ import annotations - -import _threading_local -import threading - -loc = threading.local() -loc.foo = 42 -del loc.foo -loc.baz = ["spam", "eggs"] -del loc.baz - -l2 = _threading_local.local() -l2.asdfasdf = 56 -del l2.asdfasdf diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py b/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py deleted file mode 100644 index befac6697519..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_tkinter.py +++ /dev/null @@ -1,30 +0,0 @@ -from __future__ import annotations - -import tkinter -import traceback -import types - - -def custom_handler(exc: type[BaseException], val: BaseException, tb: types.TracebackType | None) -> None: - print("oh no") - - -root = tkinter.Tk() -root.report_callback_exception = traceback.print_exception -root.report_callback_exception = custom_handler - - -def foo(x: int, y: str) -> None: - pass - - -root.after(1000, foo, 10, "lol") -root.after(1000, foo, 10, 10) # type: ignore - - -# Font size must be integer -label = tkinter.Label() -label.config(font=("", 12)) -label.config(font=("", 12.34)) # type: ignore -label.config(font=("", 12, "bold")) -label.config(font=("", 12.34, "bold")) # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py b/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py deleted file mode 100644 index 40c6efaa8ca0..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_unittest.py +++ /dev/null @@ -1,173 +0,0 @@ -from __future__ import annotations - -import unittest -from collections.abc import Iterator, Mapping -from datetime import datetime, timedelta -from decimal import Decimal -from fractions import Fraction -from typing import TypedDict -from typing_extensions import assert_type -from unittest.mock import MagicMock, Mock, patch - -case = unittest.TestCase() - -### -# Tests for assertAlmostEqual -### - -case.assertAlmostEqual(1, 2.4) -case.assertAlmostEqual(2.4, 2.41) -case.assertAlmostEqual(Fraction(49, 50), Fraction(48, 50)) -case.assertAlmostEqual(3.14, complex(5, 6)) -case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) -case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) -case.assertAlmostEqual(Decimal("1.1"), Decimal("1.11")) -case.assertAlmostEqual(2.4, 2.41, places=8) -case.assertAlmostEqual(2.4, 2.41, delta=0.02) -case.assertAlmostEqual(2.4, 2.41, None, "foo", 0.02) - -case.assertAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore -case.assertAlmostEqual("foo", "bar") # type: ignore -case.assertAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore -case.assertAlmostEqual(Decimal("0.4"), Fraction(1, 2)) # type: ignore -case.assertAlmostEqual(complex(2, 3), Decimal("0.9")) # type: ignore - -### -# Tests for assertNotAlmostEqual -### - -case.assertAlmostEqual(1, 2.4) -case.assertNotAlmostEqual(Fraction(49, 50), Fraction(48, 50)) -case.assertAlmostEqual(3.14, complex(5, 6)) -case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), delta=timedelta(hours=1)) -case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1), None, "foo", timedelta(hours=1)) - -case.assertNotAlmostEqual(2.4, 2.41, places=9, delta=0.02) # type: ignore -case.assertNotAlmostEqual("foo", "bar") # type: ignore -case.assertNotAlmostEqual(datetime(1999, 1, 2), datetime(1999, 1, 2, microsecond=1)) # type: ignore -case.assertNotAlmostEqual(Decimal("0.4"), Fraction(1, 2)) # type: ignore -case.assertNotAlmostEqual(complex(2, 3), Decimal("0.9")) # type: ignore - -### -# Tests for assertGreater -### - - -class Spam: - def __lt__(self, other: object) -> bool: - return True - - -class Eggs: - def __gt__(self, other: object) -> bool: - return True - - -class Ham: - def __lt__(self, other: Ham) -> bool: - if not isinstance(other, Ham): - return NotImplemented - return True - - -class Bacon: - def __gt__(self, other: Bacon) -> bool: - if not isinstance(other, Bacon): - return NotImplemented - return True - - -case.assertGreater(5.8, 3) -case.assertGreater(Decimal("4.5"), Fraction(3, 2)) -case.assertGreater(Fraction(3, 2), 0.9) -case.assertGreater(Eggs(), object()) -case.assertGreater(object(), Spam()) -case.assertGreater(Ham(), Ham()) -case.assertGreater(Bacon(), Bacon()) - -case.assertGreater(object(), object()) # type: ignore -case.assertGreater(datetime(1999, 1, 2), 1) # type: ignore -case.assertGreater(Spam(), Eggs()) # type: ignore -case.assertGreater(Ham(), Bacon()) # type: ignore -case.assertGreater(Bacon(), Ham()) # type: ignore - - -### -# Tests for assertDictEqual -### - - -class TD1(TypedDict): - x: int - y: str - - -class TD2(TypedDict): - a: bool - b: bool - - -class MyMapping(Mapping[str, int]): - def __getitem__(self, __key: str) -> int: - return 42 - - def __iter__(self) -> Iterator[str]: - return iter([]) - - def __len__(self) -> int: - return 0 - - -td1: TD1 = {"x": 1, "y": "foo"} -td2: TD2 = {"a": True, "b": False} -m = MyMapping() - -case.assertDictEqual({}, {}) -case.assertDictEqual({"x": 1, "y": 2}, {"x": 1, "y": 2}) -case.assertDictEqual({"x": 1, "y": "foo"}, {"y": "foo", "x": 1}) -case.assertDictEqual({"x": 1}, {}) -case.assertDictEqual({}, {"x": 1}) -case.assertDictEqual({1: "x"}, {"y": 222}) -case.assertDictEqual({1: "x"}, td1) -case.assertDictEqual(td1, {1: "x"}) -case.assertDictEqual(td1, td2) - -case.assertDictEqual(1, {}) # type: ignore -case.assertDictEqual({}, 1) # type: ignore - -# These should fail, but don't due to TypedDict limitations: -# case.assertDictEqual(m, {"": 0}) # xtype: ignore -# case.assertDictEqual({"": 0}, m) # xtype: ignore - -### -# Tests for mock.patch -### - - -@patch("sys.exit") -def f_default_new(i: int, mock: MagicMock) -> str: - return "asdf" - - -@patch("sys.exit", new=42) -def f_explicit_new(i: int) -> str: - return "asdf" - - -assert_type(f_default_new(1), str) -f_default_new("a") # Not an error due to ParamSpec limitations -assert_type(f_explicit_new(1), str) -f_explicit_new("a") # type: ignore[arg-type] - - -@patch("sys.exit", new=Mock()) -class TestXYZ(unittest.TestCase): - attr: int = 5 - - @staticmethod - def method() -> int: - return 123 - - -assert_type(TestXYZ.attr, int) -assert_type(TestXYZ.method(), int) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py b/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py deleted file mode 100644 index b485dac8dc29..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/check_xml.py +++ /dev/null @@ -1,35 +0,0 @@ -from __future__ import annotations - -import sys -from typing_extensions import assert_type -from xml.dom.minidom import Document - -document = Document() - -assert_type(document.toxml(), str) -assert_type(document.toxml(encoding=None), str) -assert_type(document.toxml(encoding="UTF8"), bytes) -assert_type(document.toxml("UTF8"), bytes) -if sys.version_info >= (3, 9): - assert_type(document.toxml(standalone=True), str) - assert_type(document.toxml("UTF8", True), bytes) - assert_type(document.toxml(encoding="UTF8", standalone=True), bytes) - - -# Because toprettyxml can mix positional and keyword variants of the "encoding" argument, which -# determines the return type, the proper stub typing isn't immediately obvious. This is a basic -# brute-force sanity check. -# Test cases like toxml -assert_type(document.toprettyxml(), str) -assert_type(document.toprettyxml(encoding=None), str) -assert_type(document.toprettyxml(encoding="UTF8"), bytes) -if sys.version_info >= (3, 9): - assert_type(document.toprettyxml(standalone=True), str) - assert_type(document.toprettyxml(encoding="UTF8", standalone=True), bytes) -# Test cases unique to toprettyxml -assert_type(document.toprettyxml(" "), str) -assert_type(document.toprettyxml(" ", "\r\n"), str) -assert_type(document.toprettyxml(" ", "\r\n", "UTF8"), bytes) -if sys.version_info >= (3, 9): - assert_type(document.toprettyxml(" ", "\r\n", "UTF8", True), bytes) - assert_type(document.toprettyxml(" ", "\r\n", standalone=True), str) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py b/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py deleted file mode 100644 index 9fe5ec8076ce..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/collections/check_defaultdict-py39.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -Tests for `defaultdict.__or__` and `defaultdict.__ror__`. -These methods were only added in py39. -""" - -from __future__ import annotations - -import os -import sys -from collections import defaultdict -from typing import Mapping, TypeVar, Union -from typing_extensions import Self, assert_type - -_KT = TypeVar("_KT") -_VT = TypeVar("_VT") - - -if sys.version_info >= (3, 9): - - class CustomDefaultDictSubclass(defaultdict[_KT, _VT]): - pass - - class CustomMappingWithDunderOr(Mapping[_KT, _VT]): - def __or__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: - return {} - - def __ror__(self, other: Mapping[_KT, _VT]) -> dict[_KT, _VT]: - return {} - - def __ior__(self, other: Mapping[_KT, _VT]) -> Self: - return self - - def test_defaultdict_dot_or( - a: defaultdict[int, int], - b: CustomDefaultDictSubclass[int, int], - c: defaultdict[str, str], - d: Mapping[int, int], - e: CustomMappingWithDunderOr[str, str], - ) -> None: - assert_type(a | b, defaultdict[int, int]) - - # In contrast to `dict.__or__`, `defaultdict.__or__` returns `Self` if called on a subclass of `defaultdict`: - assert_type(b | a, CustomDefaultDictSubclass[int, int]) - - assert_type(a | c, defaultdict[Union[int, str], Union[int, str]]) - - # arbitrary mappings are not accepted by `defaultdict.__or__`; - # it has to be a subclass of `dict` - a | d # type: ignore - - # but Mappings such as `os._Environ` or `CustomMappingWithDunderOr`, - # which define `__ror__` methods that accept `dict`, are fine - # (`os._Environ.__(r)or__` always returns `dict`, even if a `defaultdict` is passed): - assert_type(a | os.environ, dict[Union[str, int], Union[str, int]]) - assert_type(os.environ | a, dict[Union[str, int], Union[str, int]]) - - assert_type(c | os.environ, dict[str, str]) - assert_type(c | e, dict[str, str]) - - assert_type(os.environ | c, dict[str, str]) - assert_type(e | c, dict[str, str]) - - e |= c - e |= a # type: ignore - - # TODO: this test passes mypy, but fails pyright for some reason: - # c |= e - - c |= a # type: ignore diff --git a/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py b/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py deleted file mode 100644 index a9b43e23fb27..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/email/check_message.py +++ /dev/null @@ -1,6 +0,0 @@ -from email.headerregistry import Address -from email.message import EmailMessage - -msg = EmailMessage() -msg["To"] = "receiver@example.com" -msg["From"] = Address("Sender Name", "sender", "example.com") diff --git a/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py b/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py deleted file mode 100644 index c45ffee28cee..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/itertools/check_itertools_recipes.py +++ /dev/null @@ -1,410 +0,0 @@ -"""Type-annotated versions of the recipes from the itertools docs. - -These are all meant to be examples of idiomatic itertools usage, -so they should all type-check without error. -""" - -from __future__ import annotations - -import collections -import math -import operator -import sys -from itertools import chain, combinations, count, cycle, filterfalse, groupby, islice, product, repeat, starmap, tee, zip_longest -from typing import ( - Any, - Callable, - Collection, - Hashable, - Iterable, - Iterator, - Literal, - Sequence, - Tuple, - Type, - TypeVar, - Union, - overload, -) -from typing_extensions import TypeAlias, TypeVarTuple, Unpack - -_T = TypeVar("_T") -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_HashableT = TypeVar("_HashableT", bound=Hashable) -_Ts = TypeVarTuple("_Ts") - - -def take(n: int, iterable: Iterable[_T]) -> list[_T]: - "Return first n items of the iterable as a list" - return list(islice(iterable, n)) - - -# Note: the itertools docs uses the parameter name "iterator", -# but the function actually accepts any iterable -# as its second argument -def prepend(value: _T1, iterator: Iterable[_T2]) -> Iterator[_T1 | _T2]: - "Prepend a single value in front of an iterator" - # prepend(1, [2, 3, 4]) --> 1 2 3 4 - return chain([value], iterator) - - -def tabulate(function: Callable[[int], _T], start: int = 0) -> Iterator[_T]: - "Return function(0), function(1), ..." - return map(function, count(start)) - - -def repeatfunc(func: Callable[[Unpack[_Ts]], _T], times: int | None = None, *args: Unpack[_Ts]) -> Iterator[_T]: - """Repeat calls to func with specified arguments. - - Example: repeatfunc(random.random) - """ - if times is None: - return starmap(func, repeat(args)) - return starmap(func, repeat(args, times)) - - -def flatten(list_of_lists: Iterable[Iterable[_T]]) -> Iterator[_T]: - "Flatten one level of nesting" - return chain.from_iterable(list_of_lists) - - -def ncycles(iterable: Iterable[_T], n: int) -> Iterator[_T]: - "Returns the sequence elements n times" - return chain.from_iterable(repeat(tuple(iterable), n)) - - -def tail(n: int, iterable: Iterable[_T]) -> Iterator[_T]: - "Return an iterator over the last n items" - # tail(3, 'ABCDEFG') --> E F G - return iter(collections.deque(iterable, maxlen=n)) - - -# This function *accepts* any iterable, -# but it only *makes sense* to use it with an iterator -def consume(iterator: Iterator[object], n: int | None = None) -> None: - "Advance the iterator n-steps ahead. If n is None, consume entirely." - # Use functions that consume iterators at C speed. - if n is None: - # feed the entire iterator into a zero-length deque - collections.deque(iterator, maxlen=0) - else: - # advance to the empty slice starting at position n - next(islice(iterator, n, n), None) - - -@overload -def nth(iterable: Iterable[_T], n: int, default: None = None) -> _T | None: ... - - -@overload -def nth(iterable: Iterable[_T], n: int, default: _T1) -> _T | _T1: ... - - -def nth(iterable: Iterable[object], n: int, default: object = None) -> object: - "Returns the nth item or a default value" - return next(islice(iterable, n, None), default) - - -@overload -def quantify(iterable: Iterable[object]) -> int: ... - - -@overload -def quantify(iterable: Iterable[_T], pred: Callable[[_T], bool]) -> int: ... - - -def quantify(iterable: Iterable[object], pred: Callable[[Any], bool] = bool) -> int: - "Given a predicate that returns True or False, count the True results." - return sum(map(pred, iterable)) - - -@overload -def first_true( - iterable: Iterable[_T], default: Literal[False] = False, pred: Callable[[_T], bool] | None = None -) -> _T | Literal[False]: ... - - -@overload -def first_true(iterable: Iterable[_T], default: _T1, pred: Callable[[_T], bool] | None = None) -> _T | _T1: ... - - -def first_true(iterable: Iterable[object], default: object = False, pred: Callable[[Any], bool] | None = None) -> object: - """Returns the first true value in the iterable. - If no true value is found, returns *default* - If *pred* is not None, returns the first item - for which pred(item) is true. - """ - # first_true([a,b,c], x) --> a or b or c or x - # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x - return next(filter(pred, iterable), default) - - -_ExceptionOrExceptionTuple: TypeAlias = Union[Type[BaseException], Tuple[Type[BaseException], ...]] - - -@overload -def iter_except(func: Callable[[], _T], exception: _ExceptionOrExceptionTuple, first: None = None) -> Iterator[_T]: ... - - -@overload -def iter_except( - func: Callable[[], _T], exception: _ExceptionOrExceptionTuple, first: Callable[[], _T1] -) -> Iterator[_T | _T1]: ... - - -def iter_except( - func: Callable[[], object], exception: _ExceptionOrExceptionTuple, first: Callable[[], object] | None = None -) -> Iterator[object]: - """Call a function repeatedly until an exception is raised. - Converts a call-until-exception interface to an iterator interface. - Like builtins.iter(func, sentinel) but uses an exception instead - of a sentinel to end the loop. - Examples: - iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator - iter_except(d.popitem, KeyError) # non-blocking dict iterator - iter_except(d.popleft, IndexError) # non-blocking deque iterator - iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue - iter_except(s.pop, KeyError) # non-blocking set iterator - """ - try: - if first is not None: - yield first() # For database APIs needing an initial cast to db.first() - while True: - yield func() - except exception: - pass - - -def sliding_window(iterable: Iterable[_T], n: int) -> Iterator[tuple[_T, ...]]: - # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG - it = iter(iterable) - window = collections.deque(islice(it, n - 1), maxlen=n) - for x in it: - window.append(x) - yield tuple(window) - - -def roundrobin(*iterables: Iterable[_T]) -> Iterator[_T]: - "roundrobin('ABC', 'D', 'EF') --> A D E B F C" - # Recipe credited to George Sakkis - num_active = len(iterables) - nexts: Iterator[Callable[[], _T]] = cycle(iter(it).__next__ for it in iterables) - while num_active: - try: - for next in nexts: - yield next() - except StopIteration: - # Remove the iterator we just exhausted from the cycle. - num_active -= 1 - nexts = cycle(islice(nexts, num_active)) - - -def partition(pred: Callable[[_T], bool], iterable: Iterable[_T]) -> tuple[Iterator[_T], Iterator[_T]]: - """Partition entries into false entries and true entries. - If *pred* is slow, consider wrapping it with functools.lru_cache(). - """ - # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 - t1, t2 = tee(iterable) - return filterfalse(pred, t1), filter(pred, t2) - - -def subslices(seq: Sequence[_T]) -> Iterator[Sequence[_T]]: - "Return all contiguous non-empty subslices of a sequence" - # subslices('ABCD') --> A AB ABC ABCD B BC BCD C CD D - slices = starmap(slice, combinations(range(len(seq) + 1), 2)) - return map(operator.getitem, repeat(seq), slices) - - -def before_and_after(predicate: Callable[[_T], bool], it: Iterable[_T]) -> tuple[Iterator[_T], Iterator[_T]]: - """Variant of takewhile() that allows complete - access to the remainder of the iterator. - >>> it = iter('ABCdEfGhI') - >>> all_upper, remainder = before_and_after(str.isupper, it) - >>> ''.join(all_upper) - 'ABC' - >>> ''.join(remainder) # takewhile() would lose the 'd' - 'dEfGhI' - Note that the first iterator must be fully - consumed before the second iterator can - generate valid results. - """ - it = iter(it) - transition: list[_T] = [] - - def true_iterator() -> Iterator[_T]: - for elem in it: - if predicate(elem): - yield elem - else: - transition.append(elem) - return - - def remainder_iterator() -> Iterator[_T]: - yield from transition - yield from it - - return true_iterator(), remainder_iterator() - - -@overload -def unique_everseen(iterable: Iterable[_HashableT], key: None = None) -> Iterator[_HashableT]: ... - - -@overload -def unique_everseen(iterable: Iterable[_T], key: Callable[[_T], Hashable]) -> Iterator[_T]: ... - - -def unique_everseen(iterable: Iterable[_T], key: Callable[[_T], Hashable] | None = None) -> Iterator[_T]: - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBcCAD', str.lower) --> A B c D - seen: set[Hashable] = set() - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen.add(element) - yield element - # For order preserving deduplication, - # a faster but non-lazy solution is: - # yield from dict.fromkeys(iterable) - else: - for element in iterable: - k = key(element) - if k not in seen: - seen.add(k) - yield element - # For use cases that allow the last matching element to be returned, - # a faster but non-lazy solution is: - # t1, t2 = tee(iterable) - # yield from dict(zip(map(key, t1), t2)).values() - - -# Slightly adapted from the docs recipe; a one-liner was a bit much for pyright -def unique_justseen(iterable: Iterable[_T], key: Callable[[_T], bool] | None = None) -> Iterator[_T]: - "List unique elements, preserving order. Remember only the element just seen." - # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B - # unique_justseen('ABBcCAD', str.lower) --> A B c A D - g: groupby[_T | bool, _T] = groupby(iterable, key) - return map(next, map(operator.itemgetter(1), g)) - - -def powerset(iterable: Iterable[_T]) -> Iterator[tuple[_T, ...]]: - "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" - s = list(iterable) - return chain.from_iterable(combinations(s, r) for r in range(len(s) + 1)) - - -def polynomial_derivative(coefficients: Sequence[float]) -> list[float]: - """Compute the first derivative of a polynomial. - f(x) = x³ -4x² -17x + 60 - f'(x) = 3x² -8x -17 - """ - # polynomial_derivative([1, -4, -17, 60]) -> [3, -8, -17] - n = len(coefficients) - powers = reversed(range(1, n)) - return list(map(operator.mul, coefficients, powers)) - - -def nth_combination(iterable: Iterable[_T], r: int, index: int) -> tuple[_T, ...]: - "Equivalent to list(combinations(iterable, r))[index]" - pool = tuple(iterable) - n = len(pool) - c = math.comb(n, r) - if index < 0: - index += c - if index < 0 or index >= c: - raise IndexError - result: list[_T] = [] - while r: - c, n, r = c * r // n, n - 1, r - 1 - while index >= c: - index -= c - c, n = c * (n - r) // n, n - 1 - result.append(pool[-1 - n]) - return tuple(result) - - -if sys.version_info >= (3, 10): - - @overload - def grouper( - iterable: Iterable[_T], n: int, *, incomplete: Literal["fill"] = "fill", fillvalue: None = None - ) -> Iterator[tuple[_T | None, ...]]: ... - - @overload - def grouper( - iterable: Iterable[_T], n: int, *, incomplete: Literal["fill"] = "fill", fillvalue: _T1 - ) -> Iterator[tuple[_T | _T1, ...]]: ... - - @overload - def grouper( - iterable: Iterable[_T], n: int, *, incomplete: Literal["strict", "ignore"], fillvalue: None = None - ) -> Iterator[tuple[_T, ...]]: ... - - def grouper( - iterable: Iterable[object], n: int, *, incomplete: Literal["fill", "strict", "ignore"] = "fill", fillvalue: object = None - ) -> Iterator[tuple[object, ...]]: - "Collect data into non-overlapping fixed-length chunks or blocks" - # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx - # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError - # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF - args = [iter(iterable)] * n - if incomplete == "fill": - return zip_longest(*args, fillvalue=fillvalue) - if incomplete == "strict": - return zip(*args, strict=True) - if incomplete == "ignore": - return zip(*args) - else: - raise ValueError("Expected fill, strict, or ignore") - - def transpose(it: Iterable[Iterable[_T]]) -> Iterator[tuple[_T, ...]]: - "Swap the rows and columns of the input." - # transpose([(1, 2, 3), (11, 22, 33)]) --> (1, 11) (2, 22) (3, 33) - return zip(*it, strict=True) - - -if sys.version_info >= (3, 12): - from itertools import batched - - def sum_of_squares(it: Iterable[float]) -> float: - "Add up the squares of the input values." - # sum_of_squares([10, 20, 30]) -> 1400 - return math.sumprod(*tee(it)) - - def convolve(signal: Iterable[float], kernel: Iterable[float]) -> Iterator[float]: - """Discrete linear convolution of two iterables. - The kernel is fully consumed before the calculations begin. - The signal is consumed lazily and can be infinite. - Convolutions are mathematically commutative. - If the signal and kernel are swapped, - the output will be the same. - Article: https://betterexplained.com/articles/intuitive-convolution/ - Video: https://www.youtube.com/watch?v=KuXjwB4LzSA - """ - # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) - # convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate - # convolve(data, [1, -2, 1]) --> 2nd derivative estimate - kernel = tuple(kernel)[::-1] - n = len(kernel) - padded_signal = chain(repeat(0, n - 1), signal, repeat(0, n - 1)) - windowed_signal = sliding_window(padded_signal, n) - return map(math.sumprod, repeat(kernel), windowed_signal) - - def polynomial_eval(coefficients: Sequence[float], x: float) -> float: - """Evaluate a polynomial at a specific value. - Computes with better numeric stability than Horner's method. - """ - # Evaluate x³ -4x² -17x + 60 at x = 2.5 - # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125 - n = len(coefficients) - if not n: - return type(x)(0) - powers = map(pow, repeat(x), reversed(range(n))) - return math.sumprod(coefficients, powers) - - def matmul(m1: Sequence[Collection[float]], m2: Sequence[Collection[float]]) -> Iterator[tuple[float, ...]]: - "Multiply two matrices." - # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) --> (49, 80), (41, 60) - n = len(m2[0]) - return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py deleted file mode 100644 index 10a33ffb83d5..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_MutableMapping.py +++ /dev/null @@ -1,18 +0,0 @@ -from __future__ import annotations - -from typing import Any, Union -from typing_extensions import assert_type - - -def check_setdefault_method() -> None: - d: dict[int, str] = {} - d2: dict[int, str | None] = {} - d3: dict[int, Any] = {} - - d.setdefault(1) # type: ignore - assert_type(d.setdefault(1, "x"), str) - assert_type(d2.setdefault(1), Union[str, None]) - assert_type(d2.setdefault(1, None), Union[str, None]) - assert_type(d2.setdefault(1, "x"), Union[str, None]) - assert_type(d3.setdefault(1), Union[Any, None]) - assert_type(d3.setdefault(1, "x"), Any) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py deleted file mode 100644 index 44eb548e04a9..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_all.py +++ /dev/null @@ -1,14 +0,0 @@ -# pyright: reportWildcardImportFromLibrary=false -""" -This tests that star imports work when using "all += " syntax. -""" -from __future__ import annotations - -import sys -from typing import * -from zipfile import * - -if sys.version_info >= (3, 9): - x: Annotated[int, 42] - -p: Path diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py deleted file mode 100644 index 34c5631aeb1a..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_regression_issue_9296.py +++ /dev/null @@ -1,16 +0,0 @@ -from __future__ import annotations - -import typing as t - -KT = t.TypeVar("KT") - - -class MyKeysView(t.KeysView[KT]): - pass - - -d: dict[t.Any, t.Any] = {} -dict_keys = type(d.keys()) - -# This should not cause an error like `Member "register" is unknown`: -MyKeysView.register(dict_keys) diff --git a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py b/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py deleted file mode 100644 index 67f16dc91765..000000000000 --- a/mypy/typeshed/stdlib/@tests/test_cases/typing/check_typing_io.py +++ /dev/null @@ -1,21 +0,0 @@ -from __future__ import annotations - -import mmap -from typing import IO, AnyStr - - -def check_write(io_bytes: IO[bytes], io_str: IO[str], io_anystr: IO[AnyStr], any_str: AnyStr, buf: mmap.mmap) -> None: - io_bytes.write(b"") - io_bytes.write(buf) - io_bytes.write("") # type: ignore - io_bytes.write(any_str) # type: ignore - - io_str.write(b"") # type: ignore - io_str.write(buf) # type: ignore - io_str.write("") - io_str.write(any_str) # type: ignore - - io_anystr.write(b"") # type: ignore - io_anystr.write(buf) # type: ignore - io_anystr.write("") # type: ignore - io_anystr.write(any_str) From b74829e1c6fbbfd376fe1043a7ce37e3f120f799 Mon Sep 17 00:00:00 2001 From: gilesgc <50000301+gilesgc@users.noreply.github.com> Date: Thu, 16 May 2024 21:45:57 -0400 Subject: [PATCH 170/172] Fix for type narrowing of negative integer literals (#17256) Fixes #10514 Fixes #17118 Negative integer literals were not being correctly handled in the type narrowing process, causing mypy errors such as "Statement is unreachable" despite the checked code being valid. This fix ensures that negative integer literals are properly considered in if-statements. --- mypy/plugins/default.py | 2 +- test-data/unit/check-narrowing.test | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index 93fff5320cd5..170d3c85b5f9 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -489,7 +489,7 @@ def int_neg_callback(ctx: MethodContext, multiplier: int = -1) -> Type: return ctx.type.copy_modified( last_known_value=LiteralType( value=multiplier * value, - fallback=ctx.type, + fallback=fallback, line=ctx.type.line, column=ctx.type.column, ) diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 4d117687554e..8612df9bc663 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -2089,3 +2089,28 @@ if isinstance(x, (Z, NoneType)): # E: Subclass of "X" and "Z" cannot exist: "Z" reveal_type(x) # E: Statement is unreachable [builtins fixtures/isinstance.pyi] + +[case testTypeNarrowingReachableNegative] +# flags: --warn-unreachable +from typing import Literal + +x: Literal[-1] + +if x == -1: + assert True + +[typing fixtures/typing-medium.pyi] +[builtins fixtures/ops.pyi] + +[case testTypeNarrowingReachableNegativeUnion] +from typing import Literal + +x: Literal[-1, 1] + +if x == -1: + reveal_type(x) # N: Revealed type is "Literal[-1]" +else: + reveal_type(x) # N: Revealed type is "Literal[1]" + +[typing fixtures/typing-medium.pyi] +[builtins fixtures/ops.pyi] From 5fb8d6262f2ade83234e46334eb3fb8a4bbaedc0 Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 17 May 2024 11:23:20 +0100 Subject: [PATCH 171/172] [PEP 695] Partial support for new type parameter syntax in Python 3.12 (#17233) Add basic support for most features of PEP 695. It's still not generally useful, but it should be enough for experimentation and testing. I will continue working on follow-up PRs after this has been merged. This is currently behind a feature flag: `--enable-incomplete-feature=NewGenericSyntax` These features, among other things, are unimplemented (or at least untested): * Recursive type aliases * Checking for various errors * Inference of variance in complex cases * Dealing with unknown variance consistently * Scoping * Mypy daemon * Compilation using mypyc The trickiest remaining thing is probably variance inference in cases where some types aren't ready (i.e. not inferred) when we need variance. I have some ideas about how to tackle this, but it might need significant work. Currently the idea is to infer variance on demand when we need it, but we may need to defer if variance can't be calculated, for example if a type of an attribute is not yet ready. The current approach is to fall back to covariance in some cases, which is not ideal. Work on #15238. --- mypy/checker.py | 11 +- mypy/fastparse.py | 106 +++- mypy/join.py | 4 +- mypy/nodes.py | 54 +- mypy/options.py | 3 +- mypy/partially_defined.py | 5 + mypy/semanal.py | 174 +++++- mypy/strconv.py | 28 + mypy/subtypes.py | 83 ++- mypy/test/testparse.py | 4 + mypy/traverser.py | 6 + mypy/typestate.py | 10 +- mypy/visitor.py | 7 + mypyc/irbuild/visitor.py | 4 + test-data/unit/check-python312.test | 876 ++++++++++++++++++++++++++++ test-data/unit/parse-python312.test | 87 +++ test-data/unit/pythoneval.test | 21 + 17 files changed, 1441 insertions(+), 42 deletions(-) create mode 100644 test-data/unit/parse-python312.test diff --git a/mypy/checker.py b/mypy/checker.py index 9c10cd2fc30d..3daf64daaac4 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -146,6 +146,7 @@ from mypy.state import state from mypy.subtypes import ( find_member, + infer_class_variances, is_callable_compatible, is_equivalent, is_more_precise, @@ -2374,7 +2375,7 @@ def visit_class_def(self, defn: ClassDef) -> None: self.allow_abstract_call = old_allow_abstract_call # TODO: Apply the sig to the actual TypeInfo so we can handle decorators # that completely swap out the type. (e.g. Callable[[Type[A]], Type[B]]) - if typ.defn.type_vars: + if typ.defn.type_vars and typ.defn.type_args is None: for base_inst in typ.bases: for base_tvar, base_decl_tvar in zip( base_inst.args, base_inst.type.defn.type_vars @@ -2396,6 +2397,7 @@ def visit_class_def(self, defn: ClassDef) -> None: self.check_protocol_variance(defn) if not defn.has_incompatible_baseclass and defn.info.is_enum: self.check_enum(defn) + infer_class_variances(defn.info) def check_final_deletable(self, typ: TypeInfo) -> None: # These checks are only for mypyc. Only perform some checks that are easier @@ -2566,6 +2568,9 @@ def check_protocol_variance(self, defn: ClassDef) -> None: if they are actually covariant/contravariant, since this may break transitivity of subtyping, see PEP 544. """ + if defn.type_args is not None: + # Using new-style syntax (PEP 695), so variance will be inferred + return info = defn.info object_type = Instance(info.mro[-1], []) tvars = info.defn.type_vars @@ -3412,8 +3417,8 @@ def check_final(self, s: AssignmentStmt | OperatorAssignmentStmt | AssignmentExp if ( lv.node.final_unset_in_class and not lv.node.final_set_in_init - and not self.is_stub - and # It is OK to skip initializer in stub files. + and not self.is_stub # It is OK to skip initializer in stub files. + and # Avoid extra error messages, if there is no type in Final[...], # then we already reported the error about missing r.h.s. isinstance(s, AssignmentStmt) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index e208e4d0b7d9..ee042b96339f 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -17,6 +17,9 @@ ARG_POS, ARG_STAR, ARG_STAR2, + PARAM_SPEC_KIND, + TYPE_VAR_KIND, + TYPE_VAR_TUPLE_KIND, ArgKind, Argument, AssertStmt, @@ -79,6 +82,8 @@ TempNode, TryStmt, TupleExpr, + TypeAliasStmt, + TypeParam, UnaryExpr, Var, WhileStmt, @@ -87,7 +92,7 @@ YieldFromExpr, check_arg_names, ) -from mypy.options import Options +from mypy.options import NEW_GENERIC_SYNTAX, Options from mypy.patterns import ( AsPattern, ClassPattern, @@ -144,11 +149,6 @@ def ast3_parse( NamedExpr = ast3.NamedExpr Constant = ast3.Constant -if sys.version_info >= (3, 12): - ast_TypeAlias = ast3.TypeAlias -else: - ast_TypeAlias = Any - if sys.version_info >= (3, 10): Match = ast3.Match MatchValue = ast3.MatchValue @@ -171,11 +171,21 @@ def ast3_parse( MatchAs = Any MatchOr = Any AstNode = Union[ast3.expr, ast3.stmt, ast3.ExceptHandler] + if sys.version_info >= (3, 11): TryStar = ast3.TryStar else: TryStar = Any +if sys.version_info >= (3, 12): + ast_TypeAlias = ast3.TypeAlias + ast_ParamSpec = ast3.ParamSpec + ast_TypeVarTuple = ast3.TypeVarTuple +else: + ast_TypeAlias = Any + ast_ParamSpec = Any + ast_TypeVarTuple = Any + N = TypeVar("N", bound=Node) # There is no way to create reasonable fallbacks at this stage, @@ -884,6 +894,8 @@ def do_func_def( arg_kinds = [arg.kind for arg in args] arg_names = [None if arg.pos_only else arg.variable.name for arg in args] + # Type parameters, if using new syntax for generics (PEP 695) + explicit_type_params: list[TypeParam] | None = None arg_types: list[Type | None] = [] if no_type_check: @@ -937,12 +949,17 @@ def do_func_def( return_type = AnyType(TypeOfAny.from_error) else: if sys.version_info >= (3, 12) and n.type_params: - self.fail( - ErrorMessage("PEP 695 generics are not yet supported", code=codes.VALID_TYPE), - n.type_params[0].lineno, - n.type_params[0].col_offset, - blocker=False, - ) + if NEW_GENERIC_SYNTAX in self.options.enable_incomplete_feature: + explicit_type_params = self.translate_type_params(n.type_params) + else: + self.fail( + ErrorMessage( + "PEP 695 generics are not yet supported", code=codes.VALID_TYPE + ), + n.type_params[0].lineno, + n.type_params[0].col_offset, + blocker=False, + ) arg_types = [a.type_annotation for a in args] return_type = TypeConverter( @@ -986,7 +1003,7 @@ def do_func_def( self.class_and_function_stack.pop() self.class_and_function_stack.append("F") body = self.as_required_block(n.body, can_strip=True, is_coroutine=is_coroutine) - func_def = FuncDef(n.name, args, body, func_type) + func_def = FuncDef(n.name, args, body, func_type, explicit_type_params) if isinstance(func_def.type, CallableType): # semanal.py does some in-place modifications we want to avoid func_def.unanalyzed_type = func_def.type.copy_modified() @@ -1120,13 +1137,19 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef: self.class_and_function_stack.append("C") keywords = [(kw.arg, self.visit(kw.value)) for kw in n.keywords if kw.arg] + # Type parameters, if using new syntax for generics (PEP 695) + explicit_type_params: list[TypeParam] | None = None + if sys.version_info >= (3, 12) and n.type_params: - self.fail( - ErrorMessage("PEP 695 generics are not yet supported", code=codes.VALID_TYPE), - n.type_params[0].lineno, - n.type_params[0].col_offset, - blocker=False, - ) + if NEW_GENERIC_SYNTAX in self.options.enable_incomplete_feature: + explicit_type_params = self.translate_type_params(n.type_params) + else: + self.fail( + ErrorMessage("PEP 695 generics are not yet supported", code=codes.VALID_TYPE), + n.type_params[0].lineno, + n.type_params[0].col_offset, + blocker=False, + ) cdef = ClassDef( n.name, @@ -1135,6 +1158,7 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef: self.translate_expr_list(n.bases), metaclass=dict(keywords).get("metaclass"), keywords=keywords, + type_args=explicit_type_params, ) cdef.decorators = self.translate_expr_list(n.decorator_list) # Set lines to match the old mypy 0.700 lines, in order to keep @@ -1150,6 +1174,24 @@ def visit_ClassDef(self, n: ast3.ClassDef) -> ClassDef: self.class_and_function_stack.pop() return cdef + def translate_type_params(self, type_params: list[Any]) -> list[TypeParam]: + explicit_type_params = [] + for p in type_params: + bound = None + values: list[Type] = [] + if isinstance(p, ast_ParamSpec): # type: ignore[misc] + explicit_type_params.append(TypeParam(p.name, PARAM_SPEC_KIND, None, [])) + elif isinstance(p, ast_TypeVarTuple): # type: ignore[misc] + explicit_type_params.append(TypeParam(p.name, TYPE_VAR_TUPLE_KIND, None, [])) + else: + if isinstance(p.bound, ast3.Tuple): + conv = TypeConverter(self.errors, line=p.lineno) + values = [conv.visit(t) for t in p.bound.elts] + elif p.bound is not None: + bound = TypeConverter(self.errors, line=p.lineno).visit(p.bound) + explicit_type_params.append(TypeParam(p.name, TYPE_VAR_KIND, bound, values)) + return explicit_type_params + # Return(expr? value) def visit_Return(self, n: ast3.Return) -> ReturnStmt: node = ReturnStmt(self.visit(n.value)) @@ -1735,15 +1777,23 @@ def visit_MatchOr(self, n: MatchOr) -> OrPattern: node = OrPattern([self.visit(pattern) for pattern in n.patterns]) return self.set_line(node, n) - def visit_TypeAlias(self, n: ast_TypeAlias) -> AssignmentStmt: - self.fail( - ErrorMessage("PEP 695 type aliases are not yet supported", code=codes.VALID_TYPE), - n.lineno, - n.col_offset, - blocker=False, - ) - node = AssignmentStmt([NameExpr(n.name.id)], self.visit(n.value)) - return self.set_line(node, n) + # TypeAlias(identifier name, type_param* type_params, expr value) + def visit_TypeAlias(self, n: ast_TypeAlias) -> TypeAliasStmt | AssignmentStmt: + node: TypeAliasStmt | AssignmentStmt + if NEW_GENERIC_SYNTAX in self.options.enable_incomplete_feature: + type_params = self.translate_type_params(n.type_params) + value = self.visit(n.value) + node = TypeAliasStmt(self.visit_Name(n.name), type_params, value) + return self.set_line(node, n) + else: + self.fail( + ErrorMessage("PEP 695 type aliases are not yet supported", code=codes.VALID_TYPE), + n.lineno, + n.col_offset, + blocker=False, + ) + node = AssignmentStmt([NameExpr(n.name.id)], self.visit(n.value)) + return self.set_line(node, n) class TypeConverter: diff --git a/mypy/join.py b/mypy/join.py index 3603e9fefb7a..7e0ff301ebf8 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -6,7 +6,7 @@ import mypy.typeops from mypy.maptype import map_instance_to_supertype -from mypy.nodes import CONTRAVARIANT, COVARIANT, INVARIANT +from mypy.nodes import CONTRAVARIANT, COVARIANT, INVARIANT, VARIANCE_NOT_READY from mypy.state import state from mypy.subtypes import ( SubtypeContext, @@ -97,7 +97,7 @@ def join_instances(self, t: Instance, s: Instance) -> ProperType: elif isinstance(sa_proper, AnyType): new_type = AnyType(TypeOfAny.from_another_any, sa_proper) elif isinstance(type_var, TypeVarType): - if type_var.variance == COVARIANT: + if type_var.variance in (COVARIANT, VARIANCE_NOT_READY): new_type = join_types(ta, sa, self) if len(type_var.values) != 0 and new_type not in type_var.values: self.seen_instances.pop() diff --git a/mypy/nodes.py b/mypy/nodes.py index bb278d92392d..4c83d8081f6c 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -653,6 +653,28 @@ def set_line( self.variable.set_line(self.line, self.column, self.end_line, self.end_column) +# These specify the kind of a TypeParam +TYPE_VAR_KIND: Final = 0 +PARAM_SPEC_KIND: Final = 1 +TYPE_VAR_TUPLE_KIND: Final = 2 + + +class TypeParam: + __slots__ = ("name", "kind", "upper_bound", "values") + + def __init__( + self, + name: str, + kind: int, + upper_bound: mypy.types.Type | None, + values: list[mypy.types.Type], + ) -> None: + self.name = name + self.kind = kind + self.upper_bound = upper_bound + self.values = values + + FUNCITEM_FLAGS: Final = FUNCBASE_FLAGS + [ "is_overload", "is_generator", @@ -672,6 +694,7 @@ class FuncItem(FuncBase): "min_args", # Minimum number of arguments "max_pos", # Maximum number of positional arguments, -1 if no explicit # limit (*args not included) + "type_args", # New-style type parameters (PEP 695) "body", # Body of the function "is_overload", # Is this an overload variant of function with more than # one overload variant? @@ -689,12 +712,14 @@ def __init__( arguments: list[Argument] | None = None, body: Block | None = None, typ: mypy.types.FunctionLike | None = None, + type_args: list[TypeParam] | None = None, ) -> None: super().__init__() self.arguments = arguments or [] self.arg_names = [None if arg.pos_only else arg.variable.name for arg in self.arguments] self.arg_kinds: list[ArgKind] = [arg.kind for arg in self.arguments] self.max_pos: int = self.arg_kinds.count(ARG_POS) + self.arg_kinds.count(ARG_OPT) + self.type_args: list[TypeParam] | None = type_args self.body: Block = body or Block([]) self.type = typ self.unanalyzed_type = typ @@ -761,8 +786,9 @@ def __init__( arguments: list[Argument] | None = None, body: Block | None = None, typ: mypy.types.FunctionLike | None = None, + type_args: list[TypeParam] | None = None, ) -> None: - super().__init__(arguments, body, typ) + super().__init__(arguments, body, typ, type_args) self._name = name self.is_decorated = False self.is_conditional = False # Defined conditionally (within block)? @@ -1070,6 +1096,7 @@ class ClassDef(Statement): "name", "_fullname", "defs", + "type_args", "type_vars", "base_type_exprs", "removed_base_type_exprs", @@ -1089,6 +1116,9 @@ class ClassDef(Statement): name: str # Name of the class without module prefix _fullname: str # Fully qualified name of the class defs: Block + # New-style type parameters (PEP 695), unanalyzed + type_args: list[TypeParam] | None + # Semantically analyzed type parameters (all syntax variants) type_vars: list[mypy.types.TypeVarLikeType] # Base class expressions (not semantically analyzed -- can be arbitrary expressions) base_type_exprs: list[Expression] @@ -1111,12 +1141,14 @@ def __init__( base_type_exprs: list[Expression] | None = None, metaclass: Expression | None = None, keywords: list[tuple[str, Expression]] | None = None, + type_args: list[TypeParam] | None = None, ) -> None: super().__init__() self.name = name self._fullname = "" self.defs = defs self.type_vars = type_vars or [] + self.type_args = type_args self.base_type_exprs = base_type_exprs or [] self.removed_base_type_exprs = [] self.info = CLASSDEF_NO_INFO @@ -1607,6 +1639,25 @@ def accept(self, visitor: StatementVisitor[T]) -> T: return visitor.visit_match_stmt(self) +class TypeAliasStmt(Statement): + __slots__ = ("name", "type_args", "value") + + __match_args__ = ("name", "type_args", "value") + + name: NameExpr + type_args: list[TypeParam] + value: Expression # Will get translated into a type + + def __init__(self, name: NameExpr, type_args: list[TypeParam], value: Expression) -> None: + super().__init__() + self.name = name + self.type_args = type_args + self.value = value + + def accept(self, visitor: StatementVisitor[T]) -> T: + return visitor.visit_type_alias_stmt(self) + + # Expressions @@ -2442,6 +2493,7 @@ def accept(self, visitor: ExpressionVisitor[T]) -> T: INVARIANT: Final = 0 COVARIANT: Final = 1 CONTRAVARIANT: Final = 2 +VARIANCE_NOT_READY: Final = 3 # Variance hasn't been inferred (using Python 3.12 syntax) class TypeVarLikeExpr(SymbolNode, Expression): diff --git a/mypy/options.py b/mypy/options.py index 91639828801e..5ef6bc2a35e7 100644 --- a/mypy/options.py +++ b/mypy/options.py @@ -73,7 +73,8 @@ class BuildType: TYPE_VAR_TUPLE: Final = "TypeVarTuple" UNPACK: Final = "Unpack" PRECISE_TUPLE_TYPES: Final = "PreciseTupleTypes" -INCOMPLETE_FEATURES: Final = frozenset((PRECISE_TUPLE_TYPES,)) +NEW_GENERIC_SYNTAX: Final = "NewGenericSyntax" +INCOMPLETE_FEATURES: Final = frozenset((PRECISE_TUPLE_TYPES, NEW_GENERIC_SYNTAX)) COMPLETE_FEATURES: Final = frozenset((TYPE_VAR_TUPLE, UNPACK)) diff --git a/mypy/partially_defined.py b/mypy/partially_defined.py index b7f577110fa8..da0bb517189a 100644 --- a/mypy/partially_defined.py +++ b/mypy/partially_defined.py @@ -36,6 +36,7 @@ SymbolTable, TryStmt, TupleExpr, + TypeAliasStmt, WhileStmt, WithStmt, implicit_module_attrs, @@ -673,3 +674,7 @@ def visit_import_from(self, o: ImportFrom) -> None: name = mod self.tracker.record_definition(name) super().visit_import_from(o) + + def visit_type_alias_stmt(self, o: TypeAliasStmt) -> None: + # Type alias target may contain forward references + self.tracker.record_definition(o.name.name) diff --git a/mypy/semanal.py b/mypy/semanal.py index 91a6b1808987..f92471c159de 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -81,9 +81,13 @@ LDEF, MDEF, NOT_ABSTRACT, + PARAM_SPEC_KIND, REVEAL_LOCALS, REVEAL_TYPE, RUNTIME_PROTOCOL_DECOS, + TYPE_VAR_KIND, + TYPE_VAR_TUPLE_KIND, + VARIANCE_NOT_READY, ArgKind, AssertStmt, AssertTypeExpr, @@ -159,9 +163,11 @@ TupleExpr, TypeAlias, TypeAliasExpr, + TypeAliasStmt, TypeApplication, TypedDictExpr, TypeInfo, + TypeParam, TypeVarExpr, TypeVarLikeExpr, TypeVarTupleExpr, @@ -787,6 +793,7 @@ def file_context( self.num_incomplete_refs = 0 if active_type: + self.push_type_args(active_type.defn.type_args, active_type.defn) self.incomplete_type_stack.append(False) scope.enter_class(active_type) self.enter_class(active_type.defn.info) @@ -800,6 +807,7 @@ def file_context( self.leave_class() self._type = None self.incomplete_type_stack.pop() + self.pop_type_args(active_type.defn.type_args) del self.options # @@ -835,6 +843,10 @@ def visit_func_def(self, defn: FuncDef) -> None: self.analyze_func_def(defn) def analyze_func_def(self, defn: FuncDef) -> None: + if self.push_type_args(defn.type_args, defn) is None: + self.defer(defn) + return + self.function_stack.append(defn) if defn.type: @@ -943,6 +955,8 @@ def analyze_func_def(self, defn: FuncDef) -> None: defn.type = defn.type.copy_modified(ret_type=ret_type) self.wrapped_coro_return_types[defn] = defn.type + self.pop_type_args(defn.type_args) + def remove_unpack_kwargs(self, defn: FuncDef, typ: CallableType) -> CallableType: if not typ.arg_kinds or typ.arg_kinds[-1] is not ArgKind.ARG_STAR2: return typ @@ -1618,9 +1632,79 @@ def visit_class_def(self, defn: ClassDef) -> None: self.incomplete_type_stack.append(not defn.info) namespace = self.qualified_name(defn.name) with self.tvar_scope_frame(self.tvar_scope.class_frame(namespace)): + if self.push_type_args(defn.type_args, defn) is None: + self.mark_incomplete(defn.name, defn) + return + self.analyze_class(defn) + self.pop_type_args(defn.type_args) self.incomplete_type_stack.pop() + def push_type_args( + self, type_args: list[TypeParam] | None, context: Context + ) -> list[tuple[str, TypeVarLikeExpr]] | None: + if not type_args: + return [] + tvs: list[tuple[str, TypeVarLikeExpr]] = [] + for p in type_args: + tv = self.analyze_type_param(p) + if tv is None: + return None + tvs.append((p.name, tv)) + + for name, tv in tvs: + self.add_symbol(name, tv, context, no_progress=True) + + return tvs + + def analyze_type_param(self, type_param: TypeParam) -> TypeVarLikeExpr | None: + fullname = self.qualified_name(type_param.name) + if type_param.upper_bound: + upper_bound = self.anal_type(type_param.upper_bound) + if upper_bound is None: + return None + else: + upper_bound = self.named_type("builtins.object") + default = AnyType(TypeOfAny.from_omitted_generics) + if type_param.kind == TYPE_VAR_KIND: + values = [] + if type_param.values: + for value in type_param.values: + analyzed = self.anal_type(value) + if analyzed is None: + return None + values.append(analyzed) + return TypeVarExpr( + name=type_param.name, + fullname=fullname, + values=values, + upper_bound=upper_bound, + default=default, + variance=VARIANCE_NOT_READY, + ) + elif type_param.kind == PARAM_SPEC_KIND: + return ParamSpecExpr( + name=type_param.name, fullname=fullname, upper_bound=upper_bound, default=default + ) + else: + assert type_param.kind == TYPE_VAR_TUPLE_KIND + tuple_fallback = self.named_type("builtins.tuple", [self.object_type()]) + return TypeVarTupleExpr( + name=type_param.name, + fullname=fullname, + # Upper bound for *Ts is *tuple[object, ...], it can never be object. + upper_bound=tuple_fallback.copy_modified(), + tuple_fallback=tuple_fallback, + default=default, + ) + + def pop_type_args(self, type_args: list[TypeParam] | None) -> None: + if not type_args: + return + for tv in type_args: + names = self.current_symbol_table() + del names[tv.name] + def analyze_class(self, defn: ClassDef) -> None: fullname = self.qualified_name(defn.name) if not defn.info and not self.is_core_builtin_class(defn): @@ -1914,6 +1998,13 @@ class Foo(Bar, Generic[T]): ... removed: list[int] = [] declared_tvars: TypeVarLikeList = [] is_protocol = False + if defn.type_args is not None: + for p in defn.type_args: + node = self.lookup(p.name, context) + assert node is not None + assert isinstance(node.node, TypeVarLikeExpr) + declared_tvars.append((p.name, node.node)) + for i, base_expr in enumerate(base_type_exprs): if isinstance(base_expr, StarExpr): base_expr.valid = True @@ -5125,6 +5216,79 @@ def visit_match_stmt(self, s: MatchStmt) -> None: guard.accept(self) self.visit_block(s.bodies[i]) + def visit_type_alias_stmt(self, s: TypeAliasStmt) -> None: + self.statement = s + type_params = self.push_type_args(s.type_args, s) + if type_params is None: + self.defer(s) + return + all_type_params_names = [p.name for p in s.type_args] + + try: + tag = self.track_incomplete_refs() + res, alias_tvars, depends_on, qualified_tvars, empty_tuple_index = self.analyze_alias( + s.name.name, + s.value, + allow_placeholder=True, + declared_type_vars=type_params, + all_declared_type_params_names=all_type_params_names, + ) + if not res: + res = AnyType(TypeOfAny.from_error) + + if not self.is_func_scope(): + # Only marking incomplete for top-level placeholders makes recursive aliases like + # `A = Sequence[str | A]` valid here, similar to how we treat base classes in class + # definitions, allowing `class str(Sequence[str]): ...` + incomplete_target = isinstance(res, ProperType) and isinstance( + res, PlaceholderType + ) + else: + incomplete_target = has_placeholder(res) + + if self.found_incomplete_ref(tag) or incomplete_target: + # Since we have got here, we know this must be a type alias (incomplete refs + # may appear in nested positions), therefore use becomes_typeinfo=True. + self.mark_incomplete(s.name.name, s.value, becomes_typeinfo=True) + return + + self.add_type_alias_deps(depends_on) + # In addition to the aliases used, we add deps on unbound + # type variables, since they are erased from target type. + self.add_type_alias_deps(qualified_tvars) + # The above are only direct deps on other aliases. + # For subscripted aliases, type deps from expansion are added in deps.py + # (because the type is stored). + check_for_explicit_any( + res, self.options, self.is_typeshed_stub_file, self.msg, context=s + ) + # When this type alias gets "inlined", the Any is not explicit anymore, + # so we need to replace it with non-explicit Anys. + res = make_any_non_explicit(res) + eager = self.is_func_scope() + alias_node = TypeAlias( + res, + self.qualified_name(s.name.name), + s.line, + s.column, + alias_tvars=alias_tvars, + no_args=False, + eager=eager, + ) + + existing = self.current_symbol_table().get(s.name.name) + if ( + existing + and isinstance(existing.node, (PlaceholderNode, TypeAlias)) + and existing.node.line == s.line + ): + existing.node = alias_node + else: + self.add_symbol(s.name.name, alias_node, s) + + finally: + self.pop_type_args(s.type_args) + # # Expressions # @@ -5803,6 +5967,7 @@ def lookup( for table in reversed(self.locals): if table is not None and name in table: return table[name] + # 4. Current file global scope if name in self.globals: return self.globals[name] @@ -6115,6 +6280,7 @@ def add_symbol( module_hidden: bool = False, can_defer: bool = True, escape_comprehensions: bool = False, + no_progress: bool = False, ) -> bool: """Add symbol to the currently active symbol table. @@ -6136,7 +6302,9 @@ def add_symbol( symbol = SymbolTableNode( kind, node, module_public=module_public, module_hidden=module_hidden ) - return self.add_symbol_table_node(name, symbol, context, can_defer, escape_comprehensions) + return self.add_symbol_table_node( + name, symbol, context, can_defer, escape_comprehensions, no_progress + ) def add_symbol_skip_local(self, name: str, node: SymbolNode) -> None: """Same as above, but skipping the local namespace. @@ -6167,6 +6335,7 @@ def add_symbol_table_node( context: Context | None = None, can_defer: bool = True, escape_comprehensions: bool = False, + no_progress: bool = False, ) -> bool: """Add symbol table node to the currently active symbol table. @@ -6215,7 +6384,8 @@ def add_symbol_table_node( self.name_already_defined(name, context, existing) elif name not in self.missing_names[-1] and "*" not in self.missing_names[-1]: names[name] = symbol - self.progress = True + if not no_progress: + self.progress = True return True return False diff --git a/mypy/strconv.py b/mypy/strconv.py index 42a07c7f62fa..a96a27c45d75 100644 --- a/mypy/strconv.py +++ b/mypy/strconv.py @@ -86,6 +86,9 @@ def func_helper(self, o: mypy.nodes.FuncItem) -> list[object]: elif kind == mypy.nodes.ARG_STAR2: extra.append(("DictVarArg", [arg.variable])) a: list[Any] = [] + if o.type_args: + for p in o.type_args: + a.append(self.type_param(p)) if args: a.append(("Args", args)) if o.type: @@ -187,6 +190,9 @@ def visit_class_def(self, o: mypy.nodes.ClassDef) -> str: a.insert(1, ("TupleType", [o.info.tuple_type])) if o.info and o.info.fallback_to_any: a.insert(1, "FallbackToAny") + if o.type_args: + for p in reversed(o.type_args): + a.insert(1, self.type_param(p)) return self.dump(a, o) def visit_var(self, o: mypy.nodes.Var) -> str: @@ -323,6 +329,28 @@ def visit_match_stmt(self, o: mypy.nodes.MatchStmt) -> str: a.append(("Body", o.bodies[i].body)) return self.dump(a, o) + def visit_type_alias_stmt(self, o: mypy.nodes.TypeAliasStmt) -> str: + a: list[Any] = [o.name] + for p in o.type_args: + a.append(self.type_param(p)) + a.append(o.value) + return self.dump(a, o) + + def type_param(self, p: mypy.nodes.TypeParam) -> list[Any]: + a: list[Any] = [] + if p.kind == mypy.nodes.PARAM_SPEC_KIND: + prefix = "**" + elif p.kind == mypy.nodes.TYPE_VAR_TUPLE_KIND: + prefix = "*" + else: + prefix = "" + a.append(prefix + p.name) + if p.upper_bound: + a.append(p.upper_bound) + if p.values: + a.append(("Values", p.values)) + return [("TypeParam", a)] + # Expressions # Simple expressions diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 4d5e7335b14f..a5523fbe0d45 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -8,7 +8,7 @@ import mypy.constraints import mypy.typeops from mypy.erasetype import erase_type -from mypy.expandtype import expand_self_type, expand_type_by_instance +from mypy.expandtype import expand_self_type, expand_type, expand_type_by_instance from mypy.maptype import map_instance_to_supertype # Circular import; done in the function instead. @@ -19,6 +19,7 @@ CONTRAVARIANT, COVARIANT, INVARIANT, + VARIANCE_NOT_READY, Decorator, FuncBase, OverloadedFuncDef, @@ -66,7 +67,7 @@ ) from mypy.types_utils import flatten_types from mypy.typestate import SubtypeKind, type_state -from mypy.typevars import fill_typevars_with_any +from mypy.typevars import fill_typevars, fill_typevars_with_any # Flags for detected protocol members IS_SETTABLE: Final = 1 @@ -361,7 +362,10 @@ def check_type_parameter( p_left = get_proper_type(left) if isinstance(p_left, UninhabitedType) and p_left.ambiguous: variance = COVARIANT - if variance == COVARIANT: + # If variance hasn't been inferred yet, we are lenient and default to + # covariance. This shouldn't happen often, but it's very difficult to + # avoid these cases altogether. + if variance == COVARIANT or variance == VARIANCE_NOT_READY: if proper_subtype: return is_proper_subtype(left, right, subtype_context=subtype_context) else: @@ -575,8 +579,12 @@ def visit_instance(self, left: Instance) -> bool: else: type_params = zip(t.args, right.args, right.type.defn.type_vars) if not self.subtype_context.ignore_type_params: + tried_infer = False for lefta, righta, tvar in type_params: if isinstance(tvar, TypeVarType): + if tvar.variance == VARIANCE_NOT_READY and not tried_infer: + infer_class_variances(right.type) + tried_infer = True if not check_type_parameter( lefta, righta, @@ -1978,3 +1986,72 @@ def is_more_precise(left: Type, right: Type, *, ignore_promotions: bool = False) if isinstance(right, AnyType): return True return is_proper_subtype(left, right, ignore_promotions=ignore_promotions) + + +def all_non_object_members(info: TypeInfo) -> set[str]: + members = set(info.names) + for base in info.mro[1:-1]: + members.update(base.names) + return members + + +def infer_variance(info: TypeInfo, i: int) -> bool: + """Infer the variance of the ith type variable of a generic class. + + Return True if successful. This can fail if some inferred types aren't ready. + """ + object_type = Instance(info.mro[-1], []) + + for variance in COVARIANT, CONTRAVARIANT, INVARIANT: + tv = info.defn.type_vars[i] + assert isinstance(tv, TypeVarType) + if tv.variance != VARIANCE_NOT_READY: + continue + tv.variance = variance + co = True + contra = True + tvar = info.defn.type_vars[i] + self_type = fill_typevars(info) + for member in all_non_object_members(info): + if member in ("__init__", "__new__"): + continue + node = info[member].node + if isinstance(node, Var) and node.type is None: + tv.variance = VARIANCE_NOT_READY + return False + if isinstance(self_type, TupleType): + self_type = mypy.typeops.tuple_fallback(self_type) + + flags = get_member_flags(member, self_type) + typ = find_member(member, self_type, self_type) + settable = IS_SETTABLE in flags + if typ: + typ2 = expand_type(typ, {tvar.id: object_type}) + if not is_subtype(typ, typ2): + co = False + if not is_subtype(typ2, typ): + contra = False + if settable: + co = False + if co: + v = COVARIANT + elif contra: + v = CONTRAVARIANT + else: + v = INVARIANT + if v == variance: + break + tv.variance = VARIANCE_NOT_READY + return True + + +def infer_class_variances(info: TypeInfo) -> bool: + if not info.defn.type_args: + return True + tvs = info.defn.type_vars + success = True + for i, tv in enumerate(tvs): + if isinstance(tv, TypeVarType) and tv.variance == VARIANCE_NOT_READY: + if not infer_variance(info, i): + success = False + return success diff --git a/mypy/test/testparse.py b/mypy/test/testparse.py index e33fa7e53ff0..e215920a6797 100644 --- a/mypy/test/testparse.py +++ b/mypy/test/testparse.py @@ -23,6 +23,8 @@ class ParserSuite(DataSuite): if sys.version_info < (3, 10): files.remove("parse-python310.test") + if sys.version_info < (3, 12): + files.remove("parse-python312.test") def run_case(self, testcase: DataDrivenTestCase) -> None: test_parser(testcase) @@ -39,6 +41,8 @@ def test_parser(testcase: DataDrivenTestCase) -> None: if testcase.file.endswith("python310.test"): options.python_version = (3, 10) + elif testcase.file.endswith("python312.test"): + options.python_version = (3, 12) else: options.python_version = defaults.PYTHON3_VERSION diff --git a/mypy/traverser.py b/mypy/traverser.py index d11dd395f978..225de27e7002 100644 --- a/mypy/traverser.py +++ b/mypy/traverser.py @@ -71,6 +71,7 @@ TupleExpr, TypeAlias, TypeAliasExpr, + TypeAliasStmt, TypeApplication, TypedDictExpr, TypeVarExpr, @@ -243,6 +244,11 @@ def visit_match_stmt(self, o: MatchStmt) -> None: guard.accept(self) o.bodies[i].accept(self) + def visit_type_alias_stmt(self, o: TypeAliasStmt) -> None: + o.name.accept(self) + # TODO: params + o.value.accept(self) + def visit_member_expr(self, o: MemberExpr) -> None: o.expr.accept(self) diff --git a/mypy/typestate.py b/mypy/typestate.py index c5a5da03eae5..0082c5564705 100644 --- a/mypy/typestate.py +++ b/mypy/typestate.py @@ -8,9 +8,9 @@ from typing import Dict, Final, Set, Tuple from typing_extensions import TypeAlias as _TypeAlias -from mypy.nodes import TypeInfo +from mypy.nodes import VARIANCE_NOT_READY, TypeInfo from mypy.server.trigger import make_trigger -from mypy.types import Instance, Type, TypeVarId, get_proper_type +from mypy.types import Instance, Type, TypeVarId, TypeVarType, get_proper_type MAX_NEGATIVE_CACHE_TYPES: Final = 1000 MAX_NEGATIVE_CACHE_ENTRIES: Final = 10000 @@ -192,6 +192,12 @@ def record_subtype_cache_entry( # These are unlikely to match, due to the large space of # possible values. Avoid uselessly increasing cache sizes. return + if any( + (isinstance(tv, TypeVarType) and tv.variance == VARIANCE_NOT_READY) + for tv in right.type.defn.type_vars + ): + # Variance indeterminate -- don't know the result + return cache = self._subtype_caches.setdefault(right.type, {}) cache.setdefault(kind, set()).add((left, right)) diff --git a/mypy/visitor.py b/mypy/visitor.py index c5aa3caa8295..340e1af64e00 100644 --- a/mypy/visitor.py +++ b/mypy/visitor.py @@ -309,6 +309,10 @@ def visit_try_stmt(self, o: mypy.nodes.TryStmt) -> T: def visit_match_stmt(self, o: mypy.nodes.MatchStmt) -> T: pass + @abstractmethod + def visit_type_alias_stmt(self, o: mypy.nodes.TypeAliasStmt) -> T: + pass + @trait @mypyc_attr(allow_interpreted_subclasses=True) @@ -460,6 +464,9 @@ def visit_with_stmt(self, o: mypy.nodes.WithStmt) -> T: def visit_match_stmt(self, o: mypy.nodes.MatchStmt) -> T: pass + def visit_type_alias_stmt(self, o: mypy.nodes.TypeAliasStmt) -> T: + pass + # Expressions (default no-op implementation) def visit_int_expr(self, o: mypy.nodes.IntExpr) -> T: diff --git a/mypyc/irbuild/visitor.py b/mypyc/irbuild/visitor.py index 12e186fd40d8..e7256f036e4c 100644 --- a/mypyc/irbuild/visitor.py +++ b/mypyc/irbuild/visitor.py @@ -70,6 +70,7 @@ TryStmt, TupleExpr, TypeAliasExpr, + TypeAliasStmt, TypeApplication, TypedDictExpr, TypeVarExpr, @@ -249,6 +250,9 @@ def visit_nonlocal_decl(self, stmt: NonlocalDecl) -> None: def visit_match_stmt(self, stmt: MatchStmt) -> None: transform_match_stmt(self.builder, stmt) + def visit_type_alias_stmt(self, stmt: TypeAliasStmt) -> None: + self.bail('The "type" statement is not yet supported by mypyc', stmt.line) + # Expressions def visit_name_expr(self, expr: NameExpr) -> Value: diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 2b99a42628b1..53656ae5e3fb 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -82,3 +82,879 @@ reveal_type(ba2) # N: Revealed type is "def (*Any) -> builtins.str" [builtins fixtures/tuple.pyi] [typing fixtures/typing-full.pyi] + +[case testPEP695GenericFunctionSyntax] +# flags: --enable-incomplete-feature=NewGenericSyntax + +def ident[TV](x: TV) -> TV: + y: TV = x + y = 1 # E: Incompatible types in assignment (expression has type "int", variable has type "TV") + return x + +reveal_type(ident(1)) # N: Revealed type is "builtins.int" +reveal_type(ident('x')) # N: Revealed type is "builtins.str" + +a: TV # E: Name "TV" is not defined + +def tup[T, S](x: T, y: S) -> tuple[T, S]: + reveal_type((x, y)) # N: Revealed type is "Tuple[T`-1, S`-2]" + return (x, y) + +reveal_type(tup(1, 'x')) # N: Revealed type is "Tuple[builtins.int, builtins.str]" +[builtins fixtures/tuple.pyi] + +[case testPEP695GenericClassSyntax] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T]: + x: T + + def __init__(self, x: T) -> None: + self.x = x + + def ident(self, x: T) -> T: + y: T = x + if int(): + return self.x + else: + return y + +reveal_type(C("x")) # N: Revealed type is "__main__.C[builtins.str]" +c: C[int] = C(1) +reveal_type(c.x) # N: Revealed type is "builtins.int" +reveal_type(c.ident(1)) # N: Revealed type is "builtins.int" + +[case testPEP695GenericMethodInGenericClass] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T]: + def m[S](self, x: S) -> T | S: ... + +a: C[int] = C[object]() # E: Incompatible types in assignment (expression has type "C[object]", variable has type "C[int]") +b: C[object] = C[int]() + +reveal_type(C[str]().m(1)) # N: Revealed type is "Union[builtins.str, builtins.int]" + +[case testPEP695InferVarianceSimpleFromMethod] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Invariant[T]: + def f(self, x: T) -> None: + pass + + def g(self) -> T | None: + return None + +a: Invariant[object] +b: Invariant[int] +if int(): + a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") +if int(): + b = a # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") + +class Covariant[T]: + def g(self) -> T | None: + return None + +c: Covariant[object] +d: Covariant[int] +if int(): + c = d +if int(): + d = c # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") + +class Contravariant[T]: + def f(self, x: T) -> None: + pass + +e: Contravariant[object] +f: Contravariant[int] +if int(): + e = f # E: Incompatible types in assignment (expression has type "Contravariant[int]", variable has type "Contravariant[object]") +if int(): + f = e + +[case testPEP695InferVarianceSimpleFromAttribute] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Invariant1[T]: + def __init__(self, x: T) -> None: + self.x = x + +a: Invariant1[object] +b: Invariant1[int] +if int(): + a = b # E: Incompatible types in assignment (expression has type "Invariant1[int]", variable has type "Invariant1[object]") +if int(): + b = a # E: Incompatible types in assignment (expression has type "Invariant1[object]", variable has type "Invariant1[int]") + +class Invariant2[T]: + def __init__(self) -> None: + self.x: list[T] = [] + +a2: Invariant2[object] +b2: Invariant2[int] +if int(): + a2 = b2 # E: Incompatible types in assignment (expression has type "Invariant2[int]", variable has type "Invariant2[object]") +if int(): + b2 = a2 # E: Incompatible types in assignment (expression has type "Invariant2[object]", variable has type "Invariant2[int]") + +class Invariant3[T]: + def __init__(self) -> None: + self.x: T | None = None + +a3: Invariant3[object] +b3: Invariant3[int] +if int(): + a3 = b3 # E: Incompatible types in assignment (expression has type "Invariant3[int]", variable has type "Invariant3[object]") +if int(): + b3 = a3 # E: Incompatible types in assignment (expression has type "Invariant3[object]", variable has type "Invariant3[int]") + +[case testPEP695InferVarianceRecursive] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Invariant[T]: + def f(self, x: Invariant[T]) -> Invariant[T]: + return x + +class Covariant[T]: + def f(self) -> Covariant[T]: + return self + +class Contravariant[T]: + def f(self, x: Contravariant[T]) -> None: + pass + +a: Invariant[object] +b: Invariant[int] +if int(): + a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") +if int(): + b = a # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") + +c: Covariant[object] +d: Covariant[int] +if int(): + c = d +if int(): + d = c # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") + +e: Contravariant[object] +f: Contravariant[int] +if int(): + e = f # E: Incompatible types in assignment (expression has type "Contravariant[int]", variable has type "Contravariant[object]") +if int(): + f = e + +[case testPEP695InferVarianceCalculateOnDemand] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Covariant[T]: + def __init__(self) -> None: + self.x = [1] + + def f(self) -> None: + c = Covariant[int]() + # We need to know that T is covariant here + self.g(c) + c2 = Covariant[object]() + self.h(c2) # E: Argument 1 to "h" of "Covariant" has incompatible type "Covariant[object]"; expected "Covariant[int]" + + def g(self, x: Covariant[object]) -> None: pass + def h(self, x: Covariant[int]) -> None: pass + +[case testPEP695InferVarianceNotReadyWhenNeeded] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Covariant[T]: + def f(self) -> None: + c = Covariant[int]() + # We need to know that T is covariant here + self.g(c) + c2 = Covariant[object]() + self.h(c2) # E: Argument 1 to "h" of "Covariant" has incompatible type "Covariant[object]"; expected "Covariant[int]" + + def g(self, x: Covariant[object]) -> None: pass + def h(self, x: Covariant[int]) -> None: pass + + def __init__(self) -> None: + self.x = [1] + +class Invariant[T]: + def f(self) -> None: + c = Invariant(1) + # We need to know that T is invariant here, and for this we need the type + # of self.x, which won't be available on the first type checking pass, + # since __init__ is defined later in the file. In this case we fall back + # covariance. + self.g(c) + c2 = Invariant(object()) + self.h(c2) # E: Argument 1 to "h" of "Invariant" has incompatible type "Invariant[object]"; expected "Invariant[int]" + + def g(self, x: Invariant[object]) -> None: pass + def h(self, x: Invariant[int]) -> None: pass + + def __init__(self, x: T) -> None: + self.x = x + +# Now we should have the variance correct. +a: Invariant[object] +b: Invariant[int] +if int(): + a = b # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") +if int(): + b = a # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") + +[case testPEP695InferVarianceNotReadyForJoin] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Invariant[T]: + def f(self) -> None: + # Assume covariance if variance us not ready + reveal_type([Invariant(1), Invariant(object())]) \ + # N: Revealed type is "builtins.list[__main__.Invariant[builtins.object]]" + + def __init__(self, x: T) -> None: + self.x = x + +reveal_type([Invariant(1), Invariant(object())]) # N: Revealed type is "builtins.list[builtins.object]" + +[case testPEP695InferVarianceNotReadyForMeet] +# flags: --enable-incomplete-feature=NewGenericSyntax + +from typing import TypeVar, Callable + +S = TypeVar("S") +def c(a: Callable[[S], None], b: Callable[[S], None]) -> S: ... + +def a1(x: Invariant[int]) -> None: pass +def a2(x: Invariant[object]) -> None: pass + +class Invariant[T]: + def f(self) -> None: + reveal_type(c(a1, a2)) # N: Revealed type is "__main__.Invariant[builtins.int]" + + def __init__(self, x: T) -> None: + self.x = x + +reveal_type(c(a1, a2)) # N: Revealed type is "Never" + +[case testPEP695InheritInvariant] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Invariant[T]: + x: T + +class Subclass[T](Invariant[T]): + pass + +x: Invariant[int] +y: Invariant[object] +if int(): + x = y # E: Incompatible types in assignment (expression has type "Invariant[object]", variable has type "Invariant[int]") +if int(): + y = x # E: Incompatible types in assignment (expression has type "Invariant[int]", variable has type "Invariant[object]") + +a: Subclass[int] +b: Subclass[object] +if int(): + a = b # E: Incompatible types in assignment (expression has type "Subclass[object]", variable has type "Subclass[int]") +if int(): + b = a # E: Incompatible types in assignment (expression has type "Subclass[int]", variable has type "Subclass[object]") + +[case testPEP695InheritanceMakesInvariant] +# flags: --enable-incomplete-feature=NewGenericSyntax +class Covariant[T]: + def f(self) -> T: + ... + +class Subclass[T](Covariant[list[T]]): + pass + +x: Covariant[int] = Covariant[object]() # E: Incompatible types in assignment (expression has type "Covariant[object]", variable has type "Covariant[int]") +y: Covariant[object] = Covariant[int]() + +a: Subclass[int] = Subclass[object]() # E: Incompatible types in assignment (expression has type "Subclass[object]", variable has type "Subclass[int]") +b: Subclass[object] = Subclass[int]() # E: Incompatible types in assignment (expression has type "Subclass[int]", variable has type "Subclass[object]") + +[case testPEP695InheritCoOrContravariant] +# flags: --enable-incomplete-feature=NewGenericSyntax +class Contravariant[T]: + def f(self, x: T) -> None: pass + +class CovSubclass[T](Contravariant[T]): + pass + +a: CovSubclass[int] = CovSubclass[object]() +b: CovSubclass[object] = CovSubclass[int]() # E: Incompatible types in assignment (expression has type "CovSubclass[int]", variable has type "CovSubclass[object]") + +class Covariant[T]: + def f(self) -> T: ... + +class CoSubclass[T](Covariant[T]): + pass + +c: CoSubclass[int] = CoSubclass[object]() # E: Incompatible types in assignment (expression has type "CoSubclass[object]", variable has type "CoSubclass[int]") +d: CoSubclass[object] = CoSubclass[int]() + +class InvSubclass[T](Covariant[T]): + def g(self, x: T) -> None: pass + +e: InvSubclass[int] = InvSubclass[object]() # E: Incompatible types in assignment (expression has type "InvSubclass[object]", variable has type "InvSubclass[int]") +f: InvSubclass[object] = InvSubclass[int]() # E: Incompatible types in assignment (expression has type "InvSubclass[int]", variable has type "InvSubclass[object]") + +[case testPEP695FinalAttribute] +# flags: --enable-incomplete-feature=NewGenericSyntax +from typing import Final + +class C[T]: + def __init__(self, x: T) -> None: + self.x: Final = x + +a: C[int] = C[object](1) # E: Incompatible types in assignment (expression has type "C[object]", variable has type "C[int]") +b: C[object] = C[int](1) + +[case testPEP695TwoTypeVariables] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T, S]: + def f(self, x: T) -> None: ... + def g(self) -> S: ... + +a: C[int, int] = C[object, int]() +b: C[object, int] = C[int, int]() # E: Incompatible types in assignment (expression has type "C[int, int]", variable has type "C[object, int]") +c: C[int, int] = C[int, object]() # E: Incompatible types in assignment (expression has type "C[int, object]", variable has type "C[int, int]") +d: C[int, object] = C[int, int]() + +[case testPEP695Properties] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class R[T]: + @property + def p(self) -> T: ... + +class RW[T]: + @property + def p(self) -> T: ... + @p.setter + def p(self, x: T) -> None: ... + +a: R[int] = R[object]() # E: Incompatible types in assignment (expression has type "R[object]", variable has type "R[int]") +b: R[object] = R[int]() +c: RW[int] = RW[object]() # E: Incompatible types in assignment (expression has type "RW[object]", variable has type "RW[int]") +d: RW[object] = RW[int]() # E: Incompatible types in assignment (expression has type "RW[int]", variable has type "RW[object]") +[builtins fixtures/property.pyi] + +[case testPEP695Protocol] +# flags: --enable-incomplete-feature=NewGenericSyntax +from typing import Protocol + +class PContra[T](Protocol): + def f(self, x: T) -> None: ... + +PContra() # E: Cannot instantiate protocol class "PContra" +a: PContra[int] +b: PContra[object] +if int(): + a = b +if int(): + b = a # E: Incompatible types in assignment (expression has type "PContra[int]", variable has type "PContra[object]") + +class PCov[T](Protocol): + def f(self) -> T: ... + +PCov() # E: Cannot instantiate protocol class "PCov" +c: PCov[int] +d: PCov[object] +if int(): + c = d # E: Incompatible types in assignment (expression has type "PCov[object]", variable has type "PCov[int]") +if int(): + d = c + +class PInv[T](Protocol): + def f(self, x: T) -> T: ... + +PInv() # E: Cannot instantiate protocol class "PInv" +e: PInv[int] +f: PInv[object] +if int(): + e = f # E: Incompatible types in assignment (expression has type "PInv[object]", variable has type "PInv[int]") +if int(): + f = e # E: Incompatible types in assignment (expression has type "PInv[int]", variable has type "PInv[object]") + +[case testPEP695TypeAlias] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T]: pass +class D[T, S]: pass + +type A[S] = C[S] + +a: A[int] +reveal_type(a) # N: Revealed type is "__main__.C[builtins.int]" + +type A2[T] = C[C[T]] +a2: A2[str] +reveal_type(a2) # N: Revealed type is "__main__.C[__main__.C[builtins.str]]" + +type A3[T, S] = D[S, C[T]] +a3: A3[int, str] +reveal_type(a3) # N: Revealed type is "__main__.D[builtins.str, __main__.C[builtins.int]]" + +type A4 = int | str +a4: A4 +reveal_type(a4) # N: Revealed type is "Union[builtins.int, builtins.str]" + +[case testPEP695TypeAliasWithUnusedTypeParams] +# flags: --enable-incomplete-feature=NewGenericSyntax +type A[T] = int +a: A[str] +reveal_type(a) # N: Revealed type is "builtins.int" + +[case testPEP695TypeAliasForwardReference1] +# flags: --enable-incomplete-feature=NewGenericSyntax + +type A[T] = C[T] + +a: A[int] +reveal_type(a) # N: Revealed type is "__main__.C[builtins.int]" + +class C[T]: pass + +[case testPEP695TypeAliasForwardReference2] +# flags: --enable-incomplete-feature=NewGenericSyntax + +type X = C +type A = X + +a: A +reveal_type(a) # N: Revealed type is "__main__.C" + +class C: pass + +[case testPEP695TypeAliasForwardReference3] +# flags: --enable-incomplete-feature=NewGenericSyntax + +type X = D +type A = C[X] + +a: A +reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" + +class C[T]: pass +class D: pass + +[case testPEP695TypeAliasForwardReference4] +# flags: --enable-incomplete-feature=NewGenericSyntax + +type A = C + +# Note that this doesn't actually work at runtime, but we currently don't +# keep track whether a type alias is valid in various runtime type contexts. +class D(A): + pass + +class C: pass + +x: C = D() +y: D = C() # E: Incompatible types in assignment (expression has type "C", variable has type "D") + +[case testPEP695TypeAliasForwardReference5] +# flags: --enable-incomplete-feature=NewGenericSyntax +type A = str +type B[T] = C[T] +class C[T]: pass +a: A +b: B[int] +c: C[str] +reveal_type(a) # N: Revealed type is "builtins.str" +reveal_type(b) # N: Revealed type is "__main__.C[builtins.int]" +reveal_type(c) # N: Revealed type is "__main__.C[builtins.str]" + +[case testPEP695TypeAliasWithUndefineName] +# flags: --enable-incomplete-feature=NewGenericSyntax +type A[T] = XXX # E: Name "XXX" is not defined +a: A[int] +reveal_type(a) # N: Revealed type is "Any" + +[case testPEP695TypeAliasInvalidType] +# flags: --enable-incomplete-feature=NewGenericSyntax +type A = int | 1 # E: Invalid type: try using Literal[1] instead? +a: A +reveal_type(a) # N: Revealed type is "Union[builtins.int, Any]" +type B = int + str # E: Invalid type alias: expression is not a valid type +b: B +reveal_type(b) # N: Revealed type is "Any" + +[case testPEP695TypeAliasBoundForwardReference] +# mypy: enable-incomplete-feature=NewGenericSyntax +type B[T: Foo] = list[T] +class Foo: pass + +[case testPEP695UpperBound] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class D: + x: int +class E(D): pass + +class C[T: D]: pass + +a: C[D] +b: C[E] +reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" +reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" + +c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" + +def f[T: D](a: T) -> T: + reveal_type(a.x) # N: Revealed type is "builtins.int" + return a + +reveal_type(f(D())) # N: Revealed type is "__main__.D" +reveal_type(f(E())) # N: Revealed type is "__main__.E" +f(1) # E: Value of type variable "T" of "f" cannot be "int" + +[case testPEP695UpperBoundForwardReference1] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T: D]: pass + +a: C[D] +b: C[E] +reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" +reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" + +c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" + +class D: pass +class E(D): pass + +[case testPEP695UpperBoundForwardReference2] +# flags: --enable-incomplete-feature=NewGenericSyntax + +type A = D +class C[T: A]: pass + +class D: pass +class E(D): pass + +a: C[D] +b: C[E] +reveal_type(a) # N: Revealed type is "__main__.C[__main__.D]" +reveal_type(b) # N: Revealed type is "__main__.C[__main__.E]" + +c: C[int] # E: Type argument "int" of "C" must be a subtype of "D" + +[case testPEP695UpperBoundForwardReference3] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class D[T]: pass +class E[T](D[T]): pass + +type A = D[X] + +class C[T: A]: pass + +class X: pass + +a: C[D[X]] +b: C[E[X]] +reveal_type(a) # N: Revealed type is "__main__.C[__main__.D[__main__.X]]" +reveal_type(b) # N: Revealed type is "__main__.C[__main__.E[__main__.X]]" + +c: C[D[int]] # E: Type argument "D[int]" of "C" must be a subtype of "D[X]" + +[case testPEP695UpperBoundForwardReference4] +# flags: --enable-incomplete-feature=NewGenericSyntax + +def f[T: D](a: T) -> T: + reveal_type(a.x) # N: Revealed type is "builtins.int" + return a + +class D: + x: int +class E(D): pass + +reveal_type(f(D())) # N: Revealed type is "__main__.D" +reveal_type(f(E())) # N: Revealed type is "__main__.E" +f(1) # E: Value of type variable "T" of "f" cannot be "int" + +[case testPEP695UpperBoundUndefinedName] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T: XX]: # E: Name "XX" is not defined + pass + +a: C[int] + +def f[T: YY](x: T) -> T: # E: Name "YY" is not defined + return x +reveal_type(f) # N: Revealed type is "def [T <: Any] (x: T`-1) -> T`-1" + +[case testPEP695UpperBoundWithMultipleParams] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T, S: int]: pass +class D[A: int, B]: pass + +def f[T: int, S: int | str](x: T, y: S) -> T | S: + return x + +C[str, int]() +C[str, str]() # E: Value of type variable "S" of "C" cannot be "str" +D[int, str]() +D[str, str]() # E: Value of type variable "A" of "D" cannot be "str" +f(1, 1) +u: int | str +f(1, u) +f('x', None) # E: Value of type variable "T" of "f" cannot be "str" \ + # E: Value of type variable "S" of "f" cannot be "None" + +[case testPEP695InferVarianceOfTupleType] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class Cov[T](tuple[int, str]): + def f(self) -> T: pass + +class Cov2[T](tuple[T, T]): + pass + +class Contra[T](tuple[int, str]): + def f(self, x: T) -> None: pass + +a: Cov[object] = Cov[int]() +b: Cov[int] = Cov[object]() # E: Incompatible types in assignment (expression has type "Cov[object]", variable has type "Cov[int]") + +c: Cov2[object] = Cov2[int]() +d: Cov2[int] = Cov2[object]() # E: Incompatible types in assignment (expression has type "Cov2[object]", variable has type "Cov2[int]") + +e: Contra[int] = Contra[object]() +f: Contra[object] = Contra[int]() # E: Incompatible types in assignment (expression has type "Contra[int]", variable has type "Contra[object]") +[builtins fixtures/tuple-simple.pyi] + +[case testPEP695ValueRestiction] +# flags: --enable-incomplete-feature=NewGenericSyntax + +def f[T: (int, str)](x: T) -> T: + reveal_type(x) # N: Revealed type is "builtins.int" \ + # N: Revealed type is "builtins.str" + return x + +reveal_type(f(1)) # N: Revealed type is "builtins.int" +reveal_type(f('x')) # N: Revealed type is "builtins.str" +f(None) # E: Value of type variable "T" of "f" cannot be "None" + +class C[T: (object, None)]: pass + +a: C[object] +b: C[None] +c: C[int] # E: Value of type variable "T" of "C" cannot be "int" + +[case testPEP695ValueRestictionForwardReference] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T: (int, D)]: + def __init__(self, x: T) -> None: + a = x + if int(): + a = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") \ + # E: Incompatible types in assignment (expression has type "str", variable has type "D") + self.x: T = x + +reveal_type(C(1).x) # N: Revealed type is "builtins.int" +C(None) # E: Value of type variable "T" of "C" cannot be "None" + +class D: pass + +C(D()) + +[case testPEP695ValueRestictionUndefinedName] +# flags: --enable-incomplete-feature=NewGenericSyntax + +class C[T: (int, XX)]: # E: Name "XX" is not defined + pass + +def f[S: (int, YY)](x: S) -> S: # E: Name "YY" is not defined + return x + +[case testPEP695ParamSpec] +# flags: --enable-incomplete-feature=NewGenericSyntax +from typing import Callable + +def g[**P](f: Callable[P, None], *args: P.args, **kwargs: P.kwargs) -> None: + f(*args, **kwargs) + f(1, *args, **kwargs) # E: Argument 1 has incompatible type "int"; expected "P.args" + +def h(x: int, y: str) -> None: pass + +g(h, 1, y='x') +g(h, 1, x=1) # E: "g" gets multiple values for keyword argument "x" \ + # E: Missing positional argument "y" in call to "g" + +class C[**P, T]: + def m(self, *args: P.args, **kwargs: P.kwargs) -> T: ... + +a: C[[int, str], None] +reveal_type(a) # N: Revealed type is "__main__.C[[builtins.int, builtins.str], None]" +reveal_type(a.m) # N: Revealed type is "def (builtins.int, builtins.str)" +[builtins fixtures/tuple.pyi] + +[case testPEP695ParamSpecTypeAlias] +# flags: --enable-incomplete-feature=NewGenericSyntax +from typing import Callable + +type C[**P] = Callable[P, int] + +f: C[[str, int | None]] +reveal_type(f) # N: Revealed type is "def (builtins.str, Union[builtins.int, None]) -> builtins.int" +[builtins fixtures/tuple.pyi] + +[case testPEP695TypeVarTuple] +# flags: --enable-incomplete-feature=NewGenericSyntax + +def f[*Ts](t: tuple[*Ts]) -> tuple[*Ts]: + reveal_type(t) # N: Revealed type is "Tuple[Unpack[Ts`-1]]" + return t + +reveal_type(f((1, 'x'))) # N: Revealed type is "Tuple[Literal[1]?, Literal['x']?]" +a: tuple[int, ...] +reveal_type(f(a)) # N: Revealed type is "builtins.tuple[builtins.int, ...]" + +class C[T, *Ts]: + pass + +b: C[int, str, None] +reveal_type(b) # N: Revealed type is "__main__.C[builtins.int, builtins.str, None]" +c: C[str] +reveal_type(c) # N: Revealed type is "__main__.C[builtins.str]" +b = c # E: Incompatible types in assignment (expression has type "C[str]", variable has type "C[int, str, None]") +[builtins fixtures/tuple.pyi] + +[case testPEP695TypeVarTupleAlias] +# flags: --enable-incomplete-feature=NewGenericSyntax +from typing import Callable + +type C[*Ts] = tuple[*Ts, int] + +a: C[str, None] +reveal_type(a) # N: Revealed type is "Tuple[builtins.str, None, builtins.int]" +[builtins fixtures/tuple.pyi] + +[case testPEP695IncrementalFunction] +# flags: --enable-incomplete-feature=NewGenericSyntax +import a + +[file a.py] +import b + +[file a.py.2] +import b +reveal_type(b.f(1)) +reveal_type(b.g(1, 'x')) +b.g('x', 'x') +b.g(1, 2) + +[file b.py] +def f[T](x: T) -> T: + return x + +def g[T: int, S: (str, None)](x: T, y: S) -> T | S: + return x + +[out2] +tmp/a.py:2: note: Revealed type is "builtins.int" +tmp/a.py:3: note: Revealed type is "Union[builtins.int, builtins.str]" +tmp/a.py:4: error: Value of type variable "T" of "g" cannot be "str" +tmp/a.py:5: error: Value of type variable "S" of "g" cannot be "int" + +[case testPEP695IncrementalClass] +# flags: --enable-incomplete-feature=NewGenericSyntax +import a + +[file a.py] +import b + +[file a.py.2] +from b import C, D +x: C[int] +reveal_type(x) + +class N(int): pass +class SS(str): pass + +y1: D[int, str] +y2: D[N, str] +y3: D[int, None] +y4: D[int, None] +y5: D[int, SS] # Error +y6: D[object, str] # Error + +[file b.py] +class C[T]: pass + +class D[T: int, S: (str, None)]: + pass + +[out2] +tmp/a.py:3: note: Revealed type is "b.C[builtins.int]" +tmp/a.py:12: error: Value of type variable "S" of "D" cannot be "SS" +tmp/a.py:13: error: Type argument "object" of "D" must be a subtype of "int" + +[case testPEP695IncrementalParamSpecAndTypeVarTuple] +# flags: --enable-incomplete-feature=NewGenericSyntax +import a + +[file a.py] +import b + +[file a.py.2] +from b import C, D +x1: C[()] +x2: C[int] +x3: C[int, str] +y: D[[int, str]] +reveal_type(y.m) + +[file b.py] +class C[*Ts]: pass +class D[**P]: + def m(self, *args: P.args, **kwargs: P.kwargs) -> None: pass + +[builtins fixtures/tuple.pyi] +[out2] +tmp/a.py:6: note: Revealed type is "def (builtins.int, builtins.str)" + +[case testPEP695IncrementalTypeAlias] +# flags: --enable-incomplete-feature=NewGenericSyntax +import a + +[file a.py] +import b + +[file a.py.2] +from b import A, B +a: A +reveal_type(a) +b: B[int] +reveal_type(b) + +[file b.py] +type A = str +class Foo[T]: pass +type B[T] = Foo[T] + +[builtins fixtures/tuple.pyi] +[out2] +tmp/a.py:3: note: Revealed type is "builtins.str" +tmp/a.py:5: note: Revealed type is "b.Foo[builtins.int]" + +[case testPEP695UndefinedNameInGenericFunction] +# mypy: enable-incomplete-feature=NewGenericSyntax + +def f[T](x: T) -> T: + return unknown() # E: Name "unknown" is not defined + +class C: + def m[T](self, x: T) -> T: + return unknown() # E: Name "unknown" is not defined diff --git a/test-data/unit/parse-python312.test b/test-data/unit/parse-python312.test new file mode 100644 index 000000000000..28204ccd647b --- /dev/null +++ b/test-data/unit/parse-python312.test @@ -0,0 +1,87 @@ +[case testPEP695TypeAlias] +# mypy: enable-incomplete-feature=NewGenericSyntax +type A[T] = C[T] +[out] +MypyFile:1( + TypeAliasStmt:2( + NameExpr(A) + TypeParam( + T) + IndexExpr:2( + NameExpr(C) + NameExpr(T)))) + +[case testPEP695GenericFunction] +# mypy: enable-incomplete-feature=NewGenericSyntax + +def f[T](): pass +def g[T: str](): pass +def h[T: (int, str)](): pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + T) + Block:3( + PassStmt:3())) + FuncDef:4( + g + TypeParam( + T + str?) + Block:4( + PassStmt:4())) + FuncDef:5( + h + TypeParam( + T + Values( + int? + str?)) + Block:5( + PassStmt:5()))) + +[case testPEP695ParamSpec] +# mypy: enable-incomplete-feature=NewGenericSyntax + +def f[**P](): pass +class C[T: int, **P]: pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + **P) + Block:3( + PassStmt:3())) + ClassDef:4( + C + TypeParam( + T + int?) + TypeParam( + **P) + PassStmt:4())) + +[case testPEP695TypeVarTuple] +# mypy: enable-incomplete-feature=NewGenericSyntax + +def f[*Ts](): pass +class C[T: int, *Ts]: pass +[out] +MypyFile:1( + FuncDef:3( + f + TypeParam( + *Ts) + Block:3( + PassStmt:3())) + ClassDef:4( + C + TypeParam( + T + int?) + TypeParam( + *Ts) + PassStmt:4())) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index b51a965c95da..0ed3540b6bb9 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -2091,3 +2091,24 @@ def f(d: Description) -> None: reveal_type(d.name_fn) [out] _testDataclassStrictOptionalAlwaysSet.py:9: note: Revealed type is "def (Union[builtins.int, None]) -> Union[builtins.str, None]" + +[case testPEP695VarianceInference] +# flags: --python-version=3.12 --enable-incomplete-feature=NewGenericSyntax +from typing import Callable, Final + +class Job[_R_co]: + def __init__(self, target: Callable[[], _R_co]) -> None: + self.target: Final = target + +def func( + action: Job[int | None], + a1: Job[int | None], + a2: Job[int], + a3: Job[None], +) -> None: + action = a1 + action = a2 + action = a3 + a2 = action # Error +[out] +_testPEP695VarianceInference.py:17: error: Incompatible types in assignment (expression has type "Job[None]", variable has type "Job[int]") From 3b97e6e60b561b18ef23bfd98a4296b23f60a10a Mon Sep 17 00:00:00 2001 From: Jukka Lehtosalo Date: Fri, 17 May 2024 15:02:45 +0100 Subject: [PATCH 172/172] [PEP 695] Implement new scoping rules for type parameters (#17258) Type parameters get a separate scope with some special features. Work on #15238. --- mypy/nodes.py | 10 +- mypy/semanal.py | 118 ++++++++++++---- mypy/typeanal.py | 37 +++-- test-data/unit/check-python312.test | 203 ++++++++++++++++++++++++++++ 4 files changed, 323 insertions(+), 45 deletions(-) diff --git a/mypy/nodes.py b/mypy/nodes.py index 4c83d8081f6c..6657ab8cb65f 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -2502,7 +2502,7 @@ class TypeVarLikeExpr(SymbolNode, Expression): Note that they are constructed by the semantic analyzer. """ - __slots__ = ("_name", "_fullname", "upper_bound", "default", "variance") + __slots__ = ("_name", "_fullname", "upper_bound", "default", "variance", "is_new_style") _name: str _fullname: str @@ -2525,6 +2525,7 @@ def __init__( upper_bound: mypy.types.Type, default: mypy.types.Type, variance: int = INVARIANT, + is_new_style: bool = False, ) -> None: super().__init__() self._name = name @@ -2532,6 +2533,7 @@ def __init__( self.upper_bound = upper_bound self.default = default self.variance = variance + self.is_new_style = is_new_style @property def name(self) -> str: @@ -2570,8 +2572,9 @@ def __init__( upper_bound: mypy.types.Type, default: mypy.types.Type, variance: int = INVARIANT, + is_new_style: bool = False, ) -> None: - super().__init__(name, fullname, upper_bound, default, variance) + super().__init__(name, fullname, upper_bound, default, variance, is_new_style) self.values = values def accept(self, visitor: ExpressionVisitor[T]) -> T: @@ -2648,8 +2651,9 @@ def __init__( tuple_fallback: mypy.types.Instance, default: mypy.types.Type, variance: int = INVARIANT, + is_new_style: bool = False, ) -> None: - super().__init__(name, fullname, upper_bound, default, variance) + super().__init__(name, fullname, upper_bound, default, variance, is_new_style) self.tuple_fallback = tuple_fallback def accept(self, visitor: ExpressionVisitor[T]) -> T: diff --git a/mypy/semanal.py b/mypy/semanal.py index f92471c159de..a66f43e17dd2 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -317,6 +317,14 @@ CORE_BUILTIN_CLASSES: Final = ["object", "bool", "function"] +# Python has several different scope/namespace kinds with subtly different semantics. +SCOPE_GLOBAL: Final = 0 # Module top level +SCOPE_CLASS: Final = 1 # Class body +SCOPE_FUNC: Final = 2 # Function or lambda +SCOPE_COMPREHENSION: Final = 3 # Comprehension or generator expression +SCOPE_ANNOTATION: Final = 4 # Annotation scopes for type parameters and aliases (PEP 695) + + # Used for tracking incomplete references Tag: _TypeAlias = int @@ -342,8 +350,8 @@ class SemanticAnalyzer( nonlocal_decls: list[set[str]] # Local names of function scopes; None for non-function scopes. locals: list[SymbolTable | None] - # Whether each scope is a comprehension scope. - is_comprehension_stack: list[bool] + # Type of each scope (SCOPE_*, indexes match locals) + scope_stack: list[int] # Nested block depths of scopes block_depth: list[int] # TypeInfo of directly enclosing class (or None) @@ -417,7 +425,7 @@ def __init__( errors: Report analysis errors using this instance """ self.locals = [None] - self.is_comprehension_stack = [False] + self.scope_stack = [SCOPE_GLOBAL] # Saved namespaces from previous iteration. Every top-level function/method body is # analyzed in several iterations until all names are resolved. We need to save # the local namespaces for the top level function and all nested functions between @@ -880,6 +888,7 @@ def analyze_func_def(self, defn: FuncDef) -> None: # Don't store not ready types (including placeholders). if self.found_incomplete_ref(tag) or has_placeholder(result): self.defer(defn) + # TODO: pop type args return assert isinstance(result, ProperType) if isinstance(result, CallableType): @@ -1645,6 +1654,8 @@ def push_type_args( ) -> list[tuple[str, TypeVarLikeExpr]] | None: if not type_args: return [] + self.locals.append(SymbolTable()) + self.scope_stack.append(SCOPE_ANNOTATION) tvs: list[tuple[str, TypeVarLikeExpr]] = [] for p in type_args: tv = self.analyze_type_param(p) @@ -1653,10 +1664,23 @@ def push_type_args( tvs.append((p.name, tv)) for name, tv in tvs: - self.add_symbol(name, tv, context, no_progress=True) + if self.is_defined_type_param(name): + self.fail(f'"{name}" already defined as a type parameter', context) + else: + self.add_symbol(name, tv, context, no_progress=True, type_param=True) return tvs + def is_defined_type_param(self, name: str) -> bool: + for names in self.locals: + if names is None: + continue + if name in names: + node = names[name].node + if isinstance(node, TypeVarLikeExpr): + return True + return False + def analyze_type_param(self, type_param: TypeParam) -> TypeVarLikeExpr | None: fullname = self.qualified_name(type_param.name) if type_param.upper_bound: @@ -1681,10 +1705,15 @@ def analyze_type_param(self, type_param: TypeParam) -> TypeVarLikeExpr | None: upper_bound=upper_bound, default=default, variance=VARIANCE_NOT_READY, + is_new_style=True, ) elif type_param.kind == PARAM_SPEC_KIND: return ParamSpecExpr( - name=type_param.name, fullname=fullname, upper_bound=upper_bound, default=default + name=type_param.name, + fullname=fullname, + upper_bound=upper_bound, + default=default, + is_new_style=True, ) else: assert type_param.kind == TYPE_VAR_TUPLE_KIND @@ -1696,14 +1725,14 @@ def analyze_type_param(self, type_param: TypeParam) -> TypeVarLikeExpr | None: upper_bound=tuple_fallback.copy_modified(), tuple_fallback=tuple_fallback, default=default, + is_new_style=True, ) def pop_type_args(self, type_args: list[TypeParam] | None) -> None: if not type_args: return - for tv in type_args: - names = self.current_symbol_table() - del names[tv.name] + self.locals.pop() + self.scope_stack.pop() def analyze_class(self, defn: ClassDef) -> None: fullname = self.qualified_name(defn.name) @@ -1785,8 +1814,18 @@ def analyze_class(self, defn: ClassDef) -> None: defn.info.is_protocol = is_protocol self.recalculate_metaclass(defn, declared_metaclass) defn.info.runtime_protocol = False + + if defn.type_args: + # PEP 695 type parameters are not in scope in class decorators, so + # temporarily disable type parameter namespace. + type_params_names = self.locals.pop() + self.scope_stack.pop() for decorator in defn.decorators: self.analyze_class_decorator(defn, decorator) + if defn.type_args: + self.locals.append(type_params_names) + self.scope_stack.append(SCOPE_ANNOTATION) + self.analyze_class_body_common(defn) def setup_type_vars(self, defn: ClassDef, tvar_defs: list[TypeVarLikeType]) -> None: @@ -1938,7 +1977,7 @@ def enter_class(self, info: TypeInfo) -> None: # Remember previous active class self.type_stack.append(self.type) self.locals.append(None) # Add class scope - self.is_comprehension_stack.append(False) + self.scope_stack.append(SCOPE_CLASS) self.block_depth.append(-1) # The class body increments this to 0 self.loop_depth.append(0) self._type = info @@ -1949,7 +1988,7 @@ def leave_class(self) -> None: self.block_depth.pop() self.loop_depth.pop() self.locals.pop() - self.is_comprehension_stack.pop() + self.scope_stack.pop() self._type = self.type_stack.pop() self.missing_names.pop() @@ -2923,8 +2962,8 @@ class C: [(j := i) for i in [1, 2, 3]] is a syntax error that is not enforced by Python parser, but at later steps. """ - for i, is_comprehension in enumerate(reversed(self.is_comprehension_stack)): - if not is_comprehension and i < len(self.locals) - 1: + for i, scope_type in enumerate(reversed(self.scope_stack)): + if scope_type != SCOPE_COMPREHENSION and i < len(self.locals) - 1: if self.locals[-1 - i] is None: self.fail( "Assignment expression within a comprehension" @@ -5188,8 +5227,14 @@ def visit_nonlocal_decl(self, d: NonlocalDecl) -> None: self.fail("nonlocal declaration not allowed at module level", d) else: for name in d.names: - for table in reversed(self.locals[:-1]): + for table, scope_type in zip( + reversed(self.locals[:-1]), reversed(self.scope_stack[:-1]) + ): if table is not None and name in table: + if scope_type == SCOPE_ANNOTATION: + self.fail( + f'nonlocal binding not allowed for type parameter "{name}"', d + ) break else: self.fail(f'No binding for nonlocal "{name}" found', d) @@ -5350,7 +5395,7 @@ def visit_star_expr(self, expr: StarExpr) -> None: def visit_yield_from_expr(self, e: YieldFromExpr) -> None: if not self.is_func_scope(): self.fail('"yield from" outside function', e, serious=True, blocker=True) - elif self.is_comprehension_stack[-1]: + elif self.scope_stack[-1] == SCOPE_COMPREHENSION: self.fail( '"yield from" inside comprehension or generator expression', e, @@ -5848,7 +5893,7 @@ def visit__promote_expr(self, expr: PromoteExpr) -> None: def visit_yield_expr(self, e: YieldExpr) -> None: if not self.is_func_scope(): self.fail('"yield" outside function', e, serious=True, blocker=True) - elif self.is_comprehension_stack[-1]: + elif self.scope_stack[-1] == SCOPE_COMPREHENSION: self.fail( '"yield" inside comprehension or generator expression', e, @@ -6281,6 +6326,7 @@ def add_symbol( can_defer: bool = True, escape_comprehensions: bool = False, no_progress: bool = False, + type_param: bool = False, ) -> bool: """Add symbol to the currently active symbol table. @@ -6303,7 +6349,7 @@ def add_symbol( kind, node, module_public=module_public, module_hidden=module_hidden ) return self.add_symbol_table_node( - name, symbol, context, can_defer, escape_comprehensions, no_progress + name, symbol, context, can_defer, escape_comprehensions, no_progress, type_param ) def add_symbol_skip_local(self, name: str, node: SymbolNode) -> None: @@ -6336,6 +6382,7 @@ def add_symbol_table_node( can_defer: bool = True, escape_comprehensions: bool = False, no_progress: bool = False, + type_param: bool = False, ) -> bool: """Add symbol table node to the currently active symbol table. @@ -6355,7 +6402,9 @@ def add_symbol_table_node( can_defer: if True, defer current target if adding a placeholder context: error context (see above about None value) """ - names = self.current_symbol_table(escape_comprehensions=escape_comprehensions) + names = self.current_symbol_table( + escape_comprehensions=escape_comprehensions, type_param=type_param + ) existing = names.get(name) if isinstance(symbol.node, PlaceholderNode) and can_defer: if context is not None: @@ -6673,7 +6722,7 @@ def enter( names = self.saved_locals.setdefault(function, SymbolTable()) self.locals.append(names) is_comprehension = isinstance(function, (GeneratorExpr, DictionaryComprehension)) - self.is_comprehension_stack.append(is_comprehension) + self.scope_stack.append(SCOPE_FUNC if not is_comprehension else SCOPE_COMPREHENSION) self.global_decls.append(set()) self.nonlocal_decls.append(set()) # -1 since entering block will increment this to 0. @@ -6684,7 +6733,7 @@ def enter( yield finally: self.locals.pop() - self.is_comprehension_stack.pop() + self.scope_stack.pop() self.global_decls.pop() self.nonlocal_decls.pop() self.block_depth.pop() @@ -6692,11 +6741,14 @@ def enter( self.missing_names.pop() def is_func_scope(self) -> bool: - return self.locals[-1] is not None + scope_type = self.scope_stack[-1] + if scope_type == SCOPE_ANNOTATION: + scope_type = self.scope_stack[-2] + return scope_type in (SCOPE_FUNC, SCOPE_COMPREHENSION) def is_nested_within_func_scope(self) -> bool: """Are we underneath a function scope, even if we are in a nested class also?""" - return any(l is not None for l in self.locals) + return any(s in (SCOPE_FUNC, SCOPE_COMPREHENSION) for s in self.scope_stack) def is_class_scope(self) -> bool: return self.type is not None and not self.is_func_scope() @@ -6713,14 +6765,24 @@ def current_symbol_kind(self) -> int: kind = GDEF return kind - def current_symbol_table(self, escape_comprehensions: bool = False) -> SymbolTable: - if self.is_func_scope(): - assert self.locals[-1] is not None + def current_symbol_table( + self, escape_comprehensions: bool = False, type_param: bool = False + ) -> SymbolTable: + if type_param and self.scope_stack[-1] == SCOPE_ANNOTATION: + n = self.locals[-1] + assert n is not None + return n + elif self.is_func_scope(): + if self.scope_stack[-1] == SCOPE_ANNOTATION: + n = self.locals[-2] + else: + n = self.locals[-1] + assert n is not None if escape_comprehensions: - assert len(self.locals) == len(self.is_comprehension_stack) + assert len(self.locals) == len(self.scope_stack) # Retrieve the symbol table from the enclosing non-comprehension scope. - for i, is_comprehension in enumerate(reversed(self.is_comprehension_stack)): - if not is_comprehension: + for i, scope_type in enumerate(reversed(self.scope_stack)): + if scope_type != SCOPE_COMPREHENSION: if i == len(self.locals) - 1: # The last iteration. # The caller of the comprehension is in the global space. names = self.globals @@ -6734,7 +6796,7 @@ def current_symbol_table(self, escape_comprehensions: bool = False) -> SymbolTab else: assert False, "Should have at least one non-comprehension scope" else: - names = self.locals[-1] + names = n assert names is not None elif self.type is not None: names = self.type.names diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 5cde7da721ec..31d451b0831a 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -894,6 +894,7 @@ def analyze_unbound_type_without_type_info( t = t.copy_modified(args=self.anal_array(t.args)) # TODO: Move this message building logic to messages.py. notes: list[str] = [] + error_code = codes.VALID_TYPE if isinstance(sym.node, Var): notes.append( "See https://mypy.readthedocs.io/en/" @@ -912,25 +913,33 @@ def analyze_unbound_type_without_type_info( message = 'Module "{}" is not valid as a type' notes.append("Perhaps you meant to use a protocol matching the module structure?") elif unbound_tvar: - message = 'Type variable "{}" is unbound' - short = name.split(".")[-1] - notes.append( - ( - '(Hint: Use "Generic[{}]" or "Protocol[{}]" base class' - ' to bind "{}" inside a class)' - ).format(short, short, short) - ) - notes.append( - '(Hint: Use "{}" in function signature to bind "{}"' - " inside a function)".format(short, short) - ) + assert isinstance(sym.node, TypeVarLikeExpr) + if sym.node.is_new_style: + # PEP 695 type paramaters are never considered unbound -- they are undefined + # in contexts where they aren't valid, such as in argument default values. + message = 'Name "{}" is not defined' + name = name.split(".")[-1] + error_code = codes.NAME_DEFINED + else: + message = 'Type variable "{}" is unbound' + short = name.split(".")[-1] + notes.append( + ( + '(Hint: Use "Generic[{}]" or "Protocol[{}]" base class' + ' to bind "{}" inside a class)' + ).format(short, short, short) + ) + notes.append( + '(Hint: Use "{}" in function signature to bind "{}"' + " inside a function)".format(short, short) + ) else: message = 'Cannot interpret reference "{}" as a type' if not defining_literal: # Literal check already gives a custom error. Avoid duplicating errors. - self.fail(message.format(name), t, code=codes.VALID_TYPE) + self.fail(message.format(name), t, code=error_code) for note in notes: - self.note(note, t, code=codes.VALID_TYPE) + self.note(note, t, code=error_code) # TODO: Would it be better to always return Any instead of UnboundType # in case of an error? On one hand, UnboundType has a name so error messages diff --git a/test-data/unit/check-python312.test b/test-data/unit/check-python312.test index 53656ae5e3fb..cce22634df6d 100644 --- a/test-data/unit/check-python312.test +++ b/test-data/unit/check-python312.test @@ -958,3 +958,206 @@ def f[T](x: T) -> T: class C: def m[T](self, x: T) -> T: return unknown() # E: Name "unknown" is not defined + +[case testPEP695FunctionTypeVarAccessInFunction] +# mypy: enable-incomplete-feature=NewGenericSyntax +from typing import cast + +class C: + def m[T](self, x: T) -> T: + y: T = x + reveal_type(y) # N: Revealed type is "T`-1" + return cast(T, y) + +reveal_type(C().m(1)) # N: Revealed type is "builtins.int" + +[case testPEP695ScopingBasics] +# mypy: enable-incomplete-feature=NewGenericSyntax + +T = 1 + +def f[T](x: T) -> T: + T = 'a' + reveal_type(T) # N: Revealed type is "builtins.str" + return x + +reveal_type(T) # N: Revealed type is "builtins.int" + +class C[T]: + T = 1.2 + reveal_type(T) # N: Revealed type is "builtins.float" + +reveal_type(T) # N: Revealed type is "builtins.int" + +[case testPEP695ClassScoping] +# mypy: enable-incomplete-feature=NewGenericSyntax + +class C: + class D: pass + + def m[T: D](self, x: T, y: D) -> T: + return x + +C().m(C.D(), C.D()) +C().m(1, C.D()) # E: Value of type variable "T" of "m" of "C" cannot be "int" + +[case testPEP695NestedGenericFunction] +# mypy: enable-incomplete-feature=NewGenericSyntax +def f[T](x: T) -> T: + reveal_type(f(x)) # N: Revealed type is "T`-1" + reveal_type(f(1)) # N: Revealed type is "builtins.int" + + def ff(x: T) -> T: + y: T = x + return y + reveal_type(ff(x)) # N: Revealed type is "T`-1" + ff(1) # E: Argument 1 to "ff" has incompatible type "int"; expected "T" + + def g[S](a: S) -> S: + ff(a) # E: Argument 1 to "ff" has incompatible type "S"; expected "T" + return a + reveal_type(g(1)) # N: Revealed type is "builtins.int" + reveal_type(g(x)) # N: Revealed type is "T`-1" + + def h[S](a: S) -> S: + return a + reveal_type(h(1)) # N: Revealed type is "builtins.int" + reveal_type(h(x)) # N: Revealed type is "T`-1" + return x + +[case testPEP695NonLocalAndGlobal] +# mypy: enable-incomplete-feature=NewGenericSyntax +def f() -> None: + T = 1 + def g[T](x: T) -> T: + nonlocal T # E: nonlocal binding not allowed for type parameter "T" + T = 'x' # E: "T" is a type variable and only valid in type context + return x + reveal_type(T) # N: Revealed type is "builtins.int" + +def g() -> None: + a = 1 + def g[T](x: T) -> T: + nonlocal a + a = 'x' # E: Incompatible types in assignment (expression has type "str", variable has type "int") + return x + +x = 1 + +def h[T](a: T) -> T: + global x + x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") + return a + +class C[T]: + def m[S](self, a: S) -> S: + global x + x = '' # E: Incompatible types in assignment (expression has type "str", variable has type "int") + return a + +[case testPEP695ArgumentDefault] +# mypy: enable-incomplete-feature=NewGenericSyntax +from typing import cast + +def f[T]( + x: T = + T # E: Name "T" is not defined \ + # E: Incompatible default for argument "x" (default has type "object", argument has type "T") +) -> T: + return x + +def g[T](x: T = cast(T, None)) -> T: # E: Name "T" is not defined + return x + +class C: + def m[T](self, x: T = cast(T, None)) -> T: # E: Name "T" is not defined + return x + +[case testPEP695ListComprehension] +# mypy: enable-incomplete-feature=NewGenericSyntax +from typing import cast + +def f[T](x: T) -> T: + b = [cast(T, a) for a in [1, 2]] + reveal_type(b) # N: Revealed type is "builtins.list[T`-1]" + return x + +[case testPEP695ReuseNameInSameScope] +# mypy: enable-incomplete-feature=NewGenericSyntax + +class C[T]: + def m[S](self, x: S, y: T) -> S | T: + return x + + def m2[S](self, x: S, y: T) -> S | T: + return x + +class D[T]: + pass + +def f[T](x: T) -> T: + return x + +def g[T](x: T) -> T: + def nested[S](y: S) -> S: + return y + def nested2[S](y: S) -> S: + return y + return x + +[case testPEP695NestedScopingSpecialCases] +# mypy: enable-incomplete-feature=NewGenericSyntax +# This is adapted from PEP 695 +S = 0 + +def outer1[S]() -> None: + S = 1 + T = 1 + + def outer2[T]() -> None: + def inner1() -> None: + nonlocal S + nonlocal T # E: nonlocal binding not allowed for type parameter "T" + + def inner2() -> None: + global S + +[case testPEP695ScopingWithBaseClasses] +# mypy: enable-incomplete-feature=NewGenericSyntax +# This is adapted from PEP 695 +class Outer: + class Private: + pass + + # If the type parameter scope was like a traditional scope, + # the base class 'Private' would not be accessible here. + class Inner[T](Private, list[T]): + pass + + # Likewise, 'Inner' would not be available in these type annotations. + def method1[T](self, a: Inner[T]) -> Inner[T]: + return a + +[case testPEP695RedefineTypeParameterInScope] +# mypy: enable-incomplete-feature=NewGenericSyntax +class C[T]: + def m[T](self, x: T) -> T: # E: "T" already defined as a type parameter + return x + def m2(self) -> None: + def nested[T](x: T) -> T: # E: "T" already defined as a type parameter + return x + +def f[S, S](x: S) -> S: # E: "S" already defined as a type parameter + return x + +[case testPEP695ClassDecorator] +# mypy: enable-incomplete-feature=NewGenericSyntax +from typing import Any + +T = 0 + +def decorator(x: str) -> Any: ... + +@decorator(T) # E: Argument 1 to "decorator" has incompatible type "int"; expected "str" +class C[T]: + pass