diff --git a/.editorconfig b/.editorconfig index 461d93d21a34..07f00de06ee4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,11 +1,11 @@ root = true -[*.{py,c,cpp,h,rst,md,yml,json}] +[*.{py,c,cpp,h,rst,md,yml,json,test}] trim_trailing_whitespace = true insert_final_newline = true indent_style = space -[*.{py,c,h,json}] +[*.{py,c,h,json,test}] indent_size = 4 [*.yml] diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d44f9143bdc7..228bdb3bd4ad 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -23,7 +23,7 @@ jobs: with: python-version: '3.7' - name: Install tox - run: pip install --upgrade 'setuptools!=50' 'virtualenv<16.7.11' tox==3.20.1 + run: pip install --upgrade 'setuptools!=50' 'virtualenv>=20.6.0' tox==3.24.5 - name: Setup tox environment run: tox -e ${{ env.TOXENV }} --notest - name: Test diff --git a/.github/workflows/mypy_primer.yml b/.github/workflows/mypy_primer.yml index 88500b698707..e65d918228b4 100644 --- a/.github/workflows/mypy_primer.yml +++ b/.github/workflows/mypy_primer.yml @@ -8,6 +8,10 @@ on: - '**/*.rst' - '**/*.md' - 'mypyc/**' + - 'mypy/stubtest.py' + - 'mypy/stubgen.py' + - 'mypy/stubgenc.py' + - 'mypy/test/**' jobs: mypy_primer: diff --git a/.github/workflows/mypy_primer_comment.yml b/.github/workflows/mypy_primer_comment.yml index edc91b190e29..9aa5b7a7131e 100644 --- a/.github/workflows/mypy_primer_comment.yml +++ b/.github/workflows/mypy_primer_comment.yml @@ -38,62 +38,41 @@ jobs: fs.writeFileSync("diff.zip", Buffer.from(download.data)); - run: unzip diff.zip - - # Based on https://github.com/kanga333/comment-hider - - name: Hide old comments - uses: actions/github-script@v3 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const fs = require('fs') - - const response = await github.issues.listComments({ - issue_number: fs.readFileSync("pr_number.txt", { encoding: "utf8" }), - owner: context.repo.owner, - repo: context.repo.repo, - }) - const botCommentIds = response.data - .filter(comment => comment.user.login === 'github-actions[bot]') - .map(comment => comment.node_id) - - for (const id of botCommentIds) { - const resp = await github.graphql(` - mutation { - minimizeComment(input: {classifier: OUTDATED, subjectId: "${id}"}) { - minimizedComment { - isMinimized - } - } - } - `) - if (resp.errors) { - throw new Error(resp.errors) - } - } + # 30000 bytes is about 300 lines, posting comment fails if too long + - run: | + cat diff_*.txt | head -c 30000 | tee fulldiff.txt - name: Post comment + id: post-comment uses: actions/github-script@v3 with: - github-token: ${{secrets.GITHUB_TOKEN}} + github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs') - // Keep in sync with shards produced by mypy_primer workflow - const data = ( - ['diff_0.txt', 'diff_1.txt', 'diff_2.txt'] - .map(fileName => fs.readFileSync(fileName, { encoding: 'utf8' })) - .join('') - .substr(0, 30000) // About 300 lines - ) + const data = fs.readFileSync('fulldiff.txt', { encoding: 'utf8' }) console.log("Diff from mypy_primer:") console.log(data) + let body if (data.trim()) { - const body = 'Diff from [mypy_primer](https://github.com/hauntsaninja/mypy_primer), showing the effect of this PR on open source code:\n```diff\n' + data + '```' - await github.issues.createComment({ - issue_number: fs.readFileSync("pr_number.txt", { encoding: "utf8" }), - owner: context.repo.owner, - repo: context.repo.repo, - body - }) + body = 'Diff from [mypy_primer](https://github.com/hauntsaninja/mypy_primer), showing the effect of this PR on open source code:\n```diff\n' + data + '```' + } else { + body = 'According to [mypy_primer](https://github.com/hauntsaninja/mypy_primer), this change has no effect on the checked open source code. πŸ€–πŸŽ‰' } + const prNumber = parseInt(fs.readFileSync("pr_number.txt", { encoding: "utf8" })) + await github.issues.createComment({ + issue_number: prNumber, + owner: context.repo.owner, + repo: context.repo.repo, + body + }) + return prNumber + + - name: Hide old comments + # v0.3.0 + uses: kanga333/comment-hider@bbdf5b562fbec24e6f60572d8f712017428b92e0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + leave_visible: 1 + issue_number: ${{ steps.post-comment.outputs.result }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7b3740bc4b15..7402a97d7321 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -75,11 +75,16 @@ jobs: toxenv: py36 tox_extra_args: "-n 2 mypyc/test/test_run.py mypyc/test/test_external.py" debug_build: true - - name: Type check our own code + - name: Type check our own code (py37-ubuntu) python: '3.7' arch: x64 os: ubuntu-latest toxenv: type + - name: Type check our own code (py37-windows-64) + python: '3.7' + arch: x64 + os: windows-latest + toxenv: type - name: Code style with flake8 python: '3.7' arch: x64 @@ -102,7 +107,7 @@ jobs: ./misc/build-debug-python.sh $PYTHONVERSION $PYTHONDIR $VENV source $VENV/bin/activate - name: Install tox - run: pip install --upgrade 'setuptools!=50' 'virtualenv>=20.6.0' tox==3.20.1 + run: pip install --upgrade 'setuptools!=50' 'virtualenv>=20.6.0' tox==3.24.5 - name: Compiled with mypyc if: ${{ matrix.test_mypyc }} run: | diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9e5bdeb90a69..eafefe346d01 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,6 +54,12 @@ You can also use `tox` to run tests, for instance: tox -e py ``` +The easiest way to run a single test is: +``` +pytest -n0 -k 'test_name' +``` +There's more useful information on writing and running tests [here](test-data/unit/README.md) + ## First time contributors If you're looking for things to help with, browse our [issue tracker](https://github.com/python/mypy/issues)! @@ -63,21 +69,24 @@ In particular, look for: - [good second issues](https://github.com/python/mypy/labels/good-second-issue) - [documentation issues](https://github.com/python/mypy/labels/documentation) -It's also extremely easy to get started contributing to our sister project -[typeshed](https://github.com/python/typeshed/issues) that provides type stubs -for libraries. This is a great way to become familiar with type syntax. - -If you need help getting started, don't hesitate to ask on -[gitter](https://gitter.im/python/typing). +You do not need to ask for permission to work on any of these issues. +Just fix the issue yourself, [try to add a unit test](#running-tests) and +[open a pull request](#submitting-changes). To get help fixing a specific issue, it's often best to comment on the issue -itself. The more details you provide about what you've tried and where you've -looked, the easier it will be for you to get help. +itself. You're much more likely to get help if you provide details about what +you've tried and where you've looked (maintainers tend to help those who help +themselves). [gitter](https://gitter.im/python/typing) can also be a good place +to ask for help. Interactive debuggers like `pdb` and `ipdb` are really useful for getting started with the mypy codebase. This is a [useful tutorial](https://realpython.com/python-debugging-pdb/). +It's also extremely easy to get started contributing to our sister project +[typeshed](https://github.com/python/typeshed/issues) that provides type stubs +for libraries. This is a great way to become familiar with type syntax. + ## Submitting changes Even more excellent than a good bug report is a fix for a bug, or the diff --git a/CREDITS b/CREDITS index d0e53de5ee01..fb2fe155a9b8 100644 --- a/CREDITS +++ b/CREDITS @@ -11,15 +11,18 @@ Dropbox core team: Jukka Lehtosalo Ivan Levkivskyi + Jared Hance Non-Dropbox core team members: Ethan Smith Guido van Rossum - Jelle Zijlstra + Jelle Zijlstra Michael J. Sullivan Shantanu Jain - Xuanda Yang + Xuanda Yang + Jingchen Ye <97littleleaf11@gmail.com> + Nikita Sobolev Past Dropbox core team members: diff --git a/LICENSE b/LICENSE index 549ff6575611..991496cb4878 100644 --- a/LICENSE +++ b/LICENSE @@ -4,7 +4,8 @@ Mypy (and mypyc) are licensed under the terms of the MIT license, reproduced bel The MIT License -Copyright (c) 2015-2021 Jukka Lehtosalo and contributors +Copyright (c) 2012-2022 Jukka Lehtosalo and contributors +Copyright (c) 2015-2022 Dropbox, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/docs/source/command_line.rst b/docs/source/command_line.rst index fb30245794f7..36c13910c21a 100644 --- a/docs/source/command_line.rst +++ b/docs/source/command_line.rst @@ -524,7 +524,16 @@ of the above sections. # 'items' has type list[str] items = [item.split() for item in items] # 'items' now has type list[list[str]] - ... + + The variable must be used before it can be redefined: + + .. code-block:: python + + def process(items: list[str]) -> None: + items = "mypy" # invalid redefinition to str because the variable hasn't been used yet + print(items) + items = "100" # valid, items now has type str + items = int(items) # valid, items now has type int .. option:: --local-partial-types diff --git a/docs/source/config_file.rst b/docs/source/config_file.rst index 26589e71e86b..6373a5094b3d 100644 --- a/docs/source/config_file.rst +++ b/docs/source/config_file.rst @@ -201,7 +201,7 @@ section of the command line docs. A regular expression that matches file names, directory names and paths which mypy should ignore while recursively discovering files to check. - Use forward slashes on all platforms. + Use forward slashes (``/``) as directory separators on all platforms. .. code-block:: ini @@ -237,8 +237,9 @@ section of the command line docs. [tool.mypy] exclude = [ - "^file1\\.py$", # TOML's double-quoted strings require escaping backslashes - '^file2\.py$', # but TOML's single-quoted strings do not + "^one\\.py$", # TOML's double-quoted strings require escaping backslashes + 'two\.pyi$', # but TOML's single-quoted strings do not + '^three\.', ] A single, multi-line string: @@ -247,9 +248,10 @@ section of the command line docs. [tool.mypy] exclude = '''(?x)( - ^file1\.py$ - |^file2\.py$, - )''' + ^one\.py$ # files named "one.py" + | two\.pyi$ # or files ending with "two.pyi" + | ^three\. # or files starting with "three." + )''' # TOML's single-quoted strings do not require escaping backslashes See :ref:`using-a-pyproject-toml`. @@ -613,6 +615,24 @@ section of the command line docs. Allows variables to be redefined with an arbitrary type, as long as the redefinition is in the same block and nesting level as the original definition. + Example where this can be useful: + + .. code-block:: python + + def process(items: list[str]) -> None: + # 'items' has type list[str] + items = [item.split() for item in items] + # 'items' now has type list[list[str]] + + The variable must be used before it can be redefined: + + .. code-block:: python + + def process(items: list[str]) -> None: + items = "mypy" # invalid redefinition to str because the variable hasn't been used yet + print(items) + items = "100" # valid, items now has type str + items = int(items) # valid, items now has type int .. confval:: local_partial_types diff --git a/docs/source/error_code_list2.rst b/docs/source/error_code_list2.rst index 1e035fcf7f69..c55643ad6181 100644 --- a/docs/source/error_code_list2.rst +++ b/docs/source/error_code_list2.rst @@ -255,3 +255,36 @@ no error in practice. In such case, it might be prudent to annotate ``items: Seq This is similar in concept to ensuring that an expression's type implements an expected interface (e.g. ``Sized``), except that attempting to invoke an undefined method (e.g. ``__len__``) results in an error, while attempting to evaluate an object in boolean context without a concrete implementation results in a truthy value. + + +.. _ignore-without-code: + +Check that ``# type: ignore`` include an error code [ignore-without-code] +------------------------------------------------------------------------- + +Warn when a ``# type: ignore`` comment does not specify any error codes. +This clarifies the intent of the ignore and ensures that only the +expected errors are silenced. + +Example: + +.. code-block:: python + + # mypy: enable-error-code ignore-without-code + + class Foo: + def __init__(self, name: str) -> None: + self.name = name + + f = Foo('foo') + + # This line has a typo that mypy can't help with as both: + # - the expected error 'assignment', and + # - the unexpected error 'attr-defined' + # are silenced. + # Error: "type: ignore" comment without error code (consider "type: ignore[attr-defined]" instead) + f.nme = 42 # type: ignore + + # This line warns correctly about the typo in the attribute name + # Error: "Foo" has no attribute "nme"; maybe "name"? + f.nme = 42 # type: ignore[assignment] diff --git a/docs/source/error_codes.rst b/docs/source/error_codes.rst index 5255a6984b7b..08d56c59fba2 100644 --- a/docs/source/error_codes.rst +++ b/docs/source/error_codes.rst @@ -31,6 +31,10 @@ or config `show_error_codes = True` to display error codes. Error codes are show $ mypy --show-error-codes 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 diff --git a/docs/source/generics.rst b/docs/source/generics.rst index 7e64aa181403..7730bd0e5c10 100644 --- a/docs/source/generics.rst +++ b/docs/source/generics.rst @@ -673,6 +673,10 @@ protocols mostly follow the normal rules for generic classes. Example: y: Box[int] = ... x = y # Error -- Box is invariant +Per :pep:`PEP 544: Generic protocols <544#generic-protocols>`, ``class +ClassName(Protocol[T])`` is allowed as a shorthand for ``class +ClassName(Protocol, Generic[T])``. + The main difference between generic protocols and ordinary generic classes is that mypy checks that the declared variances of generic type variables in a protocol match how they are used in the protocol diff --git a/docs/source/literal_types.rst b/docs/source/literal_types.rst index da62b31526c9..2bca6db71ac7 100644 --- a/docs/source/literal_types.rst +++ b/docs/source/literal_types.rst @@ -1,7 +1,10 @@ +Literal types and Enums +======================= + .. _literal_types: Literal types -============= +------------- Literal types let you indicate that an expression is equal to some specific primitive value. For example, if we annotate a variable with type ``Literal["foo"]``, @@ -289,8 +292,8 @@ using ``isinstance()``: This feature is sometimes called "sum types" or "discriminated union types" in other programming languages. -Exhaustiveness checks -********************* +Exhaustiveness checking +*********************** You may want to check that some code covers all possible ``Literal`` or ``Enum`` cases. Example: @@ -356,6 +359,35 @@ mypy will spot the error: # expected "NoReturn" assert_never(x) +If runtime checking against unexpected values is not needed, you can +leave out the ``assert_never`` call in the above example, and mypy +will still generate an error about function ``validate`` returning +without a value: + +.. code-block:: python + + PossibleValues = Literal['one', 'two', 'three'] + + # Error: Missing return statement + def validate(x: PossibleValues) -> bool: + if x == 'one': + return True + elif x == 'two': + return False + +Exhaustiveness checking is also supported for match statements (Python 3.10 and later): + +.. code-block:: python + + def validate(x: PossibleValues) -> bool: + match x: + case 'one': + return True + case 'two': + return False + assert_never(x) + + Limitations *********** @@ -369,3 +401,131 @@ whatever type the parameter has. For example, ``Literal[3]`` is treated as a subtype of ``int`` and so will inherit all of ``int``'s methods directly. This means that ``Literal[3].__add__`` accepts the same arguments and has the same return type as ``int.__add__``. + + +Enums +----- + +Mypy has special support for :py:class:`enum.Enum` and its subclasses: +:py:class:`enum.IntEnum`, :py:class:`enum.Flag`, :py:class:`enum.IntFlag`, +and :py:class:`enum.StrEnum`. + +.. code-block:: python + + from enum import Enum + + class Direction(Enum): + up = 'up' + down = 'down' + + reveal_type(Direction.up) # Revealed type is "Literal[Direction.up]?" + reveal_type(Direction.down) # Revealed type is "Literal[Direction.down]?" + +You can use enums to annotate types as you would expect: + +.. code-block:: python + + class Movement: + def __init__(self, direction: Direction, speed: float) -> None: + self.direction = direction + self.speed = speed + + Movement(Direction.up, 5.0) # ok + Movement('up', 5.0) # E: Argument 1 to "Movemement" has incompatible type "str"; expected "Direction" + +Exhaustiveness checking +*********************** + +Similar to ``Literal`` types, ``Enum`` supports exhaustiveness checking. +Let's start with a definition: + +.. code-block:: python + + from enum import Enum + from typing import NoReturn + + def assert_never(value: NoReturn) -> NoReturn: + # This also works in runtime as well: + assert False, 'This code should never be reached, got: {0}'.format(value) + + class Direction(Enum): + up = 'up' + down = 'down' + +Now, let's use an exhaustiveness check: + +.. code-block:: python + + def choose_direction(direction: Direction) -> None: + if direction is Direction.up: + reveal_type(direction) # N: Revealed type is "Literal[Direction.up]" + print('Going up!') + return + elif direction is Direction.down: + print('Down') + return + # This line is never reached + assert_never(direction) + +If we forget to handle one of the cases, mypy will generate an error: + +.. code-block:: python + + def choose_direction(direction: Direction) -> None: + if direction == Direction.up: + print('Going up!') + return + assert_never(direction) # E: Argument 1 to "assert_never" has incompatible type "Direction"; expected "NoReturn" + +Exhaustiveness checking is also supported for match statements (Python 3.10 and later). + +Extra Enum checks +***************** + +Mypy also tries to support special features of ``Enum`` +the same way Python's runtime does: + +- Any ``Enum`` class with values is implicitly :ref:`final `. + This is what happens in CPython: + + .. code-block:: python + + >>> class AllDirection(Direction): + ... left = 'left' + ... right = 'right' + Traceback (most recent call last): + ... + TypeError: Other: cannot extend enumeration 'Some' + + Mypy also catches this error: + + .. code-block:: python + + class AllDirection(Direction): # E: Cannot inherit from final class "Some" + left = 'left' + right = 'right' + +- All ``Enum`` fields are implictly ``final`` as well. + + .. code-block:: python + + Direction.up = '^' # E: Cannot assign to final attribute "up" + +- All field names are checked to be unique. + + .. code-block:: python + + class Some(Enum): + x = 1 + x = 2 # E: Attempted to reuse member name "x" in Enum definition "Some" + +- Base classes have no conflicts and mixin types are correct. + + .. code-block:: python + + class WrongEnum(str, int, enum.Enum): + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "int" + ... + + class MixinAfterEnum(enum.Enum, Mixin): # E: No base classes are allowed after "enum.Enum" + ... diff --git a/docs/source/more_types.rst b/docs/source/more_types.rst index 82a6568afcb2..dd688cab7e17 100644 --- a/docs/source/more_types.rst +++ b/docs/source/more_types.rst @@ -581,6 +581,115 @@ with ``Union[int, slice]`` and ``Union[T, Sequence]``. to returning ``Any`` only if the input arguments also contain ``Any``. +Conditional overloads +--------------------- + +Sometimes it is useful to define overloads conditionally. +Common use cases include types that are unavailable at runtime or that +only exist in a certain Python version. All existing overload rules still apply. +For example, there must be at least two overloads. + +.. note:: + + Mypy can only infer a limited number of conditions. + Supported ones currently include :py:data:`~typing.TYPE_CHECKING`, ``MYPY``, + :ref:`version_and_platform_checks`, :option:`--always-true `, + and :option:`--always-false ` values. + +.. code-block:: python + + from typing import TYPE_CHECKING, Any, overload + + if TYPE_CHECKING: + class A: ... + class B: ... + + + if TYPE_CHECKING: + @overload + def func(var: A) -> A: ... + + @overload + def func(var: B) -> B: ... + + def func(var: Any) -> Any: + return var + + + reveal_type(func(A())) # Revealed type is "A" + +.. code-block:: python + + # flags: --python-version 3.10 + import sys + from typing import Any, overload + + class A: ... + class B: ... + class C: ... + class D: ... + + + if sys.version_info < (3, 7): + @overload + def func(var: A) -> A: ... + + elif sys.version_info >= (3, 10): + @overload + def func(var: B) -> B: ... + + else: + @overload + def func(var: C) -> C: ... + + @overload + def func(var: D) -> D: ... + + def func(var: Any) -> Any: + return var + + + reveal_type(func(B())) # Revealed type is "B" + reveal_type(func(C())) # No overload variant of "func" matches argument type "C" + # Possible overload variants: + # def func(var: B) -> B + # def func(var: D) -> D + # Revealed type is "Any" + + +.. note:: + + In the last example, mypy is executed with + :option:`--python-version 3.10 `. + Therefore, the condition ``sys.version_info >= (3, 10)`` will match and + the overload for ``B`` will be added. + The overloads for ``A`` and ``C`` are ignored! + The overload for ``D`` is not defined conditionally and thus is also added. + +When mypy cannot infer a condition to be always ``True`` or always ``False``, +an error is emitted. + +.. code-block:: python + + from typing import Any, overload + + class A: ... + class B: ... + + + def g(bool_var: bool) -> None: + if bool_var: # Condition can't be inferred, unable to merge overloads + @overload + def func(var: A) -> A: ... + + @overload + def func(var: B) -> B: ... + + def func(var: Any) -> Any: ... + + reveal_type(func(A())) # Revealed type is "Any" + + .. _advanced_self: Advanced uses of self-types @@ -765,68 +874,6 @@ value of type :py:class:`Coroutine[Any, Any, T] `, which is a :ref:`reveal_type() ` displays the inferred static type of an expression. -If you want to use coroutines in Python 3.4, which does not support -the ``async def`` syntax, you can instead use the :py:func:`@asyncio.coroutine ` -decorator to convert a generator into a coroutine. - -Note that we set the ``YieldType`` of the generator to be ``Any`` in the -following example. This is because the exact yield type is an implementation -detail of the coroutine runner (e.g. the :py:mod:`asyncio` event loop) and your -coroutine shouldn't have to know or care about what precisely that type is. - -.. code-block:: python - - from typing import Any, Generator - import asyncio - - @asyncio.coroutine - def countdown_2(tag: str, count: int) -> Generator[Any, None, str]: - while count > 0: - print('T-minus {} ({})'.format(count, tag)) - yield from asyncio.sleep(0.1) - count -= 1 - return "Blastoff!" - - loop = asyncio.get_event_loop() - loop.run_until_complete(countdown_2("USS Enterprise", 5)) - loop.close() - -As before, the result of calling a generator decorated with :py:func:`@asyncio.coroutine ` -will be a value of type :py:class:`Awaitable[T] `. - -.. note:: - - At runtime, you are allowed to add the :py:func:`@asyncio.coroutine ` decorator to - both functions and generators. This is useful when you want to mark a - work-in-progress function as a coroutine, but have not yet added ``yield`` or - ``yield from`` statements: - - .. code-block:: python - - import asyncio - - @asyncio.coroutine - def serialize(obj: object) -> str: - # todo: add yield/yield from to turn this into a generator - return "placeholder" - - However, mypy currently does not support converting functions into - coroutines. Support for this feature will be added in a future version, but - for now, you can manually force the function to be a generator by doing - something like this: - - .. code-block:: python - - from typing import Generator - import asyncio - - @asyncio.coroutine - def serialize(obj: object) -> Generator[None, None, str]: - # todo: add yield/yield from to turn this into a generator - if False: - yield - return "placeholder" - You may also choose to create a subclass of :py:class:`~typing.Awaitable` instead: .. code-block:: python @@ -886,11 +933,29 @@ To create an iterable coroutine, subclass :py:class:`~typing.AsyncIterator`: loop.run_until_complete(countdown_4("Serenity", 5)) loop.close() -For a more concrete example, the mypy repo has a toy webcrawler that -demonstrates how to work with coroutines. One version -`uses async/await `_ -and one -`uses yield from `_. +If you use coroutines in legacy code that was originally written for +Python 3.4, which did not support the ``async def`` syntax, you would +instead use the :py:func:`@asyncio.coroutine ` +decorator to convert a generator into a coroutine, and use a +generator type as the return type: + +.. code-block:: python + + from typing import Any, Generator + import asyncio + + @asyncio.coroutine + def countdown_2(tag: str, count: int) -> Generator[Any, None, str]: + while count > 0: + print('T-minus {} ({})'.format(count, tag)) + yield from asyncio.sleep(0.1) + count -= 1 + return "Blastoff!" + + loop = asyncio.get_event_loop() + loop.run_until_complete(countdown_2("USS Enterprise", 5)) + loop.close() + .. _typeddict: diff --git a/misc/build_wheel.py b/misc/build_wheel.py index 188660e2eefc..9d34242ead41 100644 --- a/misc/build_wheel.py +++ b/misc/build_wheel.py @@ -44,8 +44,8 @@ def create_environ(python_version: str) -> Dict[str, str]: # When cross-compiling on Intel, it is not possible to test arm64 and # the arm64 part of a universal2 wheel. Warnings will be silenced with # following CIBW_TEST_SKIP - env['CIBW_ARCHS_MACOS'] = "x86_64 arm64" - env['CIBW_TEST_SKIP'] = "*-macosx_arm64" + env['CIBW_ARCHS_MACOS'] = "x86_64 arm64 universal2" + env['CIBW_TEST_SKIP'] = "*-macosx_arm64 *_universal2:arm64" env['CIBW_BUILD_VERBOSITY'] = '1' diff --git a/misc/proper_plugin.py b/misc/proper_plugin.py index 249ad983266b..7c8e16e3e0aa 100644 --- a/misc/proper_plugin.py +++ b/misc/proper_plugin.py @@ -1,3 +1,4 @@ +from mypy import message_registry from mypy.plugin import Plugin, FunctionContext from mypy.types import ( Type, Instance, CallableType, UnionType, get_proper_type, ProperType, @@ -43,8 +44,7 @@ def isinstance_proper_hook(ctx: FunctionContext) -> Type: isinstance(get_proper_type(arg), AnyType) and is_dangerous_target(right)): if is_special_target(right): return ctx.default_return_type - ctx.api.fail('Never apply isinstance() to unexpanded types;' - ' use mypy.types.get_proper_type() first', ctx.context) + ctx.api.fail(message_registry.ISINSTANCE_ON_UNEXPANDED_TYPE, ctx.context) ctx.api.note('If you pass on the original type' # type: ignore[attr-defined] ' after the check, always use its unexpanded version', ctx.context) return ctx.default_return_type @@ -113,7 +113,7 @@ def proper_type_hook(ctx: FunctionContext) -> Type: # Minimize amount of spurious errors from overload machinery. # TODO: call the hook on the overload as a whole? if isinstance(arg_type, (UnionType, Instance)): - ctx.api.fail('Redundant call to get_proper_type()', ctx.context) + ctx.api.fail(message_registry.REDUNDANT_GET_PROPER_TYPE, ctx.context) return ctx.default_return_type @@ -126,7 +126,7 @@ def proper_types_hook(ctx: FunctionContext) -> Type: item_type = UnionType.make_union([NoneTyp(), proper_type]) ok_type = ctx.api.named_generic_type('typing.Iterable', [item_type]) if is_proper_subtype(arg_type, ok_type): - ctx.api.fail('Redundant call to get_proper_types()', ctx.context) + ctx.api.fail(message_registry.REDUNDANT_GET_PROPER_TYPE, ctx.context) return ctx.default_return_type diff --git a/mypy/build.py b/mypy/build.py index f3df5f18f54d..4b5f7e1cf5dc 100644 --- a/mypy/build.py +++ b/mypy/build.py @@ -56,7 +56,7 @@ from mypy.fscache import FileSystemCache from mypy.metastore import MetadataStore, FilesystemMetadataStore, SqliteMetadataStore from mypy.typestate import TypeState, reset_global_state -from mypy.renaming import VariableRenameVisitor +from mypy.renaming import VariableRenameVisitor, LimitedVariableRenameVisitor from mypy.config_parser import parse_mypy_comments from mypy.freetree import free_tree from mypy.stubinfo import legacy_bundled_packages, is_legacy_bundled_package @@ -511,7 +511,7 @@ def find_config_file_line_number(path: str, section: str, setting_name: str) -> in_desired_section = False try: results = [] - with open(path) as f: + with open(path, encoding="UTF-8") as f: for i, line in enumerate(f): line = line.strip() if line.startswith('[') and line.endswith(']'): @@ -2119,9 +2119,12 @@ def semantic_analysis_pass1(self) -> None: analyzer.visit_file(self.tree, self.xpath, self.id, options) # TODO: Do this while constructing the AST? self.tree.names = SymbolTable() - if options.allow_redefinition: - # Perform renaming across the AST to allow variable redefinitions - self.tree.accept(VariableRenameVisitor()) + if not self.tree.is_stub: + # Always perform some low-key variable renaming + self.tree.accept(LimitedVariableRenameVisitor()) + if options.allow_redefinition: + # Perform more renaming across the AST to allow variable redefinitions + self.tree.accept(VariableRenameVisitor()) def add_dependency(self, dep: str) -> None: if dep not in self.dependencies_set: @@ -2186,8 +2189,10 @@ def type_checker(self) -> TypeChecker: if not self._type_checker: assert self.tree is not None, "Internal error: must be called on parsed file only" manager = self.manager - self._type_checker = TypeChecker(manager.errors, manager.modules, self.options, - self.tree, self.xpath, manager.plugin) + self._type_checker = TypeChecker( + manager.errors, manager.modules, self.options, + self.tree, self.xpath, manager.plugin, + ) return self._type_checker def type_map(self) -> Dict[Expression, Type]: @@ -2369,6 +2374,13 @@ def generate_unused_ignore_notes(self) -> None: self.verify_dependencies(suppressed_only=True) self.manager.errors.generate_unused_ignore_errors(self.xpath) + def generate_ignore_without_code_notes(self) -> None: + if self.manager.errors.is_error_code_enabled(codes.IGNORE_WITHOUT_CODE): + self.manager.errors.generate_ignore_without_code_errors( + self.xpath, + self.options.warn_unused_ignores, + ) + # Module import and diagnostic glue @@ -2830,8 +2842,15 @@ def load_graph(sources: List[BuildSource], manager: BuildManager, ) manager.errors.report( -1, -1, - "Are you missing an __init__.py? Alternatively, consider using --exclude to " - "avoid checking one of them.", + "See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules " # noqa: E501 + "for more info", + severity='note', + ) + manager.errors.report( + -1, -1, + "Common resolutions include: a) using `--exclude` to avoid checking one of them, " + "b) adding `__init__.py` somewhere, c) using `--explicit-package-bases` or " + "adjusting MYPYPATH", severity='note' ) @@ -2905,6 +2924,12 @@ def load_graph(sources: List[BuildSource], manager: BuildManager, "for more info", severity='note', ) + manager.errors.report( + -1, 0, + "Common resolutions include: a) adding `__init__.py` somewhere, " + "b) using `--explicit-package-bases` or adjusting MYPYPATH", + severity='note', + ) manager.errors.raise_error() seen_files[newst_path] = newst @@ -2934,12 +2959,16 @@ def process_graph(graph: Graph, manager: BuildManager) -> None: # Order the SCC's nodes using a heuristic. # Note that ascc is a set, and scc is a list. scc = order_ascc(graph, ascc) - # If builtins is in the list, move it last. (This is a bit of - # a hack, but it's necessary because the builtins module is - # part of a small cycle involving at least {builtins, abc, - # typing}. Of these, builtins must be processed last or else - # some builtin objects will be incompletely processed.) + # Make the order of the SCC that includes 'builtins' and 'typing', + # among other things, predictable. Various things may break if + # the order changes. if 'builtins' in ascc: + scc = sorted(scc, reverse=True) + # If builtins is in the list, move it last. (This is a bit of + # a hack, but it's necessary because the builtins module is + # part of a small cycle involving at least {builtins, abc, + # typing}. Of these, builtins must be processed last or else + # some builtin objects will be incompletely processed.) scc.remove('builtins') scc.append('builtins') if manager.options.verbosity >= 2: @@ -3155,6 +3184,7 @@ def process_stale_scc(graph: Graph, scc: List[str], manager: BuildManager) -> No graph[id].finish_passes() for id in stale: graph[id].generate_unused_ignore_notes() + graph[id].generate_ignore_without_code_notes() if any(manager.errors.is_errors_for_file(graph[id].xpath) for id in stale): for id in stale: graph[id].transitive_error = True diff --git a/mypy/checker.py b/mypy/checker.py index 2f99b9b4fece..237cefaf7aaf 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -600,7 +600,8 @@ def check_overlapping_overloads(self, defn: OverloadedFuncDef) -> None: self.msg.overloaded_signatures_arg_specific(i + 1, defn.impl) # Is the overload alternative's return type a subtype of the implementation's? - if not is_subtype_no_promote(sig1.ret_type, impl.ret_type): + if not (is_subtype_no_promote(sig1.ret_type, impl.ret_type) or + is_subtype_no_promote(impl.ret_type, sig1.ret_type)): self.msg.overloaded_signatures_ret_specific(i + 1, defn.impl) # Here's the scoop about generators and coroutines. @@ -1439,12 +1440,7 @@ def check_setattr_method(self, typ: Type, context: Context) -> None: self.msg.invalid_signature_for_special_method(typ, context, '__setattr__') def check_match_args(self, var: Var, typ: Type, context: Context) -> None: - """Check that __match_args__ is final and contains literal strings""" - - if not var.is_final: - self.note("__match_args__ must be final for checking of match statements to work", - context, code=codes.LITERAL_REQ) - + """Check that __match_args__ contains literal strings""" typ = get_proper_type(typ) if not isinstance(typ, TupleType) or \ not all([is_string_literal(item) for item in typ.items]): @@ -1834,9 +1830,7 @@ def visit_class_def(self, defn: ClassDef) -> None: if typ.is_protocol and typ.defn.type_vars: self.check_protocol_variance(defn) if not defn.has_incompatible_baseclass and defn.info.is_enum: - for base in defn.info.mro[1:-1]: # we don't need self and `object` - if base.is_enum and base.fullname not in ENUM_BASES: - self.check_final_enum(defn, base) + self.check_enum(defn) def check_final_deletable(self, typ: TypeInfo) -> None: # These checks are only for mypyc. Only perform some checks that are easier @@ -1894,15 +1888,28 @@ def check_init_subclass(self, defn: ClassDef) -> None: # all other bases have already been checked. break + def check_enum(self, defn: ClassDef) -> None: + assert defn.info.is_enum + if defn.info.fullname not in ENUM_BASES: + for sym in defn.info.names.values(): + if (isinstance(sym.node, Var) and sym.node.has_explicit_value and + sym.node.name == '__members__'): + # `__members__` will always be overwritten by `Enum` and is considered + # read-only so we disallow assigning a value to it + self.fail( + message_registry.ENUM_MEMBERS_ATTR_WILL_BE_OVERRIDEN, sym.node + ) + for base in defn.info.mro[1:-1]: # we don't need self and `object` + if base.is_enum and base.fullname not in ENUM_BASES: + self.check_final_enum(defn, base) + + self.check_enum_bases(defn) + self.check_enum_new(defn) + def check_final_enum(self, defn: ClassDef, base: TypeInfo) -> None: for sym in base.names.values(): if self.is_final_enum_value(sym): - self.fail( - 'Cannot extend enum with existing members: "{}"'.format( - base.name, - ), - defn, - ) + self.fail(message_registry.ENUM_EXTEND_EXISTING_MEMBERS.format(base.name), defn) break def is_final_enum_value(self, sym: SymbolTableNode) -> bool: @@ -1931,6 +1938,49 @@ def is_final_enum_value(self, sym: SymbolTableNode) -> bool: return True return False + def check_enum_bases(self, defn: ClassDef) -> None: + enum_base: Optional[Instance] = None + for base in defn.info.bases: + if enum_base is None and base.type.is_enum: + enum_base = base + continue + elif enum_base is not None: + self.fail( + message_registry.NO_BASE_CLASS_AFTER_ENUM.format(enum_base), + defn, + ) + break + + def check_enum_new(self, defn: ClassDef) -> None: + def has_new_method(info: TypeInfo) -> bool: + new_method = info.get('__new__') + return bool( + new_method + and new_method.node + and new_method.node.fullname != 'builtins.object.__new__' + ) + + has_new = False + for base in defn.info.bases: + candidate = False + + if base.type.is_enum: + # If we have an `Enum`, then we need to check all its bases. + candidate = any( + not b.is_enum and has_new_method(b) + for b in base.type.mro[1:-1] + ) + else: + candidate = has_new_method(base.type) + + if candidate and has_new: + self.fail( + message_registry.ENUM_MULTIPLE_DATA_MIXINS.format(base), + defn, + ) + elif candidate: + has_new = True + def check_protocol_variance(self, defn: ClassDef) -> None: """Check that protocol definition is compatible with declared variances of type variables. @@ -2057,8 +2107,9 @@ class C(B, A[int]): ... # this is unsafe because... self.msg.cant_override_final(name, base2.name, ctx) if is_final_node(first.node): self.check_if_final_var_override_writable(name, second.node, ctx) - # __slots__ and __deletable__ are special and the type can vary across class hierarchy. - if name in ('__slots__', '__deletable__'): + # Some attributes like __slots__ and __deletable__ are special, and the type can + # vary across class hierarchy. + if isinstance(second.node, Var) and second.node.allow_incompatible_override: ok = True if not ok: self.msg.base_class_definitions_incompatible(name, base1, base2, @@ -2230,11 +2281,16 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type # Defer PartialType's super type checking. if (isinstance(lvalue, RefExpr) and - not (isinstance(lvalue_type, PartialType) and lvalue_type.type is None)): + not (isinstance(lvalue_type, PartialType) and + lvalue_type.type is None) and + not (isinstance(lvalue, NameExpr) and lvalue.name == '__match_args__')): if self.check_compatibility_all_supers(lvalue, lvalue_type, rvalue): # We hit an error on this line; don't check for any others return + if isinstance(lvalue, MemberExpr) and lvalue.name == '__match_args__': + self.fail(message_registry.CANNOT_MODIFY_MATCH_ARGS, lvalue) + if lvalue_type: if isinstance(lvalue_type, PartialType) and lvalue_type.type is None: # Try to infer a proper type for a variable with a partial None type. @@ -2331,7 +2387,8 @@ def check_assignment(self, lvalue: Lvalue, rvalue: Expression, infer_lvalue_type if inferred: rvalue_type = self.expr_checker.accept(rvalue) - if not inferred.is_final: + if not (inferred.is_final or (isinstance(lvalue, NameExpr) and + lvalue.name == '__match_args__')): rvalue_type = remove_instance_last_known_values(rvalue_type) self.infer_variable_type(inferred, lvalue, rvalue_type, rvalue) self.check_assignment_to_slots(lvalue) @@ -2414,16 +2471,12 @@ def check_compatibility_all_supers(self, lvalue: RefExpr, lvalue_type: Optional[ last_immediate_base = direct_bases[-1] if direct_bases else None for base in lvalue_node.info.mro[1:]: - # Only check __slots__ against the 'object' - # If a base class defines a Tuple of 3 elements, a child of - # this class should not be allowed to define it as a Tuple of - # anything other than 3 elements. The exception to this rule - # is __slots__, where it is allowed for any child class to - # redefine it. - if lvalue_node.name == "__slots__" and base.fullname != "builtins.object": - continue - # We don't care about the type of "__deletable__". - if lvalue_node.name == "__deletable__": + # The type of "__slots__" and some other attributes usually doesn't need to + # be compatible with a base class. We'll still check the type of "__slots__" + # against "object" as an exception. + if (isinstance(lvalue_node, Var) and lvalue_node.allow_incompatible_override and + not (lvalue_node.name == "__slots__" and + base.fullname == "builtins.object")): continue if is_private(lvalue_node.name): @@ -3548,7 +3601,7 @@ def visit_raise_stmt(self, s: RaiseStmt) -> None: if s.expr: self.type_check_raise(s.expr, s) if s.from_expr: - self.type_check_raise(s.from_expr, s, True) + self.type_check_raise(s.from_expr, s, optional=True) self.binder.unreachable() def type_check_raise(self, e: Expression, s: RaiseStmt, @@ -3557,24 +3610,94 @@ def type_check_raise(self, e: Expression, s: RaiseStmt, if isinstance(typ, DeletedType): self.msg.deleted_as_rvalue(typ, e) return + + if self.options.python_version[0] == 2: + # Since `raise` has very different rule on python2, we use a different helper. + # https://github.com/python/mypy/pull/11289 + self._type_check_raise_python2(e, s, typ) + return + + # Python3 case: exc_type = self.named_type('builtins.BaseException') - expected_type = UnionType([exc_type, TypeType(exc_type)]) + expected_type_items = [exc_type, TypeType(exc_type)] if optional: - expected_type.items.append(NoneType()) - if self.options.python_version[0] == 2: - # allow `raise type, value, traceback` - # https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement - # TODO: Also check tuple item types. - any_type = AnyType(TypeOfAny.implementation_artifact) - tuple_type = self.named_type('builtins.tuple') - expected_type.items.append(TupleType([any_type, any_type], tuple_type)) - expected_type.items.append(TupleType([any_type, any_type, any_type], tuple_type)) - self.check_subtype(typ, expected_type, s, message_registry.INVALID_EXCEPTION) + # This is used for `x` part in a case like `raise e from x`, + # where we allow `raise e from None`. + expected_type_items.append(NoneType()) + + self.check_subtype( + typ, UnionType.make_union(expected_type_items), s, + message_registry.INVALID_EXCEPTION, + ) if isinstance(typ, FunctionLike): # https://github.com/python/mypy/issues/11089 self.expr_checker.check_call(typ, [], [], e) + def _type_check_raise_python2(self, e: Expression, s: RaiseStmt, typ: ProperType) -> None: + # Python2 has two possible major cases: + # 1. `raise expr`, where `expr` is some expression, it can be: + # - Exception typ + # - Exception instance + # - Old style class (not supported) + # - Tuple, where 0th item is exception type or instance + # 2. `raise exc, msg, traceback`, where: + # - `exc` is exception type (not instance!) + # - `traceback` is `types.TracebackType | None` + # Important note: `raise exc, msg` is not the same as `raise (exc, msg)` + # We call `raise exc, msg, traceback` - legacy mode. + exc_type = self.named_type('builtins.BaseException') + exc_inst_or_type = UnionType([exc_type, TypeType(exc_type)]) + + if (not s.legacy_mode and (isinstance(typ, TupleType) and typ.items + or (isinstance(typ, Instance) and typ.args + and typ.type.fullname == 'builtins.tuple'))): + # `raise (exc, ...)` case: + item = typ.items[0] if isinstance(typ, TupleType) else typ.args[0] + self.check_subtype( + item, exc_inst_or_type, s, + 'When raising a tuple, first element must by derived from BaseException', + ) + return + elif s.legacy_mode: + # `raise Exception, msg` case + # `raise Exception, msg, traceback` case + # https://docs.python.org/2/reference/simple_stmts.html#the-raise-statement + assert isinstance(typ, TupleType) # Is set in fastparse2.py + if (len(typ.items) >= 2 + and isinstance(get_proper_type(typ.items[1]), NoneType)): + expected_type: Type = exc_inst_or_type + else: + expected_type = TypeType(exc_type) + self.check_subtype( + typ.items[0], expected_type, s, + 'Argument 1 must be "{}" subtype'.format(expected_type), + ) + + # Typecheck `traceback` part: + if len(typ.items) == 3: + # Now, we typecheck `traceback` argument if it is present. + # We do this after the main check for better error message + # and better ordering: first about `BaseException` subtype, + # then about `traceback` type. + traceback_type = UnionType.make_union([ + self.named_type('types.TracebackType'), + NoneType(), + ]) + self.check_subtype( + typ.items[2], traceback_type, s, + 'Argument 3 must be "{}" subtype'.format(traceback_type), + ) + else: + expected_type_items = [ + # `raise Exception` and `raise Exception()` cases: + exc_type, TypeType(exc_type), + ] + self.check_subtype( + typ, UnionType.make_union(expected_type_items), + s, message_registry.INVALID_EXCEPTION, + ) + def visit_try_stmt(self, s: TryStmt) -> None: """Type check a try statement.""" # Our enclosing frame will get the result if the try/except falls through. @@ -3973,36 +4096,57 @@ def visit_match_stmt(self, s: MatchStmt) -> None: if isinstance(subject_type, DeletedType): self.msg.deleted_as_rvalue(subject_type, s) + # We infer types of patterns twice. The first pass is used + # to infer the types of capture variables. The type of a + # capture variable may depend on multiple patterns (it + # will be a union of all capture types). This pass ignores + # guard expressions. pattern_types = [self.pattern_checker.accept(p, subject_type) for p in s.patterns] - type_maps: List[TypeMap] = [t.captures for t in pattern_types] - self.infer_variable_types_from_type_maps(type_maps) + inferred_types = self.infer_variable_types_from_type_maps(type_maps) - for pattern_type, g, b in zip(pattern_types, s.guards, s.bodies): + # 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) + pattern_type = self.pattern_checker.accept(p, current_subject_type) with self.binder.frame_context(can_skip=True, fall_through=2): if b.is_unreachable or isinstance(get_proper_type(pattern_type.type), UninhabitedType): self.push_type_map(None) + else_map: TypeMap = {} else: - self.binder.put(s.subject, pattern_type.type) + pattern_map, else_map = conditional_types_to_typemaps( + s.subject, + pattern_type.type, + pattern_type.rest_type + ) + self.remove_capture_conflicts(pattern_type.captures, + inferred_types) + self.push_type_map(pattern_map) self.push_type_map(pattern_type.captures) if g is not None: - gt = get_proper_type(self.expr_checker.accept(g)) + with self.binder.frame_context(can_skip=True, fall_through=3): + gt = get_proper_type(self.expr_checker.accept(g)) - if isinstance(gt, DeletedType): - self.msg.deleted_as_rvalue(gt, s) + if isinstance(gt, DeletedType): + self.msg.deleted_as_rvalue(gt, s) - if_map, _ = self.find_isinstance_check(g) + guard_map, guard_else_map = self.find_isinstance_check(g) + else_map = or_conditional_maps(else_map, guard_else_map) - self.push_type_map(if_map) - self.accept(b) + self.push_type_map(guard_map) + self.accept(b) + else: + self.accept(b) + self.push_type_map(else_map) # This is needed due to a quirk in frame_context. Without it types will stay narrowed # after the match. with self.binder.frame_context(can_skip=False, fall_through=2): pass - def infer_variable_types_from_type_maps(self, type_maps: List[TypeMap]) -> None: + 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: if tm is not None: @@ -4012,28 +4156,38 @@ def infer_variable_types_from_type_maps(self, type_maps: List[TypeMap]) -> None: assert isinstance(node, Var) all_captures[node].append((expr, typ)) + inferred_types: Dict[Var, Type] = {} for var, captures in all_captures.items(): - conflict = False + already_exists = False types: List[Type] = [] for expr, typ in captures: types.append(typ) - previous_type, _, inferred = self.check_lvalue(expr) + previous_type, _, _ = self.check_lvalue(expr) if previous_type is not None: - conflict = True - self.check_subtype(typ, previous_type, expr, - msg=message_registry.INCOMPATIBLE_TYPES_IN_CAPTURE, - subtype_label="pattern captures type", - supertype_label="variable has type") - for type_map in type_maps: - if type_map is not None and expr in type_map: - del type_map[expr] - - if not conflict: + already_exists = True + if self.check_subtype(typ, previous_type, expr, + msg=message_registry.INCOMPATIBLE_TYPES_IN_CAPTURE, + subtype_label="pattern captures type", + supertype_label="variable has type"): + inferred_types[var] = previous_type + + if not already_exists: new_type = UnionType.make_union(types) # Infer the union type at the first occurrence first_occurrence, _ = captures[0] + inferred_types[var] = new_type self.infer_variable_type(var, first_occurrence, new_type, first_occurrence) + return inferred_types + + def remove_capture_conflicts(self, type_map: TypeMap, inferred_types: Dict[Var, Type]) -> None: + if type_map: + for expr, typ in list(type_map.items()): + if isinstance(expr, NameExpr): + node = expr.node + assert isinstance(node, Var) + if node not in inferred_types or not is_subtype(typ, inferred_types[node]): + del type_map[expr] def make_fake_typeinfo(self, curr_module_fullname: str, @@ -5342,13 +5496,9 @@ def temp_node(self, t: Type, context: Optional[Context] = None) -> TempNode: """Create a temporary node with the given, fixed type.""" return TempNode(t, context=context) - def fail(self, msg: Union[str, ErrorMessage], context: Context, *, - code: Optional[ErrorCode] = None) -> None: + def fail(self, msg: ErrorMessage, context: Context) -> None: """Produce an error message.""" - if isinstance(msg, ErrorMessage): - self.msg.fail(msg.value, context, code=msg.code) - return - self.msg.fail(msg, context, code=code) + self.msg.fail(msg, context) def note(self, msg: str, @@ -5521,6 +5671,14 @@ def conditional_types(current_type: Type, None means no new information can be inferred. If default is set it is returned instead.""" if proposed_type_ranges: + if len(proposed_type_ranges) == 1: + target = proposed_type_ranges[0].item + target = get_proper_type(target) + if isinstance(target, LiteralType) and (target.is_enum_literal() + or isinstance(target.value, bool)): + enum_name = target.fallback.type.fullname + current_type = try_expanding_sum_type_to_union(current_type, + enum_name) proposed_items = [type_range.item for type_range in proposed_type_ranges] proposed_type = make_simplified_union(proposed_items) if isinstance(proposed_type, AnyType): diff --git a/mypy/checkexpr.py b/mypy/checkexpr.py index 9bf3ec3a4456..c8208dbb9611 100644 --- a/mypy/checkexpr.py +++ b/mypy/checkexpr.py @@ -4,7 +4,7 @@ from contextlib import contextmanager import itertools from typing import ( - Any, cast, Dict, Set, List, Tuple, Callable, Union, Optional, Sequence, Iterator + cast, Dict, Set, List, Tuple, Callable, Union, Optional, Sequence, Iterator ) from typing_extensions import ClassVar, Final, overload, TypeAlias as _TypeAlias @@ -1607,8 +1607,7 @@ def check_overload_call(self, # Record if we succeeded. Next we need to see if maybe normal procedure # gives a narrower type. if unioned_return: - # TODO: fix signature of zip() in typeshed. - returns, inferred_types = cast(Any, zip)(*unioned_return) + returns, inferred_types = zip(*unioned_return) # Note that we use `combine_function_signatures` instead of just returning # a union of inferred callables because for example a call # Union[int -> int, str -> str](Union[int, str]) is invalid and @@ -2417,8 +2416,11 @@ def dangerous_comparison(self, left: Type, right: Type, def get_operator_method(self, op: str) -> str: if op == '/' and self.chk.options.python_version[0] == 2: - # TODO also check for "from __future__ import division" - return '__div__' + return ( + '__truediv__' + if self.chk.tree.is_future_flag_set('division') + else '__div__' + ) else: return operators.op_methods[op] @@ -4094,7 +4096,7 @@ def visit_await_expr(self, e: AwaitExpr) -> Type: return self.check_awaitable_expr(actual_type, e, message_registry.INCOMPATIBLE_TYPES_IN_AWAIT) - def check_awaitable_expr(self, t: Type, ctx: Context, msg: Union[str, ErrorMessage]) -> Type: + def check_awaitable_expr(self, t: Type, ctx: Context, msg: ErrorMessage) -> Type: """Check the argument to `await` and extract the type of value. Also used by `async for` and `async with`. diff --git a/mypy/checkmember.py b/mypy/checkmember.py index 29601840647f..e7af3978867f 100644 --- a/mypy/checkmember.py +++ b/mypy/checkmember.py @@ -6,7 +6,8 @@ from mypy.types import ( Type, Instance, AnyType, TupleType, TypedDictType, CallableType, FunctionLike, TypeVarLikeType, Overloaded, TypeVarType, UnionType, PartialType, TypeOfAny, LiteralType, - DeletedType, NoneType, TypeType, has_type_vars, get_proper_type, ProperType, ParamSpecType + DeletedType, NoneType, TypeType, has_type_vars, get_proper_type, ProperType, ParamSpecType, + ENUM_REMOVED_PROPS ) from mypy.nodes import ( TypeInfo, FuncBase, Var, FuncDef, SymbolNode, SymbolTable, Context, @@ -714,7 +715,7 @@ def analyze_class_attribute_access(itype: Instance, if is_method: mx.msg.cant_assign_to_method(mx.context) if isinstance(node.node, TypeInfo): - mx.msg.fail(message_registry.CANNOT_ASSIGN_TO_TYPE.value, mx.context) + mx.msg.fail(message_registry.CANNOT_ASSIGN_TO_TYPE, mx.context) # If a final attribute was declared on `self` in `__init__`, then it # can't be accessed on the class object. @@ -831,8 +832,8 @@ def analyze_enum_class_attribute_access(itype: Instance, name: str, mx: MemberContext, ) -> Optional[Type]: - # Skip "_order_" and "__order__", since Enum will remove it - if name in ("_order_", "__order__"): + # Skip these since Enum will remove it + if name in ENUM_REMOVED_PROPS: return mx.msg.has_no_attr( mx.original_type, itype, name, mx.context, mx.module_symbol_table ) diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 2c40e856be88..a20dfb714025 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -1,4 +1,5 @@ """Pattern checker. This file is conceptually part of TypeChecker.""" + from collections import defaultdict from typing import List, Optional, Tuple, Dict, NamedTuple, Set, Union from typing_extensions import Final @@ -19,7 +20,8 @@ ) from mypy.plugin import Plugin from mypy.subtypes import is_subtype -from mypy.typeops import try_getting_str_literals_from_type, make_simplified_union +from mypy.typeops import try_getting_str_literals_from_type, make_simplified_union, \ + coerce_to_literal from mypy.types import ( ProperType, AnyType, TypeOfAny, Instance, Type, UninhabitedType, get_proper_type, TypedDictType, TupleType, NoneType, UnionType @@ -55,7 +57,7 @@ 'PatternType', [ ('type', Type), # The type the match subject can be narrowed to - ('rest_type', Type), # For exhaustiveness checking. Not used yet + ('rest_type', Type), # The remaining type if the pattern didn't match ('captures', Dict[Expression, Type]), # The variables captured by the pattern ]) @@ -177,6 +179,7 @@ def visit_or_pattern(self, o: OrPattern) -> PatternType: def visit_value_pattern(self, o: ValuePattern) -> PatternType: current_type = self.type_context[-1] 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)], @@ -259,6 +262,9 @@ def visit_sequence_pattern(self, o: SequencePattern) -> PatternType: new_inner_types = self.expand_starred_pattern_types(contracted_new_inner_types, star_position, len(inner_types)) + rest_inner_types = self.expand_starred_pattern_types(contracted_rest_inner_types, + star_position, + len(inner_types)) # # Calculate new type @@ -287,15 +293,20 @@ def visit_sequence_pattern(self, o: SequencePattern) -> PatternType: if all(is_uninhabited(typ) for typ in inner_rest_types): # All subpatterns always match, so we can apply negative narrowing - new_type, rest_type = self.chk.conditional_types_with_intersection( - current_type, [get_type_range(new_type)], o, default=current_type - ) + rest_type = TupleType(rest_inner_types, current_type.partial_fallback) else: new_inner_type = UninhabitedType() for typ in new_inner_types: new_inner_type = join_types(new_inner_type, typ) new_type = self.construct_sequence_child(current_type, new_inner_type) - if not is_subtype(new_type, current_type): + if is_subtype(new_type, current_type): + new_type, _ = self.chk.conditional_types_with_intersection( + current_type, + [get_type_range(new_type)], + o, + default=current_type + ) + else: new_type = current_type return PatternType(new_type, rest_type, captures) @@ -344,8 +355,7 @@ def expand_starred_pattern_types(self, star_pos: Optional[int], num_types: int ) -> List[Type]: - """ - Undoes the contraction done by contract_starred_pattern_types. + """Undoes the contraction done by contract_starred_pattern_types. For example if the sequence pattern is [a, *b, c] and types [bool, int, str] are extended to lenght 4 the result is [bool, int, int, str]. @@ -453,7 +463,8 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType: # Check class type # type_info = o.class_ref.node - assert type_info is not None + if type_info is None: + return PatternType(AnyType(TypeOfAny.from_error), AnyType(TypeOfAny.from_error), {}) if isinstance(type_info, TypeAlias) and not type_info.no_args: self.msg.fail(message_registry.CLASS_PATTERN_GENERIC_TYPE_ALIAS, o) return self.early_non_match() @@ -567,7 +578,7 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType: if local_errors.is_errors() or key_type is None: key_type = AnyType(TypeOfAny.from_error) self.msg.fail(message_registry.CLASS_PATTERN_UNKNOWN_KEYWORD.format(typ, keyword), - value) + pattern) inner_type, inner_rest_type, inner_captures = self.accept(pattern, key_type) if is_uninhabited(inner_type): @@ -639,6 +650,13 @@ def construct_sequence_child(self, outer_type: Type, inner_type: Type) -> Type: For example: construct_sequence_child(List[int], str) = List[str] """ + proper_type = get_proper_type(outer_type) + if isinstance(proper_type, UnionType): + types = [ + self.construct_sequence_child(item, inner_type) for item in proper_type.items + if self.can_match_sequence(get_proper_type(item)) + ] + return make_simplified_union(types) sequence = self.chk.named_generic_type("typing.Sequence", [inner_type]) if is_subtype(outer_type, self.chk.named_type("typing.Sequence")): proper_type = get_proper_type(outer_type) @@ -676,6 +694,11 @@ def get_var(expr: Expression) -> Var: def get_type_range(typ: Type) -> 'mypy.checker.TypeRange': + typ = get_proper_type(typ) + if (isinstance(typ, Instance) + and typ.last_known_value + and isinstance(typ.last_known_value.value, bool)): + typ = typ.last_known_value return mypy.checker.TypeRange(typ, is_upper_bound=False) diff --git a/mypy/checkstrformat.py b/mypy/checkstrformat.py index dcb711150870..027970484f07 100644 --- a/mypy/checkstrformat.py +++ b/mypy/checkstrformat.py @@ -177,13 +177,11 @@ def parse_format_value(format_value: str, ctx: Context, msg: MessageBuilder, custom_match, start_pos=start_pos, non_standard_format_spec=True) else: - msg.fail('Invalid conversion specifier in format string', - ctx, code=codes.STRING_FORMATTING) + msg.fail(message_registry.FORMAT_STR_INVALID_SPECIFIER, ctx) return None if conv_spec.key and ('{' in conv_spec.key or '}' in conv_spec.key): - msg.fail('Conversion value must not contain { or }', - ctx, code=codes.STRING_FORMATTING) + msg.fail(message_registry.FORMAT_STR_BRACES_IN_SPECIFIER, ctx) return None result.append(conv_spec) @@ -191,8 +189,7 @@ def parse_format_value(format_value: str, ctx: Context, msg: MessageBuilder, if (conv_spec.format_spec and conv_spec.non_standard_format_spec and ('{' in conv_spec.format_spec or '}' in conv_spec.format_spec)): if nested: - msg.fail('Formatting nesting must be at most two levels deep', - ctx, code=codes.STRING_FORMATTING) + msg.fail(message_registry.FORMAT_STR_NESTING_ATMOST_TWO_LEVELS, ctx) return None sub_conv_specs = parse_format_value(conv_spec.format_spec, ctx, msg, nested=True) @@ -230,8 +227,7 @@ def find_non_escaped_targets(format_value: str, ctx: Context, if pos < len(format_value) - 1 and format_value[pos + 1] == '}': pos += 1 else: - msg.fail('Invalid conversion specifier in format string:' - ' unexpected }', ctx, code=codes.STRING_FORMATTING) + msg.fail(message_registry.FORMAT_STR_UNEXPECTED_RBRACE, ctx) return None else: # Adjust nesting level, then either continue adding chars or move on. @@ -246,8 +242,7 @@ def find_non_escaped_targets(format_value: str, ctx: Context, next_spec = '' pos += 1 if nesting: - msg.fail('Invalid conversion specifier in format string:' - ' unmatched {', ctx, code=codes.STRING_FORMATTING) + msg.fail(message_registry.FORMAT_STR_UNMATCHED_LBRACE, ctx) return None return result @@ -326,9 +321,8 @@ def check_specs_in_format_call(self, call: CallExpr, if (not custom_special_method(actual_type, '__format__', check_all=True) or spec.conversion): # TODO: add support for some custom specs like datetime? - self.msg.fail('Unrecognized format' - ' specification "{}"'.format(spec.format_spec[1:]), - call, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.UNRECOGNIZED_FORMAT_SPEC.format( + spec.format_spec[1:]), call) continue # Adjust expected and actual types. if not spec.conv_type: @@ -344,9 +338,8 @@ def check_specs_in_format_call(self, call: CallExpr, if spec.conversion is not None: # If the explicit conversion is given, then explicit conversion is called _first_. if spec.conversion[1] not in 'rsa': - self.msg.fail('Invalid conversion type "{}",' - ' must be one of "r", "s" or "a"'.format(spec.conversion[1]), - call, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_CONVERSION_TYPE.format( + spec.conversion[1]), call) actual_type = self.named_type('builtins.str') # Perform the checks for given types. @@ -379,19 +372,14 @@ def perform_special_format_checks(self, spec: ConversionSpecifier, call: CallExp if self.chk.options.python_version >= (3, 0): if (has_type_component(actual_type, 'builtins.bytes') and not custom_special_method(actual_type, '__str__')): - self.msg.fail( - 'On Python 3 formatting "b\'abc\'" with "{}" ' - 'produces "b\'abc\'", not "abc"; ' - 'use "{!r}" if this is desired behavior', - call, code=codes.STR_BYTES_PY3) + self.msg.fail(message_registry.FORMAT_STR_BYTES_USE_REPR, call) if spec.flags: numeric_types = UnionType([self.named_type('builtins.int'), self.named_type('builtins.float')]) if (spec.conv_type and spec.conv_type not in NUMERIC_TYPES_NEW or not spec.conv_type and not is_subtype(actual_type, numeric_types) and not custom_special_method(actual_type, '__format__')): - self.msg.fail('Numeric flags are only allowed for numeric types', call, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_NUMERIC_FLAG, call) def find_replacements_in_call(self, call: CallExpr, keys: List[str]) -> List[Expression]: @@ -405,16 +393,14 @@ def find_replacements_in_call(self, call: CallExpr, if key.isdecimal(): expr = self.get_expr_by_position(int(key), call) if not expr: - self.msg.fail('Cannot find replacement for positional' - ' format specifier {}'.format(key), call, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_REPLACEMENT_NOT_FOUND.format(key), + call) expr = TempNode(AnyType(TypeOfAny.from_error)) else: expr = self.get_expr_by_name(key, call) if not expr: - self.msg.fail('Cannot find replacement for named' - ' format specifier "{}"'.format(key), call, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_NAMED_REPLACEMENT_NOT_FOUND.format( + key), call) expr = TempNode(AnyType(TypeOfAny.from_error)) result.append(expr) if not isinstance(expr, TempNode): @@ -483,8 +469,7 @@ def auto_generate_keys(self, all_specs: List[ConversionSpecifier], some_defined = any(s.key and s.key.isdecimal() for s in all_specs) all_defined = all(bool(s.key) for s in all_specs) if some_defined and not all_defined: - self.msg.fail('Cannot combine automatic field numbering and' - ' manual field specification', ctx, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_PARTIAL_FIELD_NUMBERING, ctx) return False if all_defined: return True @@ -519,8 +504,7 @@ def apply_field_accessors(self, spec: ConversionSpecifier, repl: Expression, dummy, fnam="", module=None, options=self.chk.options, errors=temp_errors ) if temp_errors.is_errors(): - self.msg.fail('Syntax error in format specifier "{}"'.format(spec.field), - ctx, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_SYNTAX_ERROR.format(spec.field), ctx) return TempNode(AnyType(TypeOfAny.from_error)) # These asserts are guaranteed by the original regexp. @@ -553,9 +537,8 @@ class User(TypedDict): '{[id]:d} -> {[name]}'.format(u) """ if not isinstance(temp_ast, (MemberExpr, IndexExpr)): - self.msg.fail('Only index and member expressions are allowed in' - ' format field accessors; got "{}"'.format(spec.field), - ctx, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_ACCESSOR_EXPR.format(spec.field), + ctx) return False if isinstance(temp_ast, MemberExpr): node = temp_ast.expr @@ -564,9 +547,8 @@ class User(TypedDict): if not isinstance(temp_ast.index, (NameExpr, IntExpr)): assert spec.key, "Call this method only after auto-generating keys!" assert spec.field - self.msg.fail('Invalid index expression in format field' - ' accessor "{}"'.format(spec.field[len(spec.key):]), ctx, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_INDEX_ACCESSOR.format( + spec.field[len(spec.key):]), ctx) return False if isinstance(temp_ast.index, NameExpr): temp_ast.index = StrExpr(temp_ast.index.name) @@ -595,8 +577,7 @@ def check_str_interpolation(self, specifiers = parse_conversion_specifiers(expr.value) has_mapping_keys = self.analyze_conversion_specifiers(specifiers, expr) if isinstance(expr, BytesExpr) and (3, 0) <= self.chk.options.python_version < (3, 5): - self.msg.fail('Bytes formatting is only supported in Python 3.5 and later', - replacements, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_BYTES_ABOVE_PY35, replacements) return AnyType(TypeOfAny.from_error) self.unicode_upcast = False @@ -697,8 +678,8 @@ def check_mapping_str_interpolation(self, specifiers: List[ConversionSpecifier], if self.chk.options.python_version >= (3, 0) and isinstance(expr, BytesExpr): # Special case: for bytes formatting keys must be bytes. if not isinstance(k, BytesExpr): - self.msg.fail('Dictionary keys in bytes formatting must be bytes,' - ' not strings', expr, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_BYTES_DICT_KEYS_MUST_BE_BYTES, + expr) key_str = cast(FormatStringExpr, k).value mapping[key_str] = self.accept(v) @@ -841,11 +822,7 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont # Couple special cases for string formatting. if self.chk.options.python_version >= (3, 0): if has_type_component(typ, 'builtins.bytes'): - self.msg.fail( - 'On Python 3 formatting "b\'abc\'" with "%s" ' - 'produces "b\'abc\'", not "abc"; ' - 'use "%r" if this is desired behavior', - context, code=codes.STR_BYTES_PY3) + self.msg.fail(message_registry.FORMAT_STR_BYTES_USE_REPR_OLD, context) return False if self.chk.options.python_version < (3, 0): if has_type_component(typ, 'builtins.unicode'): @@ -854,8 +831,7 @@ def check_s_special_cases(self, expr: FormatStringExpr, typ: Type, context: Cont # A special case for bytes formatting: b'%s' actually requires bytes on Python 3. if self.chk.options.python_version >= (3, 0): if has_type_component(typ, 'builtins.str'): - self.msg.fail("On Python 3 b'%s' requires bytes, not string", context, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_BYTES_REQUIRED_PY3, context) return False return True @@ -910,18 +886,15 @@ def conversion_type(self, p: str, context: Context, expr: FormatStringExpr, INT_TYPES = REQUIRE_INT_NEW if format_call else REQUIRE_INT_OLD if p == 'b' and not format_call: if self.chk.options.python_version < (3, 5): - self.msg.fail('Format character "b" is only supported in Python 3.5 and later', - context, code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_BYTES_SPECIFIER_PY35, context) return None if not isinstance(expr, BytesExpr): - self.msg.fail('Format character "b" is only supported on bytes patterns', context, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_INVALID_BYTES_SPECIFIER, context) return None return self.named_type('builtins.bytes') elif p == 'a': if self.chk.options.python_version < (3, 0): - self.msg.fail('Format character "a" is only supported in Python 3', context, - code=codes.STRING_FORMATTING) + self.msg.fail(message_registry.FORMAT_STR_ASCII_SPECIFIER_PY3, context) return None # TODO: return type object? return AnyType(TypeOfAny.special_form) diff --git a/mypy/constraints.py b/mypy/constraints.py index 9bc233054e91..040bcff8c99d 100644 --- a/mypy/constraints.py +++ b/mypy/constraints.py @@ -513,6 +513,10 @@ def visit_instance(self, template: Instance) -> List[Constraint]: return infer_constraints(template, mypy.typeops.tuple_fallback(actual), self.direction) + elif isinstance(actual, TypeVarType): + if not actual.values: + return infer_constraints(template, actual.upper_bound, self.direction) + return [] else: return [] @@ -658,8 +662,12 @@ def infer_against_any(self, types: Iterable[Type], any_type: AnyType) -> List[Co return res def visit_overloaded(self, template: Overloaded) -> List[Constraint]: + if isinstance(self.actual, CallableType): + items = find_matching_overload_items(template, self.actual) + else: + items = template.items res: List[Constraint] = [] - for t in template.items: + for t in items: res.extend(infer_constraints(t, self.actual, self.direction)) return res @@ -701,3 +709,22 @@ def find_matching_overload_item(overloaded: Overloaded, template: CallableType) # Fall back to the first item if we can't find a match. This is totally arbitrary -- # maybe we should just bail out at this point. return items[0] + + +def find_matching_overload_items(overloaded: Overloaded, + template: CallableType) -> List[CallableType]: + """Like find_matching_overload_item, but return all matches, not just the first.""" + items = overloaded.items + res = [] + for item in items: + # Return type may be indeterminate in the template, so ignore it when performing a + # subtype check. + if mypy.subtypes.is_callable_compatible(item, template, + is_compat=mypy.subtypes.is_subtype, + ignore_return=True): + res.append(item) + if not res: + # Falling back to all items if we can't find a match is pretty arbitrary, but + # it maintains backward compatibility. + res = items[:] + return res diff --git a/mypy/erasetype.py b/mypy/erasetype.py index 3301325eb0a1..f33b4f3a95cc 100644 --- a/mypy/erasetype.py +++ b/mypy/erasetype.py @@ -1,10 +1,10 @@ -from typing import Optional, Container, Callable +from typing import Optional, Container, Callable, List, Dict, cast from mypy.types import ( Type, TypeVisitor, UnboundType, AnyType, NoneType, TypeVarId, Instance, TypeVarType, CallableType, TupleType, TypedDictType, UnionType, Overloaded, ErasedType, PartialType, DeletedType, TypeTranslator, UninhabitedType, TypeType, TypeOfAny, LiteralType, ProperType, - get_proper_type, TypeAliasType, ParamSpecType + get_proper_type, get_proper_types, TypeAliasType, ParamSpecType ) from mypy.nodes import ARG_STAR, ARG_STAR2 @@ -161,3 +161,34 @@ def visit_type_alias_type(self, t: TypeAliasType) -> Type: # Type aliases can't contain literal values, because they are # always constructed as explicit types. return t + + def visit_union_type(self, t: UnionType) -> Type: + new = cast(UnionType, super().visit_union_type(t)) + # Erasure can result in many duplicate items; merge them. + # Call make_simplified_union only on lists of instance types + # that all have the same fullname, to avoid simplifying too + # much. + instances = [item for item in new.items + if isinstance(get_proper_type(item), Instance)] + # Avoid merge in simple cases such as optional types. + if len(instances) > 1: + instances_by_name: Dict[str, List[Instance]] = {} + new_items = get_proper_types(new.items) + for item in new_items: + if isinstance(item, Instance) and not item.args: + instances_by_name.setdefault(item.type.fullname, []).append(item) + merged: List[Type] = [] + for item in new_items: + if isinstance(item, Instance) and not item.args: + types = instances_by_name.get(item.type.fullname) + if types is not None: + if len(types) == 1: + merged.append(item) + else: + from mypy.typeops import make_simplified_union + merged.append(make_simplified_union(types)) + del instances_by_name[item.type.fullname] + else: + merged.append(item) + return UnionType.make_union(merged) + return new diff --git a/mypy/errorcodes.py b/mypy/errorcodes.py index 79dff526ca59..0a3cac8e270f 100644 --- a/mypy/errorcodes.py +++ b/mypy/errorcodes.py @@ -35,17 +35,17 @@ def __str__(self) -> str: CALL_ARG: Final[ErrorCode] = ErrorCode( "call-arg", "Check number, names and kinds of arguments in calls", "General" ) -ARG_TYPE: Final = ErrorCode("arg-type", "Check argument types in calls", "General") +ARG_TYPE: Final[ErrorCode] = ErrorCode("arg-type", "Check argument types in calls", "General") CALL_OVERLOAD: Final = ErrorCode( "call-overload", "Check that an overload variant matches arguments", "General" ) VALID_TYPE: Final[ErrorCode] = ErrorCode( "valid-type", "Check that type (annotation) is valid", "General" ) -VAR_ANNOTATED: Final = ErrorCode( +VAR_ANNOTATED: Final[ErrorCode] = ErrorCode( "var-annotated", "Require variable annotation if type can't be inferred", "General" ) -OVERRIDE: Final = ErrorCode( +OVERRIDE: Final[ErrorCode] = ErrorCode( "override", "Check that method override is compatible with base class", "General" ) RETURN: Final[ErrorCode] = ErrorCode( @@ -54,28 +54,32 @@ def __str__(self) -> str: RETURN_VALUE: Final[ErrorCode] = ErrorCode( "return-value", "Check that return value is compatible with signature", "General" ) -ASSIGNMENT: Final = ErrorCode( +ASSIGNMENT: Final[ErrorCode] = ErrorCode( "assignment", "Check that assigned value is compatible with target", "General" ) TYPE_ARG: Final[ErrorCode] = ErrorCode( "type-arg", "Check that generic type arguments are present", "General" ) -TYPE_VAR: Final = ErrorCode("type-var", "Check that type variable values are valid", "General") -UNION_ATTR: Final = ErrorCode( +TYPE_VAR: Final[ErrorCode] = ErrorCode( + "type-var", "Check that type variable values are valid", "General" +) +UNION_ATTR: Final[ErrorCode] = ErrorCode( "union-attr", "Check that attribute exists in each item of a union", "General" ) -INDEX: Final = ErrorCode("index", "Check indexing operations", "General") -OPERATOR: Final = ErrorCode("operator", "Check that operator is valid for operands", "General") -LIST_ITEM: Final = ErrorCode( +INDEX: Final[ErrorCode] = ErrorCode("index", "Check indexing operations", "General") +OPERATOR: Final[ErrorCode] = ErrorCode( + "operator", "Check that operator is valid for operands", "General" +) +LIST_ITEM: Final[ErrorCode] = ErrorCode( "list-item", "Check list items in a list expression [item, ...]", "General" ) -DICT_ITEM: Final = ErrorCode( +DICT_ITEM: Final[ErrorCode] = ErrorCode( "dict-item", "Check dict items in a dict expression {key: value, ...}", "General" ) -TYPEDDICT_ITEM: Final = ErrorCode( +TYPEDDICT_ITEM: Final[ErrorCode] = ErrorCode( "typeddict-item", "Check items when constructing TypedDict", "General" ) -HAS_TYPE: Final = ErrorCode( +HAS_TYPE: Final[ErrorCode] = ErrorCode( "has-type", "Check that type of reference can be determined", "General" ) IMPORT: Final = ErrorCode( @@ -84,22 +88,22 @@ def __str__(self) -> str: NO_REDEF: Final[ErrorCode] = ErrorCode( "no-redef", "Check that each name is defined once", "General" ) -FUNC_RETURNS_VALUE: Final = ErrorCode( +FUNC_RETURNS_VALUE: Final[ErrorCode] = ErrorCode( "func-returns-value", "Check that called function returns a value in value context", "General" ) -ABSTRACT: Final = ErrorCode( +ABSTRACT: Final[ErrorCode] = ErrorCode( "abstract", "Prevent instantiation of classes with abstract attributes", "General" ) VALID_NEWTYPE: Final[ErrorCode] = ErrorCode( "valid-newtype", "Check that argument 2 to NewType is valid", "General" ) -STRING_FORMATTING: Final = ErrorCode( +STRING_FORMATTING: Final[ErrorCode] = ErrorCode( "str-format", "Check that string formatting/interpolation is type-safe", "General" ) -STR_BYTES_PY3: Final = ErrorCode( +STR_BYTES_PY3: Final[ErrorCode] = ErrorCode( "str-bytes-safe", "Warn about dangerous coercions related to bytes and string types", "General" ) -EXIT_RETURN: Final = ErrorCode( +EXIT_RETURN: Final[ErrorCode] = ErrorCode( "exit-return", "Warn about too general return type for '__exit__'", "General" ) LITERAL_REQ: Final = ErrorCode( @@ -110,29 +114,29 @@ def __str__(self) -> str: NO_UNTYPED_DEF: Final[ErrorCode] = ErrorCode( "no-untyped-def", "Check that every function has an annotation", "General" ) -NO_UNTYPED_CALL: Final = ErrorCode( +NO_UNTYPED_CALL: Final[ErrorCode] = ErrorCode( "no-untyped-call", "Disallow calling functions without type annotations from annotated functions", "General", ) -REDUNDANT_CAST: Final = ErrorCode( +REDUNDANT_CAST: Final[ErrorCode] = ErrorCode( "redundant-cast", "Check that cast changes type of expression", "General" ) -COMPARISON_OVERLAP: Final = ErrorCode( +COMPARISON_OVERLAP: Final[ErrorCode] = ErrorCode( "comparison-overlap", "Check that types in comparisons and 'in' expressions overlap", "General" ) -NO_ANY_UNIMPORTED: Final = ErrorCode( +NO_ANY_UNIMPORTED: Final[ErrorCode] = ErrorCode( "no-any-unimported", 'Reject "Any" types from unfollowed imports', "General" ) -NO_ANY_RETURN: Final = ErrorCode( +NO_ANY_RETURN: Final[ErrorCode] = ErrorCode( "no-any-return", 'Reject returning value with "Any" type if return type is not "Any"', "General", ) -UNREACHABLE: Final = ErrorCode( +UNREACHABLE: Final[ErrorCode] = ErrorCode( "unreachable", "Warn about unreachable statements or expressions", "General" ) -REDUNDANT_EXPR: Final = ErrorCode( +REDUNDANT_EXPR: Final[ErrorCode] = ErrorCode( "redundant-expr", "Warn about redundant expressions", "General", default_enabled=False ) TRUTHY_BOOL: Final[ErrorCode] = ErrorCode( @@ -149,10 +153,21 @@ def __str__(self) -> str: "Check that overloaded functions outside stub files have an implementation", "General", ) +IGNORE_WITHOUT_CODE: Final = ErrorCode( + "ignore-without-code", + "Warn about '# type: ignore' comments which do not have error codes", + "General", + default_enabled=False, +) # Syntax errors are often blocking. SYNTAX: Final[ErrorCode] = ErrorCode("syntax", "Report syntax errors", "General") +# This is an internal marker code for a whole-file ignore. It is not intended to +# be user-visible. +FILE: Final = ErrorCode("file", "Internal marker for a whole file being ignored", "General") +del error_codes[FILE.code] + # This is a catch-all for remaining uncategorized errors. MISC: Final = ErrorCode("misc", "Miscellaneous other checks", "General") diff --git a/mypy/errors.py b/mypy/errors.py index c711456468ed..60abb739ba84 100644 --- a/mypy/errors.py +++ b/mypy/errors.py @@ -16,8 +16,13 @@ from mypy.util import DEFAULT_SOURCE_OFFSET, is_typeshed_file T = TypeVar("T") + allowed_duplicates: Final = ["@overload", "Got:", "Expected:"] +# Keep track of the original error code when the error code of a message is changed. +# This is used to give notes about out-of-date "type: ignore" comments. +original_error_codes: Final = {codes.LITERAL_REQ: codes.MISC} + class ErrorInfo: """Representation of a single error message.""" @@ -388,6 +393,24 @@ def add_error_info(self, info: ErrorInfo) -> None: info.hidden = True self.report_hidden_errors(info) self._add_error_info(file, info) + ignored_codes = self.ignored_lines.get(file, {}).get(info.line, []) + if ignored_codes and info.code: + # Something is ignored on the line, but not this error, so maybe the error + # code is incorrect. + msg = f'Error code "{info.code.code}" not covered by "type: ignore" comment' + if info.code in original_error_codes: + # If there seems to be a "type: ignore" with a stale error + # code, report a more specific note. + old_code = original_error_codes[info.code].code + if old_code in ignored_codes: + msg = (f'Error code changed to {info.code.code}; "type: ignore" comment ' + + 'may be out of date') + note = ErrorInfo( + info.import_ctx, info.file, info.module, info.type, info.function_or_member, + info.line, info.column, 'note', msg, + code=None, blocker=False, only_once=False, allow_dups=False + ) + self._add_error_info(file, note) def has_many_errors(self) -> bool: if self.many_errors_threshold < 0: @@ -485,6 +508,41 @@ def generate_unused_ignore_errors(self, file: str) -> None: None, False, False, False) self._add_error_info(file, info) + def generate_ignore_without_code_errors(self, + file: str, + is_warning_unused_ignores: bool) -> None: + if is_typeshed_file(file) or file in self.ignored_files: + return + + used_ignored_lines = self.used_ignored_lines[file] + + # If the whole file is ignored, ignore it. + if used_ignored_lines: + _, used_codes = min(used_ignored_lines.items()) + if codes.FILE.code in used_codes: + return + + for line, ignored_codes in self.ignored_lines[file].items(): + if ignored_codes: + continue + + # If the ignore is itself unused and that would be warned about, let + # that error stand alone + if is_warning_unused_ignores and not used_ignored_lines[line]: + continue + + codes_hint = '' + ignored_codes = sorted(set(used_ignored_lines[line])) + if ignored_codes: + codes_hint = f' (consider "type: ignore[{", ".join(ignored_codes)}]" instead)' + + message = f'"type: ignore" comment without error code{codes_hint}' + # Don't use report since add_error_info will ignore the error! + info = ErrorInfo(self.import_context(), file, self.current_module(), None, + None, line, -1, 'error', message, codes.IGNORE_WITHOUT_CODE, + False, False, False) + self._add_error_info(file, info) + def num_messages(self) -> int: """Return the number of generated messages.""" return sum(len(x) for x in self.error_info_map.values()) diff --git a/mypy/fastparse.py b/mypy/fastparse.py index 5baea90b29ac..e82e8bdcd8aa 100644 --- a/mypy/fastparse.py +++ b/mypy/fastparse.py @@ -45,7 +45,7 @@ from mypy.message_registry import ErrorMessage from mypy.errors import Errors from mypy.options import Options -from mypy.reachability import mark_block_unreachable +from mypy.reachability import infer_reachability_of_if_statement, mark_block_unreachable from mypy.util import bytes_to_human_readable_repr try: @@ -342,10 +342,19 @@ def fail(self, msg: ErrorMessage, line: int, column: int, - blocker: bool = True) -> None: + blocker: bool = True, + code: codes.ErrorCode = codes.SYNTAX) -> None: if blocker or not self.options.ignore_errors: self.errors.report(line, column, msg.value, blocker=blocker, code=msg.code) + def fail_merge_overload(self, node: IfStmt) -> None: + self.fail( + message_registry.FAIL_MERGE_OVERLOADS, + line=node.line, + column=node.column, + blocker=False, + ) + def visit(self, node: Optional[AST]) -> Any: if node is None: return None @@ -387,7 +396,7 @@ def translate_stmt_list(self, if (ismodule and stmts and self.type_ignores and min(self.type_ignores) < self.get_lineno(stmts[0])): self.errors.used_ignored_lines[self.errors.file][min(self.type_ignores)].append( - codes.MISC.code) + codes.FILE.code) block = Block(self.fix_function_overloads(self.translate_stmt_list(stmts))) mark_block_unreachable(block) return [block] @@ -474,12 +483,97 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: ret: List[Statement] = [] current_overload: List[OverloadPart] = [] current_overload_name: Optional[str] = None + seen_unconditional_func_def = False + last_if_stmt: Optional[IfStmt] = None + last_if_overload: Optional[Union[Decorator, FuncDef, OverloadedFuncDef]] = None + last_if_stmt_overload_name: Optional[str] = None + last_if_unknown_truth_value: Optional[IfStmt] = None + skipped_if_stmts: List[IfStmt] = [] for stmt in stmts: + if_overload_name: Optional[str] = None + if_block_with_overload: Optional[Block] = None + if_unknown_truth_value: Optional[IfStmt] = None + if ( + isinstance(stmt, IfStmt) + and len(stmt.body[0].body) == 1 + and seen_unconditional_func_def is False + and ( + isinstance(stmt.body[0].body[0], (Decorator, OverloadedFuncDef)) + or current_overload_name is not None + and isinstance(stmt.body[0].body[0], FuncDef) + ) + ): + # Check IfStmt block to determine if function overloads can be merged + if_overload_name = self._check_ifstmt_for_overloads(stmt) + if if_overload_name is not None: + if_block_with_overload, if_unknown_truth_value = \ + self._get_executable_if_block_with_overloads(stmt) + if (current_overload_name is not None and isinstance(stmt, (Decorator, FuncDef)) and stmt.name == current_overload_name): + if last_if_stmt is not None: + skipped_if_stmts.append(last_if_stmt) + if last_if_overload is not None: + # Last stmt was an IfStmt with same overload name + # Add overloads to current_overload + if isinstance(last_if_overload, OverloadedFuncDef): + current_overload.extend(last_if_overload.items) + else: + current_overload.append(last_if_overload) + last_if_stmt, last_if_overload = None, None + if last_if_unknown_truth_value: + self.fail_merge_overload(last_if_unknown_truth_value) + last_if_unknown_truth_value = None current_overload.append(stmt) + if isinstance(stmt, FuncDef): + seen_unconditional_func_def = True + elif ( + current_overload_name is not None + and isinstance(stmt, IfStmt) + and if_overload_name == current_overload_name + ): + # IfStmt only contains stmts relevant to current_overload. + # Check if stmts are reachable and add them to current_overload, + # otherwise skip IfStmt to allow subsequent overload + # or function definitions. + skipped_if_stmts.append(stmt) + if if_block_with_overload is None: + if if_unknown_truth_value is not None: + self.fail_merge_overload(if_unknown_truth_value) + continue + if last_if_overload is not None: + # Last stmt was an IfStmt with same overload name + # Add overloads to current_overload + if isinstance(last_if_overload, OverloadedFuncDef): + current_overload.extend(last_if_overload.items) + else: + current_overload.append(last_if_overload) + last_if_stmt, last_if_overload = None, None + if isinstance(if_block_with_overload.body[0], OverloadedFuncDef): + current_overload.extend(if_block_with_overload.body[0].items) + else: + current_overload.append( + cast(Union[Decorator, FuncDef], if_block_with_overload.body[0]) + ) else: + if last_if_stmt is not None: + ret.append(last_if_stmt) + last_if_stmt_overload_name = current_overload_name + last_if_stmt, last_if_overload = None, None + last_if_unknown_truth_value = None + + if current_overload and current_overload_name == last_if_stmt_overload_name: + # Remove last stmt (IfStmt) from ret if the overload names matched + # Only happens if no executable block had been found in IfStmt + skipped_if_stmts.append(cast(IfStmt, ret.pop())) + if current_overload and skipped_if_stmts: + # Add bare IfStmt (without overloads) to ret + # Required for mypy to be able to still check conditions + for if_stmt in skipped_if_stmts: + self._strip_contents_from_if_stmt(if_stmt) + ret.append(if_stmt) + skipped_if_stmts = [] if len(current_overload) == 1: ret.append(current_overload[0]) elif len(current_overload) > 1: @@ -490,20 +584,123 @@ def fix_function_overloads(self, stmts: List[Statement]) -> List[Statement]: # most of mypy/mypyc assumes that all the functions in an OverloadedFuncDef are # related, but multiple underscore functions next to each other aren't necessarily # related + seen_unconditional_func_def = False if isinstance(stmt, Decorator) and not unnamed_function(stmt.name): current_overload = [stmt] current_overload_name = stmt.name + elif ( + isinstance(stmt, IfStmt) + and if_overload_name is not None + ): + current_overload = [] + current_overload_name = if_overload_name + last_if_stmt = stmt + last_if_stmt_overload_name = None + if if_block_with_overload is not None: + last_if_overload = cast( + Union[Decorator, FuncDef, OverloadedFuncDef], + if_block_with_overload.body[0] + ) + last_if_unknown_truth_value = if_unknown_truth_value else: current_overload = [] current_overload_name = None ret.append(stmt) + if current_overload and skipped_if_stmts: + # Add bare IfStmt (without overloads) to ret + # Required for mypy to be able to still check conditions + for if_stmt in skipped_if_stmts: + self._strip_contents_from_if_stmt(if_stmt) + ret.append(if_stmt) if len(current_overload) == 1: ret.append(current_overload[0]) elif len(current_overload) > 1: ret.append(OverloadedFuncDef(current_overload)) + elif last_if_stmt is not None: + ret.append(last_if_stmt) return ret + def _check_ifstmt_for_overloads(self, stmt: IfStmt) -> Optional[str]: + """Check if IfStmt contains only overloads with the same name. + Return overload_name if found, None otherwise. + """ + # Check that block only contains a single Decorator, FuncDef, or OverloadedFuncDef. + # Multiple overloads have already been merged as OverloadedFuncDef. + if not ( + len(stmt.body[0].body) == 1 + and isinstance(stmt.body[0].body[0], (Decorator, FuncDef, OverloadedFuncDef)) + ): + return None + + overload_name = stmt.body[0].body[0].name + if stmt.else_body is None: + return overload_name + + if isinstance(stmt.else_body, Block) and len(stmt.else_body.body) == 1: + # For elif: else_body contains an IfStmt itself -> do a recursive check. + if ( + isinstance(stmt.else_body.body[0], (Decorator, FuncDef, OverloadedFuncDef)) + and stmt.else_body.body[0].name == overload_name + ): + return overload_name + if ( + isinstance(stmt.else_body.body[0], IfStmt) + and self._check_ifstmt_for_overloads(stmt.else_body.body[0]) == overload_name + ): + return overload_name + + return None + + def _get_executable_if_block_with_overloads( + self, stmt: IfStmt + ) -> Tuple[Optional[Block], Optional[IfStmt]]: + """Return block from IfStmt that will get executed. + + Return + 0 -> A block if sure that alternative blocks are unreachable. + 1 -> An IfStmt if the reachability of it can't be inferred, + i.e. the truth value is unknown. + """ + infer_reachability_of_if_statement(stmt, self.options) + if ( + stmt.else_body is None + and stmt.body[0].is_unreachable is True + ): + # always False condition with no else + return None, None + if ( + stmt.else_body is None + or stmt.body[0].is_unreachable is False + and stmt.else_body.is_unreachable is False + ): + # The truth value is unknown, thus not conclusive + return None, stmt + if stmt.else_body.is_unreachable is True: + # else_body will be set unreachable if condition is always True + return stmt.body[0], None + if stmt.body[0].is_unreachable is True: + # body will be set unreachable if condition is always False + # else_body can contain an IfStmt itself (for elif) -> do a recursive check + if isinstance(stmt.else_body.body[0], IfStmt): + return self._get_executable_if_block_with_overloads(stmt.else_body.body[0]) + return stmt.else_body, None + return None, stmt + + def _strip_contents_from_if_stmt(self, stmt: IfStmt) -> None: + """Remove contents from IfStmt. + + Needed to still be able to check the conditions after the contents + have been merged with the surrounding function overloads. + """ + if len(stmt.body) == 1: + stmt.body[0].body = [] + if stmt.else_body and len(stmt.else_body.body) == 1: + if isinstance(stmt.else_body.body[0], IfStmt): + self._strip_contents_from_if_stmt(stmt.else_body.body[0]) + else: + stmt.else_body.body = [] + def in_method_scope(self) -> bool: return self.class_and_function_stack[-2:] == ['C', 'F'] diff --git a/mypy/fastparse2.py b/mypy/fastparse2.py index 8d2671a02f33..ab7714549df7 100644 --- a/mypy/fastparse2.py +++ b/mypy/fastparse2.py @@ -218,7 +218,7 @@ def translate_stmt_list(self, if (module and stmts and self.type_ignores and min(self.type_ignores) < self.get_lineno(stmts[0])): self.errors.used_ignored_lines[self.errors.file][min(self.type_ignores)].append( - codes.MISC.code) + codes.FILE.code) block = Block(self.fix_function_overloads(self.translate_stmt_list(stmts))) mark_block_unreachable(block) return [block] @@ -665,19 +665,23 @@ def visit_With(self, n: ast27.With) -> WithStmt: typ) return self.set_line(stmt, n) + # 'raise' [test [',' test [',' test]]] def visit_Raise(self, n: ast27.Raise) -> RaiseStmt: + legacy_mode = False if n.type is None: e = None else: if n.inst is None: e = self.visit(n.type) else: + legacy_mode = True if n.tback is None: e = TupleExpr([self.visit(n.type), self.visit(n.inst)]) else: e = TupleExpr([self.visit(n.type), self.visit(n.inst), self.visit(n.tback)]) stmt = RaiseStmt(e, None) + stmt.legacy_mode = legacy_mode return self.set_line(stmt, n) # TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) diff --git a/mypy/fscache.py b/mypy/fscache.py index ea71577b5f86..d0be1abd8cb9 100644 --- a/mypy/fscache.py +++ b/mypy/fscache.py @@ -143,16 +143,13 @@ def _fake_init(self, path: str) -> os.stat_result: assert not os.path.exists(path), path # Not cached! dirname = os.path.normpath(dirname) st = self.stat(dirname) # May raise OSError - # Get stat result as a sequence so we can modify it. - # (Alas, typeshed's os.stat_result is not a sequence yet.) - tpl = tuple(st) # type: ignore[arg-type, var-annotated] - seq: List[float] = list(tpl) + # Get stat result as a list so we can modify it. + seq: List[float] = list(st) seq[stat.ST_MODE] = stat.S_IFREG | 0o444 seq[stat.ST_INO] = 1 seq[stat.ST_NLINK] = 1 seq[stat.ST_SIZE] = 0 - tpl = tuple(seq) - st = os.stat_result(tpl) + st = os.stat_result(seq) self.stat_cache[path] = st # Make listdir() and read() also pretend this file exists. self.fake_package_cache.add(dirname) diff --git a/mypy/ipc.py b/mypy/ipc.py index 8a6a310d7ff8..f48ac18075d8 100644 --- a/mypy/ipc.py +++ b/mypy/ipc.py @@ -54,9 +54,6 @@ def read(self, size: int = 100000) -> bytes: if sys.platform == 'win32': while True: ov, err = _winapi.ReadFile(self.connection, size, overlapped=True) - # TODO: remove once typeshed supports Literal types - assert isinstance(ov, _winapi.Overlapped) - assert isinstance(err, int) try: if err == _winapi.ERROR_IO_PENDING: timeout = int(self.timeout * 1000) if self.timeout else _winapi.INFINITE diff --git a/mypy/join.py b/mypy/join.py index d298b495fdc5..161c65ea800c 100644 --- a/mypy/join.py +++ b/mypy/join.py @@ -175,15 +175,15 @@ def join_types(s: Type, t: Type, instance_joiner: Optional[InstanceJoiner] = Non s = mypy.typeops.true_or_false(s) t = mypy.typeops.true_or_false(t) + if isinstance(s, UnionType) and not isinstance(t, UnionType): + s, t = t, s + if isinstance(s, AnyType): return s if isinstance(s, ErasedType): return t - if isinstance(s, UnionType) and not isinstance(t, UnionType): - s, t = t, s - if isinstance(s, NoneType) and not isinstance(t, NoneType): s, t = t, s diff --git a/mypy/meet.py b/mypy/meet.py index 2ea2bc62a660..0b336aa6f810 100644 --- a/mypy/meet.py +++ b/mypy/meet.py @@ -508,15 +508,14 @@ def visit_param_spec(self, t: ParamSpecType) -> ProperType: def visit_instance(self, t: Instance) -> ProperType: if isinstance(self.s, Instance): - si = self.s - if t.type == si.type: + if t.type == self.s.type: if is_subtype(t, self.s) or is_subtype(self.s, t): # Combine type arguments. We could have used join below # equivalently. args: List[Type] = [] # N.B: We use zip instead of indexing because the lengths might have # mismatches during daemon reprocessing. - for ta, sia in zip(t.args, si.args): + for ta, sia in zip(t.args, self.s.args): args.append(self.meet(ta, sia)) return Instance(t.type, args) else: diff --git a/mypy/message_registry.py b/mypy/message_registry.py index ca6c95324343..ceaef19ba5e7 100644 --- a/mypy/message_registry.py +++ b/mypy/message_registry.py @@ -20,6 +20,10 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": return ErrorMessage(self.value.format(*args, **kwargs), code=self.code) +# Strings +INCOMPATIBLE_TYPES: Final = "Incompatible types" +INCOMPATIBLE_TYPES_IN_ASSIGNMENT: Final = "Incompatible types in assignment" + # Invalid types INVALID_TYPE_RAW_ENUM_VALUE: Final = ErrorMessage( "Invalid type: try using Literal[{}.{}] instead?" @@ -51,17 +55,15 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": " its third type parameter in Python 2" ) YIELD_VALUE_EXPECTED: Final = ErrorMessage("Yield value expected") -INCOMPATIBLE_TYPES: Final = "Incompatible types" -INCOMPATIBLE_TYPES_IN_ASSIGNMENT: Final = "Incompatible types in assignment" INCOMPATIBLE_TYPES_IN_AWAIT: Final = ErrorMessage('Incompatible types in "await"') INCOMPATIBLE_REDEFINITION: Final = ErrorMessage("Incompatible redefinition") -INCOMPATIBLE_TYPES_IN_ASYNC_WITH_AENTER: Final = ( +INCOMPATIBLE_TYPES_IN_ASYNC_WITH_AENTER: Final = ErrorMessage( 'Incompatible types in "async with" for "__aenter__"' ) -INCOMPATIBLE_TYPES_IN_ASYNC_WITH_AEXIT: Final = ( +INCOMPATIBLE_TYPES_IN_ASYNC_WITH_AEXIT: Final = ErrorMessage( 'Incompatible types in "async with" for "__aexit__"' ) -INCOMPATIBLE_TYPES_IN_ASYNC_FOR: Final = 'Incompatible types in "async for"' +INCOMPATIBLE_TYPES_IN_ASYNC_FOR: Final = ErrorMessage('Incompatible types in "async for"') INCOMPATIBLE_TYPES_IN_YIELD: Final = ErrorMessage('Incompatible types in "yield"') INCOMPATIBLE_TYPES_IN_YIELD_FROM: Final = ErrorMessage('Incompatible types in "yield from"') @@ -72,11 +74,11 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": TUPLE_INDEX_OUT_OF_RANGE: Final = ErrorMessage("Tuple index out of range") INVALID_SLICE_INDEX: Final = ErrorMessage("Slice index must be an integer or None") CANNOT_INFER_LAMBDA_TYPE: Final = ErrorMessage("Cannot infer type of lambda") -CANNOT_ACCESS_INIT: Final = 'Cannot access "__init__" directly' +CANNOT_ACCESS_INIT: Final = ErrorMessage('Cannot access "__init__" directly') NON_INSTANCE_NEW_TYPE: Final = ErrorMessage('"__new__" must return a class instance (got {})') INVALID_NEW_TYPE: Final = ErrorMessage('Incompatible return type for "__new__"') BAD_CONSTRUCTOR_TYPE: Final = ErrorMessage("Unsupported decorated constructor type") -CANNOT_ASSIGN_TO_METHOD: Final = "Cannot assign to a method" +CANNOT_ASSIGN_TO_METHOD: Final = ErrorMessage("Cannot assign to a method", codes.ASSIGNMENT) CANNOT_ASSIGN_TO_TYPE: Final = ErrorMessage("Cannot assign to a type") INCONSISTENT_ABSTRACT_OVERLOAD: Final = ErrorMessage( "Overloaded method has both abstract and non-abstract variants" @@ -118,7 +120,7 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": MALFORMED_ASSERT: Final = ErrorMessage("Assertion is always true, perhaps remove parentheses?") DUPLICATE_TYPE_SIGNATURES: Final = ErrorMessage("Function has duplicate type signatures") DESCRIPTOR_SET_NOT_CALLABLE: Final = ErrorMessage("{}.__set__ is not callable") -DESCRIPTOR_GET_NOT_CALLABLE: Final = "{}.__get__ is not callable" +DESCRIPTOR_GET_NOT_CALLABLE: Final = ErrorMessage("{}.__get__ is not callable") MODULE_LEVEL_GETATTRIBUTE: Final = ErrorMessage( "__getattribute__ is not valid at the module level" ) @@ -140,29 +142,44 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": code=codes.TRUTHY_BOOL, ) NOT_CALLABLE: Final = '{} not callable' -PYTHON2_PRINT_FILE_TYPE: Final = ( +PYTHON2_PRINT_FILE_TYPE: Final = ErrorMessage( 'Argument "file" to "print" has incompatible type "{}"; expected "{}"' ) +ENUM_EXTEND_EXISTING_MEMBERS: Final = ErrorMessage( + 'Cannot extend enum with existing members: "{}"' +) # Generic -GENERIC_INSTANCE_VAR_CLASS_ACCESS: Final = ( +GENERIC_INSTANCE_VAR_CLASS_ACCESS: Final = ErrorMessage( "Access to generic instance variables via class is ambiguous" ) -GENERIC_CLASS_VAR_ACCESS: Final = "Access to generic class variables is ambiguous" +GENERIC_CLASS_VAR_ACCESS: Final = ErrorMessage("Access to generic class variables is ambiguous") BARE_GENERIC: Final = ErrorMessage("Missing type parameters for generic type {}", codes.TYPE_ARG) IMPLICIT_GENERIC_ANY_BUILTIN: Final = ErrorMessage( 'Implicit generic "Any". Use "{}" and specify generic parameters', codes.TYPE_ARG ) # TypeVar -INCOMPATIBLE_TYPEVAR_VALUE: Final = 'Value of type variable "{}" of {} cannot be {}' -CANNOT_USE_TYPEVAR_AS_EXPRESSION: Final = 'Type variable "{}.{}" cannot be used as an expression' -INVALID_TYPEVAR_AS_TYPEARG: Final = 'Type variable "{}" not valid as type argument value for "{}"' -INVALID_TYPEVAR_ARG_BOUND: Final = 'Type argument {} of "{}" must be a subtype of {}' -INVALID_TYPEVAR_ARG_VALUE: Final = 'Invalid type argument value for "{}"' +INCOMPATIBLE_TYPEVAR_VALUE: Final = ErrorMessage( + 'Value of type variable "{}" of {} cannot be {}', codes.TYPE_VAR +) +CANNOT_USE_TYPEVAR_AS_EXPRESSION: Final = ErrorMessage( + 'Type variable "{}.{}" cannot be used as an expression' +) +INVALID_TYPEVAR_AS_TYPEARG: Final = ErrorMessage( + 'Type variable "{}" not valid as type argument value for "{}"', codes.TYPE_VAR +) +INVALID_TYPEVAR_ARG_BOUND: Final = ErrorMessage( + 'Type argument {} of "{}" must be a subtype of {}', codes.TYPE_VAR +) +INVALID_TYPEVAR_ARG_VALUE: Final = ErrorMessage( + 'Invalid type argument value for "{}"', codes.TYPE_VAR +) TYPEVAR_VARIANCE_DEF: Final = ErrorMessage('TypeVar "{}" may only be a literal bool') TYPEVAR_BOUND_MUST_BE_TYPE: Final = ErrorMessage('TypeVar "bound" must be a type') TYPEVAR_UNEXPECTED_ARGUMENT: Final = ErrorMessage('Unexpected argument to "TypeVar()"') +PARAMSPEC_INVALID_LOCATION: Final = ErrorMessage('Invalid location for ParamSpec "{}"') +PARAMSPEC_FIRST_ARG: Final = ErrorMessage("Only the first argument to ParamSpec has defined semantics") # FastParse TYPE_COMMENT_SYNTAX_ERROR_VALUE: Final = ErrorMessage( @@ -197,6 +214,7 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": EXCEPT_EXPR_NOTNAME_UNSUPPORTED: Final = ErrorMessage( 'Sorry, "except , " is not supported', codes.SYNTAX ) +FAIL_MERGE_OVERLOADS: Final = ErrorMessage("Condition can't be inferred, unable to merge overloads") # Nodes DUPLICATE_ARGUMENT_IN_X: Final = ErrorMessage('Duplicate argument "{}" in {}') @@ -212,6 +230,370 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": KWARGS_MUST_BE_LAST: Final = ErrorMessage("A **kwargs argument must be the last argument") MULTIPLE_KWARGS: Final = ErrorMessage("You may only have one **kwargs argument") +# String formatting checks +FORMAT_STR_INVALID_SPECIFIER: Final = ErrorMessage( + "Invalid conversion specifier in format string", codes.STRING_FORMATTING +) +FORMAT_STR_BRACES_IN_SPECIFIER: Final = ErrorMessage( + "Conversion value must not contain { or }", codes.STRING_FORMATTING +) +FORMAT_STR_NESTING_ATMOST_TWO_LEVELS: Final = ErrorMessage( + "Formatting nesting must be at most two levels deep", codes.STRING_FORMATTING +) +FORMAT_STR_UNEXPECTED_RBRACE: Final = ErrorMessage( + "Invalid conversion specifier in format string: unexpected }", codes.STRING_FORMATTING +) +FORMAT_STR_UNMATCHED_LBRACE: Final = ErrorMessage( + "Invalid conversion specifier in format string: unmatched {", codes.STRING_FORMATTING +) +UNRECOGNIZED_FORMAT_SPEC: Final = ErrorMessage( + 'Unrecognized format specification "{}"', codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_CONVERSION_TYPE: Final = ErrorMessage( + 'Invalid conversion type "{}", must be one of "r", "s" or "a"', codes.STRING_FORMATTING +) +FORMAT_STR_BYTES_USE_REPR: Final = ErrorMessage( + 'On Python 3 formatting "b\'abc\'" with "{}" produces "b\'abc\'", not "abc"; use' + ' "{!r}" if this is desired behavior', + codes.STR_BYTES_PY3, +) +FORMAT_STR_BYTES_USE_REPR_OLD: Final = ErrorMessage( + 'On Python 3 formatting "b\'abc\'" with "%s" produces "b\'abc\'", not "abc"; use "%r"' + " if this is desired behavior", + codes.STR_BYTES_PY3, +) +FORMAT_STR_INVALID_NUMERIC_FLAG: Final = ErrorMessage( + "Numeric flags are only allowed for numeric types", codes.STRING_FORMATTING +) +FORMAT_STR_REPLACEMENT_NOT_FOUND: Final = ErrorMessage( + "Cannot find replacement for positional format specifier {}", codes.STRING_FORMATTING +) +FORMAT_STR_NAMED_REPLACEMENT_NOT_FOUND: Final = ErrorMessage( + 'Cannot find replacement for named format specifier "{}"', codes.STRING_FORMATTING +) +FORMAT_STR_PARTIAL_FIELD_NUMBERING: Final = ErrorMessage( + "Cannot combine automatic field numbering and manual field specification", + codes.STRING_FORMATTING, +) +FORMAT_STR_SYNTAX_ERROR: Final = ErrorMessage( + 'Syntax error in format specifier "{}"', codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_ACCESSOR_EXPR: Final = ErrorMessage( + 'Only index and member expressions are allowed in format field accessors; got "{}"', + codes.STRING_FORMATTING, +) +FORMAT_STR_INVALID_INDEX_ACCESSOR: Final = ErrorMessage( + 'Invalid index expression in format field accessor "{}"', codes.STRING_FORMATTING +) +FORMAT_STR_BYTES_ABOVE_PY35: Final = ErrorMessage( + "Bytes formatting is only supported in Python 3.5 and later", codes.STRING_FORMATTING +) +FORMAT_STR_BYTES_DICT_KEYS_MUST_BE_BYTES: Final = ErrorMessage( + "Dictionary keys in bytes formatting must be bytes, not strings", codes.STRING_FORMATTING +) +FORMAT_STR_BYTES_REQUIRED_PY3: Final = ErrorMessage( + "On Python 3 b'%s' requires bytes, not string", codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_BYTES_SPECIFIER_PY35: Final = ErrorMessage( + 'Format character "b" is only supported in Python 3.5 and later', codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_BYTES_SPECIFIER: Final = ErrorMessage( + 'Format character "b" is only supported on bytes patterns', codes.STRING_FORMATTING +) +FORMAT_STR_ASCII_SPECIFIER_PY3: Final = ErrorMessage( + 'Format character "a" is only supported in Python 3', codes.STRING_FORMATTING +) + +# strings from messages.py +MEMBER_NOT_ASSIGNABLE: Final = ErrorMessage('Member "{}" is not assignable') +UNSUPPORTED_OPERAND_FOR_IN: Final = ErrorMessage( + "Unsupported right operand type for in ({})", codes.OPERATOR +) +UNSUPPORTED_OPERAND_FOR_UNARY_MINUS: Final = ErrorMessage( + "Unsupported operand type for unary - ({})", codes.OPERATOR +) +UNSUPPORTED_OPERAND_FOR_UNARY_PLUS: Final = ErrorMessage( + "Unsupported operand type for unary + ({})", codes.OPERATOR +) +UNSUPPORTED_OPERAND_FOR_INVERT: Final = ErrorMessage( + "Unsupported operand type for ~ ({})", codes.OPERATOR +) +TYPE_NOT_GENERIC_OR_INDEXABLE: Final = ErrorMessage("The type {} is not generic and not indexable") +TYPE_NOT_INDEXABLE: Final = ErrorMessage("Value of type {} is not indexable", codes.INDEX) +UNSUPPORTED_TARGET_INDEXED_ASSIGNMENT: Final = ErrorMessage( + "Unsupported target for indexed assignment ({})", codes.INDEX +) +CALLING_FUNCTION_OF_UNKNOWN_TYPE: Final = ErrorMessage( + "Cannot call function of unknown type", codes.OPERATOR +) +TYPE_NOT_CALLABLE: Final = ErrorMessage("{} not callable", codes.OPERATOR) +TYPE_NOT_CALLABLE_2: Final = ErrorMessage("{} not callable") +TYPE_HAS_NO_ATTRIBUTE_X_MAYBE_Y: Final = ErrorMessage( + '{} has no attribute "{}"; maybe {}?{}', codes.ATTR_DEFINED +) +TYPE_HAS_NO_ATTRIBUTE_X: Final = ErrorMessage('{} has no attribute "{}"{}', codes.ATTR_DEFINED) +ITEM_HAS_NO_ATTRIBUTE_X: Final = ErrorMessage( + 'Item {} of {} has no attribute "{}"{}', codes.UNION_ATTR +) +TYPEVAR_UPPER_BOUND_HAS_NO_ATTRIBUTE: Final = ErrorMessage( + 'Item {} of the upper bound {} of type variable {} has no attribute "{}"{}', codes.UNION_ATTR +) +UNSUPPORTED_OPERANDS_LIKELY_UNION: Final = ErrorMessage( + "Unsupported operand types for {} (likely involving Union)", codes.OPERATOR +) +UNSUPPORTED_OPERANDS: Final = ErrorMessage( + "Unsupported operand types for {} ({} and {})", codes.OPERATOR +) +UNSUPPORTED_LEFT_OPERAND_TYPE_UNION: Final = ErrorMessage( + "Unsupported left operand type for {} (some union)", codes.OPERATOR +) +UNSUPPORTED_LEFT_OPERAND_TYPE: Final = ErrorMessage( + "Unsupported left operand type for {} ({})", codes.OPERATOR +) +UNTYPED_FUNCTION_CALL: Final = ErrorMessage( + "Call to untyped function {} in typed context", codes.NO_UNTYPED_CALL +) +INVALID_INDEX_TYPE: Final = ErrorMessage( + "Invalid index type {} for {}; expected type {}", codes.INDEX +) +TARGET_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "{} (expression has type {}, target has type {})", codes.ASSIGNMENT +) +VALUE_INCOMPATIBLE_TYPE: Final = ErrorMessage( + 'Value of "{}" has incompatible type {}; expected {}', codes.ARG_TYPE +) +ARGUMENT_INCOMPATIBLE_TYPE: Final = ErrorMessage( + 'Argument {} {}has incompatible type {}; expected {}', codes.ARG_TYPE +) +TYPEDDICT_VALUE_INCOMPATIBLE_TYPE: Final = ErrorMessage( + 'Value of "{}" has incompatible type {}; expected {}', codes.TYPEDDICT_ITEM +) +TYPEDDICT_ARGUMENT_INCOMPATIBLE_TYPE: Final = ErrorMessage( + 'Argument {} {}has incompatible type {}; expected {}', codes.TYPEDDICT_ITEM +) +LIST_ITEM_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "{} item {} has incompatible type {}; expected {}", codes.LIST_ITEM +) +DICT_ENTRY_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "{} entry {} has incompatible type {}: {}; expected {}: {}", codes.DICT_ITEM +) +LIST_COMP_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "List comprehension has incompatible type List[{}]; expected List[{}]" +) +SET_COMP_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "Set comprehension has incompatible type Set[{}]; expected Set[{}]" +) +DICT_COMP_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "{} expression in dictionary comprehension has incompatible type {}; expected type {}" +) +GENERATOR_INCOMPATIBLE_TYPE: Final = ErrorMessage( + "Generator has incompatible item type {}; expected {}" +) +MULTIPLE_VALUES_FOR_KWARG: Final = ErrorMessage( + '{} gets multiple values for keyword argument "{}"' +) +NO_RETURN_VALUE: Final = ErrorMessage("{} does not return a value", codes.FUNC_RETURNS_VALUE) +FUNCTION_NO_RETURN_VALUE: Final = ErrorMessage( + "Function does not return a value", codes.FUNC_RETURNS_VALUE +) +UNDERSCORE_FUNCTION_CALL: Final = ErrorMessage('Calling function named "_" is not allowed') +READING_DELETED_VALUE: Final = ErrorMessage("Trying to read deleted variable{}") +ASSIGNMENT_OUTSIDE_EXCEPT: Final = ErrorMessage("Assignment to variable{} outside except: block") +OVERLOADS_REQUIRE_ATLEAST_ONE_ARG: Final = ErrorMessage( + "All overload variants{} require at least one argument" +) +UNPACK_MORE_THAN_ONE_VALUE_NEEDED: Final = ErrorMessage( + "Need more than 1 value to unpack ({} expected)" +) +UNPACK_TOO_FEW_VALUES: Final = ErrorMessage("Need more than {} values to unpack ({} expected)") +UNPACK_TOO_MANY_VALUES: Final = ErrorMessage( + "Too many values to unpack ({} expected, {} provided)" +) +UNPACKING_STRINGS_DISALLOWED: Final = ErrorMessage("Unpacking a string is disallowed") +TYPE_NOT_ITERABLE: Final = ErrorMessage('{} object is not iterable') +INCOMPATIBLE_OPERATOR_ASSIGNMENT: Final = ErrorMessage( + "Result type of {} incompatible in assignment" +) +OVERLOAD_SIGNATURE_INCOMPATIBLE: Final = ErrorMessage( + 'Signature of "{}" incompatible with {}', codes.OVERRIDE +) +SIGNATURE_INCOMPATIBLE_WITH_SUPERTYPE: Final = ErrorMessage( + 'Signature of "{}" incompatible with {}', codes.OVERRIDE +) +ARG_INCOMPATIBLE_WITH_SUPERTYPE: Final = ErrorMessage( + 'Argument {} of "{}" is incompatible with {}; supertype defines the argument type as "{}"', + codes.OVERRIDE, +) +RETURNTYPE_INCOMPATIBLE_WITH_SUPERTYPE: Final = ErrorMessage( + 'Return type {} of "{}" incompatible with return type {} in {}', codes.OVERRIDE +) +TYPE_APPLICATION_ON_NON_GENERIC_TYPE: Final = ErrorMessage( + "Type application targets a non-generic function or class" +) +TYPE_APPLICATION_TOO_MANY_TYPES: Final = ErrorMessage( + "Type application has too many types ({} expected)" +) +TYPE_APPLICATION_TOO_FEW_TYPES: Final = ErrorMessage( + "Type application has too few types ({} expected)" +) +CANNOT_INFER_TYPE_ARG_NAMED_FUNC: Final = ErrorMessage("Cannot infer type argument {} of {}") +CANNOT_INFER_TYPE_ARG_FUNC: Final = ErrorMessage("Cannot infer function type argument") +INVALID_VAR_ARGS: Final = ErrorMessage("List or tuple expected as variable arguments") +KEYWORDS_MUST_BE_STRINGS: Final = ErrorMessage("Keywords must be strings") +ARG_MUST_BE_MAPPING: Final = ErrorMessage("Argument after ** must be a mapping{}", codes.ARG_TYPE) +MEMBER_UNDEFINED_IN_SUPERCLASS: Final = ErrorMessage('"{}" undefined in superclass') +SUPER_ARG_EXPECTED_TYPE: Final = ErrorMessage( + 'Argument 1 for "super" must be a type object; got {}', codes.ARG_TYPE +) +FORMAT_STR_TOO_FEW_ARGS: Final = ErrorMessage( + "Not enough arguments for format string", codes.STRING_FORMATTING +) +FORMAT_STR_TOO_MANY_ARGS: Final = ErrorMessage( + "Not all arguments converted during string formatting", codes.STRING_FORMATTING +) +FORMAT_STR_UNSUPPORTED_CHAR: Final = ErrorMessage( + 'Unsupported format character "{}"', codes.STRING_FORMATTING +) +STRING_INTERPOLATION_WITH_STAR_AND_KEY: Final = ErrorMessage( + "String interpolation contains both stars and mapping keys", codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_CHR_CONVERSION_RANGE: Final = ErrorMessage( + '"{}c" requires an integer in range(256) or a single byte', codes.STRING_FORMATTING +) +FORMAT_STR_INVALID_CHR_CONVERSION: Final = ErrorMessage( + '"{}c" requires int or char', codes.STRING_FORMATTING +) +KEY_NOT_IN_MAPPING: Final = ErrorMessage('Key "{}" not found in mapping', codes.STRING_FORMATTING) +FORMAT_STR_MIXED_KEYS_AND_NON_KEYS: Final = ErrorMessage( + "String interpolation mixes specifier with and without mapping keys", codes.STRING_FORMATTING +) +CANNOT_DETERMINE_TYPE: Final = ErrorMessage('Cannot determine type of "{}"', codes.HAS_TYPE) +CANNOT_DETERMINE_TYPE_IN_BASE: Final = ErrorMessage( + 'Cannot determine type of "{}" in base class "{}"' +) +DOES_NOT_ACCEPT_SELF: Final = ErrorMessage( + 'Attribute function "{}" with type {} does not accept self argument' +) +INCOMPATIBLE_SELF_ARG: Final = ErrorMessage('Invalid self argument {} to {} "{}" with type {}') +INCOMPATIBLE_CONDITIONAL_FUNCS: Final = ErrorMessage( + "All conditional function variants must have identical signatures" +) +CANNOT_INSTANTIATE_ABSTRACT_CLASS: Final = ErrorMessage( + 'Cannot instantiate abstract class "{}" with abstract attribute{} {}', codes.ABSTRACT +) +INCOMPATIBLE_BASE_CLASS_DEFNS: Final = ErrorMessage( + 'Definition of "{}" in base class "{}" is incompatible with definition in base class "{}"' +) +CANNOT_ASSIGN_TO_CLASSVAR: Final = ErrorMessage( + 'Cannot assign to class variable "{}" via instance' +) +CANNOT_OVERRIDE_TO_FINAL: Final = ErrorMessage( + 'Cannot override writable attribute "{}" with a final one' +) +CANNOT_OVERRIDE_FINAL: Final = ErrorMessage( + 'Cannot override final attribute "{}" (previously declared in base class "{}")' +) +CANNOT_ASSIGN_TO_FINAL: Final = ErrorMessage('Cannot assign to final {} "{}"') +PROTOCOL_MEMBER_CANNOT_BE_FINAL: Final = ErrorMessage("Protocol member cannot be final") +FINAL_WITHOUT_VALUE: Final = ErrorMessage("Final name must be initialized with a value") +PROPERTY_IS_READ_ONLY: Final = ErrorMessage('Property "{}" defined in "{}" is read-only') +NON_OVERLAPPING_COMPARISON: Final = ErrorMessage( + "Non-overlapping {} check ({} type: {}, {} type: {})", codes.COMPARISON_OVERLAP +) +OVERLOAD_INCONSISTENT_DECORATOR_USE: Final = ErrorMessage( + 'Overload does not consistently use the "@{}" decorator on all function signatures.' +) +OVERLOAD_INCOMPATIBLE_RETURN_TYPES: Final = ErrorMessage( + "Overloaded function signatures {} and {} overlap with incompatible return types" +) +OVERLOAD_SIGNATURE_WILL_NEVER_MATCH: Final = ErrorMessage( + "Overloaded function signature {index2} will never be matched: signature {index1}'s parameter" + " type(s) are the same or broader" +) +OVERLOAD_INCONSISTENT_TYPEVARS: Final = ErrorMessage( + "Overloaded function implementation cannot satisfy signature {} due to inconsistencies in how" + " they use type variables" +) +OVERLOAD_INCONSISTENT_ARGS: Final = ErrorMessage( + "Overloaded function implementation does not accept all possible arguments of signature {}" +) +OVERLOAD_INCONSISTENT_RETURN_TYPE: Final = ErrorMessage( + "Overloaded function implementation cannot produce return type of signature {}" +) +OPERATOR_METHOD_SIGNATURE_OVERLAP: Final = ErrorMessage( + 'Signatures of "{}" of "{}" and "{}" of {} are unsafely overlapping' +) +FORWARD_OPERATOR_NOT_CALLABLE: Final = ErrorMessage('Forward operator "{}" is not callable') +INCOMPATIBLE_SIGNATURES: Final = ErrorMessage('Signatures of "{}" and "{}" are incompatible') +INVALID_YIELD_FROM: Final = ErrorMessage('"yield from" can\'t be applied to {}') +INVALID_SIGNATURE: Final = ErrorMessage('Invalid signature {}') +INVALID_SIGNATURE_SPECIAL: Final = ErrorMessage('Invalid signature {} for "{}"') +UNSUPPORTED_TYPE_TYPE: Final = ErrorMessage('Cannot instantiate type "Type[{}]"') +REDUNDANT_CAST: Final = ErrorMessage("Redundant cast to {}", codes.REDUNDANT_CAST) +UNFOLLOWED_IMPORT: Final = ErrorMessage( + "{} becomes {} due to an unfollowed import", codes.NO_ANY_UNIMPORTED +) +ANNOTATION_NEEDED: Final = ErrorMessage('Need type {} for "{}"{}', codes.VAR_ANNOTATED) +NO_EXPLICIT_ANY: Final = ErrorMessage('Explicit "Any" is not allowed') +TYPEDDICT_MISSING_KEYS: Final = ErrorMessage("Missing {} for TypedDict {}", codes.TYPEDDICT_ITEM) +TYPEDDICT_EXTRA_KEYS: Final = ErrorMessage("Extra {} for TypedDict {}", codes.TYPEDDICT_ITEM) +TYPEDDICT_UNEXPECTED_KEYS: Final = ErrorMessage("Unexpected TypedDict {}") +TYPEDDICT_KEYS_MISMATCH: Final = ErrorMessage("Expected {} but found {}", codes.TYPEDDICT_ITEM) +TYPEDDICT_KEY_STRING_LITERAL_EXPECTED: Final = ErrorMessage( + "TypedDict key must be a string literal; expected one of {}" +) +TYPEDDICT_KEY_INVALID: Final = ErrorMessage( + '"{}" is not a valid TypedDict key; expected one of {}' +) +TYPEDDICT_UNKNOWN_KEY: Final = ErrorMessage('TypedDict {} has no key "{}"', codes.TYPEDDICT_ITEM) +TYPEDDICT_AMBIGUOUS_TYPE: Final = ErrorMessage( + "Type of TypedDict is ambiguous, could be any of ({})" +) +TYPEDDICT_CANNOT_DELETE_KEY: Final = ErrorMessage('TypedDict key "{}" cannot be deleted') +TYPEDDICT_NAMED_CANNOT_DELETE_KEY: Final = ErrorMessage( + 'Key "{}" of TypedDict {} cannot be deleted' +) +TYPEDDICT_INCONSISTENT_SETDEFAULT_ARGS: Final = ErrorMessage( + 'Argument 2 to "setdefault" of "TypedDict" has incompatible type {}; expected {}', + codes.TYPEDDICT_ITEM, +) +PARAMETERIZED_GENERICS_DISALLOWED: Final = ErrorMessage( + "Parameterized generics cannot be used with class or instance checks" +) +EXPR_HAS_ANY_TYPE: Final = ErrorMessage('Expression has type "Any"') +EXPR_CONTAINS_ANY_TYPE: Final = ErrorMessage('Expression type contains "Any" (has type {})') +INCORRECTLY_RETURNING_ANY: Final = ErrorMessage( + "Returning Any from function declared to return {}", codes.NO_ANY_RETURN +) +INVALID_EXIT_RETURN_TYPE: Final = ErrorMessage( + '"bool" is invalid as return type for "__exit__" that always returns False', codes.EXIT_RETURN +) +UNTYPED_DECORATOR_FUNCTION: Final = ErrorMessage( + "Function is untyped after decorator transformation" +) +DECORATED_TYPE_CONTAINS_ANY: Final = ErrorMessage( + 'Type of decorated function contains type "Any" ({})' +) +DECORATOR_MAKES_FUNCTION_UNTYPED: Final = ErrorMessage( + 'Untyped decorator makes function "{}" untyped' +) +CONCRETE_ONLY_ASSIGN: Final = ErrorMessage( + "Can only assign concrete classes to a variable of type {}" +) +EXPECTED_CONCRETE_CLASS: Final = ErrorMessage( + "Only concrete class can be given where {} is expected" +) +CANNOT_USE_FUNCTION_WITH_TYPE: Final = ErrorMessage("Cannot use {}() with {} type") +ISSUBCLASS_ONLY_NON_METHOD_PROTOCOL: Final = ErrorMessage( + "Only protocols that don't have non-method members can be used with issubclass()" +) +UNREACHABLE_STATEMENT: Final = ErrorMessage("Statement is unreachable", codes.UNREACHABLE) +UNREACHABLE_RIGHT_OPERAND: Final = ErrorMessage( + 'Right operand of "{}" is never evaluated', codes.UNREACHABLE +) +EXPR_IS_ALWAYS_BOOL: Final = ErrorMessage("{} is always {}", codes.REDUNDANT_EXPR) +IMPOSSIBLE_SUBCLASS: Final = ErrorMessage("Subclass of {} cannot exist: would have {}") + # Semantic Analysis METHOD_ATLEAST_ONE_ARG: Final = ErrorMessage('Method must have at least one argument') OVERLOAD_IMPLEMENTATION_IN_STUB: Final = ErrorMessage( @@ -281,7 +663,7 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": ) NO_IMPLICIT_REEXPORT: Final = ErrorMessage( 'Module "{}" does not explicitly export attribute "{}"; implicit reexport disabled', - codes.ATTR_DEFINED + codes.ATTR_DEFINED, ) INCORRECT_RELATIVE_IMPORT: Final = ErrorMessage("Relative import climbs too many namespaces") INVALID_TYPE_ALIAS_TARGET: Final = ErrorMessage( @@ -399,8 +781,10 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": ) YIELD_OUTSIDE_FUNC: Final = ErrorMessage('"yield" outside function') YIELD_FROM_OUTSIDE_FUNC: Final = ErrorMessage('"yield from" outside function') +YIELD_IN_LISTCOMP_GENEXPR: Final = ErrorMessage('"yield" inside comprehension or generator expression') YIELD_IN_ASYNC_FUNC: Final = ErrorMessage('"yield" in async function') YIELD_FROM_IN_ASYNC_FUNC: Final = ErrorMessage('"yield from" in async function') +YIELD_FROM_IN_LISTCOMP_GENEXPR: Final = ErrorMessage('"yield from" inside comprehension or generator expression') CAST_TARGET_IS_NOT_TYPE: Final = ErrorMessage('Cast target is not a type') ANY_CALL_UNSUPPORTED: Final = ErrorMessage( 'Any(...) is no longer supported. Use cast(Any, ...) instead' @@ -414,7 +798,7 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": CANNOT_RESOLVE_NAME: Final = ErrorMessage('Cannot resolve {} "{}" (possible cyclic definition)') NAME_NOT_DEFINED: Final = ErrorMessage('Name "{}" is not defined', codes.NAME_DEFINED) NAME_ALREADY_DEFINED: Final = ErrorMessage('{} "{}" already defined{}', codes.NO_REDEF) - +UNSUPPORTED_CLASS_SCOPED_IMPORT: Final = ErrorMessage('Unsupported class scoped import') # Semantic Analysis: Enum ENUM_ATTRIBUTE_UNSUPPORTED: Final = ErrorMessage("Enum type as attribute is not supported") @@ -629,6 +1013,10 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": INVALID_TYPE_ALIAS: Final = ErrorMessage("Invalid type alias: expression is not a valid type") CANNOT_RESOLVE_TYPE: Final = ErrorMessage('Cannot resolve {} "{}" (possible cyclic definition)') UNION_SYNTAX_REQUIRES_PY310: Final = ErrorMessage("X | Y syntax for unions requires Python 3.10") +NO_BASE_CLASS_AFTER_ENUM: Final = ErrorMessage('No base classes are allowed after "{}"') +ENUM_MULTIPLE_DATA_MIXINS: Final = ErrorMessage( + 'Only a single data type mixin is allowed for Enum subtypes, found extra "{}"' +) # Super TOO_MANY_ARGS_FOR_SUPER: Final = ErrorMessage('Too many arguments for "super"') @@ -667,11 +1055,16 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": DEPENDENT_FINAL_IN_CLASS_BODY: Final = ErrorMessage( "Final name declared in class body cannot depend on type variables" ) -CANNOT_ACCESS_FINAL_INSTANCE_ATTR: Final = ( +CANNOT_ACCESS_FINAL_INSTANCE_ATTR: Final = ErrorMessage( 'Cannot access final instance attribute "{}" on class object' ) CANNOT_MAKE_DELETABLE_FINAL: Final = ErrorMessage("Deletable attribute cannot be final") +# Enum +ENUM_MEMBERS_ATTR_WILL_BE_OVERRIDEN: Final = ErrorMessage( + 'Assigned "__members__" will be overriden by "Enum" internally' +) + # ClassVar CANNOT_OVERRIDE_INSTANCE_VAR: Final = ErrorMessage( 'Cannot override instance variable (previously declared on base class "{}") with class ' @@ -698,16 +1091,95 @@ def format(self, *args: object, **kwargs: object) -> "ErrorMessage": TYPE_GUARD_POS_ARG_REQUIRED: Final = ErrorMessage("Type guard requires positional argument") # Match Statement -MISSING_MATCH_ARGS: Final = 'Class "{}" doesn\'t define "__match_args__"' -OR_PATTERN_ALTERNATIVE_NAMES: Final = "Alternative patterns bind different names" -CLASS_PATTERN_GENERIC_TYPE_ALIAS: Final = ( +MISSING_MATCH_ARGS: Final = ErrorMessage('Class "{}" doesn\'t define "__match_args__"') +OR_PATTERN_ALTERNATIVE_NAMES: Final = ErrorMessage("Alternative patterns bind different names") +CLASS_PATTERN_GENERIC_TYPE_ALIAS: Final = ErrorMessage( "Class pattern class must not be a type alias with type parameters" ) -CLASS_PATTERN_TYPE_REQUIRED: Final = 'Expected type in class pattern; found "{}"' -CLASS_PATTERN_TOO_MANY_POSITIONAL_ARGS: Final = "Too many positional patterns for class pattern" -CLASS_PATTERN_KEYWORD_MATCHES_POSITIONAL: Final = ( +CLASS_PATTERN_TYPE_REQUIRED: Final = ErrorMessage('Expected type in class pattern; found "{}"') +CLASS_PATTERN_TOO_MANY_POSITIONAL_ARGS: Final = ErrorMessage( + "Too many positional patterns for class pattern" +) +CLASS_PATTERN_KEYWORD_MATCHES_POSITIONAL: Final = ErrorMessage( 'Keyword "{}" already matches a positional pattern' ) -CLASS_PATTERN_DUPLICATE_KEYWORD_PATTERN: Final = 'Duplicate keyword pattern "{}"' -CLASS_PATTERN_UNKNOWN_KEYWORD: Final = 'Class "{}" has no attribute "{}"' -MULTIPLE_ASSIGNMENTS_IN_PATTERN: Final = 'Multiple assignments to name "{}" in pattern' +CLASS_PATTERN_DUPLICATE_KEYWORD_PATTERN: Final = ErrorMessage('Duplicate keyword pattern "{}"') +CLASS_PATTERN_UNKNOWN_KEYWORD: Final = ErrorMessage('Class "{}" has no attribute "{}"') +MULTIPLE_ASSIGNMENTS_IN_PATTERN: Final = ErrorMessage( + 'Multiple assignments to name "{}" in pattern' +) + +# Plugin: attrs +CANNOT_DETERMINE_INIT_TYPE: Final = ErrorMessage("Cannot determine __init__ type from converter") +CMP_WITH_EQ_AND_ORDER: Final = ErrorMessage('Don\'t mix "cmp" with "eq" and "order"') +EQ_TRUE_IF_ORDER_TRUE: Final = ErrorMessage("eq must be True if order is True") +ARG_MUST_BE_TRUE_OR_FALSE: Final = ErrorMessage('"{}" argument must be True or False.') +AUTO_ATTRIBS_UNSUPPORTED_PY2: Final = ErrorMessage("auto_attribs is not supported in Python 2") +ATTRS_NEWSTYLE_CLASS_ONLY: Final = ErrorMessage("attrs only works with new-style classes") +KW_ONLY_UNSUPPORTED_PY2: Final = ErrorMessage("kw_only is not supported in Python 2") +DEFAULT_WITH_FACTORY: Final = ErrorMessage('Can\'t pass both "default" and "factory".') +TYPE_INVALID_ARG: Final = ErrorMessage("Invalid argument to type") +NON_DEFAULT_ATTRS_AFTER_DEFAULT: Final = ErrorMessage( + "Non-default attributes not allowed after default attributes." +) +ATTR_TOO_MANY_NAMES: Final = ErrorMessage("Too many names for one attribute") +CONVERT_WITH_CONVERTER: Final = ErrorMessage('Can\'t pass both "convert" and "converter".') +CONVERT_DEPRECATED: Final = ErrorMessage("convert is deprecated, use converter") +UNSUPPORTED_CONVERTER: Final = ErrorMessage( + "Unsupported converter, only named functions and types are currently supported" +) + +# Plugin: functools +TOTAL_ORDERING_NO_OPERATOR_DEFINED: Final = ErrorMessage( + 'No ordering operation defined when using "functools.total_ordering": < > <= >=' +) + +# Plugin: dataclasses +DATACLASS_ORDER_METHODS_DISALLOWED: Final = ErrorMessage( + "You may not have a custom {} method when order=True" +) +DATACLASS_DEFAULT_ATTRS_BEFORE_NON_DEFAULT: Final = ErrorMessage( + "Attributes without a default cannot follow attributes with one" +) +DATACLASS_SINGLE_KW_ONLY_TYPE: Final = ErrorMessage( + "There may not be more than one field with the KW_ONLY type" +) +DATACLASS_UNPACKING_KWARGS_IN_FIELD: Final = ErrorMessage( + 'Unpacking **kwargs in "field()" is not supported' +) +DATACLASS_POS_ARG_IN_FIELD: Final = ErrorMessage('"field()" does not accept positional arguments') +DATACLASS_SLOTS_ABOVE_PY310: Final = ErrorMessage( + 'Keyword argument "slots" for "dataclass" is only valid in Python 3.10 and higher' +) +DATACLASS_SLOTS_CLASH: Final = ErrorMessage( + '"{}" both defines "__slots__" and is used with "slots=True"' +) + +# Plugin: ctypes +CTYPES_VALUE_WITH_CHAR_OR_WCHAR_ONLY: Final = ErrorMessage( + 'Array attribute "value" is only available with element type "c_char" or "c_wchar", not {}' +) +CTYPES_RAW_WITH_CHAR_ONLY: Final = ErrorMessage( + 'Array attribute "raw" is only available with element type "c_char", not {}' +) +CTYPES_INCOMPATIBLE_CONSTRUCTOR_ARG: Final = ErrorMessage( + "Array constructor argument {} of type {} is not convertible to the array element type {}" +) + +# Plugin: singledispatch +SINGLEDISPATCH_ATLEAST_ONE_ARG: Final = ErrorMessage( + "Singledispatch function requires at least one argument" +) +SINGLEDISPATCH_FIRST_ARG_POSITIONAL: Final = ErrorMessage( + "First argument to singledispatch function must be a positional argument" +) +DISPATCH_TYPE_FALLBACK_SUBTYPE: Final = ErrorMessage( + "Dispatch type {} must be subtype of fallback function first argument {}" +) + +# misc/proper_plugin.py +ISINSTANCE_ON_UNEXPANDED_TYPE: Final = ErrorMessage( + "Never apply isinstance() to unexpanded types; use mypy.types.get_proper_type() first" +) +REDUNDANT_GET_PROPER_TYPE: Final = ErrorMessage("Redundant call to get_proper_type()") +CANNOT_MODIFY_MATCH_ARGS: Final = ErrorMessage('Cannot assign to "__match_args__"') diff --git a/mypy/messages.py b/mypy/messages.py index 406237783cf1..886c92228ae1 100644 --- a/mypy/messages.py +++ b/mypy/messages.py @@ -39,8 +39,10 @@ IS_SETTABLE, IS_CLASSVAR, IS_CLASS_OR_STATIC, ) from mypy.sametypes import is_same_type +from mypy.typeops import separate_union_literals from mypy.util import unmangle from mypy.errorcodes import ErrorCode +from mypy.message_registry import ErrorMessage from mypy import message_registry, errorcodes as codes TYPES_FOR_UNIMPORTED_HINTS: Final = { @@ -189,15 +191,14 @@ def report(self, end_line=end_line, code=code, allow_dups=allow_dups) def fail(self, - msg: str, + msg: ErrorMessage, context: Optional[Context], *, - code: Optional[ErrorCode] = None, file: Optional[str] = None, origin: Optional[Context] = None, allow_dups: bool = False) -> None: """Report an error message (unless disabled).""" - self.report(msg, context, 'error', code=code, file=file, + self.report(msg.value, context, 'error', code=msg.code, file=file, origin=origin, allow_dups=allow_dups) def note(self, @@ -257,10 +258,10 @@ def has_no_attr(self, if (isinstance(original_type, Instance) and original_type.type.has_readable_member(member)): - self.fail('Member "{}" is not assignable'.format(member), context) + self.fail(message_registry.MEMBER_NOT_ASSIGNABLE.format(member), context) elif member == '__contains__': - self.fail('Unsupported right operand type for in ({})'.format( - format_type(original_type)), context, code=codes.OPERATOR) + self.fail(message_registry.UNSUPPORTED_OPERAND_FOR_IN.format( + format_type(original_type)), context) elif member in op_methods.values(): # Access to a binary operator member (e.g. _add). This case does # not handle indexing operations. @@ -269,36 +270,36 @@ def has_no_attr(self, self.unsupported_left_operand(op, original_type, context) break elif member == '__neg__': - self.fail('Unsupported operand type for unary - ({})'.format( - format_type(original_type)), context, code=codes.OPERATOR) + self.fail(message_registry.UNSUPPORTED_OPERAND_FOR_UNARY_MINUS.format( + format_type(original_type)), context) elif member == '__pos__': - self.fail('Unsupported operand type for unary + ({})'.format( - format_type(original_type)), context, code=codes.OPERATOR) + self.fail(message_registry.UNSUPPORTED_OPERAND_FOR_UNARY_PLUS.format( + format_type(original_type)), context) elif member == '__invert__': - self.fail('Unsupported operand type for ~ ({})'.format( - format_type(original_type)), context, code=codes.OPERATOR) + self.fail(message_registry.UNSUPPORTED_OPERAND_FOR_INVERT.format( + format_type(original_type)), context) elif member == '__getitem__': # Indexed get. # TODO: Fix this consistently in format_type if isinstance(original_type, CallableType) and original_type.is_type_obj(): - self.fail('The type {} is not generic and not indexable'.format( + self.fail(message_registry.TYPE_NOT_GENERIC_OR_INDEXABLE.format( format_type(original_type)), context) else: - self.fail('Value of type {} is not indexable'.format( - format_type(original_type)), context, code=codes.INDEX) + self.fail(message_registry.TYPE_NOT_INDEXABLE.format( + format_type(original_type)), context) elif member == '__setitem__': # Indexed set. - self.fail('Unsupported target for indexed assignment ({})'.format( - format_type(original_type)), context, code=codes.INDEX) + self.fail(message_registry.UNSUPPORTED_TARGET_INDEXED_ASSIGNMENT.format( + format_type(original_type)), context) elif member == '__call__': if isinstance(original_type, Instance) and \ (original_type.type.fullname == 'builtins.function'): # "'function' not callable" is a confusing error message. # Explain that the problem is that the type of the function is not known. - self.fail('Cannot call function of unknown type', context, code=codes.OPERATOR) + self.fail(message_registry.CALLING_FUNCTION_OF_UNKNOWN_TYPE, context) else: - self.fail(message_registry.NOT_CALLABLE.format( - format_type(original_type)), context, code=codes.OPERATOR) + self.fail(message_registry.TYPE_NOT_CALLABLE.format(format_type(original_type)), + context) else: # The non-special case: a missing ordinary attribute. extra = '' @@ -328,21 +329,19 @@ def has_no_attr(self, matches = [] if matches: self.fail( - '{} has no attribute "{}"; maybe {}?{}'.format( + message_registry.TYPE_HAS_NO_ATTRIBUTE_X_MAYBE_Y.format( format_type(original_type), member, pretty_seq(matches, "or"), extra, ), - context, - code=codes.ATTR_DEFINED) + context) failed = True if not failed: self.fail( - '{} has no attribute "{}"{}'.format( + message_registry.TYPE_HAS_NO_ATTRIBUTE_X.format( format_type(original_type), member, extra), - context, - code=codes.ATTR_DEFINED) + context) elif isinstance(original_type, UnionType): # The checker passes "object" in lieu of "None" for attribute # checks, so we manually convert it back. @@ -350,28 +349,24 @@ def has_no_attr(self, if typ_format == '"object"' and \ any(type(item) == NoneType for item in original_type.items): typ_format = '"None"' - self.fail('Item {} of {} has no attribute "{}"{}'.format( - typ_format, orig_type_format, member, extra), context, - code=codes.UNION_ATTR) + self.fail(message_registry.ITEM_HAS_NO_ATTRIBUTE_X.format( + typ_format, orig_type_format, member, extra), context) elif isinstance(original_type, TypeVarType): bound = get_proper_type(original_type.upper_bound) if isinstance(bound, UnionType): typ_fmt, bound_fmt = format_type_distinctly(typ, bound) original_type_fmt = format_type(original_type) self.fail( - 'Item {} of the upper bound {} of type variable {} has no ' - 'attribute "{}"{}'.format( + message_registry.TYPEVAR_UPPER_BOUND_HAS_NO_ATTRIBUTE.format( typ_fmt, bound_fmt, original_type_fmt, member, extra), - context, code=codes.UNION_ATTR) + context) return AnyType(TypeOfAny.from_error) def unsupported_operand_types(self, op: str, left_type: Any, right_type: Any, - context: Context, - *, - code: ErrorCode = codes.OPERATOR) -> None: + context: Context) -> None: """Report unsupported operand types for a binary operation. Types can be Type objects or strings. @@ -389,29 +384,26 @@ def unsupported_operand_types(self, right_str = format_type(right_type) if self.disable_type_names_count: - msg = 'Unsupported operand types for {} (likely involving Union)'.format(op) + msg = message_registry.UNSUPPORTED_OPERANDS_LIKELY_UNION.format(op) else: - msg = 'Unsupported operand types for {} ({} and {})'.format( - op, left_str, right_str) - self.fail(msg, context, code=code) + msg = message_registry.UNSUPPORTED_OPERANDS.format(op, left_str, right_str) + self.fail(msg, context) def unsupported_left_operand(self, op: str, typ: Type, context: Context) -> None: if self.disable_type_names_count: - msg = 'Unsupported left operand type for {} (some union)'.format(op) + msg = message_registry.UNSUPPORTED_LEFT_OPERAND_TYPE_UNION.format(op) else: - msg = 'Unsupported left operand type for {} ({})'.format( - op, format_type(typ)) - self.fail(msg, context, code=codes.OPERATOR) + msg = message_registry.UNSUPPORTED_LEFT_OPERAND_TYPE.format(op, format_type(typ)) + self.fail(msg, context) def not_callable(self, typ: Type, context: Context) -> Type: - self.fail(message_registry.NOT_CALLABLE.format(format_type(typ)), context) + self.fail(message_registry.TYPE_NOT_CALLABLE_2.format(format_type(typ)), context) return AnyType(TypeOfAny.from_error) def untyped_function_call(self, callee: CallableType, context: Context) -> Type: name = callable_name(callee) or '(unknown)' - self.fail('Call to untyped function {} in typed context'.format(name), context, - code=codes.NO_UNTYPED_CALL) + self.fail(message_registry.UNTYPED_FUNCTION_CALL.format(name), context) return AnyType(TypeOfAny.from_error) def incompatible_argument(self, @@ -450,50 +442,42 @@ def incompatible_argument(self, if name.startswith('"{}" of'.format(variant)): if op == 'in' or variant != method: # Reversed order of base/argument. - self.unsupported_operand_types(op, arg_type, base, - context, code=codes.OPERATOR) + self.unsupported_operand_types(op, arg_type, base, context) else: - self.unsupported_operand_types(op, base, arg_type, - context, code=codes.OPERATOR) + self.unsupported_operand_types(op, base, arg_type, context) return codes.OPERATOR if name.startswith('"__cmp__" of'): - self.unsupported_operand_types("comparison", arg_type, base, - context, code=codes.OPERATOR) - return codes.INDEX + self.unsupported_operand_types("comparison", arg_type, base, context) + return codes.OPERATOR if name.startswith('"__getitem__" of'): - self.invalid_index_type(arg_type, callee.arg_types[n - 1], base, context, - code=codes.INDEX) + self.invalid_index_type(arg_type, callee.arg_types[n - 1], base, context) return codes.INDEX if name.startswith('"__setitem__" of'): if n == 1: - self.invalid_index_type(arg_type, callee.arg_types[n - 1], base, context, - code=codes.INDEX) + self.invalid_index_type(arg_type, callee.arg_types[n - 1], base, context) return codes.INDEX else: - msg = '{} (expression has type {}, target has type {})' + msg = message_registry.TARGET_INCOMPATIBLE_TYPE arg_type_str, callee_type_str = format_type_distinctly(arg_type, callee.arg_types[n - 1]) self.fail(msg.format(message_registry.INCOMPATIBLE_TYPES_IN_ASSIGNMENT, arg_type_str, callee_type_str), - context, code=codes.ASSIGNMENT) + context) return codes.ASSIGNMENT target = 'to {} '.format(name) - msg = '' - code = codes.MISC notes: List[str] = [] if callee_name == '': name = callee_name[1:-1] n -= 1 actual_type_str, expected_type_str = format_type_distinctly(arg_type, callee.arg_types[0]) - msg = '{} item {} has incompatible type {}; expected {}'.format( + msg = message_registry.LIST_ITEM_INCOMPATIBLE_TYPE.format( name.title(), n, actual_type_str, expected_type_str) - code = codes.LIST_ITEM elif callee_name == '': name = callee_name[1:-1] n -= 1 @@ -514,34 +498,32 @@ def incompatible_argument(self, value_type_str, expected_value_type_str = format_type_distinctly( value_type, expected_value_type) - msg = '{} entry {} has incompatible type {}: {}; expected {}: {}'.format( + msg = message_registry.DICT_ENTRY_INCOMPATIBLE_TYPE.format( name.title(), n, key_type_str, value_type_str, expected_key_type_str, expected_value_type_str) - code = codes.DICT_ITEM elif callee_name == '': actual_type_str, expected_type_str = map(strip_quotes, format_type_distinctly(arg_type, callee.arg_types[0])) - msg = 'List comprehension has incompatible type List[{}]; expected List[{}]'.format( + msg = message_registry.LIST_COMP_INCOMPATIBLE_TYPE.format( actual_type_str, expected_type_str) elif callee_name == '': actual_type_str, expected_type_str = map(strip_quotes, format_type_distinctly(arg_type, callee.arg_types[0])) - msg = 'Set comprehension has incompatible type Set[{}]; expected Set[{}]'.format( + msg = message_registry.SET_COMP_INCOMPATIBLE_TYPE.format( actual_type_str, expected_type_str) elif callee_name == '': actual_type_str, expected_type_str = format_type_distinctly(arg_type, callee.arg_types[n - 1]) - msg = ('{} expression in dictionary comprehension has incompatible type {}; ' - 'expected type {}').format( + msg = message_registry.DICT_COMP_INCOMPATIBLE_TYPE.format( 'Key' if n == 1 else 'Value', actual_type_str, expected_type_str) elif callee_name == '': actual_type_str, expected_type_str = format_type_distinctly(arg_type, callee.arg_types[0]) - msg = 'Generator has incompatible item type {}; expected {}'.format( + msg = message_registry.GENERATOR_INCOMPATIBLE_TYPE.format( actual_type_str, expected_type_str) else: try: @@ -574,19 +556,23 @@ def incompatible_argument(self, expected_type, bare=True) arg_label = '"{}"'.format(arg_name) + object_type = get_proper_type(object_type) if isinstance(outer_context, IndexExpr) and isinstance(outer_context.index, StrExpr): - msg = 'Value of "{}" has incompatible type {}; expected {}' .format( + if isinstance(object_type, TypedDictType): + msg = message_registry.TYPEDDICT_VALUE_INCOMPATIBLE_TYPE + else: + msg = message_registry.VALUE_INCOMPATIBLE_TYPE + msg = msg.format( outer_context.index.value, quote_type_string(arg_type_str), quote_type_string(expected_type_str)) else: - msg = 'Argument {} {}has incompatible type {}; expected {}'.format( + if isinstance(object_type, TypedDictType): + msg = message_registry.TYPEDDICT_ARGUMENT_INCOMPATIBLE_TYPE + else: + msg = message_registry.ARGUMENT_INCOMPATIBLE_TYPE + msg = msg.format( arg_label, target, quote_type_string(arg_type_str), quote_type_string(expected_type_str)) - object_type = get_proper_type(object_type) - if isinstance(object_type, TypedDictType): - code = codes.TYPEDDICT_ITEM - else: - code = codes.ARG_TYPE expected_type = get_proper_type(expected_type) if isinstance(expected_type, UnionType): expected_types = list(expected_type.items) @@ -595,11 +581,11 @@ def incompatible_argument(self, for type in get_proper_types(expected_types): if isinstance(arg_type, Instance) and isinstance(type, Instance): notes = append_invariance_notes(notes, arg_type, type) - self.fail(msg, context, code=code) + self.fail(msg, context) if notes: for note_msg in notes: - self.note(note_msg, context, code=code) - return code + self.note(note_msg, context, code=msg.code) + return msg.code def incompatible_argument_note(self, original_caller_type: ProperType, @@ -624,10 +610,10 @@ def incompatible_argument_note(self, self.note_call(original_caller_type, call, context, code=code) def invalid_index_type(self, index_type: Type, expected_type: Type, base_str: str, - context: Context, *, code: ErrorCode) -> None: + context: Context) -> None: index_str, expected_str = format_type_distinctly(index_type, expected_type) - self.fail('Invalid index type {} for {}; expected type {}'.format( - index_str, base_str, expected_str), context, code=code) + self.fail(message_registry.INVALID_INDEX_TYPE.format( + index_str, base_str, expected_str), context) def too_few_arguments(self, callee: CallableType, context: Context, argument_names: Optional[Sequence[Optional[str]]]) -> None: @@ -648,15 +634,15 @@ def too_few_arguments(self, callee: CallableType, context: Context, else: msg = 'Too few arguments' + for_function(callee) - self.fail(msg, context, code=codes.CALL_ARG) + self.fail(ErrorMessage(msg, codes.CALL_ARG), context) def missing_named_argument(self, callee: CallableType, context: Context, name: str) -> None: msg = 'Missing named argument "{}"'.format(name) + for_function(callee) - self.fail(msg, context, code=codes.CALL_ARG) + self.fail(ErrorMessage(msg, codes.CALL_ARG), context) def too_many_arguments(self, callee: CallableType, context: Context) -> None: msg = 'Too many arguments' + for_function(callee) - self.fail(msg, context, code=codes.CALL_ARG) + self.fail(ErrorMessage(msg, codes.CALL_ARG), context) self.maybe_note_about_special_args(callee, context) def too_many_arguments_from_typed_dict(self, @@ -671,12 +657,12 @@ def too_many_arguments_from_typed_dict(self, else: self.too_many_arguments(callee, context) return - self.fail(msg, context) + self.fail(ErrorMessage(msg), context) def too_many_positional_arguments(self, callee: CallableType, context: Context) -> None: msg = 'Too many positional arguments' + for_function(callee) - self.fail(msg, context) + self.fail(ErrorMessage(msg), context) self.maybe_note_about_special_args(callee, context) def maybe_note_about_special_args(self, callee: CallableType, context: Context) -> None: @@ -708,7 +694,7 @@ def unexpected_keyword_argument(self, callee: CallableType, name: str, arg_type: matches = best_matches(name, not_matching_type_args) if matches: msg += "; did you mean {}?".format(pretty_seq(matches[:3], "or")) - self.fail(msg, context, code=codes.CALL_ARG) + self.fail(ErrorMessage(msg, codes.CALL_ARG), context) module = find_defining_module(self.modules, callee) if module: assert callee.definition is not None @@ -720,7 +706,7 @@ def unexpected_keyword_argument(self, callee: CallableType, name: str, arg_type: def duplicate_argument_value(self, callee: CallableType, index: int, context: Context) -> None: - self.fail('{} gets multiple values for keyword argument "{}"'. + self.fail(message_registry.MULTIPLE_VALUES_FOR_KWARG. format(callable_name(callee) or 'Function', callee.arg_names[index]), context) @@ -731,13 +717,12 @@ def does_not_return_value(self, callee_type: Optional[Type], context: Context) - if isinstance(callee_type, FunctionLike): name = callable_name(callee_type) if name is not None: - self.fail('{} does not return a value'.format(capitalize(name)), context, - code=codes.FUNC_RETURNS_VALUE) + self.fail(message_registry.NO_RETURN_VALUE.format(capitalize(name)), context) else: - self.fail('Function does not return a value', context, code=codes.FUNC_RETURNS_VALUE) + self.fail(message_registry.FUNCTION_NO_RETURN_VALUE, context) def underscore_function_call(self, context: Context) -> None: - self.fail('Calling function named "_" is not allowed', context) + self.fail(message_registry.UNDERSCORE_FUNCTION_CALL, context) def deleted_as_rvalue(self, typ: DeletedType, context: Context) -> None: """Report an error about using an deleted type as an rvalue.""" @@ -745,7 +730,7 @@ def deleted_as_rvalue(self, typ: DeletedType, context: Context) -> None: s = "" else: s = ' "{}"'.format(typ.source) - self.fail('Trying to read deleted variable{}'.format(s), context) + self.fail(message_registry.READING_DELETED_VALUE.format(s), context) def deleted_as_lvalue(self, typ: DeletedType, context: Context) -> None: """Report an error about using an deleted type as an lvalue. @@ -757,7 +742,7 @@ def deleted_as_lvalue(self, typ: DeletedType, context: Context) -> None: s = "" else: s = ' "{}"'.format(typ.source) - self.fail('Assignment to variable{} outside except: block'.format(s), context) + self.fail(message_registry.ASSIGNMENT_OUTSIDE_EXCEPT.format(s), context) def no_variant_matches_arguments(self, overload: Overloaded, @@ -774,14 +759,14 @@ def no_variant_matches_arguments(self, arg_types_str = ', '.join(format_type(arg) for arg in arg_types) num_args = len(arg_types) if num_args == 0: - self.fail('All overload variants{} require at least one argument'.format(name_str), - context, code=code) + msg = 'All overload variants{} require at least one argument'.format(name_str) + self.fail(ErrorMessage(msg, code), context) elif num_args == 1: - self.fail('No overload variant{} matches argument type {}' - .format(name_str, arg_types_str), context, code=code) + msg = 'No overload variant{} matches argument type {}'.format(name_str, arg_types_str) + self.fail(ErrorMessage(msg, code), context) else: - self.fail('No overload variant{} matches argument types {}' - .format(name_str, arg_types_str), context, code=code) + msg = 'No overload variant{} matches argument types {}'.format(name_str, arg_types_str) + self.fail(ErrorMessage(msg, code), context) self.note( 'Possible overload variant{}:'.format(plural_s(len(overload.items))), @@ -793,32 +778,31 @@ def wrong_number_values_to_unpack(self, provided: int, expected: int, context: Context) -> None: if provided < expected: if provided == 1: - self.fail('Need more than 1 value to unpack ({} expected)'.format(expected), + self.fail(message_registry.UNPACK_MORE_THAN_ONE_VALUE_NEEDED.format(expected), context) else: - self.fail('Need more than {} values to unpack ({} expected)'.format( + self.fail(message_registry.UNPACK_TOO_FEW_VALUES.format( provided, expected), context) elif provided > expected: - self.fail('Too many values to unpack ({} expected, {} provided)'.format( + self.fail(message_registry.UNPACK_TOO_MANY_VALUES.format( expected, provided), context) def unpacking_strings_disallowed(self, context: Context) -> None: - self.fail("Unpacking a string is disallowed", context) + self.fail(message_registry.UNPACKING_STRINGS_DISALLOWED, context) def type_not_iterable(self, type: Type, context: Context) -> None: - self.fail('{} object is not iterable'.format(format_type(type)), context) + self.fail(message_registry.TYPE_NOT_ITERABLE.format(format_type(type)), context) def incompatible_operator_assignment(self, op: str, context: Context) -> None: - self.fail('Result type of {} incompatible in assignment'.format(op), - context) + self.fail(message_registry.INCOMPATIBLE_OPERATOR_ASSIGNMENT.format(op), context) def overload_signature_incompatible_with_supertype( self, name: str, name_in_super: str, supertype: str, context: Context) -> None: target = self.override_target(name, name_in_super, supertype) - self.fail('Signature of "{}" incompatible with {}'.format( - name, target), context, code=codes.OVERRIDE) + self.fail(message_registry.OVERLOAD_SIGNATURE_INCOMPATIBLE.format( + name, target), context) note_template = 'Overload variants must be defined in the same order as they are in "{}"' self.note(note_template.format(supertype), context, code=codes.OVERRIDE) @@ -829,8 +813,8 @@ def signature_incompatible_with_supertype( override: Optional[FunctionLike] = None) -> None: code = codes.OVERRIDE target = self.override_target(name, name_in_super, supertype) - self.fail('Signature of "{}" incompatible with {}'.format( - name, target), context, code=code) + self.fail(message_registry.SIGNATURE_INCOMPATIBLE_WITH_SUPERTYPE.format( + name, target), context) INCLUDE_DECORATOR = True # Include @classmethod and @staticmethod decorators, if any ALLOW_DUPS = True # Allow duplicate notes, needed when signatures are duplicates @@ -879,11 +863,9 @@ def argument_incompatible_with_supertype( context: Context) -> None: target = self.override_target(name, name_in_supertype, supertype) arg_type_in_supertype_f = format_type_bare(arg_type_in_supertype) - self.fail('Argument {} of "{}" is incompatible with {}; ' - 'supertype defines the argument type as "{}"' + self.fail(message_registry.ARG_INCOMPATIBLE_WITH_SUPERTYPE .format(arg_num, name, target, arg_type_in_supertype_f), - context, - code=codes.OVERRIDE) + context) self.note( 'This violates the Liskov substitution principle', context, @@ -912,10 +894,9 @@ def return_type_incompatible_with_supertype( context: Context) -> None: target = self.override_target(name, name_in_supertype, supertype) override_str, original_str = format_type_distinctly(override, original) - self.fail('Return type {} of "{}" incompatible with return type {} in {}' + self.fail(message_registry.RETURNTYPE_INCOMPATIBLE_WITH_SUPERTYPE .format(override_str, name, original_str, target), - context, - code=codes.OVERRIDE) + context) def override_target(self, name: str, name_in_super: str, supertype: str) -> str: @@ -928,40 +909,39 @@ def incompatible_type_application(self, expected_arg_count: int, actual_arg_count: int, context: Context) -> None: if expected_arg_count == 0: - self.fail('Type application targets a non-generic function or class', + self.fail(message_registry.TYPE_APPLICATION_ON_NON_GENERIC_TYPE, context) elif actual_arg_count > expected_arg_count: - self.fail('Type application has too many types ({} expected)' + self.fail(message_registry.TYPE_APPLICATION_TOO_MANY_TYPES .format(expected_arg_count), context) else: - self.fail('Type application has too few types ({} expected)' + self.fail(message_registry.TYPE_APPLICATION_TOO_FEW_TYPES .format(expected_arg_count), context) def could_not_infer_type_arguments(self, callee_type: CallableType, n: int, context: Context) -> None: callee_name = callable_name(callee_type) if callee_name is not None and n > 0: - self.fail('Cannot infer type argument {} of {}'.format(n, callee_name), context) + self.fail(message_registry.CANNOT_INFER_TYPE_ARG_NAMED_FUNC.format(n, callee_name), + context) else: - self.fail('Cannot infer function type argument', context) + self.fail(message_registry.CANNOT_INFER_TYPE_ARG_FUNC, context) def invalid_var_arg(self, typ: Type, context: Context) -> None: - self.fail('List or tuple expected as variable arguments', context) + self.fail(message_registry.INVALID_VAR_ARGS, context) def invalid_keyword_var_arg(self, typ: Type, is_mapping: bool, context: Context) -> None: typ = get_proper_type(typ) if isinstance(typ, Instance) and is_mapping: - self.fail('Keywords must be strings', context) + self.fail(message_registry.KEYWORDS_MUST_BE_STRINGS, context) else: suffix = '' if isinstance(typ, Instance): suffix = ', not {}'.format(format_type(typ)) - self.fail( - 'Argument after ** must be a mapping{}'.format(suffix), - context, code=codes.ARG_TYPE) + self.fail(message_registry.ARG_MUST_BE_MAPPING.format(suffix), context) def undefined_in_superclass(self, member: str, context: Context) -> None: - self.fail('"{}" undefined in superclass'.format(member), context) + self.fail(message_registry.MEMBER_UNDEFINED_IN_SUPERCLASS.format(member), context) def first_argument_for_super_must_be_type(self, actual: Type, context: Context) -> None: actual = get_proper_type(actual) @@ -971,93 +951,81 @@ def first_argument_for_super_must_be_type(self, actual: Type, context: Context) type_str = 'a non-type instance' else: type_str = format_type(actual) - self.fail('Argument 1 for "super" must be a type object; got {}'.format(type_str), context, - code=codes.ARG_TYPE) + self.fail(message_registry.SUPER_ARG_EXPECTED_TYPE.format(type_str), context) def too_few_string_formatting_arguments(self, context: Context) -> None: - self.fail('Not enough arguments for format string', context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.FORMAT_STR_TOO_FEW_ARGS, context) def too_many_string_formatting_arguments(self, context: Context) -> None: - self.fail('Not all arguments converted during string formatting', context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.FORMAT_STR_TOO_MANY_ARGS, context) def unsupported_placeholder(self, placeholder: str, context: Context) -> None: - self.fail('Unsupported format character "%s"' % placeholder, context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.FORMAT_STR_UNSUPPORTED_CHAR.format(placeholder), context) def string_interpolation_with_star_and_key(self, context: Context) -> None: - self.fail('String interpolation contains both stars and mapping keys', context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.STRING_INTERPOLATION_WITH_STAR_AND_KEY, context) def requires_int_or_single_byte(self, context: Context, format_call: bool = False) -> None: - self.fail('"{}c" requires an integer in range(256) or a single byte' + self.fail(message_registry.FORMAT_STR_INVALID_CHR_CONVERSION_RANGE .format(':' if format_call else '%'), - context, code=codes.STRING_FORMATTING) + context) def requires_int_or_char(self, context: Context, format_call: bool = False) -> None: - self.fail('"{}c" requires int or char'.format(':' if format_call else '%'), - context, code=codes.STRING_FORMATTING) + self.fail(message_registry.FORMAT_STR_INVALID_CHR_CONVERSION + .format(':' if format_call else '%'), + context) def key_not_in_mapping(self, key: str, context: Context) -> None: - self.fail('Key "%s" not found in mapping' % key, context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.KEY_NOT_IN_MAPPING.format(key), context) def string_interpolation_mixing_key_and_non_keys(self, context: Context) -> None: - self.fail('String interpolation mixes specifier with and without mapping keys', context, - code=codes.STRING_FORMATTING) + self.fail(message_registry.FORMAT_STR_MIXED_KEYS_AND_NON_KEYS, context) def cannot_determine_type(self, name: str, context: Context) -> None: - self.fail('Cannot determine type of "%s"' % name, context, code=codes.HAS_TYPE) + self.fail(message_registry.CANNOT_DETERMINE_TYPE.format(name), context) def cannot_determine_type_in_base(self, name: str, base: str, context: Context) -> None: - self.fail('Cannot determine type of "%s" in base class "%s"' % (name, base), context) + self.fail(message_registry.CANNOT_DETERMINE_TYPE_IN_BASE.format(name, base), context) def no_formal_self(self, name: str, item: CallableType, context: Context) -> None: - self.fail('Attribute function "%s" with type %s does not accept self argument' - % (name, format_type(item)), context) + self.fail(message_registry.DOES_NOT_ACCEPT_SELF.format(name, format_type(item)), context) def incompatible_self_argument(self, name: str, arg: Type, sig: CallableType, is_classmethod: bool, context: Context) -> None: kind = 'class attribute function' if is_classmethod else 'attribute function' - self.fail('Invalid self argument %s to %s "%s" with type %s' - % (format_type(arg), kind, name, format_type(sig)), context) + self.fail(message_registry.INCOMPATIBLE_SELF_ARG + .format(format_type(arg), kind, name, format_type(sig)), context) def incompatible_conditional_function_def(self, defn: FuncDef) -> None: - self.fail('All conditional function variants must have identical ' - 'signatures', defn) + self.fail(message_registry.INCOMPATIBLE_CONDITIONAL_FUNCS, defn) def cannot_instantiate_abstract_class(self, class_name: str, abstract_attributes: List[str], context: Context) -> None: attrs = format_string_list(['"%s"' % a for a in abstract_attributes]) - self.fail('Cannot instantiate abstract class "%s" with abstract ' - 'attribute%s %s' % (class_name, plural_s(abstract_attributes), - attrs), - context, code=codes.ABSTRACT) + self.fail(message_registry.CANNOT_INSTANTIATE_ABSTRACT_CLASS + .format(class_name, plural_s(abstract_attributes), attrs), + context) def base_class_definitions_incompatible(self, name: str, base1: TypeInfo, base2: TypeInfo, context: Context) -> None: - self.fail('Definition of "{}" in base class "{}" is incompatible ' - 'with definition in base class "{}"'.format( + self.fail(message_registry.INCOMPATIBLE_BASE_CLASS_DEFNS.format( name, base1.name, base2.name), context) def cant_assign_to_method(self, context: Context) -> None: - self.fail(message_registry.CANNOT_ASSIGN_TO_METHOD, context, - code=codes.ASSIGNMENT) + self.fail(message_registry.CANNOT_ASSIGN_TO_METHOD, context) def cant_assign_to_classvar(self, name: str, context: Context) -> None: - self.fail('Cannot assign to class variable "%s" via instance' % name, context) + self.fail(message_registry.CANNOT_ASSIGN_TO_CLASSVAR.format(name), context) def final_cant_override_writable(self, name: str, ctx: Context) -> None: - self.fail('Cannot override writable attribute "{}" with a final one'.format(name), ctx) + self.fail(message_registry.CANNOT_OVERRIDE_TO_FINAL.format(name), ctx) def cant_override_final(self, name: str, base_name: str, ctx: Context) -> None: - self.fail('Cannot override final attribute "{}"' - ' (previously declared in base class "{}")'.format(name, base_name), ctx) + self.fail(message_registry.CANNOT_OVERRIDE_FINAL.format(name, base_name), ctx) def cant_assign_to_final(self, name: str, attr_assign: bool, ctx: Context) -> None: """Warn about a prohibited assignment to a final attribute. @@ -1065,17 +1033,17 @@ def cant_assign_to_final(self, name: str, attr_assign: bool, ctx: Context) -> No Pass `attr_assign=True` if the assignment assigns to an attribute. """ kind = "attribute" if attr_assign else "name" - self.fail('Cannot assign to final {} "{}"'.format(kind, unmangle(name)), ctx) + self.fail(message_registry.CANNOT_ASSIGN_TO_FINAL.format(kind, unmangle(name)), ctx) def protocol_members_cant_be_final(self, ctx: Context) -> None: - self.fail("Protocol member cannot be final", ctx) + self.fail(message_registry.PROTOCOL_MEMBER_CANNOT_BE_FINAL, ctx) def final_without_value(self, ctx: Context) -> None: - self.fail("Final name must be initialized with a value", ctx) + self.fail(message_registry.FINAL_WITHOUT_VALUE, ctx) def read_only_property(self, name: str, type: TypeInfo, context: Context) -> None: - self.fail('Property "{}" defined in "{}" is read-only'.format( + self.fail(message_registry.PROPERTY_IS_READ_ONLY.format( name, type.name), context) def incompatible_typevar_value(self, @@ -1085,47 +1053,36 @@ def incompatible_typevar_value(self, context: Context) -> None: self.fail(message_registry.INCOMPATIBLE_TYPEVAR_VALUE .format(typevar_name, callable_name(callee) or 'function', format_type(typ)), - context, - code=codes.TYPE_VAR) + context) def dangerous_comparison(self, left: Type, right: Type, kind: str, ctx: Context) -> None: left_str = 'element' if kind == 'container' else 'left operand' right_str = 'container item' if kind == 'container' else 'right operand' - message = 'Non-overlapping {} check ({} type: {}, {} type: {})' + message = message_registry.NON_OVERLAPPING_COMPARISON left_typ, right_typ = format_type_distinctly(left, right) - self.fail(message.format(kind, left_str, left_typ, right_str, right_typ), ctx, - code=codes.COMPARISON_OVERLAP) + self.fail(message.format(kind, left_str, left_typ, right_str, right_typ), ctx) def overload_inconsistently_applies_decorator(self, decorator: str, context: Context) -> None: - self.fail( - 'Overload does not consistently use the "@{}" '.format(decorator) - + 'decorator on all function signatures.', - context) + self.fail(message_registry.OVERLOAD_INCONSISTENT_DECORATOR_USE.format(decorator), context) def overloaded_signatures_overlap(self, index1: int, index2: int, context: Context) -> None: - self.fail('Overloaded function signatures {} and {} overlap with ' - 'incompatible return types'.format(index1, index2), context) + self.fail(message_registry.OVERLOAD_INCOMPATIBLE_RETURN_TYPES.format(index1, index2), + context) def overloaded_signature_will_never_match(self, index1: int, index2: int, context: Context) -> None: - self.fail( - 'Overloaded function signature {index2} will never be matched: ' - 'signature {index1}\'s parameter type(s) are the same or broader'.format( - index1=index1, - index2=index2), - context) + self.fail(message_registry.OVERLOAD_SIGNATURE_WILL_NEVER_MATCH + .format(index1=index1, index2=index2), + context) def overloaded_signatures_typevar_specific(self, index: int, context: Context) -> None: - self.fail('Overloaded function implementation cannot satisfy signature {} '.format(index) + - 'due to inconsistencies in how they use type variables', context) + self.fail(message_registry.OVERLOAD_INCONSISTENT_TYPEVARS.format(index), context) def overloaded_signatures_arg_specific(self, index: int, context: Context) -> None: - self.fail('Overloaded function implementation does not accept all possible arguments ' - 'of signature {}'.format(index), context) + self.fail(message_registry.OVERLOAD_INCONSISTENT_ARGS.format(index), context) def overloaded_signatures_ret_specific(self, index: int, context: Context) -> None: - self.fail('Overloaded function implementation cannot produce return type ' - 'of signature {}'.format(index), context) + self.fail(message_registry.OVERLOAD_INCONSISTENT_RETURN_TYPE.format(index), context) def warn_both_operands_are_from_unions(self, context: Context) -> None: self.note('Both left and right operands are unions', context, code=codes.OPERATOR) @@ -1137,34 +1094,33 @@ def warn_operand_was_from_union(self, side: str, original: Type, context: Contex def operator_method_signatures_overlap( self, reverse_class: TypeInfo, reverse_method: str, forward_class: Type, forward_method: str, context: Context) -> None: - self.fail('Signatures of "{}" of "{}" and "{}" of {} ' - 'are unsafely overlapping'.format( + self.fail(message_registry.OPERATOR_METHOD_SIGNATURE_OVERLAP.format( reverse_method, reverse_class.name, forward_method, format_type(forward_class)), context) def forward_operator_not_callable( self, forward_method: str, context: Context) -> None: - self.fail('Forward operator "{}" is not callable'.format( + self.fail(message_registry.FORWARD_OPERATOR_NOT_CALLABLE.format( forward_method), context) def signatures_incompatible(self, method: str, other_method: str, context: Context) -> None: - self.fail('Signatures of "{}" and "{}" are incompatible'.format( + self.fail(message_registry.INCOMPATIBLE_SIGNATURES.format( method, other_method), context) def yield_from_invalid_operand_type(self, expr: Type, context: Context) -> Type: text = format_type(expr) if format_type(expr) != 'object' else expr - self.fail('"yield from" can\'t be applied to {}'.format(text), context) + self.fail(message_registry.INVALID_YIELD_FROM.format(text), context) return AnyType(TypeOfAny.from_error) def invalid_signature(self, func_type: Type, context: Context) -> None: - self.fail('Invalid signature {}'.format(format_type(func_type)), context) + self.fail(message_registry.INVALID_SIGNATURE.format(format_type(func_type)), context) def invalid_signature_for_special_method( self, func_type: Type, context: Context, method_name: str) -> None: - self.fail('Invalid signature {} for "{}"'.format(format_type(func_type), method_name), - context) + self.fail(message_registry.INVALID_SIGNATURE_SPECIAL.format( + format_type(func_type), method_name), context) def reveal_type(self, typ: Type, context: Context) -> None: self.note('Revealed type is "{}"'.format(typ), context) @@ -1178,15 +1134,13 @@ def reveal_locals(self, type_map: Dict[str, Optional[Type]], context: Context) - self.note(line, context) def unsupported_type_type(self, item: Type, context: Context) -> None: - self.fail('Cannot instantiate type "Type[{}]"'.format(format_type_bare(item)), context) + self.fail(message_registry.UNSUPPORTED_TYPE_TYPE.format(format_type_bare(item)), context) def redundant_cast(self, typ: Type, context: Context) -> None: - self.fail('Redundant cast to {}'.format(format_type(typ)), context, - code=codes.REDUNDANT_CAST) + self.fail(message_registry.REDUNDANT_CAST.format(format_type(typ)), context) def unimported_type_becomes_any(self, prefix: str, typ: Type, ctx: Context) -> None: - self.fail("{} becomes {} due to an unfollowed import".format(prefix, format_type(typ)), - ctx, code=codes.NO_ANY_UNIMPORTED) + self.fail(message_registry.UNFOLLOWED_IMPORT.format(prefix, format_type(typ)), ctx) def need_annotation_for_var(self, node: SymbolNode, context: Context, python_version: Optional[Tuple[int, int]] = None) -> None: @@ -1210,11 +1164,11 @@ def need_annotation_for_var(self, node: SymbolNode, context: Context, else: needed = 'comment' - self.fail('Need type {} for "{}"{}'.format(needed, unmangle(node.name), hint), context, - code=codes.VAR_ANNOTATED) + self.fail(message_registry.ANNOTATION_NEEDED.format(needed, unmangle(node.name), hint), + context) def explicit_any(self, ctx: Context) -> None: - self.fail('Explicit "Any" is not allowed', ctx) + self.fail(message_registry.NO_EXPLICIT_ANY, ctx) def unexpected_typeddict_keys( self, @@ -1229,36 +1183,34 @@ def unexpected_typeddict_keys( if actual_set < expected_set: # Use list comprehension instead of set operations to preserve order. missing = [key for key in expected_keys if key not in actual_set] - self.fail('Missing {} for TypedDict {}'.format( + self.fail(message_registry.TYPEDDICT_MISSING_KEYS.format( format_key_list(missing, short=True), format_type(typ)), - context, code=codes.TYPEDDICT_ITEM) + context) return else: extra = [key for key in actual_keys if key not in expected_set] if extra: # If there are both extra and missing keys, only report extra ones for # simplicity. - self.fail('Extra {} for TypedDict {}'.format( + self.fail(message_registry.TYPEDDICT_EXTRA_KEYS.format( format_key_list(extra, short=True), format_type(typ)), - context, code=codes.TYPEDDICT_ITEM) + context) return found = format_key_list(actual_keys, short=True) if not expected_keys: - self.fail('Unexpected TypedDict {}'.format(found), context) + self.fail(message_registry.TYPEDDICT_UNEXPECTED_KEYS.format(found), context) return expected = format_key_list(expected_keys) if actual_keys and actual_set < expected_set: found = 'only {}'.format(found) - self.fail('Expected {} but found {}'.format(expected, found), context, - code=codes.TYPEDDICT_ITEM) + self.fail(message_registry.TYPEDDICT_KEYS_MISMATCH.format(expected, found), context) def typeddict_key_must_be_string_literal( self, typ: TypedDictType, context: Context) -> None: - self.fail( - 'TypedDict key must be a string literal; expected one of {}'.format( - format_item_name_list(typ.items.keys())), context, code=codes.LITERAL_REQ) + self.fail(message_registry.TYPEDDICT_KEY_STRING_LITERAL_EXPECTED.format( + format_item_name_list(typ.items.keys())), context) def typeddict_key_not_found( self, @@ -1266,11 +1218,11 @@ def typeddict_key_not_found( item_name: str, context: Context) -> None: if typ.is_anonymous(): - self.fail('"{}" is not a valid TypedDict key; expected one of {}'.format( + self.fail(message_registry.TYPEDDICT_KEY_INVALID.format( item_name, format_item_name_list(typ.items.keys())), context) else: - self.fail('TypedDict {} has no key "{}"'.format( - format_type(typ), item_name), context, code=codes.TYPEDDICT_ITEM) + self.fail(message_registry.TYPEDDICT_UNKNOWN_KEY.format( + format_type(typ), item_name), context) matches = best_matches(item_name, typ.items.keys()) if matches: self.note("Did you mean {}?".format( @@ -1281,7 +1233,7 @@ def typeddict_context_ambiguous( types: List[TypedDictType], context: Context) -> None: formatted_types = ', '.join(list(format_type_distinctly(*types))) - self.fail('Type of TypedDict is ambiguous, could be any of ({})'.format( + self.fail(message_registry.TYPEDDICT_AMBIGUOUS_TYPE.format( formatted_types), context) def typeddict_key_cannot_be_deleted( @@ -1290,10 +1242,10 @@ def typeddict_key_cannot_be_deleted( item_name: str, context: Context) -> None: if typ.is_anonymous(): - self.fail('TypedDict key "{}" cannot be deleted'.format(item_name), + self.fail(message_registry.TYPEDDICT_CANNOT_DELETE_KEY.format(item_name), context) else: - self.fail('Key "{}" of TypedDict {} cannot be deleted'.format( + self.fail(message_registry.TYPEDDICT_NAMED_CANNOT_DELETE_KEY.format( item_name, format_type(typ)), context) def typeddict_setdefault_arguments_inconsistent( @@ -1301,30 +1253,26 @@ def typeddict_setdefault_arguments_inconsistent( default: Type, expected: Type, context: Context) -> None: - msg = 'Argument 2 to "setdefault" of "TypedDict" has incompatible type {}; expected {}' - self.fail(msg.format(format_type(default), format_type(expected)), context, - code=codes.TYPEDDICT_ITEM) + msg = message_registry.TYPEDDICT_INCONSISTENT_SETDEFAULT_ARGS + self.fail(msg.format(format_type(default), format_type(expected)), context) def type_arguments_not_allowed(self, context: Context) -> None: - self.fail('Parameterized generics cannot be used with class or instance checks', context) + self.fail(message_registry.PARAMETERIZED_GENERICS_DISALLOWED, context) def disallowed_any_type(self, typ: Type, context: Context) -> None: typ = get_proper_type(typ) if isinstance(typ, AnyType): - message = 'Expression has type "Any"' + message = message_registry.EXPR_HAS_ANY_TYPE else: - message = 'Expression type contains "Any" (has type {})'.format(format_type(typ)) + message = message_registry.EXPR_CONTAINS_ANY_TYPE.format(format_type(typ)) self.fail(message, context) def incorrectly_returning_any(self, typ: Type, context: Context) -> None: - message = 'Returning Any from function declared to return {}'.format( - format_type(typ)) - self.fail(message, context, code=codes.NO_ANY_RETURN) + message = message_registry.INCORRECTLY_RETURNING_ANY.format(format_type(typ)) + self.fail(message, context) def incorrect__exit__return(self, context: Context) -> None: - self.fail( - '"bool" is invalid as return type for "__exit__" that always returns False', context, - code=codes.EXIT_RETURN) + self.fail(message_registry.INVALID_EXIT_RETURN_TYPE, context) self.note( 'Use "typing_extensions.Literal[False]" as the return type or change it to "None"', context, code=codes.EXIT_RETURN) @@ -1336,13 +1284,13 @@ def incorrect__exit__return(self, context: Context) -> None: def untyped_decorated_function(self, typ: Type, context: Context) -> None: typ = get_proper_type(typ) if isinstance(typ, AnyType): - self.fail("Function is untyped after decorator transformation", context) + self.fail(message_registry.UNTYPED_DECORATOR_FUNCTION, context) else: - self.fail('Type of decorated function contains type "Any" ({})'.format( + self.fail(message_registry.DECORATED_TYPE_CONTAINS_ANY.format( format_type(typ)), context) def typed_function_untyped_decorator(self, func_name: str, context: Context) -> None: - self.fail('Untyped decorator makes function "{}" untyped'.format(func_name), context) + self.fail(message_registry.DECORATOR_MAKES_FUNCTION_UNTYPED.format(func_name), context) def bad_proto_variance(self, actual: int, tvar_name: str, expected: int, context: Context) -> None: @@ -1350,24 +1298,23 @@ def bad_proto_variance(self, actual: int, tvar_name: str, expected: int, ' {} one is expected'.format(variance_string(actual), tvar_name, variance_string(expected))) - self.fail(msg, context) + self.fail(ErrorMessage(msg), context) def concrete_only_assign(self, typ: Type, context: Context) -> None: - self.fail("Can only assign concrete classes to a variable of type {}" - .format(format_type(typ)), context) + self.fail(message_registry.CONCRETE_ONLY_ASSIGN.format(format_type(typ)), context) def concrete_only_call(self, typ: Type, context: Context) -> None: - self.fail("Only concrete class can be given where {} is expected" + self.fail(message_registry.EXPECTED_CONCRETE_CLASS .format(format_type(typ)), context) def cannot_use_function_with_type( self, method_name: str, type_name: str, context: Context) -> None: - self.fail("Cannot use {}() with {} type".format(method_name, type_name), context) + self.fail(message_registry.CANNOT_USE_FUNCTION_WITH_TYPE.format(method_name, type_name), + context) def report_non_method_protocol(self, tp: TypeInfo, members: List[str], context: Context) -> None: - self.fail("Only protocols that don't have non-method members can be" - " used with issubclass()", context) + self.fail(message_registry.ISSUBCLASS_ONLY_NON_METHOD_PROTOCOL, context) if len(members) < 3: attrs = ', '.join(members) self.note('Protocol "{}" has non-method member(s): {}' @@ -1384,7 +1331,7 @@ def note_call(self, context, code=code) def unreachable_statement(self, context: Context) -> None: - self.fail("Statement is unreachable", context, code=codes.UNREACHABLE) + self.fail(message_registry.UNREACHABLE_STATEMENT, context) def redundant_left_operand(self, op_name: str, context: Context) -> None: """Indicates that the left operand of a boolean expression is redundant: @@ -1398,8 +1345,7 @@ def unreachable_right_operand(self, op_name: str, context: Context) -> None: it does not change the truth value of the entire condition as a whole. 'op_name' should either be the string "and" or the string "or". """ - self.fail('Right operand of "{}" is never evaluated'.format(op_name), - context, code=codes.UNREACHABLE) + self.fail(message_registry.UNREACHABLE_RIGHT_OPERAND.format(op_name), context) def redundant_condition_in_comprehension(self, truthiness: bool, context: Context) -> None: self.redundant_expr("If condition in comprehension", truthiness, context) @@ -1408,17 +1354,18 @@ def redundant_condition_in_if(self, truthiness: bool, context: Context) -> None: self.redundant_expr("If condition", truthiness, context) def redundant_expr(self, description: str, truthiness: bool, context: Context) -> None: - self.fail("{} is always {}".format(description, str(truthiness).lower()), - context, code=codes.REDUNDANT_EXPR) + self.fail(message_registry.EXPR_IS_ALWAYS_BOOL + .format(description, str(truthiness).lower()), + context) def impossible_intersection(self, formatted_base_class_list: str, reason: str, context: Context, ) -> None: - template = "Subclass of {} cannot exist: would have {}" - self.fail(template.format(formatted_base_class_list, reason), context, - code=codes.UNREACHABLE) + self.fail(message_registry.IMPOSSIBLE_SUBCLASS + .format(formatted_base_class_list, reason), + context) def report_protocol_problems(self, subtype: Union[Instance, TupleType, TypedDictType], @@ -1590,7 +1537,7 @@ def try_report_long_tuple_assignment_error(self, error_msg = "{} ({} {}, {} {})".format(msg, subtype_label, self.format_long_tuple_type(subtype), supertype_label, self.format_long_tuple_type(supertype)) - self.fail(error_msg, context, code=code) + self.fail(ErrorMessage(error_msg, code), context) return True self.generate_incompatible_tuple_error(supertype.items, subtype.items, context, msg, code) @@ -1628,7 +1575,7 @@ def generate_incompatible_tuple_error(self, error_msg += '; {} items are omitted)'.format(str(error_cnt - 3)) else: error_msg += ')' - self.fail(error_msg, context, code=code) + self.fail(ErrorMessage(error_msg, code), context) for note in notes: self.note(note, context, code=code) @@ -1664,6 +1611,16 @@ def format_type_inner(typ: Type, def format(typ: Type) -> str: return format_type_inner(typ, verbosity, fullnames) + def format_list(types: Sequence[Type]) -> str: + return ', '.join(format(typ) for typ in types) + + def format_literal_value(typ: LiteralType) -> str: + if typ.is_enum_literal(): + underlying_type = format(typ.fallback) + return '{}.{}'.format(underlying_type, typ.value) + else: + return typ.value_repr() + # TODO: show type alias names in errors. typ = get_proper_type(typ) @@ -1686,15 +1643,10 @@ def format(typ: Type) -> str: elif itype.type.fullname in reverse_builtin_aliases: alias = reverse_builtin_aliases[itype.type.fullname] alias = alias.split('.')[-1] - items = [format(arg) for arg in itype.args] - return '{}[{}]'.format(alias, ', '.join(items)) + return '{}[{}]'.format(alias, format_list(itype.args)) else: # There are type arguments. Convert the arguments to strings. - a: List[str] = [] - for arg in itype.args: - a.append(format(arg)) - s = ', '.join(a) - return '{}[{}]'.format(base_str, s) + return '{}[{}]'.format(base_str, format_list(itype.args)) elif isinstance(typ, TypeVarType): # This is similar to non-generic instance types. return typ.name @@ -1704,10 +1656,7 @@ def format(typ: Type) -> str: # Prefer the name of the fallback class (if not tuple), as it's more informative. if typ.partial_fallback.type.fullname != 'builtins.tuple': return format(typ.partial_fallback) - items = [] - for t in typ.items: - items.append(format(t)) - s = 'Tuple[{}]'.format(', '.join(items)) + s = 'Tuple[{}]'.format(format_list(typ.items)) return s elif isinstance(typ, TypedDictType): # If the TypedDictType is named, return the name @@ -1722,24 +1671,34 @@ def format(typ: Type) -> str: s = 'TypedDict({{{}}})'.format(', '.join(items)) return s elif isinstance(typ, LiteralType): - if typ.is_enum_literal(): - underlying_type = format(typ.fallback) - return 'Literal[{}.{}]'.format(underlying_type, typ.value) - else: - return str(typ) + return 'Literal[{}]'.format(format_literal_value(typ)) elif isinstance(typ, UnionType): - # Only print Unions as Optionals if the Optional wouldn't have to contain another Union - print_as_optional = (len(typ.items) - - sum(isinstance(get_proper_type(t), NoneType) - for t in typ.items) == 1) - if print_as_optional: - rest = [t for t in typ.items if not isinstance(get_proper_type(t), NoneType)] - return 'Optional[{}]'.format(format(rest[0])) + literal_items, union_items = separate_union_literals(typ) + + # Coalesce multiple Literal[] members. This also changes output order. + # If there's just one Literal item, retain the original ordering. + if len(literal_items) > 1: + literal_str = 'Literal[{}]'.format( + ', '.join(format_literal_value(t) for t in literal_items) + ) + + if len(union_items) == 1 and isinstance(get_proper_type(union_items[0]), NoneType): + return 'Optional[{}]'.format(literal_str) + elif union_items: + return 'Union[{}, {}]'.format(format_list(union_items), literal_str) + else: + return literal_str else: - items = [] - for t in typ.items: - items.append(format(t)) - s = 'Union[{}]'.format(', '.join(items)) + # Only print Union as Optional if the Optional wouldn't have to contain another Union + print_as_optional = (len(typ.items) - + sum(isinstance(get_proper_type(t), NoneType) + for t in typ.items) == 1) + if print_as_optional: + rest = [t for t in typ.items if not isinstance(get_proper_type(t), NoneType)] + return 'Optional[{}]'.format(format(rest[0])) + else: + s = 'Union[{}]'.format(format_list(typ.items)) + return s elif isinstance(typ, NoneType): return 'None' diff --git a/mypy/nodes.py b/mypy/nodes.py index b77cef55ee0e..9a475b8b8633 100644 --- a/mypy/nodes.py +++ b/mypy/nodes.py @@ -260,7 +260,8 @@ class MypyFile(SymbolNode): __slots__ = ('_fullname', 'path', 'defs', 'alias_deps', 'is_bom', 'names', 'imports', 'ignored_lines', 'is_stub', - 'is_cache_skeleton', 'is_partial_stub_package', 'plugin_deps') + 'is_cache_skeleton', 'is_partial_stub_package', 'plugin_deps', + 'future_import_flags') # Fully qualified module name _fullname: Bogus[str] @@ -289,6 +290,8 @@ class MypyFile(SymbolNode): is_partial_stub_package: bool # Plugin-created dependencies plugin_deps: Dict[str, Set[str]] + # Future imports defined in this file. Populated during semantic analysis. + future_import_flags: Set[str] def __init__(self, defs: List[Statement], @@ -311,6 +314,7 @@ def __init__(self, self.is_stub = False self.is_cache_skeleton = False self.is_partial_stub_package = False + self.future_import_flags = set() def local_definitions(self) -> Iterator[Definition]: """Return all definitions within the module (including nested). @@ -333,6 +337,9 @@ def accept(self, visitor: NodeVisitor[T]) -> T: def is_package_init_file(self) -> bool: return len(self.path) != 0 and os.path.basename(self.path).startswith('__init__.') + def is_future_flag_set(self, flag: str) -> bool: + return flag in self.future_import_flags + def serialize(self) -> JsonDict: return {'.class': 'MypyFile', '_fullname': self._fullname, @@ -340,6 +347,7 @@ def serialize(self) -> JsonDict: 'is_stub': self.is_stub, 'path': self.path, 'is_partial_stub_package': self.is_partial_stub_package, + 'future_import_flags': list(self.future_import_flags), } @classmethod @@ -352,6 +360,7 @@ def deserialize(cls, data: JsonDict) -> 'MypyFile': tree.path = data['path'] tree.is_partial_stub_package = data['is_partial_stub_package'] tree.is_cache_skeleton = True + tree.future_import_flags = set(data['future_import_flags']) return tree @@ -845,7 +854,7 @@ def deserialize(cls, data: JsonDict) -> 'Decorator': 'is_classmethod', 'is_property', 'is_settable_property', 'is_suppressed_import', 'is_classvar', 'is_abstract_var', 'is_final', 'final_unset_in_class', 'final_set_in_init', 'explicit_self_type', 'is_ready', 'from_module_getattr', - 'has_explicit_value', + 'has_explicit_value', 'allow_incompatible_override', ] @@ -877,6 +886,7 @@ class Var(SymbolNode): 'explicit_self_type', 'from_module_getattr', 'has_explicit_value', + 'allow_incompatible_override', ) def __init__(self, name: str, type: 'Optional[mypy.types.Type]' = None) -> None: @@ -924,6 +934,8 @@ def __init__(self, name: str, type: 'Optional[mypy.types.Type]' = None) -> None: # Var can be created with an explicit value `a = 1` or without one `a: int`, # we need a way to tell which one is which. self.has_explicit_value = False + # If True, subclasses can override this with an incompatible type. + self.allow_incompatible_override = False @property def name(self) -> str: @@ -1304,16 +1316,19 @@ def accept(self, visitor: StatementVisitor[T]) -> T: class RaiseStmt(Statement): - __slots__ = ('expr', 'from_expr') + __slots__ = ('expr', 'from_expr', 'legacy_mode') # Plain 'raise' is a valid statement. expr: Optional[Expression] from_expr: Optional[Expression] + # Is set when python2 has `raise exc, msg, traceback`. + legacy_mode: bool def __init__(self, expr: Optional[Expression], from_expr: Optional[Expression]) -> None: super().__init__() self.expr = expr self.from_expr = from_expr + self.legacy_mode = False def accept(self, visitor: StatementVisitor[T]) -> T: return visitor.visit_raise_stmt(self) diff --git a/mypy/patterns.py b/mypy/patterns.py index 8557fac6daf6..f7f5f56d0ed5 100644 --- a/mypy/patterns.py +++ b/mypy/patterns.py @@ -21,6 +21,7 @@ def accept(self, visitor: PatternVisitor[T]) -> T: class AsPattern(Pattern): + """The pattern as """ # The python ast, and therefore also our ast merges capture, wildcard and as patterns into one # for easier handling. # If pattern is None this is a capture pattern. If name and pattern are both none this is a @@ -39,6 +40,7 @@ def accept(self, visitor: PatternVisitor[T]) -> T: class OrPattern(Pattern): + """The pattern | | ...""" patterns: List[Pattern] def __init__(self, patterns: List[Pattern]) -> None: @@ -50,6 +52,7 @@ def accept(self, visitor: PatternVisitor[T]) -> T: class ValuePattern(Pattern): + """The pattern x.y (or x.y.z, ...)""" expr: Expression def __init__(self, expr: Expression): @@ -73,6 +76,7 @@ def accept(self, visitor: PatternVisitor[T]) -> T: class SequencePattern(Pattern): + """The pattern [, ...]""" patterns: List[Pattern] def __init__(self, patterns: List[Pattern]): @@ -114,6 +118,7 @@ def accept(self, visitor: PatternVisitor[T]) -> T: class ClassPattern(Pattern): + """The pattern Cls(...)""" class_ref: RefExpr positionals: List[Pattern] keyword_keys: List[str] diff --git a/mypy/plugin.py b/mypy/plugin.py index cfac2e85bc04..ec6bec47045f 100644 --- a/mypy/plugin.py +++ b/mypy/plugin.py @@ -120,7 +120,7 @@ class C: pass """ from abc import abstractmethod -from typing import Any, Callable, List, Tuple, Optional, NamedTuple, TypeVar, Dict, Union +from typing import Any, Callable, List, Tuple, Optional, NamedTuple, TypeVar, Dict from mypy_extensions import trait, mypyc_attr from mypy.nodes import ( @@ -133,7 +133,6 @@ class C: pass from mypy.messages import MessageBuilder from mypy.options import Options from mypy.lookup import lookup_fully_qualified -from mypy.errorcodes import ErrorCode from mypy.message_registry import ErrorMessage @@ -223,10 +222,8 @@ def type_context(self) -> List[Optional[Type]]: """Return the type context of the plugin""" raise NotImplementedError - # TODO(tushar): remove `str` type and `code` property from here @abstractmethod - def fail(self, msg: Union[str, ErrorMessage], ctx: Context, *, - code: Optional[ErrorCode] = None) -> None: + def fail(self, msg: ErrorMessage, ctx: Context) -> None: """Emit an error message at given location.""" raise NotImplementedError @@ -285,8 +282,8 @@ def parse_bool(self, expr: Expression) -> Optional[bool]: raise NotImplementedError @abstractmethod - def fail(self, msg: Union[str, ErrorMessage], ctx: Context, serious: bool = False, *, - blocker: bool = False, code: Optional[ErrorCode] = None) -> None: + def fail(self, msg: ErrorMessage, ctx: Context, serious: bool = False, *, + blocker: bool = False) -> None: """Emit an error message at given location.""" raise NotImplementedError diff --git a/mypy/plugins/attrs.py b/mypy/plugins/attrs.py index b777bf482e8f..0b1e95f63783 100644 --- a/mypy/plugins/attrs.py +++ b/mypy/plugins/attrs.py @@ -1,5 +1,6 @@ """Plugin for supporting the attrs library (http://www.attrs.org)""" +from mypy import message_registry from mypy.backports import OrderedDict from typing import Optional, Dict, List, cast, Tuple, Iterable @@ -18,18 +19,19 @@ from mypy.plugin import SemanticAnalyzerPluginInterface from mypy.plugins.common import ( _get_argument, _get_bool_argument, _get_decorator_bool_argument, add_method, - deserialize_and_fixup_type + deserialize_and_fixup_type, add_attribute_to_class, ) from mypy.types import ( TupleType, Type, AnyType, TypeOfAny, CallableType, NoneType, TypeVarType, Overloaded, UnionType, FunctionLike, Instance, get_proper_type, + LiteralType, ) from mypy.typeops import make_simplified_union, map_type_from_supertype from mypy.typevars import fill_typevars from mypy.util import unmangle from mypy.server.trigger import make_wildcard_trigger -KW_ONLY_PYTHON_2_UNSUPPORTED = "kw_only is not supported in Python 2" +KW_ONLY_PYTHON_2_UNSUPPORTED: Final = "kw_only is not supported in Python 2" # The names of the different functions that create classes or arguments. attr_class_makers: Final = { @@ -130,7 +132,7 @@ def argument(self, ctx: 'mypy.plugin.ClassDefContext') -> Argument: init_type = UnionType.make_union([init_type, NoneType()]) if not init_type: - ctx.api.fail("Cannot determine __init__ type from converter", self.context) + ctx.api.fail(message_registry.CANNOT_DETERMINE_INIT_TYPE, self.context) init_type = AnyType(TypeOfAny.from_error) elif self.converter.name == '': # This means we had a converter but it's not of a type we can infer. @@ -210,7 +212,7 @@ def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> bool: order = _get_decorator_optional_bool_argument(ctx, 'order') if cmp is not None and any((eq is not None, order is not None)): - ctx.api.fail('Don\'t mix "cmp" with "eq" and "order"', ctx.reason) + ctx.api.fail(message_registry.CMP_WITH_EQ_AND_ORDER, ctx.reason) # cmp takes precedence due to bw-compatibility. if cmp is not None: @@ -224,7 +226,7 @@ def _determine_eq_order(ctx: 'mypy.plugin.ClassDefContext') -> bool: order = eq if eq is False and order is True: - ctx.api.fail('eq must be True if order is True', ctx.reason) + ctx.api.fail(message_registry.EQ_TRUE_IF_ORDER_TRUE, ctx.reason) return order @@ -248,7 +250,7 @@ def _get_decorator_optional_bool_argument( return False if attr_value.fullname == 'builtins.None': return None - ctx.api.fail('"{}" argument must be True or False.'.format(name), ctx.reason) + ctx.api.fail(message_registry.ARG_MUST_BE_TRUE_OR_FALSE.format(name), ctx.reason) return default return default else: @@ -278,17 +280,18 @@ def attr_class_maker_callback(ctx: 'mypy.plugin.ClassDefContext', auto_attribs = _get_decorator_optional_bool_argument(ctx, 'auto_attribs', auto_attribs_default) kw_only = _get_decorator_bool_argument(ctx, 'kw_only', False) + match_args = _get_decorator_bool_argument(ctx, 'match_args', True) if ctx.api.options.python_version[0] < 3: if auto_attribs: - ctx.api.fail("auto_attribs is not supported in Python 2", ctx.reason) + ctx.api.fail(message_registry.AUTO_ATTRIBS_UNSUPPORTED_PY2, ctx.reason) return if not info.defn.base_type_exprs: # Note: This will not catch subclassing old-style classes. - ctx.api.fail("attrs only works with new-style classes", info.defn) + ctx.api.fail(message_registry.ATTRS_NEWSTYLE_CLASS_ONLY, info.defn) return if kw_only: - ctx.api.fail(KW_ONLY_PYTHON_2_UNSUPPORTED, ctx.reason) + ctx.api.fail(message_registry.KW_ONLY_UNSUPPORTED_PY2, ctx.reason) return attributes = _analyze_class(ctx, auto_attribs, kw_only) @@ -307,6 +310,10 @@ def attr_class_maker_callback(ctx: 'mypy.plugin.ClassDefContext', _add_attrs_magic_attribute(ctx, [(attr.name, info[attr.name].type) for attr in attributes]) if slots: _add_slots(ctx, attributes) + if match_args and ctx.api.options.python_version[:2] >= (3, 10): + # `.__match_args__` is only added for python3.10+, but the argument + # exists for earlier versions as well. + _add_match_args(ctx, attributes) # Save the attributes so that subclasses can reuse them. ctx.cls.info.metadata['attrs'] = { @@ -407,9 +414,7 @@ def _analyze_class(ctx: 'mypy.plugin.ClassDefContext', context = attribute.context if i >= len(super_attrs) else ctx.cls if not attribute.has_default and last_default: - ctx.api.fail( - "Non-default attributes not allowed after default attributes.", - context) + ctx.api.fail(message_registry.NON_DEFAULT_ATTRS_AFTER_DEFAULT, context) last_default |= attribute.has_default return attributes @@ -532,7 +537,7 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', return None if len(stmt.lvalues) > 1: - ctx.api.fail("Too many names for one attribute", stmt) + ctx.api.fail(message_registry.ATTR_TOO_MANY_NAMES, stmt) return None # This is the type that belongs in the __init__ method for this attrib. @@ -544,7 +549,7 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', # See https://github.com/python-attrs/attrs/issues/481 for explanation. kw_only |= _get_bool_argument(ctx, rvalue, 'kw_only', False) if kw_only and ctx.api.options.python_version[0] < 3: - ctx.api.fail(KW_ONLY_PYTHON_2_UNSUPPORTED, stmt) + ctx.api.fail(message_registry.KW_ONLY_UNSUPPORTED_PY2, stmt) return None # TODO: Check for attr.NOTHING @@ -552,7 +557,7 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', attr_has_factory = bool(_get_argument(rvalue, 'factory')) if attr_has_default and attr_has_factory: - ctx.api.fail('Can\'t pass both "default" and "factory".', rvalue) + ctx.api.fail(message_registry.DEFAULT_WITH_FACTORY, rvalue) elif attr_has_factory: attr_has_default = True @@ -562,7 +567,7 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', try: un_type = expr_to_unanalyzed_type(type_arg, ctx.api.options, ctx.api.is_stub_file) except TypeTranslationError: - ctx.api.fail('Invalid argument to type', type_arg) + ctx.api.fail(message_registry.TYPE_INVALID_ARG, type_arg) else: init_type = ctx.api.anal_type(un_type) if init_type and isinstance(lhs.node, Var) and not lhs.node.type: @@ -574,9 +579,9 @@ def _attribute_from_attrib_maker(ctx: 'mypy.plugin.ClassDefContext', converter = _get_argument(rvalue, 'converter') convert = _get_argument(rvalue, 'convert') if convert and converter: - ctx.api.fail('Can\'t pass both "convert" and "converter".', rvalue) + ctx.api.fail(message_registry.CONVERT_WITH_CONVERTER, rvalue) elif convert: - ctx.api.fail("convert is deprecated, use converter", rvalue) + ctx.api.fail(message_registry.CONVERT_DEPRECATED, rvalue) converter = convert converter_info = _parse_converter(ctx, converter) @@ -613,10 +618,7 @@ def _parse_converter(ctx: 'mypy.plugin.ClassDefContext', return argument # Signal that we have an unsupported converter. - ctx.api.fail( - "Unsupported converter, only named functions and types are currently supported", - converter - ) + ctx.api.fail(message_registry.UNSUPPORTED_CONVERTER, converter) return Converter('') return Converter(None) @@ -733,10 +735,12 @@ def _add_attrs_magic_attribute(ctx: 'mypy.plugin.ClassDefContext', ti.names[name] = SymbolTableNode(MDEF, var, plugin_generated=True) attributes_type = Instance(ti, []) + # TODO: refactor using `add_attribute_to_class` var = Var(name=MAGIC_ATTR_NAME, type=TupleType(attributes_types, fallback=attributes_type)) var.info = ctx.cls.info var.is_classvar = True var._fullname = f"{ctx.cls.fullname}.{MAGIC_ATTR_CLS_NAME}" + var.allow_incompatible_override = True ctx.cls.info.names[MAGIC_ATTR_NAME] = SymbolTableNode( kind=MDEF, node=var, @@ -751,6 +755,29 @@ def _add_slots(ctx: 'mypy.plugin.ClassDefContext', ctx.cls.info.slots = {attr.name for attr in attributes} +def _add_match_args(ctx: 'mypy.plugin.ClassDefContext', + attributes: List[Attribute]) -> None: + if ('__match_args__' not in ctx.cls.info.names + or ctx.cls.info.names['__match_args__'].plugin_generated): + str_type = ctx.api.named_type('builtins.str') + match_args = TupleType( + [ + str_type.copy_modified( + last_known_value=LiteralType(attr.name, fallback=str_type), + ) + for attr in attributes + if not attr.kw_only and attr.init + ], + fallback=ctx.api.named_type('builtins.tuple'), + ) + add_attribute_to_class( + api=ctx.api, + cls=ctx.cls, + name='__match_args__', + typ=match_args, + ) + + class MethodAdder: """Helper to add methods to a TypeInfo. diff --git a/mypy/plugins/common.py b/mypy/plugins/common.py index 95f4618da4a1..30090cd5227b 100644 --- a/mypy/plugins/common.py +++ b/mypy/plugins/common.py @@ -1,11 +1,12 @@ from typing import List, Optional, Union +from mypy import message_registry from mypy.nodes import ( ARG_POS, MDEF, Argument, Block, CallExpr, ClassDef, Expression, SYMBOL_FUNCBASE_TYPES, FuncDef, PassStmt, RefExpr, SymbolTableNode, Var, JsonDict, ) from mypy.plugin import CheckerPluginInterface, ClassDefContext, SemanticAnalyzerPluginInterface -from mypy.semanal import set_callable_name +from mypy.semanal import set_callable_name, ALLOW_INCOMPATIBLE_OVERRIDE from mypy.types import ( CallableType, Overloaded, Type, TypeVarType, deserialize_type, get_proper_type, ) @@ -39,7 +40,7 @@ def _get_bool_argument(ctx: ClassDefContext, expr: CallExpr, if attr_value: ret = ctx.api.parse_bool(attr_value) if ret is None: - ctx.api.fail('"{}" argument must be True or False.'.format(name), expr) + ctx.api.fail(message_registry.ARG_MUST_BE_TRUE_OR_FALSE.format(name), expr) return default return ret return default @@ -162,6 +163,8 @@ def add_attribute_to_class( name: str, typ: Type, final: bool = False, + no_serialize: bool = False, + override_allow_incompatible: bool = False, ) -> None: """ Adds a new attribute to a class definition. @@ -179,8 +182,17 @@ def add_attribute_to_class( node = Var(name, typ) node.info = info node.is_final = final + if name in ALLOW_INCOMPATIBLE_OVERRIDE: + node.allow_incompatible_override = True + else: + node.allow_incompatible_override = override_allow_incompatible node._fullname = info.fullname + '.' + name - info.names[name] = SymbolTableNode(MDEF, node, plugin_generated=True) + info.names[name] = SymbolTableNode( + MDEF, + node, + plugin_generated=True, + no_serialize=no_serialize, + ) def deserialize_and_fixup_type( diff --git a/mypy/plugins/ctypes.py b/mypy/plugins/ctypes.py index 87ffcdfe3339..e171340c792f 100644 --- a/mypy/plugins/ctypes.py +++ b/mypy/plugins/ctypes.py @@ -4,7 +4,7 @@ # Fully qualified instead of "from mypy.plugin import ..." to avoid circular import problems. import mypy.plugin -from mypy import nodes +from mypy import message_registry, nodes from mypy.maptype import map_instance_to_supertype from mypy.messages import format_type from mypy.subtypes import is_subtype @@ -125,17 +125,15 @@ def array_constructor_callback(ctx: 'mypy.plugin.FunctionContext') -> Type: "The stub of the ctypes.Array constructor should have a single vararg parameter" for arg_num, (arg_kind, arg_type) in enumerate(zip(ctx.arg_kinds[0], ctx.arg_types[0]), 1): if arg_kind == nodes.ARG_POS and not is_subtype(arg_type, allowed): - ctx.api.msg.fail( - 'Array constructor argument {} of type {}' - ' is not convertible to the array element type {}' + ctx.api.fail( + message_registry.CTYPES_INCOMPATIBLE_CONSTRUCTOR_ARG .format(arg_num, format_type(arg_type), format_type(et)), ctx.context) elif arg_kind == nodes.ARG_STAR: ty = ctx.api.named_generic_type("typing.Iterable", [allowed]) if not is_subtype(arg_type, ty): it = ctx.api.named_generic_type("typing.Iterable", [et]) - ctx.api.msg.fail( - 'Array constructor argument {} of type {}' - ' is not convertible to the array element type {}' + ctx.api.fail( + message_registry.CTYPES_INCOMPATIBLE_CONSTRUCTOR_ARG .format(arg_num, format_type(arg_type), format_type(it)), ctx.context) return ctx.default_return_type @@ -203,9 +201,8 @@ def array_value_callback(ctx: 'mypy.plugin.AttributeContext') -> Type: elif isinstance(tp, Instance) and tp.type.fullname == 'ctypes.c_wchar': types.append(_get_text_type(ctx.api)) else: - ctx.api.msg.fail( - 'Array attribute "value" is only available' - ' with element type "c_char" or "c_wchar", not {}' + ctx.api.fail( + message_registry.CTYPES_VALUE_WITH_CHAR_OR_WCHAR_ONLY .format(format_type(et)), ctx.context) return make_simplified_union(types) return ctx.default_attr_type @@ -221,9 +218,8 @@ def array_raw_callback(ctx: 'mypy.plugin.AttributeContext') -> Type: or isinstance(tp, Instance) and tp.type.fullname == 'ctypes.c_char'): types.append(_get_bytes_type(ctx.api)) else: - ctx.api.msg.fail( - 'Array attribute "raw" is only available' - ' with element type "c_char", not {}' + ctx.api.fail( + message_registry.CTYPES_RAW_WITH_CHAR_ONLY .format(format_type(et)), ctx.context) return make_simplified_union(types) return ctx.default_attr_type diff --git a/mypy/plugins/dataclasses.py b/mypy/plugins/dataclasses.py index 091c627f5c1b..0e33aac49589 100644 --- a/mypy/plugins/dataclasses.py +++ b/mypy/plugins/dataclasses.py @@ -3,6 +3,7 @@ from typing import Dict, List, Set, Tuple, Optional from typing_extensions import Final +from mypy import message_registry from mypy.nodes import ( ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, ARG_STAR, ARG_STAR2, MDEF, Argument, AssignmentStmt, CallExpr, Context, Expression, JsonDict, @@ -179,7 +180,7 @@ def transform(self) -> None: # Add <, >, <=, >=, but only if the class has an eq method. if decorator_arguments['order']: if not decorator_arguments['eq']: - ctx.api.fail('eq must be True if order is True', ctx.cls) + ctx.api.fail(message_registry.EQ_TRUE_IF_ORDER_TRUE, ctx.cls) for method_name in ['__lt__', '__gt__', '__le__', '__ge__']: # Like for __eq__ and __ne__, we want "other" to match @@ -196,7 +197,7 @@ def transform(self) -> None: if existing_method is not None and not existing_method.plugin_generated: assert existing_method.node ctx.api.fail( - 'You may not have a custom %s method when order=True' % method_name, + message_registry.DATACLASS_ORDER_METHODS_DISALLOWED.format(method_name), existing_method.node, ) @@ -227,7 +228,7 @@ def transform(self) -> None: literals: List[Type] = [LiteralType(attr.name, str_type) for attr in attributes if attr.is_in_init] match_args_type = TupleType(literals, ctx.api.named_type("builtins.tuple")) - add_attribute_to_class(ctx.api, ctx.cls, "__match_args__", match_args_type, final=True) + add_attribute_to_class(ctx.api, ctx.cls, "__match_args__", match_args_type) self._add_dataclass_fields_magic_attribute() @@ -245,8 +246,7 @@ def add_slots(self, # This means that version is lower than `3.10`, # it is just a non-existent argument for `dataclass` function. self._ctx.api.fail( - 'Keyword argument "slots" for "dataclass" ' - 'is only valid in Python 3.10 and higher', + message_registry.DATACLASS_SLOTS_ABOVE_PY310, self._ctx.reason, ) return @@ -259,9 +259,7 @@ def add_slots(self, # And `@dataclass(slots=True)` is used. # In runtime this raises a type error. self._ctx.api.fail( - '"{}" both defines "__slots__" and is used with "slots=True"'.format( - self._ctx.cls.name, - ), + message_registry.DATACLASS_SLOTS_CLASH.format(self._ctx.cls.name), self._ctx.cls, ) return @@ -432,7 +430,7 @@ def collect_attributes(self) -> Optional[List[DataclassAttribute]]: context = (Context(line=attr.line, column=attr.column) if attr in attrs else ctx.cls) ctx.api.fail( - 'Attributes without a default cannot follow attributes with one', + message_registry.DATACLASS_DEFAULT_ATTRS_BEFORE_NON_DEFAULT, context, ) @@ -441,7 +439,7 @@ def collect_attributes(self) -> Optional[List[DataclassAttribute]]: context = (Context(line=attr.line, column=attr.column) if attr in attrs else ctx.cls) ctx.api.fail( - 'There may not be more than one field with the KW_ONLY type', + message_registry.DATACLASS_SINGLE_KW_ONLY_TYPE, context, ) found_kw_sentinel = found_kw_sentinel or self._is_kw_only_type(attr.type) @@ -537,9 +535,9 @@ def _collect_field_args(expr: Expression, # This means that `field` is used with `**` unpacking, # the best we can do for now is not to fail. # TODO: we can infer what's inside `**` and try to collect it. - message = 'Unpacking **kwargs in "field()" is not supported' + message = message_registry.DATACLASS_UNPACKING_KWARGS_IN_FIELD else: - message = '"field()" does not accept positional arguments' + message = message_registry.DATACLASS_POS_ARG_IN_FIELD ctx.api.fail(message, expr) return True, {} assert name is not None diff --git a/mypy/plugins/default.py b/mypy/plugins/default.py index c57c5f9a18d9..acbb0460ae07 100644 --- a/mypy/plugins/default.py +++ b/mypy/plugins/default.py @@ -2,10 +2,9 @@ from typing import Callable, Optional, List from mypy import message_registry -from mypy.nodes import Expression, StrExpr, IntExpr, DictExpr, UnaryExpr +from mypy.nodes import StrExpr, IntExpr, DictExpr, UnaryExpr from mypy.plugin import ( - Plugin, FunctionContext, MethodContext, MethodSigContext, AttributeContext, ClassDefContext, - CheckerPluginInterface, + Plugin, FunctionContext, MethodContext, MethodSigContext, AttributeContext, ClassDefContext ) from mypy.plugins.common import try_getting_str_literals from mypy.types import ( @@ -26,8 +25,6 @@ def get_function_hook(self, fullname: str if fullname in ('contextlib.contextmanager', 'contextlib.asynccontextmanager'): return contextmanager_callback - elif fullname == 'builtins.open' and self.python_version[0] == 3: - return open_callback elif fullname == 'ctypes.Array': return ctypes.array_constructor_callback elif fullname == 'functools.singledispatch': @@ -74,8 +71,6 @@ def get_method_hook(self, fullname: str return ctypes.array_getitem_callback elif fullname == 'ctypes.Array.__iter__': return ctypes.array_iter_callback - elif fullname == 'pathlib.Path.open': - return path_open_callback elif fullname == singledispatch.SINGLEDISPATCH_REGISTER_METHOD: return singledispatch.singledispatch_register_callback elif fullname == singledispatch.REGISTER_CALLABLE_CALL_METHOD: @@ -129,58 +124,6 @@ def get_class_decorator_hook(self, fullname: str return None -def open_callback(ctx: FunctionContext) -> Type: - """Infer a better return type for 'open'.""" - return _analyze_open_signature( - arg_types=ctx.arg_types, - args=ctx.args, - mode_arg_index=1, - default_return_type=ctx.default_return_type, - api=ctx.api, - ) - - -def path_open_callback(ctx: MethodContext) -> Type: - """Infer a better return type for 'pathlib.Path.open'.""" - return _analyze_open_signature( - arg_types=ctx.arg_types, - args=ctx.args, - mode_arg_index=0, - default_return_type=ctx.default_return_type, - api=ctx.api, - ) - - -def _analyze_open_signature(arg_types: List[List[Type]], - args: List[List[Expression]], - mode_arg_index: int, - default_return_type: Type, - api: CheckerPluginInterface, - ) -> Type: - """A helper for analyzing any function that has approximately - the same signature as the builtin 'open(...)' function. - - Currently, the only thing the caller can customize is the index - of the 'mode' argument. If the mode argument is omitted or is a - string literal, we refine the return type to either 'TextIO' or - 'BinaryIO' as appropriate. - """ - mode = None - if not arg_types or len(arg_types[mode_arg_index]) != 1: - mode = 'r' - else: - mode_expr = args[mode_arg_index][0] - if isinstance(mode_expr, StrExpr): - mode = mode_expr.value - if mode is not None: - assert isinstance(default_return_type, Instance) # type: ignore - if 'b' in mode: - return api.named_generic_type('typing.BinaryIO', []) - else: - return api.named_generic_type('typing.TextIO', []) - return default_return_type - - def contextmanager_callback(ctx: FunctionContext) -> Type: """Infer a better return type for 'contextlib.contextmanager'.""" # Be defensive, just in case. diff --git a/mypy/plugins/functools.py b/mypy/plugins/functools.py index e52d478927e8..94bd941eb819 100644 --- a/mypy/plugins/functools.py +++ b/mypy/plugins/functools.py @@ -3,6 +3,7 @@ from typing_extensions import Final import mypy.plugin +from mypy import message_registry from mypy.nodes import ARG_POS, ARG_STAR2, Argument, FuncItem, Var from mypy.plugins.common import add_method_to_class from mypy.types import AnyType, CallableType, get_proper_type, Type, TypeOfAny, UnboundType @@ -32,9 +33,7 @@ def functools_total_ordering_maker_callback(ctx: mypy.plugin.ClassDefContext, comparison_methods = _analyze_class(ctx) if not comparison_methods: - ctx.api.fail( - 'No ordering operation defined when using "functools.total_ordering": < > <= >=', - ctx.reason) + ctx.api.fail(message_registry.TOTAL_ORDERING_NO_OPERATOR_DEFINED, ctx.reason) return # prefer __lt__ to __le__ to __gt__ to __ge__ diff --git a/mypy/plugins/singledispatch.py b/mypy/plugins/singledispatch.py index f4b3d7c19425..299e5c876a46 100644 --- a/mypy/plugins/singledispatch.py +++ b/mypy/plugins/singledispatch.py @@ -1,3 +1,4 @@ +from mypy import message_registry from mypy.messages import format_type from mypy.plugins.common import add_method_to_class from mypy.nodes import ( @@ -9,6 +10,7 @@ FunctionLike ) from mypy.plugin import CheckerPluginInterface, FunctionContext, MethodContext, MethodSigContext +from mypy.message_registry import ErrorMessage from typing import List, NamedTuple, Optional, Sequence, TypeVar, Union from typing_extensions import Final @@ -71,7 +73,7 @@ def make_fake_register_class_instance(api: CheckerPluginInterface, type_args: Se PluginContext = Union[FunctionContext, MethodContext] -def fail(ctx: PluginContext, msg: str, context: Optional[Context]) -> None: +def fail(ctx: PluginContext, msg: ErrorMessage, context: Optional[Context]) -> None: """Emit an error message. This tries to emit an error message at the location specified by `context`, falling back to the @@ -95,7 +97,7 @@ def create_singledispatch_function_callback(ctx: FunctionContext) -> Type: if len(func_type.arg_kinds) < 1: fail( ctx, - 'Singledispatch function requires at least one argument', + message_registry.SINGLEDISPATCH_ATLEAST_ONE_ARG, func_type.definition, ) return ctx.default_return_type @@ -103,7 +105,7 @@ def create_singledispatch_function_callback(ctx: FunctionContext) -> Type: elif not func_type.arg_kinds[0].is_positional(star=True): fail( ctx, - 'First argument to singledispatch function must be a positional argument', + message_registry.SINGLEDISPATCH_FIRST_ARG_POSITIONAL, func_type.definition, ) return ctx.default_return_type @@ -173,7 +175,7 @@ def register_function(ctx: PluginContext, singledispatch_obj: Instance, func: Ty fallback_dispatch_type = fallback.arg_types[0] if not is_subtype(dispatch_type, fallback_dispatch_type): - fail(ctx, 'Dispatch type {} must be subtype of fallback function first argument {}'.format( + fail(ctx, message_registry.DISPATCH_TYPE_FALLBACK_SUBTYPE.format( format_type(dispatch_type), format_type(fallback_dispatch_type) ), func.definition) return diff --git a/mypy/pyinfo.py b/mypy/pyinfo.py index 3834c04e218e..ab2d3286bd5c 100644 --- a/mypy/pyinfo.py +++ b/mypy/pyinfo.py @@ -19,7 +19,7 @@ def getprefixes(): # type: () -> Tuple[str, str] - return sys.base_prefix, sys.prefix + return getattr(sys, "base_prefix", sys.prefix), sys.prefix def getsitepackages(): diff --git a/mypy/renaming.py b/mypy/renaming.py index c200e94d58e7..ae21631f0f0a 100644 --- a/mypy/renaming.py +++ b/mypy/renaming.py @@ -1,11 +1,11 @@ from contextlib import contextmanager -from typing import Dict, Iterator, List +from typing import Dict, Iterator, List, Set from typing_extensions import Final from mypy.nodes import ( Block, AssignmentStmt, NameExpr, MypyFile, FuncDef, Lvalue, ListExpr, TupleExpr, WhileStmt, ForStmt, BreakStmt, ContinueStmt, TryStmt, WithStmt, MatchStmt, StarExpr, - ImportFrom, MemberExpr, IndexExpr, Import, ClassDef + ImportFrom, MemberExpr, IndexExpr, Import, ImportAll, ClassDef ) from mypy.patterns import AsPattern from mypy.traverser import TraverserVisitor @@ -262,15 +262,9 @@ def flush_refs(self) -> None: # as it will be publicly visible outside the module. to_rename = refs[:-1] for i, item in enumerate(to_rename): - self.rename_refs(item, i) + rename_refs(item, i) self.refs.pop() - def rename_refs(self, names: List[NameExpr], index: int) -> None: - name = names[0].name - new_name = name + "'" * (index + 1) - for expr in names: - expr.name = new_name - # Helpers for determining which assignments define new variables def clear(self) -> None: @@ -392,3 +386,162 @@ def record_assignment(self, name: str, can_be_redefined: bool) -> bool: else: # Assigns to an existing variable. return False + + +class LimitedVariableRenameVisitor(TraverserVisitor): + """Perform some limited variable renaming in with statements. + + This allows reusing a variable in multiple with statements with + different types. For example, the two instances of 'x' can have + incompatible types: + + with C() as x: + f(x) + with D() as x: + g(x) + + The above code gets renamed conceptually into this (not valid Python!): + + with C() as x': + f(x') + with D() as x: + g(x) + + If there's a reference to a variable defined in 'with' outside the + statement, or if there's any trickiness around variable visibility + (e.g. function definitions), we give up and won't perform renaming. + + The main use case is to allow binding both readable and writable + binary files into the same variable. These have different types: + + with open(fnam, 'rb') as f: ... + with open(fnam, 'wb') as f: ... + """ + + def __init__(self) -> None: + # Short names of variables bound in with statements using "as" + # in a surrounding scope + self.bound_vars: List[str] = [] + # Stack of names that can't be safely renamed, per scope ('*' means that + # no names can be renamed) + self.skipped: List[Set[str]] = [] + # References to variables that we may need to rename. Stack of + # scopes; each scope is a mapping from name to list of collections + # of names that refer to the same logical variable. + self.refs: List[Dict[str, List[List[NameExpr]]]] = [] + + def visit_mypy_file(self, file_node: MypyFile) -> None: + """Rename variables within a file. + + This is the main entry point to this class. + """ + with self.enter_scope(): + for d in file_node.defs: + d.accept(self) + + def visit_func_def(self, fdef: FuncDef) -> None: + self.reject_redefinition_of_vars_in_scope() + with self.enter_scope(): + for arg in fdef.arguments: + self.record_skipped(arg.variable.name) + super().visit_func_def(fdef) + + def visit_class_def(self, cdef: ClassDef) -> None: + self.reject_redefinition_of_vars_in_scope() + with self.enter_scope(): + super().visit_class_def(cdef) + + def visit_with_stmt(self, stmt: WithStmt) -> None: + for expr in stmt.expr: + expr.accept(self) + old_len = len(self.bound_vars) + for target in stmt.target: + if target is not None: + self.analyze_lvalue(target) + for target in stmt.target: + if target: + target.accept(self) + stmt.body.accept(self) + + while len(self.bound_vars) > old_len: + self.bound_vars.pop() + + def analyze_lvalue(self, lvalue: Lvalue) -> None: + if isinstance(lvalue, NameExpr): + name = lvalue.name + if name in self.bound_vars: + # Name bound in a surrounding with statement, so it can be renamed + self.visit_name_expr(lvalue) + else: + var_info = self.refs[-1] + if name not in var_info: + var_info[name] = [] + var_info[name].append([]) + self.bound_vars.append(name) + elif isinstance(lvalue, (ListExpr, TupleExpr)): + for item in lvalue.items: + self.analyze_lvalue(item) + elif isinstance(lvalue, MemberExpr): + lvalue.expr.accept(self) + elif isinstance(lvalue, IndexExpr): + lvalue.base.accept(self) + lvalue.index.accept(self) + elif isinstance(lvalue, StarExpr): + self.analyze_lvalue(lvalue.expr) + + def visit_import(self, imp: Import) -> None: + # We don't support renaming imports + for id, as_id in imp.ids: + self.record_skipped(as_id or id) + + def visit_import_from(self, imp: ImportFrom) -> None: + # We don't support renaming imports + for id, as_id in imp.names: + self.record_skipped(as_id or id) + + def visit_import_all(self, imp: ImportAll) -> None: + # Give up, since we don't know all imported names yet + self.reject_redefinition_of_vars_in_scope() + + def visit_name_expr(self, expr: NameExpr) -> None: + name = expr.name + if name in self.bound_vars: + # Record reference so that it can be renamed later + for scope in reversed(self.refs): + if name in scope: + scope[name][-1].append(expr) + else: + self.record_skipped(name) + + @contextmanager + def enter_scope(self) -> Iterator[None]: + self.skipped.append(set()) + self.refs.append({}) + yield None + self.flush_refs() + + def reject_redefinition_of_vars_in_scope(self) -> None: + self.record_skipped('*') + + def record_skipped(self, name: str) -> None: + self.skipped[-1].add(name) + + def flush_refs(self) -> None: + ref_dict = self.refs.pop() + skipped = self.skipped.pop() + if '*' not in skipped: + for name, refs in ref_dict.items(): + if len(refs) <= 1 or name in skipped: + continue + # At module top level we must not rename the final definition, + # as it may be publicly visible + to_rename = refs[:-1] + for i, item in enumerate(to_rename): + rename_refs(item, i) + + +def rename_refs(names: List[NameExpr], index: int) -> None: + name = names[0].name + new_name = name + "'" * (index + 1) + for expr in names: + expr.name = new_name diff --git a/mypy/report.py b/mypy/report.py index 380a8c6b6441..23b5c78ef929 100644 --- a/mypy/report.py +++ b/mypy/report.py @@ -245,10 +245,10 @@ def _write_out_report(self, f.write(separator + '\n') for row_values in rows: r = ("{:>{}}" * len(widths)).format(*itertools.chain(*zip(row_values, widths))) - f.writelines(r + '\n') + f.write(r + '\n') f.write(separator + '\n') footer_str = ("{:>{}}" * len(widths)).format(*itertools.chain(*zip(footer, widths))) - f.writelines(footer_str + '\n') + f.write(footer_str + '\n') def _report_any_exprs(self) -> None: total_any = sum(num_any for num_any, _ in self.counts.values()) diff --git a/mypy/semanal.py b/mypy/semanal.py index 8b63d8e6c354..3b7c90a4c0da 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -51,7 +51,7 @@ from contextlib import contextmanager from typing import ( - List, Dict, Set, Tuple, cast, TypeVar, Union, Optional, Callable, Iterator, Iterable + Any, List, Dict, Set, Tuple, cast, TypeVar, Union, Optional, Callable, Iterator, Iterable ) from typing_extensions import Final, TypeAlias as _TypeAlias @@ -78,7 +78,7 @@ typing_extensions_aliases, EnumCallExpr, RUNTIME_PROTOCOL_DECOS, FakeExpression, Statement, AssignmentExpr, ParamSpecExpr, EllipsisExpr, TypeVarLikeExpr, implicit_module_attrs, - MatchStmt, + MatchStmt, FuncBase ) from mypy.patterns import ( AsPattern, OrPattern, ValuePattern, SequencePattern, @@ -95,11 +95,11 @@ from mypy.message_registry import ErrorMessage from mypy import message_registry, errorcodes as codes from mypy.types import ( - FunctionLike, UnboundType, TypeVarType, TupleType, UnionType, StarType, + NEVER_NAMES, FunctionLike, UnboundType, TypeVarType, TupleType, UnionType, StarType, CallableType, Overloaded, Instance, Type, AnyType, LiteralType, LiteralValue, TypeTranslator, TypeOfAny, TypeType, NoneType, PlaceholderType, TPDICT_NAMES, ProperType, get_proper_type, get_proper_types, TypeAliasType, TypeVarLikeType, - PROTOCOL_NAMES, TYPE_ALIAS_NAMES, FINAL_TYPE_NAMES, FINAL_DECORATOR_NAMES, + PROTOCOL_NAMES, TYPE_ALIAS_NAMES, FINAL_TYPE_NAMES, FINAL_DECORATOR_NAMES, REVEAL_TYPE_NAMES, is_named_instance, ) from mypy.typeops import function_type, get_type_vars @@ -117,6 +117,7 @@ ) from mypy.util import ( correct_relative_import, unmangle, module_prefix, is_typeshed_file, unnamed_function, + is_dunder, ) from mypy.scope import Scope from mypy.semanal_shared import ( @@ -153,6 +154,10 @@ # available very early on. CORE_BUILTIN_CLASSES: Final = ["object", "bool", "function"] +# Subclasses can override these Var attributes with incompatible types. This can also be +# set for individual attributes using 'allow_incompatible_override' of Var. +ALLOW_INCOMPATIBLE_OVERRIDE: Final = ('__slots__', '__deletable__', '__match_args__') + # Used for tracking incomplete references Tag: _TypeAlias = int @@ -227,7 +232,6 @@ class SemanticAnalyzer(NodeVisitor[None], errors: Errors # Keeps track of generated errors plugin: Plugin # Mypy plugin for special casing of library features statement: Optional[Statement] = None # Statement/definition being analyzed - future_import_flags: Set[str] # Mapping from 'async def' function definitions to their return type wrapped as a # 'Coroutine[Any, Any, T]'. Used to keep track of whether a function definition's @@ -292,8 +296,6 @@ def __init__(self, # current SCC or top-level function. self.deferral_debug_context: List[Tuple[str, int]] = [] - self.future_import_flags: Set[str] = set() - # mypyc doesn't properly handle implementing an abstractproperty # with a regular attribute so we make them properties @property @@ -2174,11 +2176,14 @@ def can_be_type_alias(self, rv: Expression, allow_none: bool = False) -> bool: return True if allow_none and isinstance(rv, NameExpr) and rv.fullname == 'builtins.None': return True - if (isinstance(rv, OpExpr) - and rv.op == '|' - and self.can_be_type_alias(rv.left, allow_none=True) - and self.can_be_type_alias(rv.right, allow_none=True)): - return True + if isinstance(rv, OpExpr) and rv.op == '|': + if self.is_stub_file: + return True + if ( + self.can_be_type_alias(rv.left, allow_none=True) + and self.can_be_type_alias(rv.right, allow_none=True) + ): + return True return False def is_type_ref(self, rv: Expression, bare: bool = False) -> bool: @@ -2221,11 +2226,7 @@ def is_type_ref(self, rv: Expression, bare: bool = False) -> bool: # Assignment color = Color['RED'] defines a variable, not an alias. return not rv.node.is_enum if isinstance(rv.node, Var): - return rv.node.fullname in ( - 'typing.NoReturn', - 'typing_extensions.NoReturn', - 'mypy_extensions.NoReturn', - ) + return rv.node.fullname in NEVER_NAMES if isinstance(rv, NameExpr): n = self.lookup(rv.name, rv) @@ -2474,8 +2475,9 @@ def store_final_status(self, s: AssignmentStmt) -> None: cur_node = self.type.names.get(lval.name, None) if (cur_node and isinstance(cur_node.node, Var) and not (isinstance(s.rvalue, TempNode) and s.rvalue.no_rhs)): - cur_node.node.is_final = True - s.is_final_def = True + # Double underscored members are writable on an `Enum`. + # (Except read-only `__members__` but that is handled in type checker) + cur_node.node.is_final = s.is_final_def = not is_dunder(cur_node.node.name) # Special case: deferred initialization of a final attribute in __init__. # In this case we just pretend this is a valid final definition to suppress @@ -2641,7 +2643,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool: pep_613 = False if s.unanalyzed_type is not None and isinstance(s.unanalyzed_type, UnboundType): - lookup = self.lookup(s.unanalyzed_type.name, s, suppress_errors=True) + lookup = self.lookup_qualified(s.unanalyzed_type.name, s, suppress_errors=True) if lookup and lookup.fullname in TYPE_ALIAS_NAMES: pep_613 = True if not pep_613 and s.unanalyzed_type is not None: @@ -2906,18 +2908,20 @@ def make_name_lvalue_var( self, lvalue: NameExpr, kind: int, inferred: bool, has_explicit_value: bool, ) -> Var: """Return a Var node for an lvalue that is a name expression.""" - v = Var(lvalue.name) + name = lvalue.name + v = Var(name) v.set_line(lvalue) v.is_inferred = inferred if kind == MDEF: assert self.type is not None v.info = self.type v.is_initialized_in_class = True + v.allow_incompatible_override = name in ALLOW_INCOMPATIBLE_OVERRIDE if kind != LDEF: - v._fullname = self.qualified_name(lvalue.name) + v._fullname = self.qualified_name(name) else: # fullanme should never stay None - v._fullname = lvalue.name + v._fullname = name v.is_ready = False # Type not inferred yet v.has_explicit_value = has_explicit_value return v @@ -3283,6 +3287,12 @@ def process_paramspec_declaration(self, s: AssignmentStmt) -> bool: if not self.check_typevarlike_name(call, name, s): return False + # ParamSpec is different from a regular TypeVar: + # arguments are not semantically valid. But, allowed in runtime. + # So, we need to warn users about possible invalid usage. + if len(call.args) > 1: + self.fail(message_registry.PARAMSPEC_FIRST_ARG, s) + # PEP 612 reserves the right to define bound, covariant and contravariant arguments to # ParamSpec in a later PEP. If and when that happens, we should do something # on the lines of process_typevar_parameters @@ -3818,13 +3828,15 @@ def visit_star_expr(self, expr: StarExpr) -> None: expr.expr.accept(self) def visit_yield_from_expr(self, e: YieldFromExpr) -> None: - if not self.is_func_scope(): # not sure + if not self.is_func_scope(): self.fail(message_registry.YIELD_FROM_OUTSIDE_FUNC, e, serious=True, blocker=True) + elif self.is_comprehension_stack[-1]: + self.fail(message_registry.YIELD_FROM_IN_LISTCOMP_GENEXPR, + e, serious=True, blocker=True) + elif self.function_stack[-1].is_coroutine: + self.fail(message_registry.YIELD_FROM_IN_ASYNC_FUNC, e, serious=True, blocker=True) else: - if self.function_stack[-1].is_coroutine: - self.fail(message_registry.YIELD_FROM_IN_ASYNC_FUNC, e, serious=True, blocker=True) - else: - self.function_stack[-1].is_generator = True + self.function_stack[-1].is_generator = True if e.expr: e.expr.accept(self) @@ -3851,7 +3863,7 @@ def visit_call_expr(self, expr: CallExpr) -> None: expr.analyzed.line = expr.line expr.analyzed.column = expr.column expr.analyzed.accept(self) - elif refers_to_fullname(expr.callee, 'builtins.reveal_type'): + elif refers_to_fullname(expr.callee, REVEAL_TYPE_NAMES): if not self.check_fixed_args(expr, 1, 'reveal_type'): return expr.analyzed = RevealExpr(kind=REVEAL_TYPE, expr=expr.args[0]) @@ -4200,21 +4212,22 @@ def visit__promote_expr(self, expr: PromoteExpr) -> None: if analyzed is not None: expr.type = analyzed - def visit_yield_expr(self, expr: YieldExpr) -> None: + def visit_yield_expr(self, e: YieldExpr) -> None: if not self.is_func_scope(): - self.fail(message_registry.YIELD_OUTSIDE_FUNC, expr, serious=True, blocker=True) - else: - if self.function_stack[-1].is_coroutine: - if self.options.python_version < (3, 6): - self.fail(message_registry.YIELD_IN_ASYNC_FUNC, expr, serious=True, - blocker=True) - else: - self.function_stack[-1].is_generator = True - self.function_stack[-1].is_async_generator = True + self.fail(message_registry.YIELD_OUTSIDE_FUNC, e, serious=True, blocker=True) + elif self.is_comprehension_stack[-1]: + self.fail(message_registry.YIELD_IN_LISTCOMP_GENEXPR, + e, serious=True, blocker=True) + elif self.function_stack[-1].is_coroutine: + if self.options.python_version < (3, 6): + self.fail(message_registry.YIELD_IN_ASYNC_FUNC, e, serious=True, blocker=True) else: self.function_stack[-1].is_generator = True - if expr.expr: - expr.expr.accept(self) + self.function_stack[-1].is_async_generator = True + else: + self.function_stack[-1].is_generator = True + if e.expr: + e.expr.accept(self) def visit_await_expr(self, expr: AwaitExpr) -> None: if not self.is_func_scope(): @@ -4765,6 +4778,48 @@ def add_module_symbol(self, module_hidden=module_hidden ) + def _get_node_for_class_scoped_import( + self, name: str, symbol_node: Optional[SymbolNode], context: Context + ) -> Optional[SymbolNode]: + if symbol_node is None: + return None + # I promise this type checks; I'm just making mypyc issues go away. + # mypyc is absolutely convinced that `symbol_node` narrows to a Var in the following, + # when it can also be a FuncBase. Once fixed, `f` in the following can be removed. + # See also https://github.com/mypyc/mypyc/issues/892 + f = cast(Any, lambda x: x) + if isinstance(f(symbol_node), (FuncBase, Var)): + # For imports in class scope, we construct a new node to represent the symbol and + # set its `info` attribute to `self.type`. + existing = self.current_symbol_table().get(name) + if ( + # The redefinition checks in `add_symbol_table_node` don't work for our + # constructed Var / FuncBase, so check for possible redefinitions here. + existing is not None + and isinstance(f(existing.node), (FuncBase, Var)) + and ( + isinstance(f(existing.type), f(AnyType)) + or f(existing.type) == f(symbol_node).type + ) + ): + return existing.node + + # Construct the new node + if isinstance(f(symbol_node), FuncBase): + # In theory we could construct a new node here as well, but in practice + # it doesn't work well, see #12197 + typ: Optional[Type] = AnyType(TypeOfAny.from_error) + self.fail(message_registry.UNSUPPORTED_CLASS_SCOPED_IMPORT, context) + else: + typ = f(symbol_node).type + symbol_node = Var(name, typ) + symbol_node._fullname = self.qualified_name(name) + assert self.type is not None # guaranteed by is_class_scope + symbol_node.info = self.type + symbol_node.line = context.line + symbol_node.column = context.column + return symbol_node + def add_imported_symbol(self, name: str, node: SymbolTableNode, @@ -4773,7 +4828,13 @@ def add_imported_symbol(self, module_hidden: bool) -> None: """Add an alias to an existing symbol through import.""" assert not module_hidden or not module_public - symbol = SymbolTableNode(node.kind, node.node, + + symbol_node: Optional[SymbolNode] = node.node + + if self.is_class_scope(): + symbol_node = self._get_node_for_class_scoped_import(name, symbol_node, context) + + symbol = SymbolTableNode(node.kind, symbol_node, module_public=module_public, module_hidden=module_hidden) self.add_symbol_table_node(name, symbol, context) @@ -5118,23 +5179,18 @@ def in_checked_function(self) -> bool: # no regular functions. return True - # TODO(tushar): remove `str` type and `code` property from here def fail(self, - msg: Union[str, ErrorMessage], + msg: ErrorMessage, ctx: Context, serious: bool = False, *, - code: Optional[ErrorCode] = None, blocker: bool = False) -> None: if not serious and not self.in_checked_function(): return # In case it's a bug and we don't really have context assert ctx is not None, msg - if isinstance(msg, ErrorMessage): - self.errors.report(ctx.get_line(), ctx.get_column(), msg.value, code=msg.code, - blocker=blocker) - return - self.errors.report(ctx.get_line(), ctx.get_column(), msg, blocker=blocker, code=code) + self.errors.report(ctx.get_line(), ctx.get_column(), msg.value, code=msg.code, + blocker=blocker) def note(self, msg: str, ctx: Context, code: Optional[ErrorCode] = None) -> None: if not self.in_checked_function(): @@ -5305,10 +5361,12 @@ def parse_bool(self, expr: Expression) -> Optional[bool]: def set_future_import_flags(self, module_name: str) -> None: if module_name in FUTURE_IMPORTS: - self.future_import_flags.add(FUTURE_IMPORTS[module_name]) + self.modules[self.cur_mod_id].future_import_flags.add( + FUTURE_IMPORTS[module_name], + ) def is_future_flag_set(self, flag: str) -> bool: - return flag in self.future_import_flags + return self.modules[self.cur_mod_id].is_future_flag_set(flag) class HasPlaceholders(TypeQuery[bool]): diff --git a/mypy/semanal_enum.py b/mypy/semanal_enum.py index fadd58078706..71ed7e4b1fc3 100644 --- a/mypy/semanal_enum.py +++ b/mypy/semanal_enum.py @@ -13,17 +13,18 @@ ) from mypy.semanal_shared import SemanticAnalyzerInterface from mypy.options import Options -from mypy.types import get_proper_type, LiteralType +from mypy.types import get_proper_type, LiteralType, ENUM_REMOVED_PROPS from mypy.message_registry import ErrorMessage from mypy import message_registry + # Note: 'enum.EnumMeta' is deliberately excluded from this list. Classes that directly use # enum.EnumMeta do not necessarily automatically have the 'name' and 'value' attributes. ENUM_BASES: Final = frozenset(( - 'enum.Enum', 'enum.IntEnum', 'enum.Flag', 'enum.IntFlag', + 'enum.Enum', 'enum.IntEnum', 'enum.Flag', 'enum.IntFlag', 'enum.StrEnum', )) ENUM_SPECIAL_PROPS: Final = frozenset(( - 'name', 'value', '_name_', '_value_', '_order_', '__order__', + 'name', 'value', '_name_', '_value_', *ENUM_REMOVED_PROPS, # Also attributes from `object`: '__module__', '__annotations__', '__doc__', '__slots__', '__dict__', )) diff --git a/mypy/semanal_main.py b/mypy/semanal_main.py index 7e187945da48..d935252ba9cf 100644 --- a/mypy/semanal_main.py +++ b/mypy/semanal_main.py @@ -307,7 +307,7 @@ def semantic_analyze_target(target: str, Return tuple with these items: - list of deferred targets - was some definition incomplete (need to run another pass) - - were any new names were defined (or placeholders replaced) + - were any new names defined (or placeholders replaced) """ state.manager.processed_targets.append(target) tree = state.tree diff --git a/mypy/semanal_shared.py b/mypy/semanal_shared.py index 337bc0f50a16..388ca5006724 100644 --- a/mypy/semanal_shared.py +++ b/mypy/semanal_shared.py @@ -2,7 +2,7 @@ from abc import abstractmethod -from typing import Optional, List, Callable, Union +from typing import Optional, List, Callable from typing_extensions import Final from mypy_extensions import trait @@ -45,10 +45,9 @@ def lookup_fully_qualified(self, name: str) -> SymbolTableNode: def lookup_fully_qualified_or_none(self, name: str) -> Optional[SymbolTableNode]: raise NotImplementedError - # TODO(tushar): remove `str` type and `code` property from here @abstractmethod - def fail(self, msg: Union[str, ErrorMessage], ctx: Context, serious: bool = False, *, - blocker: bool = False, code: Optional[ErrorCode] = None) -> None: + def fail(self, msg: ErrorMessage, ctx: Context, serious: bool = False, *, + blocker: bool = False) -> None: raise NotImplementedError @abstractmethod diff --git a/mypy/semanal_typeargs.py b/mypy/semanal_typeargs.py index 50e01145d60a..15c9523235bd 100644 --- a/mypy/semanal_typeargs.py +++ b/mypy/semanal_typeargs.py @@ -5,7 +5,7 @@ operations, including subtype checks. """ -from typing import List, Optional, Set +from typing import List, Set from mypy.nodes import TypeInfo, Context, MypyFile, FuncItem, ClassDef, Block, FakeInfo from mypy.types import ( @@ -18,9 +18,9 @@ from mypy.errors import Errors from mypy.scope import Scope from mypy.options import Options -from mypy.errorcodes import ErrorCode -from mypy import message_registry, errorcodes as codes +from mypy import message_registry from mypy.messages import format_type +from mypy.message_registry import ErrorMessage class TypeArgumentAnalyzer(MixedTraverserVisitor): @@ -74,7 +74,7 @@ def visit_instance(self, t: Instance) -> None: if isinstance(tvar, TypeVarType): if isinstance(arg, ParamSpecType): # TODO: Better message - self.fail(f'Invalid location for ParamSpec "{arg.name}"', t) + self.fail(message_registry.PARAMSPEC_INVALID_LOCATION.format(arg.name), t) continue if tvar.values: if isinstance(arg, TypeVarType): @@ -83,7 +83,7 @@ def visit_instance(self, t: Instance) -> None: self.fail( message_registry.INVALID_TYPEVAR_AS_TYPEARG.format( arg.name, info.name), - t, code=codes.TYPE_VAR) + t) continue else: arg_values = [arg] @@ -92,7 +92,7 @@ def visit_instance(self, t: Instance) -> None: self.fail( message_registry.INVALID_TYPEVAR_ARG_BOUND.format( format_type(arg), info.name, format_type(tvar.upper_bound)), - t, code=codes.TYPE_VAR) + t) super().visit_instance(t) def check_type_var_values(self, type: TypeInfo, actuals: List[Type], arg_name: str, @@ -104,15 +104,14 @@ def check_type_var_values(self, type: TypeInfo, actuals: List[Type], arg_name: s if len(actuals) > 1 or not isinstance(actual, Instance): self.fail( message_registry.INVALID_TYPEVAR_ARG_VALUE.format(type.name), - context, code=codes.TYPE_VAR) + context) else: class_name = '"{}"'.format(type.name) actual_type_name = '"{}"'.format(actual.type.name) self.fail( message_registry.INCOMPATIBLE_TYPEVAR_VALUE.format( arg_name, class_name, actual_type_name), - context, - code=codes.TYPE_VAR) + context) - def fail(self, msg: str, context: Context, *, code: Optional[ErrorCode] = None) -> None: - self.errors.report(context.get_line(), context.get_column(), msg, code=code) + def fail(self, msg: ErrorMessage, context: Context) -> None: + self.errors.report(context.get_line(), context.get_column(), msg.value, code=msg.code) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index b0a2c4e64587..dafb446a835a 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -649,9 +649,11 @@ def visit_func_def(self, o: FuncDef, is_abstract: bool = False, # type "UnboundType" and will not match. if not isinstance(get_proper_type(annotated_type), AnyType): annotation = ": {}".format(self.print_annotation(annotated_type)) + + if kind.is_named() and not any(arg.startswith('*') for arg in args): + args.append('*') + if arg_.initializer: - if kind.is_named() and not any(arg.startswith('*') for arg in args): - args.append('*') if not annotation: typename = self.get_str_type_of_node(arg_.initializer, True, False) if typename == '': diff --git a/mypy/stubinfo.py b/mypy/stubinfo.py index 9945a12c121f..d1bcb4a6c157 100644 --- a/mypy/stubinfo.py +++ b/mypy/stubinfo.py @@ -59,7 +59,6 @@ def is_legacy_bundled_package(prefix: str, py_version: int) -> bool: 'maxminddb': StubInfo('types-maxminddb'), 'mock': StubInfo('types-mock'), 'OpenSSL': StubInfo('types-pyOpenSSL'), - 'orjson': StubInfo('types-orjson', py_version=3), 'paramiko': StubInfo('types-paramiko'), 'pathlib2': StubInfo('types-pathlib2', py_version=2), 'pkg_resources': StubInfo('types-setuptools', py_version=3), diff --git a/mypy/stubtest.py b/mypy/stubtest.py index d0f62dfc3ed2..b568017cfa5f 100644 --- a/mypy/stubtest.py +++ b/mypy/stubtest.py @@ -25,7 +25,7 @@ from mypy import nodes from mypy.config_parser import parse_config_file from mypy.options import Options -from mypy.util import FancyFormatter, bytes_to_human_readable_repr, is_dunder, SPECIAL_DUNDERS +from mypy.util import FancyFormatter, bytes_to_human_readable_repr, is_dunder class Missing: @@ -144,6 +144,11 @@ def get_description(self, concise: bool = False) -> str: return "".join(output) +# ==================== +# Core logic +# ==================== + + def test_module(module_name: str) -> Iterator[Error]: """Tests a given module's stub against introspecting it at runtime. @@ -204,12 +209,15 @@ def verify_mypyfile( to_check = set( m for m, o in stub.names.items() - if not o.module_hidden and (not m.startswith("_") or hasattr(runtime, m)) + if not o.module_hidden and (not is_probably_private(m) or hasattr(runtime, m)) ) def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool: obj = getattr(r, attr) - obj_mod = getattr(obj, "__module__", None) + try: + obj_mod = getattr(obj, "__module__", None) + except Exception: + return False if obj_mod is not None: return obj_mod == r.__name__ return not isinstance(obj, types.ModuleType) @@ -220,7 +228,7 @@ def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool: else [ m for m in dir(runtime) - if not m.startswith("_") + if not is_probably_private(m) # Ensure that the object's module is `runtime`, since in the absence of __all__ we # don't have a good way to detect re-exports at runtime. and _belongs_to_runtime(runtime, m) @@ -228,7 +236,7 @@ def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool: ) # Check all things declared in module's __all__, falling back to our best guess to_check.update(runtime_public_contents) - to_check.difference_update({"__file__", "__doc__", "__name__", "__builtins__", "__package__"}) + to_check.difference_update(IGNORED_MODULE_DUNDERS) for entry in sorted(to_check): stub_entry = stub.names[entry].node if entry in stub.names else MISSING @@ -236,11 +244,19 @@ def _belongs_to_runtime(r: types.ModuleType, attr: str) -> bool: # Don't recursively check exported modules, since that leads to infinite recursion continue assert stub_entry is not None - yield from verify( - stub_entry, - getattr(runtime, entry, MISSING), - object_path + [entry], - ) + try: + runtime_entry = getattr(runtime, entry, MISSING) + except Exception: + # Catch all exceptions in case the runtime raises an unexpected exception + # from __getattr__ or similar. + continue + yield from verify(stub_entry, runtime_entry, object_path + [entry]) + + +if sys.version_info >= (3, 7): + _WrapperDescriptorType = types.WrapperDescriptorType +else: + _WrapperDescriptorType = type(object.__init__) @verify.register(nodes.TypeInfo) @@ -254,13 +270,32 @@ def verify_typeinfo( yield Error(object_path, "is not a type", stub, runtime, stub_desc=repr(stub)) return - # Check everything already defined in the stub + try: + class SubClass(runtime): # type: ignore + pass + except TypeError: + # Enum classes are implicitly @final + if not stub.is_final and not issubclass(runtime, enum.Enum): + yield Error( + object_path, + "cannot be subclassed at runtime, but isn't marked with @final in the stub", + stub, + runtime, + stub_desc=repr(stub), + ) + except Exception: + # The class probably wants its subclasses to do something special. + # Examples: ctypes.Array, ctypes._SimpleCData + pass + + # Check everything already defined on the stub class itself (i.e. not inherited) to_check = set(stub.names) - # There's a reasonable case to be made that we should always check all dunders, but it's - # currently quite noisy. We could turn this into a denylist instead of an allowlist. + # Check all public things on the runtime class to_check.update( # cast to workaround mypyc complaints - m for m in cast(Any, vars)(runtime) if not m.startswith("_") or m in SPECIAL_DUNDERS + m + for m in cast(Any, vars)(runtime) + if not is_probably_private(m) and m not in IGNORABLE_CLASS_DUNDERS ) for entry in sorted(to_check): @@ -274,8 +309,16 @@ def verify_typeinfo( except Exception: # Catch all exceptions in case the runtime raises an unexpected exception # from __getattr__ or similar. - pass - else: + continue + # Do not error for an object missing from the stub + # If the runtime object is a types.WrapperDescriptorType object + # and has a non-special dunder name. + # The vast majority of these are false positives. + if not ( + isinstance(stub_to_verify, Missing) + and isinstance(runtime_attr, _WrapperDescriptorType) + and is_dunder(mangled_entry, exclude_special=True) + ): yield from verify(stub_to_verify, runtime_attr, object_path + [entry]) @@ -587,6 +630,7 @@ def _verify_signature( if ( runtime_arg.kind != inspect.Parameter.POSITIONAL_ONLY and stub_arg.variable.name.startswith("__") + and not is_dunder(function_name, exclude_special=True) # noisy for dunder methods ): yield ( 'stub argument "{}" should be positional or keyword ' @@ -676,19 +720,39 @@ def verify_funcitem( yield Error(object_path, "is inconsistent, " + message, stub, runtime) signature = safe_inspect_signature(runtime) + runtime_is_coroutine = inspect.iscoroutinefunction(runtime) + + if signature: + stub_sig = Signature.from_funcitem(stub) + runtime_sig = Signature.from_inspect_signature(signature) + runtime_sig_desc = f'{"async " if runtime_is_coroutine else ""}def {signature}' + stub_desc = f'def {stub_sig!r}' + else: + runtime_sig_desc, stub_desc = None, None + + # Don't raise an error if the stub is a coroutine, but the runtime isn't. + # That results in false positives. + # See https://github.com/python/typeshed/issues/7344 + if runtime_is_coroutine and not stub.is_coroutine: + yield Error( + object_path, + 'is an "async def" function at runtime, but not in the stub', + stub, + runtime, + stub_desc=stub_desc, + runtime_desc=runtime_sig_desc + ) + if not signature: return - stub_sig = Signature.from_funcitem(stub) - runtime_sig = Signature.from_inspect_signature(signature) - for message in _verify_signature(stub_sig, runtime_sig, function_name=stub.name): yield Error( object_path, "is inconsistent, " + message, stub, runtime, - runtime_desc="def " + str(signature), + runtime_desc=runtime_sig_desc, ) @@ -899,6 +963,78 @@ def verify_typealias( ) +# ==================== +# Helpers +# ==================== + + +IGNORED_MODULE_DUNDERS = frozenset( + { + "__file__", + "__doc__", + "__name__", + "__builtins__", + "__package__", + "__cached__", + "__loader__", + "__spec__", + "__path__", # mypy adds __path__ to packages, but C packages don't have it + "__getattr__", # resulting behaviour might be typed explicitly + # TODO: remove the following from this list + "__author__", + "__version__", + "__copyright__", + } +) + +IGNORABLE_CLASS_DUNDERS = frozenset( + { + # Special attributes + "__dict__", + "__text_signature__", + "__weakref__", + "__del__", # Only ever called when an object is being deleted, who cares? + "__hash__", + "__getattr__", # resulting behaviour might be typed explicitly + "__setattr__", # defining this on a class can cause worse type checking + # isinstance/issubclass hooks that type-checkers don't usually care about + "__instancecheck__", + "__subclasshook__", + "__subclasscheck__", + # Pickle methods + "__setstate__", + "__getstate__", + "__getnewargs__", + "__getinitargs__", + "__reduce_ex__", + "__reduce__", + # ctypes weirdness + "__ctype_be__", + "__ctype_le__", + "__ctypes_from_outparam__", + # mypy limitations + "__abstractmethods__", # Classes with metaclass=ABCMeta inherit this attribute + "__new_member__", # If an enum defines __new__, the method is renamed as __new_member__ + "__dataclass_fields__", # Generated by dataclasses + "__dataclass_params__", # Generated by dataclasses + "__doc__", # mypy's semanal for namedtuples assumes this is str, not Optional[str] + # typing implementation details, consider removing some of these: + "__parameters__", + "__origin__", + "__args__", + "__orig_bases__", + "__final__", + # Consider removing these: + "__match_args__", + "__slots__", + } +) + + +def is_probably_private(name: str) -> bool: + return name.startswith("_") and not is_dunder(name) + + def is_probably_a_function(runtime: Any) -> bool: return ( isinstance(runtime, (types.FunctionType, types.BuiltinFunctionType)) @@ -932,6 +1068,14 @@ def is_subtype_helper(left: mypy.types.Type, right: mypy.types.Type) -> bool: # Pretend Literal[0, 1] is a subtype of bool to avoid unhelpful errors. return True + if ( + isinstance(right, mypy.types.TypedDictType) + and isinstance(left, mypy.types.Instance) + and left.type.fullname == "builtins.dict" + ): + # Special case checks against TypedDicts + return True + with mypy.state.strict_optional_set(True): return mypy.subtypes.is_subtype(left, right) @@ -1033,6 +1177,11 @@ def anytype() -> mypy.types.AnyType: return mypy.types.LiteralType(value=value, fallback=fallback) +# ==================== +# Build and entrypoint +# ==================== + + _all_stubs: Dict[str, nodes.MypyFile] = {} @@ -1099,19 +1248,27 @@ def get_stub(module: str) -> Optional[nodes.MypyFile]: return _all_stubs.get(module) -def get_typeshed_stdlib_modules(custom_typeshed_dir: Optional[str]) -> List[str]: +def get_typeshed_stdlib_modules( + custom_typeshed_dir: Optional[str], + version_info: Optional[Tuple[int, int]] = None +) -> List[str]: """Returns a list of stdlib modules in typeshed (for current Python version).""" stdlib_py_versions = mypy.modulefinder.load_stdlib_py_versions(custom_typeshed_dir) - packages = set() + if version_info is None: + version_info = sys.version_info[0:2] # Typeshed's minimum supported Python 3 is Python 3.6 if sys.version_info < (3, 6): version_info = (3, 6) - else: - version_info = sys.version_info[0:2] - for module, versions in stdlib_py_versions.items(): - minver, maxver = versions - if version_info >= minver and (maxver is None or version_info <= maxver): - packages.add(module) + + def exists_in_version(module: str) -> bool: + assert version_info is not None + parts = module.split(".") + for i in range(len(parts), 0, -1): + current_module = ".".join(parts[:i]) + if current_module in stdlib_py_versions: + minver, maxver = stdlib_py_versions[current_module] + return version_info >= minver and (maxver is None or version_info <= maxver) + return False if custom_typeshed_dir: typeshed_dir = Path(custom_typeshed_dir) @@ -1124,7 +1281,7 @@ def get_typeshed_stdlib_modules(custom_typeshed_dir: Optional[str]) -> List[str] if path.stem == "__init__": path = path.parent module = ".".join(path.relative_to(stdlib_dir).parts[:-1] + (path.stem,)) - if module.split(".")[0] in packages: + if exists_in_version(module): modules.append(module) return sorted(modules) @@ -1161,7 +1318,8 @@ def test_stubs(args: argparse.Namespace, use_builtins_fixtures: bool = False) -> if args.check_typeshed: assert not args.modules, "Cannot pass both --check-typeshed and a list of modules" modules = get_typeshed_stdlib_modules(args.custom_typeshed_dir) - annoying_modules = {"antigravity", "this"} + # typeshed added a stub for __main__, but that causes stubtest to check itself + annoying_modules = {"antigravity", "this", "__main__"} modules = [m for m in modules if m not in annoying_modules] assert modules, "No modules to check" diff --git a/mypy/subtypes.py b/mypy/subtypes.py index 51a9dfbb8bc1..a261e3712328 100644 --- a/mypy/subtypes.py +++ b/mypy/subtypes.py @@ -763,7 +763,7 @@ def non_method_protocol_members(tp: TypeInfo) -> List[str]: for member in tp.protocol_members: typ = get_proper_type(find_member(member, instance, instance)) - if not isinstance(typ, CallableType): + if not isinstance(typ, (Overloaded, CallableType)): result.append(member) return result diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py index 6cc556004337..759942c57ce7 100644 --- a/mypy/test/teststubtest.py +++ b/mypy/test/teststubtest.py @@ -7,7 +7,6 @@ import tempfile import textwrap import unittest -from pathlib import Path from typing import Any, Callable, Iterator, List, Optional import mypy.stubtest @@ -16,18 +15,53 @@ @contextlib.contextmanager -def use_tmp_dir() -> Iterator[None]: +def use_tmp_dir(mod_name: str) -> Iterator[str]: current = os.getcwd() + current_syspath = sys.path[:] with tempfile.TemporaryDirectory() as tmp: try: os.chdir(tmp) - yield + if sys.path[0] != tmp: + sys.path.insert(0, tmp) + yield tmp finally: + sys.path = current_syspath[:] + if mod_name in sys.modules: + del sys.modules[mod_name] + os.chdir(current) TEST_MODULE_NAME = "test_module" + +stubtest_typing_stub = """ +Any = object() + +class _SpecialForm: + def __getitem__(self, typeargs: Any) -> object: ... + +Callable: _SpecialForm = ... +Generic: _SpecialForm = ... + +class TypeVar: + def __init__(self, name, covariant: bool = ..., contravariant: bool = ...) -> None: ... + +_T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) +_K = TypeVar("_K") +_V = TypeVar("_V") +_S = TypeVar("_S", contravariant=True) +_R = TypeVar("_R", covariant=True) + +class Coroutine(Generic[_T_co, _S, _R]): ... +class Iterable(Generic[_T_co]): ... +class Mapping(Generic[_K, _V]): ... +class Sequence(Iterable[_T_co]): ... +class Tuple(Sequence[_T_co]): ... +def overload(func: _T) -> _T: ... +""" + stubtest_builtins_stub = """ from typing import Generic, Mapping, Sequence, TypeVar, overload @@ -37,6 +71,7 @@ def use_tmp_dir() -> Iterator[None]: VT = TypeVar('VT') class object: + __module__: str def __init__(self) -> None: pass class type: ... @@ -63,9 +98,11 @@ def staticmethod(f: T) -> T: ... def run_stubtest( stub: str, runtime: str, options: List[str], config_file: Optional[str] = None, ) -> str: - with use_tmp_dir(): + with use_tmp_dir(TEST_MODULE_NAME) as tmp_dir: with open("builtins.pyi", "w") as f: f.write(stubtest_builtins_stub) + with open("typing.pyi", "w") as f: + f.write(stubtest_typing_stub) with open("{}.pyi".format(TEST_MODULE_NAME), "w") as f: f.write(stub) with open("{}.py".format(TEST_MODULE_NAME), "w") as f: @@ -74,21 +111,14 @@ def run_stubtest( with open("{}_config.ini".format(TEST_MODULE_NAME), "w") as f: f.write(config_file) options = options + ["--mypy-config-file", "{}_config.ini".format(TEST_MODULE_NAME)] - if sys.path[0] != ".": - sys.path.insert(0, ".") - if TEST_MODULE_NAME in sys.modules: - del sys.modules[TEST_MODULE_NAME] - output = io.StringIO() with contextlib.redirect_stdout(output): test_stubs( parse_options([TEST_MODULE_NAME] + options), use_builtins_fixtures=True ) - - module_path = Path(os.getcwd()) / TEST_MODULE_NAME # remove cwd as it's not available from outside - return output.getvalue().replace(str(module_path), TEST_MODULE_NAME) + return output.getvalue().replace(tmp_dir + os.sep, "") class Case: @@ -112,7 +142,11 @@ def test(*args: Any, **kwargs: Any) -> None: for c in cases: if c.error is None: continue - expected_error = "{}.{}".format(TEST_MODULE_NAME, c.error) + expected_error = c.error + if expected_error == "": + expected_error = TEST_MODULE_NAME + elif not expected_error.startswith(f"{TEST_MODULE_NAME}."): + expected_error = f"{TEST_MODULE_NAME}.{expected_error}" assert expected_error not in expected_errors, ( "collect_cases merges cases into a single stubtest invocation; we already " "expect an error for {}".format(expected_error) @@ -172,6 +206,30 @@ class X: error="X.mistyped_var", ) + @collect_cases + def test_coroutines(self) -> Iterator[Case]: + yield Case( + stub="def bar() -> int: ...", + runtime="async def bar(): return 5", + error="bar", + ) + # Don't error for this one -- we get false positives otherwise + yield Case( + stub="async def foo() -> int: ...", + runtime="def foo(): return 5", + error=None, + ) + yield Case( + stub="def baz() -> int: ...", + runtime="def baz(): return 5", + error=None, + ) + yield Case( + stub="async def bingo() -> int: ...", + runtime="async def bingo(): return 5", + error=None, + ) + @collect_cases def test_arg_name(self) -> Iterator[Case]: yield Case( @@ -657,6 +715,16 @@ def h(x: str): ... yield Case( stub="from mystery import A, B as B, C as D # type: ignore", runtime="", error="B" ) + yield Case( + stub="class Y: ...", + runtime="__all__ += ['Y']\nclass Y:\n def __or__(self, other): return self|other", + error="Y.__or__" + ) + yield Case( + stub="class Z: ...", + runtime="__all__ += ['Z']\nclass Z:\n def __reduce__(self): return (Z,)", + error=None + ) @collect_cases def test_missing_no_runtime_all(self) -> Iterator[Case]: @@ -666,7 +734,9 @@ def test_missing_no_runtime_all(self) -> Iterator[Case]: @collect_cases def test_non_public_1(self) -> Iterator[Case]: - yield Case(stub="__all__: list[str]", runtime="", error=None) # dummy case + yield Case( + stub="__all__: list[str]", runtime="", error="test_module.__all__" + ) # dummy case yield Case(stub="_f: int", runtime="def _f(): ...", error="_f") @collect_cases @@ -678,7 +748,7 @@ def test_non_public_2(self) -> Iterator[Case]: yield Case(stub="g: int", runtime="def g(): ...", error="g") @collect_cases - def test_special_dunders(self) -> Iterator[Case]: + def test_dunders(self) -> Iterator[Case]: yield Case( stub="class A:\n def __init__(self, a: int, b: int) -> None: ...", runtime="class A:\n def __init__(self, a, bx): pass", @@ -691,8 +761,13 @@ def test_special_dunders(self) -> Iterator[Case]: ) if sys.version_info >= (3, 6): yield Case( - stub="class C:\n def __init_subclass__(cls, e: int, **kwargs: int) -> None: ...", - runtime="class C:\n def __init_subclass__(cls, e, **kwargs): pass", + stub=( + "class C:\n" + " def __init_subclass__(\n" + " cls, e: int = ..., **kwargs: int\n" + " ) -> None: ...\n" + ), + runtime="class C:\n def __init_subclass__(cls, e=1, **kwargs): pass", error=None, ) if sys.version_info >= (3, 9): @@ -702,6 +777,19 @@ def test_special_dunders(self) -> Iterator[Case]: error=None, ) + @collect_cases + def test_not_subclassable(self) -> Iterator[Case]: + yield Case( + stub="class CanBeSubclassed: ...", + runtime="class CanBeSubclassed: ...", + error=None, + ) + yield Case( + stub="class CannotBeSubclassed:\n def __init_subclass__(cls) -> None: ...", + runtime="class CannotBeSubclassed:\n def __init_subclass__(cls): raise TypeError", + error="CannotBeSubclassed", + ) + @collect_cases def test_name_mangling(self) -> Iterator[Case]: yield Case( @@ -828,6 +916,41 @@ def test_bad_literal(self) -> Iterator[Case]: error='WRONG_BOOL_2', ) + @collect_cases + def test_special_subtype(self) -> Iterator[Case]: + yield Case( + stub=""" + b1: bool + b2: bool + b3: bool + """, + runtime=""" + b1 = 0 + b2 = 1 + b3 = 2 + """, + error="b3", + ) + yield Case( + stub=""" + from typing_extensions import TypedDict + + class _Options(TypedDict): + a: str + b: int + + opt1: _Options + opt2: _Options + opt3: _Options + """, + runtime=""" + opt1 = {"a": "3.", "b": 14} + opt2 = {"some": "stuff"} # false negative + opt3 = 0 + """, + error="opt3", + ) + def remove_color_code(s: str) -> str: return re.sub("\\x1b.*?m", "", s) # this works! @@ -948,12 +1071,19 @@ def test_missing_stubs(self) -> None: assert "error: not_a_module failed to find stubs" in remove_color_code(output.getvalue()) def test_get_typeshed_stdlib_modules(self) -> None: - stdlib = mypy.stubtest.get_typeshed_stdlib_modules(None) + stdlib = mypy.stubtest.get_typeshed_stdlib_modules(None, (3, 6)) assert "builtins" in stdlib assert "os" in stdlib assert "os.path" in stdlib assert "asyncio" in stdlib - assert ("dataclasses" in stdlib) == (sys.version_info >= (3, 7)) + assert "graphlib" not in stdlib + assert "formatter" in stdlib + assert "importlib.metadata" not in stdlib + + stdlib = mypy.stubtest.get_typeshed_stdlib_modules(None, (3, 10)) + assert "graphlib" in stdlib + assert "formatter" not in stdlib + assert "importlib.metadata" in stdlib def test_signature(self) -> None: def f(a: int, b: int, *, c: int, d: int = 0, **kwargs: Any) -> None: @@ -972,7 +1102,7 @@ def test_config_file(self) -> None: "plugins={}/test-data/unit/plugins/decimal_to_int.py\n".format(root_dir) ) output = run_stubtest(stub=stub, runtime=runtime, options=[]) - assert output == ( + assert remove_color_code(output) == ( "error: test_module.temp variable differs from runtime type Literal[5]\n" "Stub: at line 2\ndecimal.Decimal\nRuntime:\n5\n\n" ) diff --git a/mypy/test/testtypes.py b/mypy/test/testtypes.py index 0d37fe795bbc..6af1c18145cf 100644 --- a/mypy/test/testtypes.py +++ b/mypy/test/testtypes.py @@ -3,7 +3,7 @@ from typing import List, Tuple from mypy.test.helpers import Suite, assert_equal, assert_type, skip -from mypy.erasetype import erase_type +from mypy.erasetype import erase_type, remove_instance_last_known_values from mypy.expandtype import expand_type from mypy.join import join_types, join_simple from mypy.meet import meet_types, narrow_declared_type @@ -11,7 +11,8 @@ from mypy.indirection import TypeIndirectionVisitor from mypy.types import ( UnboundType, AnyType, CallableType, TupleType, TypeVarType, Type, Instance, NoneType, - Overloaded, TypeType, UnionType, UninhabitedType, TypeVarId, TypeOfAny, get_proper_type + Overloaded, TypeType, UnionType, UninhabitedType, TypeVarId, TypeOfAny, ProperType, + get_proper_type ) from mypy.nodes import ARG_POS, ARG_OPT, ARG_STAR, ARG_STAR2, CONTRAVARIANT, INVARIANT, COVARIANT from mypy.subtypes import is_subtype, is_more_precise, is_proper_subtype @@ -1092,3 +1093,46 @@ def assert_simple_is_same(self, s: Type, t: Type, expected: bool, strict: bool) '({} == {}) is {{}} ({{}} expected)'.format(s, t)) assert_equal(hash(s) == hash(t), expected, '(hash({}) == hash({}) is {{}} ({{}} expected)'.format(s, t)) + + +class RemoveLastKnownValueSuite(Suite): + def setUp(self) -> None: + self.fx = TypeFixture() + + def test_optional(self) -> None: + t = UnionType.make_union([self.fx.a, self.fx.nonet]) + self.assert_union_result(t, [self.fx.a, self.fx.nonet]) + + def test_two_instances(self) -> None: + t = UnionType.make_union([self.fx.a, self.fx.b]) + self.assert_union_result(t, [self.fx.a, self.fx.b]) + + def test_multiple_same_instances(self) -> None: + t = UnionType.make_union([self.fx.a, self.fx.a]) + assert remove_instance_last_known_values(t) == self.fx.a + t = UnionType.make_union([self.fx.a, self.fx.a, self.fx.b]) + self.assert_union_result(t, [self.fx.a, self.fx.b]) + t = UnionType.make_union([self.fx.a, self.fx.nonet, self.fx.a, self.fx.b]) + self.assert_union_result(t, [self.fx.a, self.fx.nonet, self.fx.b]) + + def test_single_last_known_value(self) -> None: + t = UnionType.make_union([self.fx.lit1_inst, self.fx.nonet]) + self.assert_union_result(t, [self.fx.a, self.fx.nonet]) + + def test_last_known_values_with_merge(self) -> None: + t = UnionType.make_union([self.fx.lit1_inst, self.fx.lit2_inst, self.fx.lit4_inst]) + assert remove_instance_last_known_values(t) == self.fx.a + t = UnionType.make_union([self.fx.lit1_inst, + self.fx.b, + self.fx.lit2_inst, + self.fx.lit4_inst]) + self.assert_union_result(t, [self.fx.a, self.fx.b]) + + def test_generics(self) -> None: + t = UnionType.make_union([self.fx.ga, self.fx.gb]) + self.assert_union_result(t, [self.fx.ga, self.fx.gb]) + + def assert_union_result(self, t: ProperType, expected: List[Type]) -> None: + t2 = remove_instance_last_known_values(t) + assert type(t2) is UnionType + assert t2.items == expected diff --git a/mypy/test/typefixture.py b/mypy/test/typefixture.py index 1a5dd8164136..7d4faeccf432 100644 --- a/mypy/test/typefixture.py +++ b/mypy/test/typefixture.py @@ -157,9 +157,11 @@ def make_type_var(name: str, id: int, values: List[Type], upper_bound: Type, self.lit1 = LiteralType(1, self.a) self.lit2 = LiteralType(2, self.a) self.lit3 = LiteralType("foo", self.d) + self.lit4 = LiteralType(4, self.a) self.lit1_inst = Instance(self.ai, [], last_known_value=self.lit1) self.lit2_inst = Instance(self.ai, [], last_known_value=self.lit2) self.lit3_inst = Instance(self.di, [], last_known_value=self.lit3) + self.lit4_inst = Instance(self.ai, [], last_known_value=self.lit4) self.type_a = TypeType.make_normalized(self.a) self.type_b = TypeType.make_normalized(self.b) diff --git a/mypy/typeanal.py b/mypy/typeanal.py index 7b114af26dc9..89fd27fbcb75 100644 --- a/mypy/typeanal.py +++ b/mypy/typeanal.py @@ -6,7 +6,7 @@ from mypy.backports import OrderedDict from typing import ( - Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable, Sequence, Union + Callable, List, Optional, Set, Tuple, Iterator, TypeVar, Iterable, Sequence ) from typing_extensions import Final from mypy_extensions import DefaultNamedArg @@ -14,7 +14,7 @@ from mypy.messages import MessageBuilder, quote_type_string, format_type_bare from mypy.options import Options from mypy.types import ( - Type, UnboundType, TupleType, TypedDictType, UnionType, Instance, AnyType, + NEVER_NAMES, Type, UnboundType, TupleType, TypedDictType, UnionType, Instance, AnyType, CallableType, NoneType, ErasedType, DeletedType, TypeList, TypeVarType, SyntheticTypeVisitor, StarType, PartialType, EllipsisType, UninhabitedType, TypeType, CallableArgument, TypeQuery, union_items, TypeOfAny, LiteralType, RawExpressionType, @@ -348,7 +348,7 @@ def try_analyze_special_unbound_type(self, t: UnboundType, fullname: str) -> Opt self.fail(message_registry.CLASSVAR_ATMOST_ONE_TYPE_ARG, t) return AnyType(TypeOfAny.from_error) return self.anal_type(t.args[0]) - elif fullname in ('mypy_extensions.NoReturn', 'typing.NoReturn'): + elif fullname in NEVER_NAMES: return UninhabitedType(is_noreturn=True) elif fullname in LITERAL_TYPE_NAMES: return self.analyze_literal_type(t) @@ -490,7 +490,12 @@ def analyze_unbound_type_without_type_info(self, t: UnboundType, sym: SymbolTabl message = message_registry.VARIABLE_NOT_VALID_TYPE elif isinstance(sym.node, (SYMBOL_FUNCBASE_TYPES, Decorator)): message = message_registry.FUNCTION_NOT_VALID_TYPE - notes.append('Perhaps you need "Callable[...]" or a callback protocol?') + if name == 'builtins.any': + notes.append('Perhaps you meant "typing.Any" instead of "any"?') + elif name == 'builtins.callable': + notes.append('Perhaps you meant "typing.Callable" instead of "callable"?') + else: + notes.append('Perhaps you need "Callable[...]" or a callback protocol?') elif isinstance(sym.node, MypyFile): # TODO: suggest a protocol when supported. message = message_registry.MODULE_NOT_VALID_TYPE @@ -927,8 +932,7 @@ def analyze_literal_param(self, idx: int, arg: Type, ctx: Context) -> Optional[L def analyze_type(self, t: Type) -> Type: return t.accept(self) - # TODO(tushar): remove `str` type and `code` property from here - def fail(self, msg: Union[str, ErrorMessage], ctx: Context) -> None: + def fail(self, msg: ErrorMessage, ctx: Context) -> None: self.fail_func(msg, ctx) def note(self, msg: str, ctx: Context, *, code: Optional[ErrorCode] = None) -> None: diff --git a/mypy/typeops.py b/mypy/typeops.py index 88d4bc744bdf..57fdfeadad9a 100644 --- a/mypy/typeops.py +++ b/mypy/typeops.py @@ -14,7 +14,8 @@ TupleType, Instance, FunctionLike, Type, CallableType, TypeVarLikeType, Overloaded, TypeVarType, UninhabitedType, FormalArgument, UnionType, NoneType, AnyType, TypeOfAny, TypeType, ProperType, LiteralType, get_proper_type, get_proper_types, - copy_type, TypeAliasType, TypeQuery, ParamSpecType + copy_type, TypeAliasType, TypeQuery, ParamSpecType, + ENUM_REMOVED_PROPS ) from mypy.nodes import ( FuncBase, FuncItem, FuncDef, OverloadedFuncDef, TypeInfo, ARG_STAR, ARG_STAR2, ARG_POS, @@ -715,8 +716,8 @@ class Status(Enum): for name, symbol in typ.type.names.items(): if not isinstance(symbol.node, Var): continue - # Skip "_order_" and "__order__", since Enum will remove it - if name in ("_order_", "__order__"): + # Skip these since Enum will remove it + if name in ENUM_REMOVED_PROPS: continue new_items.append(LiteralType(name, typ)) # SymbolTables are really just dicts, and dicts are guaranteed to preserve @@ -845,3 +846,18 @@ def is_redundant_literal_instance(general: ProperType, specific: ProperType) -> return True return False + + +def separate_union_literals(t: UnionType) -> Tuple[Sequence[LiteralType], Sequence[Type]]: + """Separate literals from other members in a union type.""" + literal_items = [] + union_items = [] + + for item in t.items: + proper = get_proper_type(item) + if isinstance(proper, LiteralType): + literal_items.append(proper) + else: + union_items.append(item) + + return literal_items, union_items diff --git a/mypy/types.py b/mypy/types.py index d3987897995e..dadbb84fe1c8 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -126,6 +126,28 @@ 'typing.Reversible', ) +REVEAL_TYPE_NAMES: Final = ( + 'builtins.reveal_type', + 'typing.reveal_type', + 'typing_extensions.reveal_type', +) + +# Attributes that can optionally be defined in the body of a subclass of +# enum.Enum but are removed from the class __dict__ by EnumMeta. +ENUM_REMOVED_PROPS: Final = ( + '_ignore_', + '_order_', + '__order__', +) + +NEVER_NAMES: Final = ( + 'typing.NoReturn', + 'typing_extensions.NoReturn', + 'mypy_extensions.NoReturn', + 'typing.Never', + 'typing_extensions.Never', +) + # A placeholder used for Bogus[...] parameters _dummy: Final[Any] = object() @@ -360,6 +382,9 @@ def __repr__(self) -> str: else: return "NotRequired[{}]".format(self.item) + def accept(self, visitor: 'TypeVisitor[T]') -> T: + return self.item.accept(visitor) + class ProperType(Type): """Not a type alias. diff --git a/mypy/typeshed/stdlib/@python2/_typeshed/xml.pyi b/mypy/typeshed/stdlib/@python2/_typeshed/xml.pyi index 6a5d2531ca72..eaff9a641db4 100644 --- a/mypy/typeshed/stdlib/@python2/_typeshed/xml.pyi +++ b/mypy/typeshed/stdlib/@python2/_typeshed/xml.pyi @@ -1,7 +1,6 @@ # Stub-only types. This module does not exist at runtime. -from typing import Any -from typing_extensions import Protocol +from typing import Any, Protocol # As defined https://docs.python.org/3/library/xml.dom.html#domimplementation-objects class DOMImplementation(Protocol): diff --git a/mypy/typeshed/stdlib/@python2/_winreg.pyi b/mypy/typeshed/stdlib/@python2/_winreg.pyi index 7297626ac8b3..5b8ec1130ca1 100644 --- a/mypy/typeshed/stdlib/@python2/_winreg.pyi +++ b/mypy/typeshed/stdlib/@python2/_winreg.pyi @@ -1,96 +1,96 @@ +import sys from types import TracebackType from typing import Any, Tuple, Type, Union -_KeyType = Union[HKEYType, int] +if sys.platform == "win32": + _KeyType = Union[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 CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = ..., access: int = ...) -> HKEYType: ... + def DeleteKey(__key: _KeyType, __sub_key: str) -> None: ... + def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = ..., reserved: int = ...) -> 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(__str: 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 = ..., access: int = ...) -> HKEYType: ... + def OpenKeyEx(key: _KeyType, sub_key: str, reserved: int = ..., access: int = ...) -> 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 SetValueEx( + __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: ... + HKEY_CLASSES_ROOT: int + HKEY_CURRENT_USER: int + HKEY_LOCAL_MACHINE: int + HKEY_USERS: int + HKEY_PERFORMANCE_DATA: int + HKEY_CURRENT_CONFIG: int + HKEY_DYN_DATA: 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 CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = ..., access: int = ...) -> HKEYType: ... -def DeleteKey(__key: _KeyType, __sub_key: str) -> None: ... -def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = ..., reserved: int = ...) -> 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(__str: 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 = ..., access: int = ...) -> HKEYType: ... -def OpenKeyEx(key: _KeyType, sub_key: str, reserved: int = ..., access: int = ...) -> 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 SetValueEx( - __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: ... + KEY_ALL_ACCESS: int + KEY_WRITE: int + KEY_READ: int + KEY_EXECUTE: int + KEY_QUERY_VALUE: int + KEY_SET_VALUE: int + KEY_CREATE_SUB_KEY: int + KEY_ENUMERATE_SUB_KEYS: int + KEY_NOTIFY: int + KEY_CREATE_LINK: int -HKEY_CLASSES_ROOT: int -HKEY_CURRENT_USER: int -HKEY_LOCAL_MACHINE: int -HKEY_USERS: int -HKEY_PERFORMANCE_DATA: int -HKEY_CURRENT_CONFIG: int -HKEY_DYN_DATA: int + KEY_WOW64_64KEY: int + KEY_WOW64_32KEY: int -KEY_ALL_ACCESS: int -KEY_WRITE: int -KEY_READ: int -KEY_EXECUTE: int -KEY_QUERY_VALUE: int -KEY_SET_VALUE: int -KEY_CREATE_SUB_KEY: int -KEY_ENUMERATE_SUB_KEYS: int -KEY_NOTIFY: int -KEY_CREATE_LINK: int + REG_BINARY: int + REG_DWORD: int + REG_DWORD_LITTLE_ENDIAN: int + REG_DWORD_BIG_ENDIAN: int + REG_EXPAND_SZ: int + REG_LINK: int + REG_MULTI_SZ: int + REG_NONE: int + REG_RESOURCE_LIST: int + REG_FULL_RESOURCE_DESCRIPTOR: int + REG_RESOURCE_REQUIREMENTS_LIST: int + REG_SZ: int -KEY_WOW64_64KEY: int -KEY_WOW64_32KEY: int + 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_BINARY: int -REG_DWORD: int -REG_DWORD_LITTLE_ENDIAN: int -REG_DWORD_BIG_ENDIAN: int -REG_EXPAND_SZ: int -REG_LINK: int -REG_MULTI_SZ: int -REG_NONE: int -REG_RESOURCE_LIST: int -REG_FULL_RESOURCE_DESCRIPTOR: int -REG_RESOURCE_REQUIREMENTS_LIST: int -REG_SZ: int + error = OSError -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 - -error = OSError - -# Though this class has a __name__ of PyHKEY, it's exposed as HKEYType for some reason -class HKEYType: - def __bool__(self) -> bool: ... - def __int__(self) -> int: ... - def __enter__(self) -> HKEYType: ... - def __exit__( - self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> bool | None: ... - def Close(self) -> None: ... - def Detach(self) -> int: ... + # Though this class has a __name__ of PyHKEY, it's exposed as HKEYType for some reason + class HKEYType: + def __bool__(self) -> bool: ... + def __int__(self) -> int: ... + def __enter__(self) -> HKEYType: ... + def __exit__( + self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> bool | None: ... + def Close(self) -> None: ... + def Detach(self) -> int: ... diff --git a/mypy/typeshed/stdlib/@python2/contextlib.pyi b/mypy/typeshed/stdlib/@python2/contextlib.pyi index 6aabf5a16e47..6782fbf1874c 100644 --- a/mypy/typeshed/stdlib/@python2/contextlib.pyi +++ b/mypy/typeshed/stdlib/@python2/contextlib.pyi @@ -1,6 +1,5 @@ from types import TracebackType -from typing import IO, Any, Callable, ContextManager, Iterable, Iterator, Optional, Type, TypeVar -from typing_extensions import Protocol +from typing import IO, Any, Callable, ContextManager, Iterable, Iterator, Optional, Protocol, Type, TypeVar _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) diff --git a/mypy/typeshed/stdlib/@python2/crypt.pyi b/mypy/typeshed/stdlib/@python2/crypt.pyi index c4036dbe7a5a..a7c0cb1e8fbc 100644 --- a/mypy/typeshed/stdlib/@python2/crypt.pyi +++ b/mypy/typeshed/stdlib/@python2/crypt.pyi @@ -1 +1,4 @@ -def crypt(word: str, salt: str) -> str: ... +import sys + +if sys.platform != "win32": + def crypt(word: str, salt: str) -> str: ... diff --git a/mypy/typeshed/stdlib/@python2/ctypes/__init__.pyi b/mypy/typeshed/stdlib/@python2/ctypes/__init__.pyi index 33184cc2ff88..8a10ff954e27 100644 --- a/mypy/typeshed/stdlib/@python2/ctypes/__init__.pyi +++ b/mypy/typeshed/stdlib/@python2/ctypes/__init__.pyi @@ -150,7 +150,7 @@ def create_unicode_buffer(init: _UnionT[int, Text], size: int | None = ...) -> A if sys.platform == "win32": def DllCanUnloadNow() -> int: ... def DllGetClassObject(rclsid: Any, riid: Any, ppv: Any) -> int: ... # TODO not documented - def FormatError(code: int) -> str: ... + def FormatError(code: int = ...) -> str: ... def GetLastError() -> int: ... def get_errno() -> int: ... diff --git a/mypy/typeshed/stdlib/@python2/distutils/command/bdist_msi.pyi b/mypy/typeshed/stdlib/@python2/distutils/command/bdist_msi.pyi index a761792018a9..150229fb01c9 100644 --- a/mypy/typeshed/stdlib/@python2/distutils/command/bdist_msi.pyi +++ b/mypy/typeshed/stdlib/@python2/distutils/command/bdist_msi.pyi @@ -1,6 +1,8 @@ -from distutils.cmd import Command +import sys -class bdist_msi(Command): - def initialize_options(self) -> None: ... - def finalize_options(self) -> None: ... - def run(self) -> None: ... +if sys.platform == "win32": + from distutils.cmd import Command + class bdist_msi(Command): + def initialize_options(self) -> None: ... + def finalize_options(self) -> None: ... + def run(self) -> None: ... diff --git a/mypy/typeshed/stdlib/@python2/fcntl.pyi b/mypy/typeshed/stdlib/@python2/fcntl.pyi index b3730270f1cc..0d9d598ab7c5 100644 --- a/mypy/typeshed/stdlib/@python2/fcntl.pyi +++ b/mypy/typeshed/stdlib/@python2/fcntl.pyi @@ -1,82 +1,83 @@ +import sys from _typeshed import FileDescriptorLike from typing import Any -FASYNC: int -FD_CLOEXEC: int +if sys.platform != "win32": + FASYNC: int + FD_CLOEXEC: int -DN_ACCESS: int -DN_ATTRIB: int -DN_CREATE: int -DN_DELETE: int -DN_MODIFY: int -DN_MULTISHOT: int -DN_RENAME: int -F_DUPFD: int -F_EXLCK: int -F_GETFD: int -F_GETFL: int -F_GETLEASE: int -F_GETLK: int -F_GETLK64: int -F_GETOWN: int -F_GETSIG: int -F_NOTIFY: int -F_RDLCK: int -F_SETFD: int -F_SETFL: int -F_SETLEASE: int -F_SETLK: int -F_SETLK64: int -F_SETLKW: int -F_SETLKW64: int -F_SETOWN: int -F_SETSIG: int -F_SHLCK: int -F_UNLCK: int -F_WRLCK: int -I_ATMARK: int -I_CANPUT: int -I_CKBAND: int -I_FDINSERT: int -I_FIND: int -I_FLUSH: int -I_FLUSHBAND: int -I_GETBAND: int -I_GETCLTIME: int -I_GETSIG: int -I_GRDOPT: int -I_GWROPT: int -I_LINK: int -I_LIST: int -I_LOOK: int -I_NREAD: int -I_PEEK: int -I_PLINK: int -I_POP: int -I_PUNLINK: int -I_PUSH: int -I_RECVFD: int -I_SENDFD: int -I_SETCLTIME: int -I_SETSIG: int -I_SRDOPT: int -I_STR: int -I_SWROPT: int -I_UNLINK: int -LOCK_EX: int -LOCK_MAND: int -LOCK_NB: int -LOCK_READ: int -LOCK_RW: int -LOCK_SH: int -LOCK_UN: int -LOCK_WRITE: int + DN_ACCESS: int + DN_ATTRIB: int + DN_CREATE: int + DN_DELETE: int + DN_MODIFY: int + DN_MULTISHOT: int + DN_RENAME: int + F_DUPFD: int + F_EXLCK: int + F_GETFD: int + F_GETFL: int + F_GETLEASE: int + F_GETLK: int + F_GETLK64: int + F_GETOWN: int + F_GETSIG: int + F_NOTIFY: int + F_RDLCK: int + F_SETFD: int + F_SETFL: int + F_SETLEASE: int + F_SETLK: int + F_SETLK64: int + F_SETLKW: int + F_SETLKW64: int + F_SETOWN: int + F_SETSIG: int + F_SHLCK: int + F_UNLCK: int + F_WRLCK: int + I_ATMARK: int + I_CANPUT: int + I_CKBAND: int + I_FDINSERT: int + I_FIND: int + I_FLUSH: int + I_FLUSHBAND: int + I_GETBAND: int + I_GETCLTIME: int + I_GETSIG: int + I_GRDOPT: int + I_GWROPT: int + I_LINK: int + I_LIST: int + I_LOOK: int + I_NREAD: int + I_PEEK: int + I_PLINK: int + I_POP: int + I_PUNLINK: int + I_PUSH: int + I_RECVFD: int + I_SENDFD: int + I_SETCLTIME: int + I_SETSIG: int + I_SRDOPT: int + I_STR: int + I_SWROPT: int + I_UNLINK: int + LOCK_EX: int + LOCK_MAND: int + LOCK_NB: int + LOCK_READ: int + LOCK_RW: int + LOCK_SH: int + LOCK_UN: int + LOCK_WRITE: int -# TODO All these return either int or bytes depending on the value of -# cmd (not on the type of arg). -def fcntl(fd: FileDescriptorLike, op: int, arg: int | bytes = ...) -> Any: ... - -# TODO: arg: int or read-only buffer interface or read-write buffer interface -def ioctl(fd: FileDescriptorLike, op: int, arg: int | bytes = ..., mutate_flag: bool = ...) -> Any: ... -def flock(fd: FileDescriptorLike, op: int) -> None: ... -def lockf(fd: FileDescriptorLike, op: int, length: int = ..., start: int = ..., whence: int = ...) -> Any: ... + # TODO All these return either int or bytes depending on the value of + # cmd (not on the type of arg). + def fcntl(fd: FileDescriptorLike, op: int, arg: int | bytes = ...) -> Any: ... + # TODO: arg: int or read-only buffer interface or read-write buffer interface + def ioctl(fd: FileDescriptorLike, op: int, arg: int | bytes = ..., mutate_flag: bool = ...) -> Any: ... + def flock(fd: FileDescriptorLike, op: int) -> None: ... + def lockf(fd: FileDescriptorLike, op: int, length: int = ..., start: int = ..., whence: int = ...) -> Any: ... diff --git a/mypy/typeshed/stdlib/@python2/grp.pyi b/mypy/typeshed/stdlib/@python2/grp.pyi index 63898b26bf17..6e937ec0f262 100644 --- a/mypy/typeshed/stdlib/@python2/grp.pyi +++ b/mypy/typeshed/stdlib/@python2/grp.pyi @@ -1,11 +1,12 @@ +import sys from typing import List, NamedTuple -class struct_group(NamedTuple): - gr_name: str - gr_passwd: str | None - gr_gid: int - gr_mem: List[str] - -def getgrall() -> List[struct_group]: ... -def getgrgid(id: int) -> struct_group: ... -def getgrnam(name: str) -> struct_group: ... +if sys.platform != "win32": + class struct_group(NamedTuple): + gr_name: str + gr_passwd: str | None + gr_gid: int + gr_mem: List[str] + def getgrall() -> List[struct_group]: ... + def getgrgid(id: int) -> struct_group: ... + def getgrnam(name: str) -> struct_group: ... diff --git a/mypy/typeshed/stdlib/@python2/pty.pyi b/mypy/typeshed/stdlib/@python2/pty.pyi index e8afa2df5166..d9d9fd98e41b 100644 --- a/mypy/typeshed/stdlib/@python2/pty.pyi +++ b/mypy/typeshed/stdlib/@python2/pty.pyi @@ -1,15 +1,16 @@ +import sys from typing import Callable, Iterable, Tuple -_Reader = Callable[[int], bytes] +if sys.platform != "win32": + _Reader = Callable[[int], bytes] -STDIN_FILENO: int -STDOUT_FILENO: int -STDERR_FILENO: int + STDIN_FILENO: int + STDOUT_FILENO: int + STDERR_FILENO: int -CHILD: int - -def openpty() -> Tuple[int, int]: ... -def master_open() -> Tuple[int, str]: ... -def slave_open(tty_name: str) -> int: ... -def fork() -> Tuple[int, int]: ... -def spawn(argv: str | Iterable[str], master_read: _Reader = ..., stdin_read: _Reader = ...) -> None: ... + CHILD: int + def openpty() -> Tuple[int, int]: ... + def master_open() -> Tuple[int, str]: ... + def slave_open(tty_name: str) -> int: ... + def fork() -> Tuple[int, int]: ... + def spawn(argv: str | Iterable[str], master_read: _Reader = ..., stdin_read: _Reader = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/@python2/pwd.pyi b/mypy/typeshed/stdlib/@python2/pwd.pyi index 83020c1576dd..583999fd84b7 100644 --- a/mypy/typeshed/stdlib/@python2/pwd.pyi +++ b/mypy/typeshed/stdlib/@python2/pwd.pyi @@ -1,14 +1,15 @@ +import sys from typing import List, Tuple -class struct_passwd(Tuple[str, str, int, int, str, str, str]): - pw_name: str - pw_passwd: str - pw_uid: int - pw_gid: int - pw_gecos: str - pw_dir: str - pw_shell: str - -def getpwall() -> List[struct_passwd]: ... -def getpwuid(__uid: int) -> struct_passwd: ... -def getpwnam(__name: str) -> struct_passwd: ... +if sys.platform != "win32": + class struct_passwd(Tuple[str, str, int, int, str, str, str]): + pw_name: str + pw_passwd: str + pw_uid: int + pw_gid: int + pw_gecos: str + pw_dir: str + pw_shell: str + def getpwall() -> List[struct_passwd]: ... + def getpwuid(__uid: int) -> struct_passwd: ... + def getpwnam(__name: str) -> struct_passwd: ... diff --git a/mypy/typeshed/stdlib/@python2/readline.pyi b/mypy/typeshed/stdlib/@python2/readline.pyi index fb9b12d9a8e9..9b82d9bae636 100644 --- a/mypy/typeshed/stdlib/@python2/readline.pyi +++ b/mypy/typeshed/stdlib/@python2/readline.pyi @@ -1,30 +1,31 @@ +import sys from typing import Callable, Optional, Sequence, Text -_CompleterT = Optional[Callable[[str, int], Optional[str]]] -_CompDispT = Optional[Callable[[str, Sequence[str], int], None]] - -def parse_and_bind(__string: str) -> None: ... -def read_init_file(__filename: Text | None = ...) -> None: ... -def get_line_buffer() -> str: ... -def insert_text(__string: str) -> None: ... -def redisplay() -> None: ... -def read_history_file(__filename: Text | None = ...) -> None: ... -def write_history_file(__filename: Text | None = ...) -> None: ... -def get_history_length() -> int: ... -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_startup_hook(__function: Callable[[], None] | None = ...) -> None: ... -def set_pre_input_hook(__function: Callable[[], None] | None = ...) -> None: ... -def set_completer(__function: _CompleterT = ...) -> None: ... -def get_completer() -> _CompleterT: ... -def get_completion_type() -> int: ... -def get_begidx() -> int: ... -def get_endidx() -> int: ... -def set_completer_delims(__string: str) -> None: ... -def get_completer_delims() -> str: ... -def set_completion_display_matches_hook(__function: _CompDispT = ...) -> None: ... +if sys.platform != "win32": + _CompleterT = Optional[Callable[[str, int], Optional[str]]] + _CompDispT = Optional[Callable[[str, Sequence[str], int], None]] + def parse_and_bind(__string: str) -> None: ... + def read_init_file(__filename: Text | None = ...) -> None: ... + def get_line_buffer() -> str: ... + def insert_text(__string: str) -> None: ... + def redisplay() -> None: ... + def read_history_file(__filename: Text | None = ...) -> None: ... + def write_history_file(__filename: Text | None = ...) -> None: ... + def get_history_length() -> int: ... + 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_startup_hook(__function: Callable[[], None] | None = ...) -> None: ... + def set_pre_input_hook(__function: Callable[[], None] | None = ...) -> None: ... + def set_completer(__function: _CompleterT = ...) -> None: ... + def get_completer() -> _CompleterT: ... + def get_completion_type() -> int: ... + def get_begidx() -> int: ... + def get_endidx() -> int: ... + def set_completer_delims(__string: str) -> None: ... + def get_completer_delims() -> str: ... + def set_completion_display_matches_hook(__function: _CompDispT = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/@python2/resource.pyi b/mypy/typeshed/stdlib/@python2/resource.pyi index ad9502db1940..476438d53674 100644 --- a/mypy/typeshed/stdlib/@python2/resource.pyi +++ b/mypy/typeshed/stdlib/@python2/resource.pyi @@ -1,46 +1,42 @@ +import sys from typing import NamedTuple, Tuple -class error(Exception): ... - -RLIM_INFINITY: int - -def getrlimit(resource: int) -> Tuple[int, int]: ... -def setrlimit(resource: int, limits: Tuple[int, int]) -> None: ... - -RLIMIT_CORE: int -RLIMIT_CPU: int -RLIMIT_FSIZE: int -RLIMIT_DATA: int -RLIMIT_STACK: int -RLIMIT_RSS: int -RLIMIT_NPROC: int -RLIMIT_NOFILE: int -RLIMIT_OFILE: int -RLIMIT_MEMLOCK: int -RLIMIT_VMEM: int -RLIMIT_AS: int - -class _RUsage(NamedTuple): - ru_utime: float - ru_stime: float - ru_maxrss: int - ru_ixrss: int - ru_idrss: int - ru_isrss: int - ru_minflt: int - ru_majflt: int - ru_nswap: int - ru_inblock: int - ru_oublock: int - ru_msgsnd: int - ru_msgrcv: int - ru_nsignals: int - ru_nvcsw: int - ru_nivcsw: int - -def getrusage(who: int) -> _RUsage: ... -def getpagesize() -> int: ... - -RUSAGE_SELF: int -RUSAGE_CHILDREN: int -RUSAGE_BOTH: int +if sys.platform != "win32": + class error(Exception): ... + RLIM_INFINITY: int + def getrlimit(resource: int) -> Tuple[int, int]: ... + def setrlimit(resource: int, limits: Tuple[int, int]) -> None: ... + RLIMIT_CORE: int + RLIMIT_CPU: int + RLIMIT_FSIZE: int + RLIMIT_DATA: int + RLIMIT_STACK: int + RLIMIT_RSS: int + RLIMIT_NPROC: int + RLIMIT_NOFILE: int + RLIMIT_OFILE: int + RLIMIT_MEMLOCK: int + RLIMIT_VMEM: int + RLIMIT_AS: int + class _RUsage(NamedTuple): + ru_utime: float + ru_stime: float + ru_maxrss: int + ru_ixrss: int + ru_idrss: int + ru_isrss: int + ru_minflt: int + ru_majflt: int + ru_nswap: int + ru_inblock: int + ru_oublock: int + ru_msgsnd: int + ru_msgrcv: int + ru_nsignals: int + ru_nvcsw: int + ru_nivcsw: int + def getrusage(who: int) -> _RUsage: ... + def getpagesize() -> int: ... + RUSAGE_SELF: int + RUSAGE_CHILDREN: int + RUSAGE_BOTH: int diff --git a/mypy/typeshed/stdlib/@python2/spwd.pyi b/mypy/typeshed/stdlib/@python2/spwd.pyi index 756c142a61da..95122ce43d1e 100644 --- a/mypy/typeshed/stdlib/@python2/spwd.pyi +++ b/mypy/typeshed/stdlib/@python2/spwd.pyi @@ -1,15 +1,16 @@ +import sys from typing import List, NamedTuple -class struct_spwd(NamedTuple): - sp_nam: str - sp_pwd: str - sp_lstchg: int - sp_min: int - sp_max: int - sp_warn: int - sp_inact: int - sp_expire: int - sp_flag: int - -def getspall() -> List[struct_spwd]: ... -def getspnam(name: str) -> struct_spwd: ... +if sys.platform != "win32": + class struct_spwd(NamedTuple): + sp_nam: str + sp_pwd: str + sp_lstchg: int + sp_min: int + sp_max: int + sp_warn: int + sp_inact: int + sp_expire: int + sp_flag: int + def getspall() -> List[struct_spwd]: ... + def getspnam(name: str) -> struct_spwd: ... diff --git a/mypy/typeshed/stdlib/@python2/syslog.pyi b/mypy/typeshed/stdlib/@python2/syslog.pyi index 49169f40db5c..eaeeb7715e48 100644 --- a/mypy/typeshed/stdlib/@python2/syslog.pyi +++ b/mypy/typeshed/stdlib/@python2/syslog.pyi @@ -1,43 +1,44 @@ +import sys from typing import overload -LOG_ALERT: int -LOG_AUTH: int -LOG_CONS: int -LOG_CRIT: int -LOG_CRON: int -LOG_DAEMON: int -LOG_DEBUG: int -LOG_EMERG: int -LOG_ERR: int -LOG_INFO: int -LOG_KERN: int -LOG_LOCAL0: int -LOG_LOCAL1: int -LOG_LOCAL2: int -LOG_LOCAL3: int -LOG_LOCAL4: int -LOG_LOCAL5: int -LOG_LOCAL6: int -LOG_LOCAL7: int -LOG_LPR: int -LOG_MAIL: int -LOG_NDELAY: int -LOG_NEWS: int -LOG_NOTICE: int -LOG_NOWAIT: int -LOG_PERROR: int -LOG_PID: int -LOG_SYSLOG: int -LOG_USER: int -LOG_UUCP: int -LOG_WARNING: int - -def LOG_MASK(a: int) -> int: ... -def LOG_UPTO(a: int) -> int: ... -def closelog() -> None: ... -def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... -def setlogmask(x: int) -> int: ... -@overload -def syslog(priority: int, message: str) -> None: ... -@overload -def syslog(message: str) -> None: ... +if sys.platform != "win32": + LOG_ALERT: int + LOG_AUTH: int + LOG_CONS: int + LOG_CRIT: int + LOG_CRON: int + LOG_DAEMON: int + LOG_DEBUG: int + LOG_EMERG: int + LOG_ERR: int + LOG_INFO: int + LOG_KERN: int + LOG_LOCAL0: int + LOG_LOCAL1: int + LOG_LOCAL2: int + LOG_LOCAL3: int + LOG_LOCAL4: int + LOG_LOCAL5: int + LOG_LOCAL6: int + LOG_LOCAL7: int + LOG_LPR: int + LOG_MAIL: int + LOG_NDELAY: int + LOG_NEWS: int + LOG_NOTICE: int + LOG_NOWAIT: int + LOG_PERROR: int + LOG_PID: int + LOG_SYSLOG: int + LOG_USER: int + LOG_UUCP: int + LOG_WARNING: int + def LOG_MASK(a: int) -> int: ... + def LOG_UPTO(a: int) -> int: ... + def closelog() -> None: ... + def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... + def setlogmask(x: int) -> int: ... + @overload + def syslog(priority: int, message: str) -> None: ... + @overload + def syslog(message: str) -> None: ... diff --git a/mypy/typeshed/stdlib/@python2/termios.pyi b/mypy/typeshed/stdlib/@python2/termios.pyi index 0c627f4b72bd..cee6b85f9ba5 100644 --- a/mypy/typeshed/stdlib/@python2/termios.pyi +++ b/mypy/typeshed/stdlib/@python2/termios.pyi @@ -1,246 +1,246 @@ +import sys from _typeshed import FileDescriptorLike from typing import Any, List, Union -_Attr = List[Union[int, List[Union[bytes, int]]]] +if sys.platform != "win32": + _Attr = List[Union[int, List[Union[bytes, int]]]] -# TODO constants not really documented -B0: int -B1000000: int -B110: int -B115200: int -B1152000: int -B1200: int -B134: int -B150: int -B1500000: int -B1800: int -B19200: int -B200: int -B2000000: int -B230400: int -B2400: int -B2500000: int -B300: int -B3000000: int -B3500000: int -B38400: int -B4000000: int -B460800: int -B4800: int -B50: int -B500000: int -B57600: int -B576000: int -B600: int -B75: int -B921600: int -B9600: int -BRKINT: int -BS0: int -BS1: int -BSDLY: int -CBAUD: int -CBAUDEX: int -CDSUSP: int -CEOF: int -CEOL: int -CEOT: int -CERASE: int -CFLUSH: int -CIBAUD: int -CINTR: int -CKILL: int -CLNEXT: int -CLOCAL: int -CQUIT: int -CR0: int -CR1: int -CR2: int -CR3: int -CRDLY: int -CREAD: int -CRPRNT: int -CRTSCTS: int -CS5: int -CS6: int -CS7: int -CS8: int -CSIZE: int -CSTART: int -CSTOP: int -CSTOPB: int -CSUSP: int -CWERASE: int -ECHO: int -ECHOCTL: int -ECHOE: int -ECHOK: int -ECHOKE: int -ECHONL: int -ECHOPRT: int -EXTA: int -EXTB: int -FF0: int -FF1: int -FFDLY: int -FIOASYNC: int -FIOCLEX: int -FIONBIO: int -FIONCLEX: int -FIONREAD: int -FLUSHO: int -HUPCL: int -ICANON: int -ICRNL: int -IEXTEN: int -IGNBRK: int -IGNCR: int -IGNPAR: int -IMAXBEL: int -INLCR: int -INPCK: int -IOCSIZE_MASK: int -IOCSIZE_SHIFT: int -ISIG: int -ISTRIP: int -IUCLC: int -IXANY: int -IXOFF: int -IXON: int -NCC: int -NCCS: int -NL0: int -NL1: int -NLDLY: int -NOFLSH: int -N_MOUSE: int -N_PPP: int -N_SLIP: int -N_STRIP: int -N_TTY: int -OCRNL: int -OFDEL: int -OFILL: int -OLCUC: int -ONLCR: int -ONLRET: int -ONOCR: int -OPOST: int -PARENB: int -PARMRK: int -PARODD: int -PENDIN: int -TAB0: int -TAB1: int -TAB2: int -TAB3: int -TABDLY: int -TCFLSH: int -TCGETA: int -TCGETS: int -TCIFLUSH: int -TCIOFF: int -TCIOFLUSH: int -TCION: int -TCOFLUSH: int -TCOOFF: int -TCOON: int -TCSADRAIN: int -TCSAFLUSH: int -TCSANOW: int -TCSBRK: int -TCSBRKP: int -TCSETA: int -TCSETAF: int -TCSETAW: int -TCSETS: int -TCSETSF: int -TCSETSW: int -TCXONC: int -TIOCCONS: int -TIOCEXCL: int -TIOCGETD: int -TIOCGICOUNT: int -TIOCGLCKTRMIOS: int -TIOCGPGRP: int -TIOCGSERIAL: int -TIOCGSOFTCAR: int -TIOCGWINSZ: int -TIOCINQ: int -TIOCLINUX: int -TIOCMBIC: int -TIOCMBIS: int -TIOCMGET: int -TIOCMIWAIT: int -TIOCMSET: int -TIOCM_CAR: int -TIOCM_CD: int -TIOCM_CTS: int -TIOCM_DSR: int -TIOCM_DTR: int -TIOCM_LE: int -TIOCM_RI: int -TIOCM_RNG: int -TIOCM_RTS: int -TIOCM_SR: int -TIOCM_ST: int -TIOCNOTTY: int -TIOCNXCL: int -TIOCOUTQ: int -TIOCPKT: int -TIOCPKT_DATA: int -TIOCPKT_DOSTOP: int -TIOCPKT_FLUSHREAD: int -TIOCPKT_FLUSHWRITE: int -TIOCPKT_NOSTOP: int -TIOCPKT_START: int -TIOCPKT_STOP: int -TIOCSCTTY: int -TIOCSERCONFIG: int -TIOCSERGETLSR: int -TIOCSERGETMULTI: int -TIOCSERGSTRUCT: int -TIOCSERGWILD: int -TIOCSERSETMULTI: int -TIOCSERSWILD: int -TIOCSER_TEMT: int -TIOCSETD: int -TIOCSLCKTRMIOS: int -TIOCSPGRP: int -TIOCSSERIAL: int -TIOCSSOFTCAR: int -TIOCSTI: int -TIOCSWINSZ: int -TOSTOP: int -VDISCARD: int -VEOF: int -VEOL: int -VEOL2: int -VERASE: int -VINTR: int -VKILL: int -VLNEXT: int -VMIN: int -VQUIT: int -VREPRINT: int -VSTART: int -VSTOP: int -VSUSP: int -VSWTC: int -VSWTCH: int -VT0: int -VT1: int -VTDLY: int -VTIME: int -VWERASE: int -XCASE: int -XTABS: int - -def tcgetattr(__fd: FileDescriptorLike) -> List[Any]: ... -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: ... - -class error(Exception): ... + # TODO constants not really documented + B0: int + B1000000: int + B110: int + B115200: int + B1152000: int + B1200: int + B134: int + B150: int + B1500000: int + B1800: int + B19200: int + B200: int + B2000000: int + B230400: int + B2400: int + B2500000: int + B300: int + B3000000: int + B3500000: int + B38400: int + B4000000: int + B460800: int + B4800: int + B50: int + B500000: int + B57600: int + B576000: int + B600: int + B75: int + B921600: int + B9600: int + BRKINT: int + BS0: int + BS1: int + BSDLY: int + CBAUD: int + CBAUDEX: int + CDSUSP: int + CEOF: int + CEOL: int + CEOT: int + CERASE: int + CFLUSH: int + CIBAUD: int + CINTR: int + CKILL: int + CLNEXT: int + CLOCAL: int + CQUIT: int + CR0: int + CR1: int + CR2: int + CR3: int + CRDLY: int + CREAD: int + CRPRNT: int + CRTSCTS: int + CS5: int + CS6: int + CS7: int + CS8: int + CSIZE: int + CSTART: int + CSTOP: int + CSTOPB: int + CSUSP: int + CWERASE: int + ECHO: int + ECHOCTL: int + ECHOE: int + ECHOK: int + ECHOKE: int + ECHONL: int + ECHOPRT: int + EXTA: int + EXTB: int + FF0: int + FF1: int + FFDLY: int + FIOASYNC: int + FIOCLEX: int + FIONBIO: int + FIONCLEX: int + FIONREAD: int + FLUSHO: int + HUPCL: int + ICANON: int + ICRNL: int + IEXTEN: int + IGNBRK: int + IGNCR: int + IGNPAR: int + IMAXBEL: int + INLCR: int + INPCK: int + IOCSIZE_MASK: int + IOCSIZE_SHIFT: int + ISIG: int + ISTRIP: int + IUCLC: int + IXANY: int + IXOFF: int + IXON: int + NCC: int + NCCS: int + NL0: int + NL1: int + NLDLY: int + NOFLSH: int + N_MOUSE: int + N_PPP: int + N_SLIP: int + N_STRIP: int + N_TTY: int + OCRNL: int + OFDEL: int + OFILL: int + OLCUC: int + ONLCR: int + ONLRET: int + ONOCR: int + OPOST: int + PARENB: int + PARMRK: int + PARODD: int + PENDIN: int + TAB0: int + TAB1: int + TAB2: int + TAB3: int + TABDLY: int + TCFLSH: int + TCGETA: int + TCGETS: int + TCIFLUSH: int + TCIOFF: int + TCIOFLUSH: int + TCION: int + TCOFLUSH: int + TCOOFF: int + TCOON: int + TCSADRAIN: int + TCSAFLUSH: int + TCSANOW: int + TCSBRK: int + TCSBRKP: int + TCSETA: int + TCSETAF: int + TCSETAW: int + TCSETS: int + TCSETSF: int + TCSETSW: int + TCXONC: int + TIOCCONS: int + TIOCEXCL: int + TIOCGETD: int + TIOCGICOUNT: int + TIOCGLCKTRMIOS: int + TIOCGPGRP: int + TIOCGSERIAL: int + TIOCGSOFTCAR: int + TIOCGWINSZ: int + TIOCINQ: int + TIOCLINUX: int + TIOCMBIC: int + TIOCMBIS: int + TIOCMGET: int + TIOCMIWAIT: int + TIOCMSET: int + TIOCM_CAR: int + TIOCM_CD: int + TIOCM_CTS: int + TIOCM_DSR: int + TIOCM_DTR: int + TIOCM_LE: int + TIOCM_RI: int + TIOCM_RNG: int + TIOCM_RTS: int + TIOCM_SR: int + TIOCM_ST: int + TIOCNOTTY: int + TIOCNXCL: int + TIOCOUTQ: int + TIOCPKT: int + TIOCPKT_DATA: int + TIOCPKT_DOSTOP: int + TIOCPKT_FLUSHREAD: int + TIOCPKT_FLUSHWRITE: int + TIOCPKT_NOSTOP: int + TIOCPKT_START: int + TIOCPKT_STOP: int + TIOCSCTTY: int + TIOCSERCONFIG: int + TIOCSERGETLSR: int + TIOCSERGETMULTI: int + TIOCSERGSTRUCT: int + TIOCSERGWILD: int + TIOCSERSETMULTI: int + TIOCSERSWILD: int + TIOCSER_TEMT: int + TIOCSETD: int + TIOCSLCKTRMIOS: int + TIOCSPGRP: int + TIOCSSERIAL: int + TIOCSSOFTCAR: int + TIOCSTI: int + TIOCSWINSZ: int + TOSTOP: int + VDISCARD: int + VEOF: int + VEOL: int + VEOL2: int + VERASE: int + VINTR: int + VKILL: int + VLNEXT: int + VMIN: int + VQUIT: int + VREPRINT: int + VSTART: int + VSTOP: int + VSUSP: int + VSWTC: int + VSWTCH: int + VT0: int + VT1: int + VTDLY: int + VTIME: int + VWERASE: int + XCASE: int + XTABS: int + def tcgetattr(__fd: FileDescriptorLike) -> List[Any]: ... + 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: ... + class error(Exception): ... diff --git a/mypy/typeshed/stdlib/@python2/tty.pyi b/mypy/typeshed/stdlib/@python2/tty.pyi index c0dc418e9933..56e85108c75e 100644 --- a/mypy/typeshed/stdlib/@python2/tty.pyi +++ b/mypy/typeshed/stdlib/@python2/tty.pyi @@ -1,15 +1,16 @@ +import sys from typing import IO, Union _FD = Union[int, IO[str]] -# XXX: Undocumented integer constants -IFLAG: int -OFLAG: int -CFLAG: int -LFLAG: int -ISPEED: int -OSPEED: int -CC: int - -def setraw(fd: _FD, when: int = ...) -> None: ... -def setcbreak(fd: _FD, when: int = ...) -> None: ... +if sys.platform != "win32": + # XXX: Undocumented integer constants + IFLAG: int + OFLAG: int + CFLAG: int + LFLAG: int + ISPEED: int + OSPEED: int + CC: int + def setraw(fd: _FD, when: int = ...) -> None: ... + def setcbreak(fd: _FD, when: int = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/@python2/types.pyi b/mypy/typeshed/stdlib/@python2/types.pyi index 72b9321a860f..0feee4530586 100644 --- a/mypy/typeshed/stdlib/@python2/types.pyi +++ b/mypy/typeshed/stdlib/@python2/types.pyi @@ -148,7 +148,7 @@ class FrameType: f_exc_traceback: None f_globals: Dict[str, Any] f_lasti: int - f_lineno: int + f_lineno: int | None f_locals: Dict[str, Any] f_restricted: bool f_trace: Callable[[], None] diff --git a/mypy/typeshed/stdlib/VERSIONS b/mypy/typeshed/stdlib/VERSIONS index 9b9271117fa7..e82161d97cb6 100644 --- a/mypy/typeshed/stdlib/VERSIONS +++ b/mypy/typeshed/stdlib/VERSIONS @@ -29,8 +29,8 @@ _compression: 3.6- _csv: 2.7- _curses: 2.7- _decimal: 3.6- -_dummy_thread: 3.6- -_dummy_threading: 2.7- +_dummy_thread: 3.6-3.8 +_dummy_threading: 2.7-3.8 _heapq: 2.7- _imp: 3.6- _json: 2.7- @@ -103,8 +103,9 @@ decimal: 2.7- difflib: 2.7- dis: 2.7- distutils: 2.7- +distutils.command.bdist_msi: 2.7-3.10 doctest: 2.7- -dummy_threading: 2.7- +dummy_threading: 2.7-3.8 email: 2.7- encodings: 2.7- ensurepip: 2.7- @@ -138,6 +139,7 @@ imghdr: 2.7- imp: 2.7- importlib: 2.7- importlib.metadata: 3.8- +importlib.metadata._meta: 3.10- importlib.resources: 3.7- inspect: 2.7- io: 2.7- @@ -259,6 +261,7 @@ typing: 3.5- typing_extensions: 2.7- unicodedata: 2.7- unittest: 2.7- +unittest._log: 3.9- urllib: 2.7- uu: 2.7- uuid: 2.7- diff --git a/mypy/typeshed/stdlib/_bisect.pyi b/mypy/typeshed/stdlib/_bisect.pyi index 6da6e7f58823..1f67dadd89a0 100644 --- a/mypy/typeshed/stdlib/_bisect.pyi +++ b/mypy/typeshed/stdlib/_bisect.pyi @@ -1,21 +1,31 @@ import sys -from _typeshed import SupportsLessThan +from _typeshed import SupportsRichComparison from typing import Callable, MutableSequence, Sequence, TypeVar _T = TypeVar("_T") if sys.version_info >= (3, 10): def bisect_left( - a: Sequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsLessThan] | None = ... + a: Sequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsRichComparison] | None = ... ) -> int: ... def bisect_right( - a: Sequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsLessThan] | None = ... + a: Sequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsRichComparison] | None = ... ) -> int: ... def insort_left( - a: MutableSequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsLessThan] | None = ... + a: MutableSequence[_T], + x: _T, + lo: int = ..., + hi: int | None = ..., + *, + key: Callable[[_T], SupportsRichComparison] | None = ..., ) -> None: ... def insort_right( - a: MutableSequence[_T], x: _T, lo: int = ..., hi: int | None = ..., *, key: Callable[[_T], SupportsLessThan] | None = ... + a: MutableSequence[_T], + x: _T, + lo: int = ..., + hi: int | None = ..., + *, + key: Callable[[_T], SupportsRichComparison] | None = ..., ) -> None: ... else: diff --git a/mypy/typeshed/stdlib/_codecs.pyi b/mypy/typeshed/stdlib/_codecs.pyi index 5e4a9ad6da3d..470722a293a3 100644 --- a/mypy/typeshed/stdlib/_codecs.pyi +++ b/mypy/typeshed/stdlib/_codecs.pyi @@ -1,13 +1,13 @@ import codecs import sys -from typing import Any, Callable, Dict, Tuple, Union +from typing import Any, Callable, Union # This type is not exposed; it is defined in unicodeobject.c class _EncodingMap: def size(self) -> int: ... -_MapT = Union[Dict[int, int], _EncodingMap] -_Handler = Callable[[Exception], Tuple[str, int]] +_MapT = Union[dict[int, int], _EncodingMap] +_Handler = Callable[[Exception], tuple[str, int]] def register(__search_function: Callable[[str], Any]) -> None: ... def register_error(__errors: str, __handler: _Handler) -> None: ... @@ -24,10 +24,22 @@ def escape_decode(__data: str | bytes, __errors: str | None = ...) -> tuple[str, def escape_encode(__data: bytes, __errors: str | None = ...) -> tuple[bytes, int]: ... def latin_1_decode(__data: bytes, __errors: str | None = ...) -> tuple[str, int]: ... def latin_1_encode(__str: str, __errors: str | None = ...) -> tuple[bytes, int]: ... -def raw_unicode_escape_decode(__data: str | bytes, __errors: str | None = ...) -> tuple[str, int]: ... + +if sys.version_info >= (3, 9): + def raw_unicode_escape_decode(__data: str | bytes, __errors: str | None = ..., __final: bool = ...) -> tuple[str, int]: ... + +else: + def raw_unicode_escape_decode(__data: str | bytes, __errors: str | None = ...) -> tuple[str, int]: ... + def raw_unicode_escape_encode(__str: str, __errors: str | None = ...) -> tuple[bytes, int]: ... def readbuffer_encode(__data: str | bytes, __errors: str | None = ...) -> tuple[bytes, int]: ... -def unicode_escape_decode(__data: str | bytes, __errors: str | None = ...) -> tuple[str, int]: ... + +if sys.version_info >= (3, 9): + def unicode_escape_decode(__data: str | bytes, __errors: str | None = ..., __final: bool = ...) -> tuple[str, int]: ... + +else: + def unicode_escape_decode(__data: str | bytes, __errors: str | None = ...) -> tuple[str, int]: ... + def unicode_escape_encode(__str: str, __errors: str | None = ...) -> tuple[bytes, int]: ... if sys.version_info < (3, 8): diff --git a/mypy/typeshed/stdlib/_compat_pickle.pyi b/mypy/typeshed/stdlib/_compat_pickle.pyi index 76aba3020321..50fb22442cc9 100644 --- a/mypy/typeshed/stdlib/_compat_pickle.pyi +++ b/mypy/typeshed/stdlib/_compat_pickle.pyi @@ -1,10 +1,8 @@ -from typing import Tuple - IMPORT_MAPPING: dict[str, str] NAME_MAPPING: dict[tuple[str, str], tuple[str, str]] -PYTHON2_EXCEPTIONS: Tuple[str, ...] -MULTIPROCESSING_EXCEPTIONS: Tuple[str, ...] +PYTHON2_EXCEPTIONS: tuple[str, ...] +MULTIPROCESSING_EXCEPTIONS: tuple[str, ...] REVERSE_IMPORT_MAPPING: dict[str, str] REVERSE_NAME_MAPPING: dict[tuple[str, str], tuple[str, str]] -PYTHON3_OSERROR_EXCEPTIONS: Tuple[str, ...] -PYTHON3_IMPORTERROR_EXCEPTIONS: Tuple[str, ...] +PYTHON3_OSERROR_EXCEPTIONS: tuple[str, ...] +PYTHON3_IMPORTERROR_EXCEPTIONS: tuple[str, ...] diff --git a/mypy/typeshed/stdlib/_compression.pyi b/mypy/typeshed/stdlib/_compression.pyi index 8f81847ff492..31940e3eb15b 100644 --- a/mypy/typeshed/stdlib/_compression.pyi +++ b/mypy/typeshed/stdlib/_compression.pyi @@ -1,6 +1,6 @@ from _typeshed import WriteableBuffer from io import BufferedIOBase, RawIOBase -from typing import Any, Callable, Protocol, Tuple, Type +from typing import Any, Callable, Protocol, Type BUFFER_SIZE: Any @@ -16,7 +16,7 @@ class DecompressReader(RawIOBase): self, fp: _Reader, decomp_factory: Callable[..., object], - trailing_error: Type[Exception] | Tuple[Type[Exception], ...] = ..., + trailing_error: Type[Exception] | tuple[Type[Exception], ...] = ..., **decomp_args: Any, ) -> None: ... def readable(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/_csv.pyi b/mypy/typeshed/stdlib/_csv.pyi index 1dc43780f687..54e9099bbdcd 100644 --- a/mypy/typeshed/stdlib/_csv.pyi +++ b/mypy/typeshed/stdlib/_csv.pyi @@ -1,4 +1,4 @@ -from typing import Any, Iterable, Iterator, List, Protocol, Type, Union +from typing import Any, Iterable, Iterator, Protocol, Type, Union QUOTE_ALL: int QUOTE_MINIMAL: int @@ -20,7 +20,7 @@ class Dialect: _DialectLike = Union[str, Dialect, Type[Dialect]] -class _reader(Iterator[List[str]]): +class _reader(Iterator[list[str]]): dialect: Dialect line_num: int def __next__(self) -> list[str]: ... @@ -31,7 +31,7 @@ class _writer: def writerows(self, rows: Iterable[Iterable[Any]]) -> None: ... class _Writer(Protocol): - def write(self, s: str) -> Any: ... + def write(self, __s: str) -> object: ... def writer(csvfile: _Writer, dialect: _DialectLike = ..., **fmtparams: Any) -> _writer: ... def reader(csvfile: Iterable[str], dialect: _DialectLike = ..., **fmtparams: Any) -> _reader: ... diff --git a/mypy/typeshed/stdlib/_curses.pyi b/mypy/typeshed/stdlib/_curses.pyi index e0f978c5cae1..9f23eeb1c6dc 100644 --- a/mypy/typeshed/stdlib/_curses.pyi +++ b/mypy/typeshed/stdlib/_curses.pyi @@ -1,548 +1,547 @@ import sys -from typing import IO, Any, BinaryIO, NamedTuple, Union, overload +from _typeshed import SupportsRead +from typing import IO, Any, NamedTuple, Union, overload -_chtype = Union[str, bytes, int] +if sys.platform != "win32": + _chtype = Union[str, bytes, int] -# 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.version_info >= (3, 7): - 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 = ...) -> None: ... -def color_content(__color_number: int) -> tuple[int, int, int]: ... - -# Changed in Python 3.8.8 and 3.9.2 -if sys.version_info >= (3, 8): - def color_pair(pair_number: int) -> int: ... - -else: - def color_pair(__color_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 = ...) -> None: ... -def endwin() -> None: ... -def erasechar() -> bytes: ... -def filter() -> None: ... -def flash() -> None: ... -def flushinp() -> None: ... -def getmouse() -> tuple[int, int, int, int, int]: ... -def getsyx() -> tuple[int, int]: ... -def getwin(__file: BinaryIO) -> _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 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 = ...) -> 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: bytes) -> None: ... -def qiflush(__flag: bool = ...) -> None: ... -def raw(__flag: bool = ...) -> 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: ... -def setsyx(__y: int, __x: int) -> None: ... -def setupterm(term: str | None = ..., fd: int = ...) -> 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: ... -def tparm( - __str: bytes, - __i1: int = ..., - __i2: int = ..., - __i3: int = ..., - __i4: int = ..., - __i5: int = ..., - __i6: int = ..., - __i7: int = ..., - __i8: int = ..., - __i9: int = ..., -) -> bytes: ... -def typeahead(__fd: int) -> None: ... -def unctrl(__ch: _chtype) -> bytes: ... -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() -> int: ... -def use_default_colors() -> None: ... -def use_env(__flag: bool) -> None: ... - -class error(Exception): ... - -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: ... - @overload - def get_wch(self) -> int | str: ... - @overload - 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) -> _chtype: ... - @overload - def getstr(self, n: int) -> _chtype: ... - @overload - def getstr(self, y: int, x: int) -> _chtype: ... - @overload - def getstr(self, y: int, x: int, n: int) -> _chtype: ... - 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) -> _chtype: ... - @overload - def inch(self, y: int, x: int) -> _chtype: ... - @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 = ...) -> _chtype: ... - @overload - def instr(self, y: int, x: int, n: int = ...) -> _chtype: ... - 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: ... - -if sys.version_info >= (3, 8): - class _ncurses_version(NamedTuple): - major: int - minor: int - patch: int - ncurses_version: _ncurses_version - window = _CursesWindow # undocumented + # 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.version_info >= (3, 7): + 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 = ...) -> None: ... + def color_content(__color_number: int) -> tuple[int, int, int]: ... + # Changed in Python 3.8.8 and 3.9.2 + if sys.version_info >= (3, 8): + def color_pair(pair_number: int) -> int: ... + else: + def color_pair(__color_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 = ...) -> 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: ... + 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: ... + 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 = ...) -> 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: bytes) -> None: ... + def qiflush(__flag: bool = ...) -> None: ... + def raw(__flag: bool = ...) -> 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 = ..., fd: int = ...) -> 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: bytes, + __i1: int = ..., + __i2: int = ..., + __i3: int = ..., + __i4: int = ..., + __i5: int = ..., + __i6: int = ..., + __i7: int = ..., + __i8: int = ..., + __i9: int = ..., + ) -> bytes: ... + def typeahead(__fd: int) -> None: ... + def unctrl(__ch: _chtype) -> bytes: ... + 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): ... + 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: ... + @overload + def get_wch(self) -> int | str: ... + @overload + 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: ... + if sys.version_info >= (3, 8): + class _ncurses_version(NamedTuple): + major: int + minor: int + patch: int + ncurses_version: _ncurses_version + window = _CursesWindow # undocumented diff --git a/mypy/typeshed/stdlib/_dummy_thread.pyi b/mypy/typeshed/stdlib/_dummy_thread.pyi index 886d9d739780..6e936726a48f 100644 --- a/mypy/typeshed/stdlib/_dummy_thread.pyi +++ b/mypy/typeshed/stdlib/_dummy_thread.pyi @@ -1,15 +1,15 @@ -from typing import Any, Callable, NoReturn, Tuple +from typing import Any, Callable, NoReturn TIMEOUT_MAX: int error = RuntimeError -def start_new_thread(function: Callable[..., Any], args: Tuple[Any, ...], kwargs: dict[str, Any] = ...) -> None: ... +def start_new_thread(function: Callable[..., Any], args: tuple[Any, ...], kwargs: dict[str, Any] = ...) -> None: ... def exit() -> NoReturn: ... def get_ident() -> int: ... def allocate_lock() -> LockType: ... def stack_size(size: int | None = ...) -> int: ... -class LockType(object): +class LockType: locked_status: bool def __init__(self) -> None: ... def acquire(self, waitflag: bool | None = ..., timeout: int = ...) -> bool: ... diff --git a/mypy/typeshed/stdlib/_dummy_threading.pyi b/mypy/typeshed/stdlib/_dummy_threading.pyi index 64998d86bf9f..075ea4637f73 100644 --- a/mypy/typeshed/stdlib/_dummy_threading.pyi +++ b/mypy/typeshed/stdlib/_dummy_threading.pyi @@ -28,7 +28,7 @@ TIMEOUT_MAX: float class ThreadError(Exception): ... -class local(object): +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/_imp.pyi b/mypy/typeshed/stdlib/_imp.pyi index b61c9f29b96d..23272591df4c 100644 --- a/mypy/typeshed/stdlib/_imp.pyi +++ b/mypy/typeshed/stdlib/_imp.pyi @@ -1,7 +1,11 @@ +import sys import types from importlib.machinery import ModuleSpec from typing import Any +if sys.version_info >= (3, 7): + check_hash_based_pycs: str + def create_builtin(__spec: ModuleSpec) -> types.ModuleType: ... def create_dynamic(__spec: ModuleSpec, __file: Any = ...) -> None: ... def acquire_lock() -> None: ... diff --git a/mypy/typeshed/stdlib/_markupbase.pyi b/mypy/typeshed/stdlib/_markupbase.pyi index 368d32bd5b4c..2c497f65bb43 100644 --- a/mypy/typeshed/stdlib/_markupbase.pyi +++ b/mypy/typeshed/stdlib/_markupbase.pyi @@ -1,6 +1,17 @@ +import sys +from typing import Any + class ParserBase: def __init__(self) -> None: ... - def error(self, message: str) -> None: ... def reset(self) -> None: ... def getpos(self) -> tuple[int, int]: ... def unknown_decl(self, data: str) -> None: ... + def parse_comment(self, i: int, report: int = ...) -> int: ... # undocumented + def parse_declaration(self, i: int) -> int: ... # undocumented + def parse_marked_section(self, i: int, report: int = ...) -> int: ... # undocumented + def updatepos(self, i: int, j: int) -> int: ... # undocumented + if sys.version_info < (3, 10): + # Removed from ParserBase: https://bugs.python.org/issue31844 + def error(self, message: str) -> Any: ... # undocumented + lineno: int # undocumented + offset: int # undocumented diff --git a/mypy/typeshed/stdlib/_msi.pyi b/mypy/typeshed/stdlib/_msi.pyi index 754febe68da9..b7e852f38ae9 100644 --- a/mypy/typeshed/stdlib/_msi.pyi +++ b/mypy/typeshed/stdlib/_msi.pyi @@ -10,8 +10,8 @@ if sys.platform == "win32": def Modify(self, mode: int, record: _Record) -> None: ... def Close(self) -> None: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] # Actual typename Summary, not exposed by the implementation class _Summary: def GetProperty(self, propid: int) -> str | bytes | None: ... @@ -19,8 +19,8 @@ if sys.platform == "win32": def SetProperty(self, propid: int, value: str | bytes) -> None: ... def Persist(self) -> None: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] # Actual typename Database, not exposed by the implementation class _Database: def OpenView(self, sql: str) -> _View: ... @@ -28,8 +28,8 @@ if sys.platform == "win32": def GetSummaryInformation(self, updateCount: int) -> _Summary: ... def Close(self) -> None: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] # Actual typename Record, not exposed by the implementation class _Record: def GetFieldCount(self) -> int: ... @@ -40,8 +40,8 @@ if sys.platform == "win32": def SetInteger(self, field: int, int: int) -> None: ... def ClearData(self) -> None: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] def UuidCreate() -> str: ... def FCICreate(cabname: str, files: list[str]) -> None: ... def OpenDatabase(name: str, flags: int) -> _Database: ... diff --git a/mypy/typeshed/stdlib/_operator.pyi b/mypy/typeshed/stdlib/_operator.pyi index bea438861886..77a88d4fa141 100644 --- a/mypy/typeshed/stdlib/_operator.pyi +++ b/mypy/typeshed/stdlib/_operator.pyi @@ -1,60 +1,141 @@ -# In reality the import is the other way around, but this way we can keep the operator stub in 2and3 -from operator import ( - abs as abs, - add as add, - and_ as and_, - attrgetter as attrgetter, - concat as concat, - contains as contains, - countOf as countOf, - delitem as delitem, - eq as eq, - floordiv as floordiv, - ge as ge, - getitem as getitem, - gt as gt, - iadd as iadd, - iand as iand, - iconcat as iconcat, - ifloordiv as ifloordiv, - ilshift as ilshift, - imatmul as imatmul, - imod as imod, - imul as imul, - index as index, - indexOf as indexOf, - inv as inv, - invert as invert, - ior as ior, - ipow as ipow, - irshift as irshift, - is_ as is_, - is_not as is_not, - isub as isub, - itemgetter as itemgetter, - itruediv as itruediv, - ixor as ixor, - le as le, - length_hint as length_hint, - lshift as lshift, - lt as lt, - matmul as matmul, - methodcaller as methodcaller, - mod as mod, - mul as mul, - ne as ne, - neg as neg, - not_ as not_, - or_ as or_, - pos as pos, - pow as pow, - rshift as rshift, - setitem as setitem, - sub as sub, - truediv as truediv, - truth as truth, - xor as xor, +import sys +from _typeshed import SupportsAnyComparison +from typing import ( + Any, + AnyStr, + Callable, + Container, + Generic, + Iterable, + Mapping, + MutableMapping, + MutableSequence, + Protocol, + Sequence, + SupportsAbs, + TypeVar, + overload, ) -from typing import AnyStr +from typing_extensions import ParamSpec, SupportsIndex, final + +_R = TypeVar("_R") +_T = TypeVar("_T") +_T_co = TypeVar("_T_co", covariant=True) +_K = TypeVar("_K") +_V = TypeVar("_V") +_P = ParamSpec("_P") + +class _SupportsInversion(Protocol[_T_co]): + def __invert__(self) -> _T_co: ... + +class _SupportsNeg(Protocol[_T_co]): + def __neg__(self) -> _T_co: ... + +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: SupportsAnyComparison, __b: SupportsAnyComparison) -> Any: ... +def le(__a: SupportsAnyComparison, __b: SupportsAnyComparison) -> Any: ... +def eq(__a: object, __b: object) -> Any: ... +def ne(__a: object, __b: object) -> Any: ... +def ge(__a: SupportsAnyComparison, __b: SupportsAnyComparison) -> Any: ... +def gt(__a: SupportsAnyComparison, __b: SupportsAnyComparison) -> 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: ... +@overload +def delitem(__a: MutableSequence[Any], __b: slice) -> None: ... +@overload +def delitem(__a: MutableMapping[_K, Any], __b: _K) -> None: ... +@overload +def getitem(__a: Sequence[_T], __b: SupportsIndex) -> _T: ... +@overload +def getitem(__a: Sequence[_T], __b: slice) -> Sequence[_T]: ... +@overload +def getitem(__a: Mapping[_K, _V], __b: _K) -> _V: ... +def indexOf(__a: Iterable[_T], __b: _T) -> int: ... +@overload +def setitem(__a: MutableSequence[_T], __b: SupportsIndex, __c: _T) -> None: ... +@overload +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 = ...) -> int: ... +@final +class attrgetter(Generic[_T_co]): + @overload + def __new__(cls, attr: str) -> attrgetter[Any]: ... + @overload + 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]]: ... + @overload + 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: ... + +@final +class itemgetter(Generic[_T_co]): + @overload + def __new__(cls, item: Any) -> itemgetter[Any]: ... + @overload + def __new__(cls, item: Any, __item2: Any) -> itemgetter[tuple[Any, Any]]: ... + @overload + def __new__(cls, item: Any, __item2: Any, __item3: Any) -> itemgetter[tuple[Any, Any, Any]]: ... + @overload + def __new__(cls, item: Any, __item2: Any, __item3: Any, __item4: Any) -> itemgetter[tuple[Any, Any, Any, Any]]: ... + @overload + def __new__(cls, item: Any, *items: Any) -> itemgetter[tuple[Any, ...]]: ... + def __call__(self, obj: Any) -> _T_co: ... + +@final +class methodcaller: + 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: ... + +if sys.version_info >= (3, 11): + def call(__obj: Callable[_P, _R], *args: _P.args, **kwargs: _P.kwargs) -> _R: ... def _compare_digest(__a: AnyStr, __b: AnyStr) -> bool: ... diff --git a/mypy/typeshed/stdlib/_osx_support.pyi b/mypy/typeshed/stdlib/_osx_support.pyi index ce1fffc00e8c..ffb25d5a2c0e 100644 --- a/mypy/typeshed/stdlib/_osx_support.pyi +++ b/mypy/typeshed/stdlib/_osx_support.pyi @@ -1,4 +1,5 @@ -from typing import Iterable, Sequence, Tuple, TypeVar +import sys +from typing import Iterable, Sequence, TypeVar _T = TypeVar("_T") _K = TypeVar("_K") @@ -6,12 +7,18 @@ _V = TypeVar("_V") __all__: list[str] -_UNIVERSAL_CONFIG_VARS: Tuple[str, ...] # undocumented -_COMPILER_CONFIG_VARS: Tuple[str, ...] # undocumented +_UNIVERSAL_CONFIG_VARS: tuple[str, ...] # undocumented +_COMPILER_CONFIG_VARS: tuple[str, ...] # undocumented _INITPRE: str # undocumented def _find_executable(executable: str, path: str | None = ...) -> str | None: ... # undocumented -def _read_output(commandstring: str) -> str | None: ... # undocumented + +if sys.version_info >= (3, 8): + def _read_output(commandstring: str, capture_stderr: bool = ...) -> str | None: ... # undocumented + +else: + def _read_output(commandstring: str) -> 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 0eae723e7a67..5481100cacfc 100644 --- a/mypy/typeshed/stdlib/_posixsubprocess.pyi +++ b/mypy/typeshed/stdlib/_posixsubprocess.pyi @@ -1,24 +1,24 @@ -# NOTE: These are incomplete! - +import sys from typing import Callable, Sequence -def cloexec_pipe() -> tuple[int, int]: ... -def fork_exec( - args: Sequence[str], - executable_list: Sequence[bytes], - close_fds: bool, - fds_to_keep: Sequence[int], - cwd: str, - env_list: Sequence[bytes], - p2cread: int, - p2cwrite: int, - c2pred: int, - c2pwrite: int, - errread: int, - errwrite: int, - errpipe_read: int, - errpipe_write: int, - restore_signals: int, - start_new_session: int, - preexec_fn: Callable[[], None], -) -> int: ... +if sys.platform != "win32": + def cloexec_pipe() -> tuple[int, int]: ... + def fork_exec( + args: Sequence[str], + executable_list: Sequence[bytes], + close_fds: bool, + fds_to_keep: Sequence[int], + cwd: str, + env_list: Sequence[bytes], + p2cread: int, + p2cwrite: int, + c2pred: int, + c2pwrite: int, + errread: int, + errwrite: int, + errpipe_read: int, + errpipe_write: int, + restore_signals: int, + start_new_session: int, + preexec_fn: Callable[[], None], + ) -> int: ... diff --git a/mypy/typeshed/stdlib/_py_abc.pyi b/mypy/typeshed/stdlib/_py_abc.pyi index 8d7938918271..697a7f17111a 100644 --- a/mypy/typeshed/stdlib/_py_abc.pyi +++ b/mypy/typeshed/stdlib/_py_abc.pyi @@ -1,4 +1,4 @@ -from typing import Any, Tuple, Type, TypeVar +from typing import Any, Type, TypeVar _T = TypeVar("_T") @@ -6,5 +6,5 @@ _T = TypeVar("_T") def get_cache_token() -> object: ... class ABCMeta(type): - def __new__(__mcls, __name: str, __bases: Tuple[Type[Any], ...], __namespace: dict[str, Any]) -> ABCMeta: ... + def __new__(__mcls, __name: str, __bases: tuple[Type[Any], ...], __namespace: dict[str, Any]) -> ABCMeta: ... def register(cls, subclass: Type[_T]) -> Type[_T]: ... diff --git a/mypy/typeshed/stdlib/_random.pyi b/mypy/typeshed/stdlib/_random.pyi index fa80c6d98144..9aff4b3cb026 100644 --- a/mypy/typeshed/stdlib/_random.pyi +++ b/mypy/typeshed/stdlib/_random.pyi @@ -1,9 +1,7 @@ -from typing import Tuple - # Actually Tuple[(int,) * 625] -_State = Tuple[int, ...] +_State = tuple[int, ...] -class Random(object): +class Random: def __init__(self, seed: object = ...) -> None: ... def seed(self, __n: object = ...) -> None: ... def getstate(self) -> _State: ... diff --git a/mypy/typeshed/stdlib/_socket.pyi b/mypy/typeshed/stdlib/_socket.pyi index 846f64d5a433..d7d7f73ea37d 100644 --- a/mypy/typeshed/stdlib/_socket.pyi +++ b/mypy/typeshed/stdlib/_socket.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadableBuffer, WriteableBuffer from collections.abc import Iterable -from typing import Any, SupportsInt, Tuple, Union, overload +from typing import Any, SupportsInt, Union, overload if sys.version_info >= (3, 8): from typing import SupportsIndex @@ -10,12 +10,12 @@ if sys.version_info >= (3, 8): else: _FD = SupportsInt -_CMSG = Tuple[int, int, bytes] -_CMSGArg = Tuple[int, int, ReadableBuffer] +_CMSG = tuple[int, int, bytes] +_CMSGArg = tuple[int, int, ReadableBuffer] # Addresses can be either tuples of varying lengths (AF_INET, AF_INET6, # AF_NETLINK, AF_TIPC) or strings (AF_UNIX). -_Address = Union[Tuple[Any, ...], str] +_Address = Union[tuple[Any, ...], str] _RetAddress = Any # TODO Most methods allow bytes as address objects @@ -527,6 +527,8 @@ class socket: family: int type: int proto: int + @property + def timeout(self) -> float | None: ... def __init__(self, family: int = ..., type: int = ..., proto: int = ..., fileno: _FD | None = ...) -> None: ... def bind(self, __address: _Address | bytes) -> None: ... def close(self) -> None: ... diff --git a/mypy/typeshed/stdlib/_stat.pyi b/mypy/typeshed/stdlib/_stat.pyi index 634f7da02563..83d832e4dd8e 100644 --- a/mypy/typeshed/stdlib/_stat.pyi +++ b/mypy/typeshed/stdlib/_stat.pyi @@ -1,54 +1,68 @@ -SF_APPEND: int -SF_ARCHIVED: int -SF_IMMUTABLE: int -SF_NOUNLINK: int -SF_SNAPSHOT: int -ST_ATIME: int -ST_CTIME: int -ST_DEV: int -ST_GID: int -ST_INO: int -ST_MODE: int -ST_MTIME: int -ST_NLINK: int -ST_SIZE: int -ST_UID: int -S_ENFMT: int -S_IEXEC: int -S_IFBLK: int -S_IFCHR: int -S_IFDIR: int +import sys +from typing_extensions import Literal + +SF_APPEND: Literal[0x00040000] +SF_ARCHIVED: Literal[0x00010000] +SF_IMMUTABLE: Literal[0x00020000] +SF_NOUNLINK: Literal[0x00100000] +SF_SNAPSHOT: Literal[0x00200000] + +ST_MODE: Literal[0] +ST_INO: Literal[1] +ST_DEV: Literal[2] +ST_NLINK: Literal[3] +ST_UID: Literal[4] +ST_GID: Literal[5] +ST_SIZE: Literal[6] +ST_ATIME: Literal[7] +ST_MTIME: Literal[8] +ST_CTIME: Literal[9] + +S_IFIFO: Literal[0o010000] +S_IFLNK: Literal[0o120000] +S_IFREG: Literal[0o100000] +S_IFSOCK: Literal[0o140000] +S_IFBLK: Literal[0o060000] +S_IFCHR: Literal[0o020000] +S_IFDIR: Literal[0o040000] + +# These are 0 on systems that don't support the specific kind of file. +# Example: Linux doesn't support door files, so S_IFDOOR is 0 on linux. S_IFDOOR: int -S_IFIFO: int -S_IFLNK: int S_IFPORT: int -S_IFREG: int -S_IFSOCK: int S_IFWHT: int -S_IREAD: int -S_IRGRP: int -S_IROTH: int -S_IRUSR: int -S_IRWXG: int -S_IRWXO: int -S_IRWXU: int -S_ISGID: int -S_ISUID: int -S_ISVTX: int -S_IWGRP: int -S_IWOTH: int -S_IWRITE: int -S_IWUSR: int -S_IXGRP: int -S_IXOTH: int -S_IXUSR: int -UF_APPEND: int -UF_COMPRESSED: int -UF_HIDDEN: int -UF_IMMUTABLE: int -UF_NODUMP: int -UF_NOUNLINK: int -UF_OPAQUE: int + +S_ISUID: Literal[0o4000] +S_ISGID: Literal[0o2000] +S_ISVTX: Literal[0o1000] + +S_IRWXU: Literal[0o0700] +S_IRUSR: Literal[0o0400] +S_IWUSR: Literal[0o0200] +S_IXUSR: Literal[0o0100] + +S_IRWXG: Literal[0o0070] +S_IRGRP: Literal[0o0040] +S_IWGRP: Literal[0o0020] +S_IXGRP: Literal[0o0010] + +S_IRWXO: Literal[0o0007] +S_IROTH: Literal[0o0004] +S_IWOTH: Literal[0o0002] +S_IXOTH: Literal[0o0001] + +S_ENFMT: Literal[0o2000] +S_IREAD: Literal[0o0400] +S_IWRITE: Literal[0o0200] +S_IEXEC: Literal[0o0100] + +UF_APPEND: Literal[0x00000004] +UF_COMPRESSED: Literal[0x00000020] # OS X 10.6+ only +UF_HIDDEN: Literal[0x00008000] # OX X 10.5+ only +UF_IMMUTABLE: Literal[0x00000002] +UF_NODUMP: Literal[0x00000001] +UF_NOUNLINK: Literal[0x00000010] +UF_OPAQUE: Literal[0x00000008] def S_IMODE(mode: int) -> int: ... def S_IFMT(mode: int) -> int: ... @@ -63,3 +77,27 @@ def S_ISREG(mode: int) -> bool: ... 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): + IO_REPARSE_TAG_SYMLINK: int + IO_REPARSE_TAG_MOUNT_POINT: int + IO_REPARSE_TAG_APPEXECLINK: int + +if sys.platform == "win32": + FILE_ATTRIBUTE_ARCHIVE: Literal[32] + FILE_ATTRIBUTE_COMPRESSED: Literal[2048] + FILE_ATTRIBUTE_DEVICE: Literal[64] + FILE_ATTRIBUTE_DIRECTORY: Literal[16] + FILE_ATTRIBUTE_ENCRYPTED: Literal[16384] + FILE_ATTRIBUTE_HIDDEN: Literal[2] + FILE_ATTRIBUTE_INTEGRITY_STREAM: Literal[32768] + FILE_ATTRIBUTE_NORMAL: Literal[128] + FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: Literal[8192] + FILE_ATTRIBUTE_NO_SCRUB_DATA: Literal[131072] + FILE_ATTRIBUTE_OFFLINE: Literal[4096] + FILE_ATTRIBUTE_READONLY: Literal[1] + FILE_ATTRIBUTE_REPARSE_POINT: Literal[1024] + FILE_ATTRIBUTE_SPARSE_FILE: Literal[512] + FILE_ATTRIBUTE_SYSTEM: Literal[4] + FILE_ATTRIBUTE_TEMPORARY: Literal[256] + FILE_ATTRIBUTE_VIRTUAL: Literal[65536] diff --git a/mypy/typeshed/stdlib/_thread.pyi b/mypy/typeshed/stdlib/_thread.pyi index 2f4252981b68..03318a0b2d41 100644 --- a/mypy/typeshed/stdlib/_thread.pyi +++ b/mypy/typeshed/stdlib/_thread.pyi @@ -1,7 +1,8 @@ import sys +from _typeshed import structseq from threading import Thread from types import TracebackType -from typing import Any, Callable, NoReturn, Optional, Tuple, Type +from typing import Any, Callable, NoReturn, Optional, Type from typing_extensions import final error = RuntimeError @@ -20,7 +21,7 @@ class LockType: self, type: Type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None ) -> None: ... -def start_new_thread(function: Callable[..., Any], args: Tuple[Any, ...], kwargs: dict[str, Any] = ...) -> int: ... +def start_new_thread(function: Callable[..., Any], args: tuple[Any, ...], kwargs: dict[str, Any] = ...) -> int: ... def interrupt_main() -> None: ... def exit() -> NoReturn: ... def allocate_lock() -> LockType: ... @@ -32,7 +33,9 @@ TIMEOUT_MAX: float if sys.version_info >= (3, 8): def get_native_id() -> int: ... # only available on some platforms @final - class _ExceptHookArgs(Tuple[Type[BaseException], Optional[BaseException], Optional[TracebackType], Optional[Thread]]): + class _ExceptHookArgs( + structseq[Any], tuple[Type[BaseException], Optional[BaseException], Optional[TracebackType], Optional[Thread]] + ): @property def exc_type(self) -> Type[BaseException]: ... @property diff --git a/mypy/typeshed/stdlib/_threading_local.pyi b/mypy/typeshed/stdlib/_threading_local.pyi index bab69a7c2e7d..9e1e3f48d286 100644 --- a/mypy/typeshed/stdlib/_threading_local.pyi +++ b/mypy/typeshed/stdlib/_threading_local.pyi @@ -1,7 +1,7 @@ -from typing import Any, Dict +from typing import Any from weakref import ReferenceType -localdict = Dict[Any, Any] +localdict = dict[Any, Any] class _localimpl: key: str diff --git a/mypy/typeshed/stdlib/_tkinter.pyi b/mypy/typeshed/stdlib/_tkinter.pyi index e97edf5b4fae..b6c8ccd1c380 100644 --- a/mypy/typeshed/stdlib/_tkinter.pyi +++ b/mypy/typeshed/stdlib/_tkinter.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any from typing_extensions import Literal, final @@ -68,7 +69,8 @@ class TkappType: quit: Any record: Any setvar: Any - split: Any + if sys.version_info < (3, 11): + split: Any splitlist: Any unsetvar: Any wantobjects: Any diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 0d4c42afc285..a7f8c5147103 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -7,7 +7,7 @@ import ctypes import mmap import sys from os import PathLike -from typing import AbstractSet, Any, Awaitable, Container, Iterable, Protocol, TypeVar, Union +from typing import AbstractSet, Any, Awaitable, ClassVar, Container, Generic, Iterable, Protocol, Type, TypeVar, Union from typing_extensions import Literal, final _KT = TypeVar("_KT") @@ -35,16 +35,6 @@ class SupportsNext(Protocol[_T_co]): class SupportsAnext(Protocol[_T_co]): def __anext__(self) -> Awaitable[_T_co]: ... -class SupportsLessThan(Protocol): - def __lt__(self, __other: Any) -> bool: ... - -SupportsLessThanT = TypeVar("SupportsLessThanT", bound=SupportsLessThan) # noqa: Y001 - -class SupportsGreaterThan(Protocol): - def __gt__(self, __other: Any) -> bool: ... - -SupportsGreaterThanT = TypeVar("SupportsGreaterThanT", bound=SupportsGreaterThan) # noqa: Y001 - # Comparison protocols class SupportsDunderLT(Protocol): @@ -209,3 +199,20 @@ else: @final class NoneType: def __bool__(self) -> Literal[False]: ... + +# This is an internal CPython type that is like, but subtly different from, a NamedTuple +# Subclasses of this type are found in multiple modules. +# In typeshed, `structseq` is only ever used as a mixin in combination with a fixed-length `Tuple` +# See discussion at #6546 & #6560 +# `structseq` classes are unsubclassable, so are all decorated with `@final`. +class structseq(Generic[_T_co]): + n_fields: ClassVar[int] + n_unnamed_fields: ClassVar[int] + n_sequence_fields: ClassVar[int] + # The first parameter will generally only take an iterable of a specific length. + # E.g. `os.uname_result` takes any iterable of length exactly 5. + # + # The second parameter will accept a dict of any kind without raising an exception, + # but only has any meaning if you supply it a dict where the keys are strings. + # https://github.com/python/typeshed/pull/6560#discussion_r767149830 + def __new__(cls: Type[_T], sequence: Iterable[_T_co], dict: dict[str, Any] = ...) -> _T: ... diff --git a/mypy/typeshed/stdlib/_typeshed/dbapi.pyi b/mypy/typeshed/stdlib/_typeshed/dbapi.pyi new file mode 100644 index 000000000000..eee4fc03874e --- /dev/null +++ b/mypy/typeshed/stdlib/_typeshed/dbapi.pyi @@ -0,0 +1,36 @@ +# PEP 249 Database API 2.0 Types +# https://www.python.org/dev/peps/pep-0249/ + +from collections.abc import Mapping, Sequence +from typing import Any, Protocol + +DBAPITypeCode = Any | None +# Strictly speaking, this should be a Sequence, but the type system does +# not support fixed-length sequences. +DBAPIColumnDescription = tuple[str, DBAPITypeCode, int | None, int | None, int | None, int | None, bool | None] + +class DBAPIConnection(Protocol): + def close(self) -> object: ... + def commit(self) -> object: ... + # optional: + # def rollback(self) -> Any: ... + def cursor(self) -> DBAPICursor: ... + +class DBAPICursor(Protocol): + @property + def description(self) -> Sequence[DBAPIColumnDescription] | None: ... + @property + def rowcount(self) -> int: ... + # optional: + # 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 fetchone(self) -> Sequence[Any] | None: ... + 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: ... diff --git a/mypy/typeshed/stdlib/_typeshed/wsgi.pyi b/mypy/typeshed/stdlib/_typeshed/wsgi.pyi index 658b0fed2c6c..031d1472b6c5 100644 --- a/mypy/typeshed/stdlib/_typeshed/wsgi.pyi +++ b/mypy/typeshed/stdlib/_typeshed/wsgi.pyi @@ -3,7 +3,7 @@ # See the README.md file in this directory for more information. from sys import _OptExcInfo -from typing import Any, Callable, Dict, Iterable, Protocol +from typing import Any, Callable, Iterable, Protocol # stable class StartResponse(Protocol): @@ -11,7 +11,7 @@ class StartResponse(Protocol): self, status: str, headers: list[tuple[str, str]], exc_info: _OptExcInfo | None = ... ) -> Callable[[bytes], Any]: ... -WSGIEnvironment = Dict[str, Any] # stable +WSGIEnvironment = dict[str, Any] # stable WSGIApplication = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] # stable # WSGI input streams per PEP 3333, stable diff --git a/mypy/typeshed/stdlib/_typeshed/xml.pyi b/mypy/typeshed/stdlib/_typeshed/xml.pyi index d53b743af2d3..231c2b86e912 100644 --- a/mypy/typeshed/stdlib/_typeshed/xml.pyi +++ b/mypy/typeshed/stdlib/_typeshed/xml.pyi @@ -1,7 +1,6 @@ # See the README.md file in this directory for more information. -from typing import Any -from typing_extensions import Protocol +from typing import Any, Protocol # As defined https://docs.python.org/3/library/xml.dom.html#domimplementation-objects class DOMImplementation(Protocol): diff --git a/mypy/typeshed/stdlib/_weakref.pyi b/mypy/typeshed/stdlib/_weakref.pyi index dcaef25b3f0f..00dc2d5114b8 100644 --- a/mypy/typeshed/stdlib/_weakref.pyi +++ b/mypy/typeshed/stdlib/_weakref.pyi @@ -11,6 +11,7 @@ _T = TypeVar("_T") @final class CallableProxyType(Generic[_C]): # "weakcallableproxy" def __getattr__(self, attr: str) -> Any: ... + __call__: _C @final class ProxyType(Generic[_T]): # "weakproxy" diff --git a/mypy/typeshed/stdlib/_winapi.pyi b/mypy/typeshed/stdlib/_winapi.pyi index 83089d485c17..eba236597840 100644 --- a/mypy/typeshed/stdlib/_winapi.pyi +++ b/mypy/typeshed/stdlib/_winapi.pyi @@ -2,133 +2,194 @@ import sys from typing import Any, NoReturn, Sequence, overload from typing_extensions import Literal, final -CREATE_NEW_CONSOLE: int -CREATE_NEW_PROCESS_GROUP: int -DUPLICATE_CLOSE_SOURCE: int -DUPLICATE_SAME_ACCESS: int -ERROR_ALREADY_EXISTS: int -ERROR_BROKEN_PIPE: int -ERROR_IO_PENDING: int -ERROR_MORE_DATA: int -ERROR_NETNAME_DELETED: int -ERROR_NO_DATA: int -ERROR_NO_SYSTEM_RESOURCES: int -ERROR_OPERATION_ABORTED: int -ERROR_PIPE_BUSY: int -ERROR_PIPE_CONNECTED: int -ERROR_SEM_TIMEOUT: int -FILE_FLAG_FIRST_PIPE_INSTANCE: int -FILE_FLAG_OVERLAPPED: int -FILE_GENERIC_READ: int -FILE_GENERIC_WRITE: int -GENERIC_READ: int -GENERIC_WRITE: int -INFINITE: int -NMPWAIT_WAIT_FOREVER: int -NULL: int -OPEN_EXISTING: int -PIPE_ACCESS_DUPLEX: int -PIPE_ACCESS_INBOUND: int -PIPE_READMODE_MESSAGE: int -PIPE_TYPE_MESSAGE: int -PIPE_UNLIMITED_INSTANCES: int -PIPE_WAIT: int -PROCESS_ALL_ACCESS: int -PROCESS_DUP_HANDLE: int -STARTF_USESHOWWINDOW: int -STARTF_USESTDHANDLES: int -STD_ERROR_HANDLE: int -STD_INPUT_HANDLE: int -STD_OUTPUT_HANDLE: int -STILL_ACTIVE: int -SW_HIDE: int -WAIT_ABANDONED_0: int -WAIT_OBJECT_0: int -WAIT_TIMEOUT: int +if sys.platform == "win32": + if sys.version_info >= (3, 7): + ABOVE_NORMAL_PRIORITY_CLASS: Literal[32768] + BELOW_NORMAL_PRIORITY_CLASS: Literal[16384] + CREATE_BREAKAWAY_FROM_JOB: Literal[16777216] + CREATE_DEFAULT_ERROR_MODE: Literal[67108864] + CREATE_NO_WINDOW: Literal[134217728] + CREATE_NEW_CONSOLE: Literal[16] + CREATE_NEW_PROCESS_GROUP: Literal[512] + if sys.version_info >= (3, 7): + DETACHED_PROCESS: Literal[8] + DUPLICATE_CLOSE_SOURCE: Literal[1] + DUPLICATE_SAME_ACCESS: Literal[2] -def CloseHandle(__handle: int) -> None: ... -@overload -def ConnectNamedPipe(handle: int, overlapped: Literal[True]) -> Overlapped: ... -@overload -def ConnectNamedPipe(handle: int, overlapped: Literal[False] = ...) -> None: ... -@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, -) -> int: ... -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, -) -> 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, -) -> 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 = ..., -) -> int: ... -def ExitProcess(__ExitCode: int) -> NoReturn: ... + ERROR_ALREADY_EXISTS: Literal[183] + ERROR_BROKEN_PIPE: Literal[109] + ERROR_IO_PENDING: Literal[997] + ERROR_MORE_DATA: Literal[234] + ERROR_NETNAME_DELETED: Literal[64] + ERROR_NO_DATA: Literal[232] + ERROR_NO_SYSTEM_RESOURCES: Literal[1450] + ERROR_OPERATION_ABORTED: Literal[995] + ERROR_PIPE_BUSY: Literal[231] + ERROR_PIPE_CONNECTED: Literal[535] + ERROR_SEM_TIMEOUT: Literal[121] -if sys.version_info >= (3, 7): - def GetACP() -> int: ... - def GetFileType(handle: int) -> int: ... + FILE_FLAG_FIRST_PIPE_INSTANCE: Literal[524288] + FILE_FLAG_OVERLAPPED: Literal[1073741824] + 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] + if sys.version_info >= (3, 7): + FILE_TYPE_CHAR: Literal[2] + FILE_TYPE_DISK: Literal[1] + FILE_TYPE_PIPE: Literal[3] + FILE_TYPE_REMOTE: Literal[32768] + FILE_TYPE_UNKNOWN: Literal[0] -def GetCurrentProcess() -> int: ... -def GetExitCodeProcess(__process: int) -> int: ... -def GetLastError() -> 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 = ...) -> tuple[int, int] | tuple[bytes, int, int]: ... -@overload -def ReadFile(handle: int, size: int, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... -@overload -def ReadFile(handle: int, size: int, overlapped: Literal[False] = ...) -> tuple[bytes, int]: ... -@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 -) -> None: ... -def TerminateProcess(__handle: int, __exit_code: int) -> None: ... -def WaitForMultipleObjects(__handle_seq: Sequence[int], __wait_flag: bool, __milliseconds: int = ...) -> int: ... -def WaitForSingleObject(__handle: int, __milliseconds: int) -> int: ... -def WaitNamedPipe(__name: str, __timeout: int) -> None: ... -@overload -def WriteFile(handle: int, buffer: bytes, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... -@overload -def WriteFile(handle: int, buffer: bytes, overlapped: Literal[False] = ...) -> tuple[int, int]: ... -@overload -def WriteFile(handle: int, buffer: bytes, overlapped: int | bool) -> tuple[Any, int]: ... -@final -class Overlapped: - event: int - def GetOverlappedResult(self, __wait: bool) -> tuple[int, int]: ... - def cancel(self) -> None: ... - def getbuffer(self) -> bytes | None: ... + GENERIC_READ: Literal[2147483648] + GENERIC_WRITE: Literal[1073741824] + if sys.version_info >= (3, 7): + HIGH_PRIORITY_CLASS: Literal[128] + INFINITE: Literal[4294967295] + if sys.version_info >= (3, 8): + INVALID_HANDLE_VALUE: int # very large number + if sys.version_info >= (3, 7): + IDLE_PRIORITY_CLASS: Literal[64] + NORMAL_PRIORITY_CLASS: Literal[32] + REALTIME_PRIORITY_CLASS: Literal[256] + NMPWAIT_WAIT_FOREVER: Literal[4294967295] + + if sys.version_info >= (3, 8): + MEM_COMMIT: Literal[4096] + MEM_FREE: Literal[65536] + MEM_IMAGE: Literal[16777216] + MEM_MAPPED: Literal[262144] + MEM_PRIVATE: Literal[131072] + MEM_RESERVE: Literal[8192] + + NULL: Literal[0] + OPEN_EXISTING: Literal[3] + + PIPE_ACCESS_DUPLEX: Literal[3] + PIPE_ACCESS_INBOUND: Literal[1] + PIPE_READMODE_MESSAGE: Literal[2] + PIPE_TYPE_MESSAGE: Literal[4] + PIPE_UNLIMITED_INSTANCES: Literal[255] + PIPE_WAIT: Literal[0] + if sys.version_info >= (3, 8): + PAGE_EXECUTE: Literal[16] + PAGE_EXECUTE_READ: Literal[32] + PAGE_EXECUTE_READWRITE: Literal[64] + PAGE_EXECUTE_WRITECOPY: Literal[128] + PAGE_GUARD: Literal[256] + PAGE_NOACCESS: Literal[1] + PAGE_NOCACHE: Literal[512] + PAGE_READONLY: Literal[2] + PAGE_READWRITE: Literal[4] + PAGE_WRITECOMBINE: Literal[1024] + PAGE_WRITECOPY: Literal[8] + + PROCESS_ALL_ACCESS: Literal[2097151] + PROCESS_DUP_HANDLE: Literal[64] + if sys.version_info >= (3, 8): + SEC_COMMIT: Literal[134217728] + SEC_IMAGE: Literal[16777216] + SEC_LARGE_PAGES: Literal[2147483648] + SEC_NOCACHE: Literal[268435456] + SEC_RESERVE: Literal[67108864] + SEC_WRITECOMBINE: Literal[1073741824] + STARTF_USESHOWWINDOW: Literal[1] + STARTF_USESTDHANDLES: Literal[256] + STD_ERROR_HANDLE: Literal[4294967284] + STD_INPUT_HANDLE: Literal[4294967286] + STD_OUTPUT_HANDLE: Literal[4294967285] + STILL_ACTIVE: Literal[259] + SW_HIDE: Literal[0] + if sys.version_info >= (3, 8): + SYNCHRONIZE: Literal[1048576] + WAIT_ABANDONED_0: Literal[128] + WAIT_OBJECT_0: Literal[0] + WAIT_TIMEOUT: Literal[258] + def CloseHandle(__handle: int) -> None: ... + @overload + def ConnectNamedPipe(handle: int, overlapped: Literal[True]) -> Overlapped: ... + @overload + def ConnectNamedPipe(handle: int, overlapped: Literal[False] = ...) -> None: ... + @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, + ) -> int: ... + 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, + ) -> 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, + ) -> 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 = ..., + ) -> int: ... + def ExitProcess(__ExitCode: int) -> NoReturn: ... + if sys.version_info >= (3, 7): + def GetACP() -> int: ... + def GetFileType(handle: int) -> int: ... + def GetCurrentProcess() -> int: ... + def GetExitCodeProcess(__process: int) -> int: ... + def GetLastError() -> 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 = ...) -> tuple[int, int] | tuple[bytes, int, int]: ... + @overload + def ReadFile(handle: int, size: int, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... + @overload + def ReadFile(handle: int, size: int, overlapped: Literal[False] = ...) -> tuple[bytes, int]: ... + @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 + ) -> None: ... + def TerminateProcess(__handle: int, __exit_code: int) -> None: ... + def WaitForMultipleObjects(__handle_seq: Sequence[int], __wait_flag: bool, __milliseconds: int = ...) -> int: ... + def WaitForSingleObject(__handle: int, __milliseconds: int) -> int: ... + def WaitNamedPipe(__name: str, __timeout: int) -> None: ... + @overload + def WriteFile(handle: int, buffer: bytes, overlapped: Literal[True]) -> tuple[Overlapped, int]: ... + @overload + def WriteFile(handle: int, buffer: bytes, overlapped: Literal[False] = ...) -> tuple[int, int]: ... + @overload + def WriteFile(handle: int, buffer: bytes, overlapped: int | bool) -> tuple[Any, int]: ... + @final + class Overlapped: + event: int + def GetOverlappedResult(self, __wait: bool) -> tuple[int, int]: ... + def cancel(self) -> None: ... + def getbuffer(self) -> bytes | None: ... diff --git a/mypy/typeshed/stdlib/abc.pyi b/mypy/typeshed/stdlib/abc.pyi index 7896e910c81f..3c53692e1b36 100644 --- a/mypy/typeshed/stdlib/abc.pyi +++ b/mypy/typeshed/stdlib/abc.pyi @@ -1,5 +1,6 @@ +import sys from _typeshed import SupportsWrite -from typing import Any, Callable, Tuple, Type, TypeVar +from typing import Any, Callable, Type, TypeVar _T = TypeVar("_T") _FuncT = TypeVar("_FuncT", bound=Callable[..., Any]) @@ -7,7 +8,7 @@ _FuncT = TypeVar("_FuncT", bound=Callable[..., Any]) # These definitions have special processing in mypy class ABCMeta(type): __abstractmethods__: frozenset[str] - def __init__(self, name: str, bases: Tuple[type, ...], namespace: dict[str, Any]) -> None: ... + def __init__(self, name: str, bases: tuple[type, ...], namespace: dict[str, Any]) -> None: ... def __instancecheck__(cls: ABCMeta, instance: Any) -> Any: ... def __subclasscheck__(cls: ABCMeta, subclass: Any) -> Any: ... def _dump_registry(cls: ABCMeta, file: SupportsWrite[str] | None = ...) -> None: ... @@ -24,3 +25,6 @@ def abstractclassmethod(callable: _FuncT) -> _FuncT: ... class ABC(metaclass=ABCMeta): ... def get_cache_token() -> object: ... + +if sys.version_info >= (3, 10): + def update_abstractmethods(cls: Type[_T]) -> Type[_T]: ... diff --git a/mypy/typeshed/stdlib/aifc.pyi b/mypy/typeshed/stdlib/aifc.pyi index 79f470a366bb..e19bf2478bf3 100644 --- a/mypy/typeshed/stdlib/aifc.pyi +++ b/mypy/typeshed/stdlib/aifc.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import Self from types import TracebackType -from typing import IO, Any, NamedTuple, Tuple, Type, Union, overload +from typing import IO, Any, NamedTuple, Type, Union, overload from typing_extensions import Literal class Error(Exception): ... @@ -15,7 +15,7 @@ class _aifc_params(NamedTuple): compname: bytes _File = Union[str, IO[bytes]] -_Marker = Tuple[int, int, bytes] +_Marker = tuple[int, int, bytes] class Aifc_read: def __init__(self, f: _File) -> None: ... diff --git a/mypy/typeshed/stdlib/argparse.pyi b/mypy/typeshed/stdlib/argparse.pyi index b9a09f56a812..51933dc66668 100644 --- a/mypy/typeshed/stdlib/argparse.pyi +++ b/mypy/typeshed/stdlib/argparse.pyi @@ -1,20 +1,5 @@ import sys -from typing import ( - IO, - Any, - Callable, - Generator, - Generic, - Iterable, - NoReturn, - Pattern, - Protocol, - Sequence, - Tuple, - Type, - TypeVar, - overload, -) +from typing import IO, Any, Callable, Generator, Generic, Iterable, NoReturn, Pattern, Protocol, Sequence, Type, TypeVar, overload _T = TypeVar("_T") _ActionT = TypeVar("_ActionT", bound=Action) @@ -66,11 +51,11 @@ class _ActionsContainer: nargs: int | str = ..., const: Any = ..., default: Any = ..., - type: Callable[[str], _T] | Callable[[str], _T] | FileType = ..., + type: Callable[[str], _T] | FileType = ..., choices: Iterable[_T] | None = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., dest: str | None = ..., version: str = ..., **kwargs: Any, @@ -143,11 +128,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): @overload def parse_args(self, args: Sequence[str] | None = ...) -> Namespace: ... @overload - def parse_args(self, args: Sequence[str] | None, namespace: None) -> Namespace: ... # type: ignore + def parse_args(self, args: Sequence[str] | None, namespace: None) -> Namespace: ... # type: ignore[misc] @overload def parse_args(self, args: Sequence[str] | None, namespace: _N) -> _N: ... @overload - def parse_args(self, *, namespace: None) -> Namespace: ... # type: ignore + def parse_args(self, *, namespace: None) -> Namespace: ... # type: ignore[misc] @overload def parse_args(self, *, namespace: _N) -> _N: ... if sys.version_info >= (3, 7): @@ -274,7 +259,7 @@ class HelpFormatter: def _format_text(self, text: str) -> str: ... def _format_action(self, action: Action) -> str: ... def _format_action_invocation(self, action: Action) -> str: ... - def _metavar_formatter(self, action: Action, default_metavar: str) -> Callable[[int], Tuple[str, ...]]: ... + def _metavar_formatter(self, action: Action, default_metavar: str) -> Callable[[int], tuple[str, ...]]: ... def _format_args(self, action: Action, default_metavar: str) -> str: ... def _expand_help(self, action: Action) -> str: ... def _iter_indented_subactions(self, action: Action) -> Generator[Action, None, None]: ... @@ -299,7 +284,7 @@ class Action(_AttributeHolder): choices: Iterable[Any] | None required: bool help: str | None - metavar: str | Tuple[str, ...] | None + metavar: str | tuple[str, ...] | None def __init__( self, option_strings: Sequence[str], @@ -311,7 +296,7 @@ class Action(_AttributeHolder): choices: Iterable[_T] | None = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... def __call__( self, parser: ArgumentParser, namespace: Namespace, values: str | Sequence[Any] | None, option_string: str | None = ... @@ -330,7 +315,7 @@ if sys.version_info >= (3, 9): choices: Iterable[_T] | None = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... class Namespace(_AttributeHolder): @@ -375,7 +360,7 @@ class _StoreConstAction(Action): default: Any = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... # undocumented @@ -403,7 +388,7 @@ class _AppendConstAction(Action): default: Any = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... # undocumented @@ -440,7 +425,7 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): dest: str = ..., required: bool = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... else: def __init__( @@ -450,7 +435,7 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]): parser_class: Type[_ArgumentParserT], dest: str = ..., help: str | None = ..., - metavar: str | Tuple[str, ...] | None = ..., + metavar: str | tuple[str, ...] | None = ..., ) -> None: ... # TODO: Type keyword args properly. def add_parser(self, name: str, **kwargs: Any) -> _ArgumentParserT: ... diff --git a/mypy/typeshed/stdlib/array.pyi b/mypy/typeshed/stdlib/array.pyi index 6f4444b10f96..f49eb2c916c2 100644 --- a/mypy/typeshed/stdlib/array.pyi +++ b/mypy/typeshed/stdlib/array.pyi @@ -1,6 +1,6 @@ import sys from typing import Any, BinaryIO, Generic, Iterable, MutableSequence, TypeVar, Union, overload -from typing_extensions import Literal +from typing_extensions import Literal, SupportsIndex _IntTypeCode = Literal["b", "B", "h", "H", "i", "I", "l", "L", "q", "Q"] _FloatTypeCode = Literal["f", "d"] @@ -48,14 +48,14 @@ class array(MutableSequence[_T], Generic[_T]): def tostring(self) -> bytes: ... def __len__(self) -> int: ... @overload - def __getitem__(self, __i: int) -> _T: ... + def __getitem__(self, __i: SupportsIndex) -> _T: ... @overload def __getitem__(self, __s: slice) -> array[_T]: ... @overload # type: ignore # Overrides MutableSequence - def __setitem__(self, __i: int, __o: _T) -> None: ... + def __setitem__(self, __i: SupportsIndex, __o: _T) -> None: ... @overload def __setitem__(self, __s: slice, __o: array[_T]) -> None: ... - def __delitem__(self, __i: int | slice) -> None: ... + def __delitem__(self, __i: SupportsIndex | slice) -> None: ... def __add__(self, __x: array[_T]) -> array[_T]: ... def __ge__(self, __other: array[_T]) -> bool: ... def __gt__(self, __other: array[_T]) -> bool: ... diff --git a/mypy/typeshed/stdlib/ast.pyi b/mypy/typeshed/stdlib/ast.pyi index 00c62c30c037..8494a3a99126 100644 --- a/mypy/typeshed/stdlib/ast.pyi +++ b/mypy/typeshed/stdlib/ast.pyi @@ -8,7 +8,7 @@ # sys. import sys import typing as _typing -from _ast import * # type: ignore +from _ast import * from typing import Any, Iterator, TypeVar, overload from typing_extensions import Literal @@ -165,6 +165,57 @@ if sys.version_info >= (3, 8): feature_version: None | int | _typing.Tuple[int, int] = ..., ) -> Module: ... @overload + def parse( + source: str | bytes, + filename: str | bytes, + mode: Literal["eval"], + *, + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> Expression: ... + @overload + def parse( + source: str | bytes, + filename: str | bytes, + mode: Literal["func_type"], + *, + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> FunctionType: ... + @overload + def parse( + source: str | bytes, + filename: str | bytes, + mode: Literal["single"], + *, + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> Interactive: ... + @overload + def parse( + source: str | bytes, + *, + mode: Literal["eval"], + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> Expression: ... + @overload + def parse( + source: str | bytes, + *, + mode: Literal["func_type"], + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> FunctionType: ... + @overload + def parse( + source: str | bytes, + *, + mode: Literal["single"], + type_comments: bool = ..., + feature_version: None | int | _typing.Tuple[int, int] = ..., + ) -> Interactive: ... + @overload def parse( source: str | bytes, filename: str | bytes = ..., @@ -178,6 +229,14 @@ else: @overload def parse(source: str | bytes, filename: str | bytes = ..., mode: Literal["exec"] = ...) -> Module: ... @overload + def parse(source: str | bytes, filename: str | bytes, mode: Literal["eval"]) -> Expression: ... + @overload + def parse(source: str | bytes, filename: str | bytes, mode: Literal["single"]) -> Interactive: ... + @overload + def parse(source: str | bytes, *, mode: Literal["eval"]) -> Expression: ... + @overload + def parse(source: str | bytes, *, mode: Literal["single"]) -> Interactive: ... + @overload def parse(source: str | bytes, filename: str | bytes = ..., mode: str = ...) -> AST: ... if sys.version_info >= (3, 9): diff --git a/mypy/typeshed/stdlib/asyncio/__init__.pyi b/mypy/typeshed/stdlib/asyncio/__init__.pyi index 42e7aa9ba6d8..f2f7c6b0d165 100644 --- a/mypy/typeshed/stdlib/asyncio/__init__.pyi +++ b/mypy/typeshed/stdlib/asyncio/__init__.pyi @@ -2,7 +2,7 @@ import sys from typing import Type from .base_events import BaseEventLoop as BaseEventLoop -from .coroutines import coroutine as coroutine, iscoroutine as iscoroutine, iscoroutinefunction as iscoroutinefunction +from .coroutines import iscoroutine as iscoroutine, iscoroutinefunction as iscoroutinefunction from .events import ( AbstractEventLoop as AbstractEventLoop, AbstractEventLoopPolicy as AbstractEventLoopPolicy, @@ -71,39 +71,48 @@ from .transports import ( WriteTransport as WriteTransport, ) -if sys.version_info >= (3, 7): - from .events import get_running_loop as get_running_loop +if sys.version_info < (3, 11): + from .coroutines import coroutine as coroutine + +if sys.version_info >= (3, 9): + from .threads import to_thread as to_thread + if sys.version_info >= (3, 8): from .exceptions import ( CancelledError as CancelledError, IncompleteReadError as IncompleteReadError, InvalidStateError as InvalidStateError, LimitOverrunError as LimitOverrunError, - SendfileNotAvailableError as SendfileNotAvailableError, TimeoutError as TimeoutError, ) else: - if sys.version_info >= (3, 7): - from .events import SendfileNotAvailableError as SendfileNotAvailableError from .futures import CancelledError as CancelledError, InvalidStateError as InvalidStateError, TimeoutError as TimeoutError from .streams import IncompleteReadError as IncompleteReadError, LimitOverrunError as LimitOverrunError -if sys.version_info >= (3, 7): - from .protocols import BufferedProtocol as BufferedProtocol +if sys.version_info >= (3, 8): + from .exceptions import SendfileNotAvailableError as SendfileNotAvailableError +elif sys.version_info >= (3, 7): + from .events import SendfileNotAvailableError as SendfileNotAvailableError if sys.version_info >= (3, 7): + from .events import get_running_loop as get_running_loop + from .protocols import BufferedProtocol as BufferedProtocol from .runners import run as run - -if sys.version_info >= (3, 7): - from .tasks import all_tasks as all_tasks, create_task as create_task, current_task as current_task -if sys.version_info >= (3, 9): - from .threads import to_thread as to_thread + from .tasks import ( + _enter_task as _enter_task, + _leave_task as _leave_task, + _register_task as _register_task, + _unregister_task as _unregister_task, + all_tasks as all_tasks, + create_task as create_task, + current_task as current_task, + ) DefaultEventLoopPolicy: Type[AbstractEventLoopPolicy] + if sys.platform == "win32": from .windows_events import * - -if sys.platform != "win32": +else: from .streams import open_unix_connection as open_unix_connection, start_unix_server as start_unix_server from .unix_events import ( AbstractChildWatcher as AbstractChildWatcher, diff --git a/mypy/typeshed/stdlib/asyncio/base_events.pyi b/mypy/typeshed/stdlib/asyncio/base_events.pyi index 15471f54483f..674baf49ba05 100644 --- a/mypy/typeshed/stdlib/asyncio/base_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_events.pyi @@ -9,18 +9,18 @@ from asyncio.tasks import Task from asyncio.transports import BaseTransport from collections.abc import Iterable from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket -from typing import IO, Any, Awaitable, Callable, Dict, Generator, Sequence, Tuple, TypeVar, Union, overload +from typing import IO, Any, Awaitable, Callable, Generator, Sequence, TypeVar, Union, overload from typing_extensions import Literal if sys.version_info >= (3, 7): from contextvars import Context _T = TypeVar("_T") -_Context = Dict[str, Any] +_Context = dict[str, Any] _ExceptionHandler = Callable[[AbstractEventLoop, _Context], Any] _ProtocolFactory = Callable[[], BaseProtocol] _SSLContext = Union[bool, None, ssl.SSLContext] -_TransProtPair = Tuple[BaseTransport, BaseProtocol] +_TransProtPair = tuple[BaseTransport, BaseProtocol] class Server(AbstractServer): if sys.version_info >= (3, 7): @@ -37,7 +37,7 @@ class Server(AbstractServer): def __init__(self, loop: AbstractEventLoop, sockets: list[socket]) -> None: ... if sys.version_info >= (3, 8): @property - def sockets(self) -> Tuple[socket, ...]: ... + def sockets(self) -> tuple[socket, ...]: ... elif sys.version_info >= (3, 7): @property def sockets(self) -> list[socket]: ... @@ -285,20 +285,35 @@ class BaseEventLoop(AbstractEventLoop, metaclass=ABCMeta): async def connect_accepted_socket( self, protocol_factory: _ProtocolFactory, sock: socket, *, ssl: _SSLContext = ... ) -> _TransProtPair: ... - async def create_datagram_endpoint( - self, - protocol_factory: _ProtocolFactory, - local_addr: tuple[str, int] | None = ..., - remote_addr: tuple[str, int] | None = ..., - *, - family: int = ..., - proto: int = ..., - flags: int = ..., - reuse_address: bool | None = ..., - reuse_port: bool | None = ..., - allow_broadcast: bool | None = ..., - sock: socket | None = ..., - ) -> _TransProtPair: ... + if sys.version_info >= (3, 11): + async def create_datagram_endpoint( + self, + protocol_factory: _ProtocolFactory, + local_addr: tuple[str, int] | None = ..., + remote_addr: tuple[str, int] | None = ..., + *, + family: int = ..., + proto: int = ..., + flags: int = ..., + reuse_port: bool | None = ..., + allow_broadcast: bool | None = ..., + sock: socket | None = ..., + ) -> _TransProtPair: ... + else: + async def create_datagram_endpoint( + self, + protocol_factory: _ProtocolFactory, + local_addr: tuple[str, int] | None = ..., + remote_addr: tuple[str, int] | None = ..., + *, + family: int = ..., + proto: int = ..., + flags: int = ..., + reuse_address: bool | None = ..., + reuse_port: bool | None = ..., + allow_broadcast: bool | None = ..., + sock: socket | None = ..., + ) -> _TransProtPair: ... # Pipes and subprocesses. async def connect_read_pipe(self, protocol_factory: _ProtocolFactory, pipe: Any) -> _TransProtPair: ... async def connect_write_pipe(self, protocol_factory: _ProtocolFactory, pipe: Any) -> _TransProtPair: ... diff --git a/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi b/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi index 23034790a4a9..94c7c01dd1bc 100644 --- a/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_subprocess.pyi @@ -1,6 +1,6 @@ import subprocess from collections import deque -from typing import IO, Any, Callable, Optional, Sequence, Tuple, Union +from typing import IO, Any, Callable, Optional, Sequence, Union from . import events, futures, protocols, transports @@ -15,7 +15,7 @@ class BaseSubprocessTransport(transports.SubprocessTransport): _pid: int | None # undocumented _returncode: int | None # undocumented _exit_waiters: list[futures.Future[Any]] # undocumented - _pending_calls: deque[tuple[Callable[..., Any], Tuple[Any, ...]]] # undocumented + _pending_calls: deque[tuple[Callable[..., Any], tuple[Any, ...]]] # undocumented _pipes: dict[int, _File] # undocumented _finished: bool # undocumented def __init__( @@ -46,11 +46,11 @@ class BaseSubprocessTransport(transports.SubprocessTransport): def get_protocol(self) -> protocols.BaseProtocol: ... def is_closing(self) -> bool: ... def close(self) -> None: ... - def get_pid(self) -> int | None: ... # type: ignore + def get_pid(self) -> int | None: ... # type: ignore[override] def get_returncode(self) -> int | None: ... - def get_pipe_transport(self, fd: int) -> _File: ... # type: ignore + def get_pipe_transport(self, fd: int) -> _File: ... # type: ignore[override] def _check_proc(self) -> None: ... # undocumented - def send_signal(self, signal: int) -> None: ... # type: ignore + def send_signal(self, signal: int) -> None: ... # type: ignore[override] def terminate(self) -> None: ... def kill(self) -> None: ... async def _connect_pipes(self, waiter: futures.Future[Any] | None) -> None: ... # undocumented diff --git a/mypy/typeshed/stdlib/asyncio/constants.pyi b/mypy/typeshed/stdlib/asyncio/constants.pyi index 2010fe9123ae..230cf4faf483 100644 --- a/mypy/typeshed/stdlib/asyncio/constants.pyi +++ b/mypy/typeshed/stdlib/asyncio/constants.pyi @@ -1,12 +1,13 @@ import enum import sys +from typing_extensions import Literal -LOG_THRESHOLD_FOR_CONNLOST_WRITES: int -ACCEPT_RETRY_DELAY: int -DEBUG_STACK_DEPTH: int +LOG_THRESHOLD_FOR_CONNLOST_WRITES: Literal[5] +ACCEPT_RETRY_DELAY: Literal[1] +DEBUG_STACK_DEPTH: Literal[10] if sys.version_info >= (3, 7): SSL_HANDSHAKE_TIMEOUT: float - SENDFILE_FALLBACK_READBUFFER_SIZE: int + SENDFILE_FALLBACK_READBUFFER_SIZE: Literal[262144] class _SendfileMode(enum.Enum): UNSUPPORTED: int diff --git a/mypy/typeshed/stdlib/asyncio/coroutines.pyi b/mypy/typeshed/stdlib/asyncio/coroutines.pyi index df94d5ba156a..6c2d8179d1f1 100644 --- a/mypy/typeshed/stdlib/asyncio/coroutines.pyi +++ b/mypy/typeshed/stdlib/asyncio/coroutines.pyi @@ -1,16 +1,20 @@ import sys import types -from collections.abc import Callable, Coroutine -from typing import Any, TypeVar +from collections.abc import Coroutine +from typing import Any from typing_extensions import TypeGuard -_F = TypeVar("_F", bound=Callable[..., Any]) +if sys.version_info < (3, 11): + from collections.abc import Callable + from typing import TypeVar + + _F = TypeVar("_F", bound=Callable[..., Any]) + def coroutine(func: _F) -> _F: ... -def coroutine(func: _F) -> _F: ... def iscoroutinefunction(func: object) -> bool: ... -if sys.version_info < (3, 8): - def iscoroutine(obj: object) -> TypeGuard[types.GeneratorType[Any, Any, Any] | Coroutine[Any, Any, Any]]: ... +if sys.version_info >= (3, 8): + def iscoroutine(obj: object) -> TypeGuard[Coroutine[Any, Any, Any]]: ... else: - def iscoroutine(obj: object) -> TypeGuard[Coroutine[Any, Any, Any]]: ... + def iscoroutine(obj: object) -> TypeGuard[types.GeneratorType[Any, Any, Any] | Coroutine[Any, Any, Any]]: ... diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 6ef9117b6491..81b30b7e0065 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import FileDescriptorLike, Self from abc import ABCMeta, abstractmethod from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket -from typing import IO, Any, Awaitable, Callable, Dict, Generator, Sequence, Tuple, TypeVar, Union, overload +from typing import IO, Any, Awaitable, Callable, Generator, Sequence, TypeVar, Union, overload from typing_extensions import Literal from .base_events import Server @@ -17,11 +17,11 @@ if sys.version_info >= (3, 7): from contextvars import Context _T = TypeVar("_T") -_Context = Dict[str, Any] +_Context = dict[str, Any] _ExceptionHandler = Callable[[AbstractEventLoop, _Context], Any] _ProtocolFactory = Callable[[], BaseProtocol] _SSLContext = Union[bool, None, ssl.SSLContext] -_TransProtPair = Tuple[BaseTransport, BaseProtocol] +_TransProtPair = tuple[BaseTransport, BaseProtocol] class Handle: _cancelled = False diff --git a/mypy/typeshed/stdlib/asyncio/proactor_events.pyi b/mypy/typeshed/stdlib/asyncio/proactor_events.pyi index 6c8c558e5dfa..1e9cff1b1dd6 100644 --- a/mypy/typeshed/stdlib/asyncio/proactor_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/proactor_events.pyi @@ -1,7 +1,7 @@ import sys from socket import socket -from typing import Any, Mapping, Type -from typing_extensions import Literal, Protocol +from typing import Any, Mapping, Protocol, Type +from typing_extensions import Literal from . import base_events, constants, events, futures, streams, transports diff --git a/mypy/typeshed/stdlib/asyncio/streams.pyi b/mypy/typeshed/stdlib/asyncio/streams.pyi index 595222280d58..6dae893e3b97 100644 --- a/mypy/typeshed/stdlib/asyncio/streams.pyi +++ b/mypy/typeshed/stdlib/asyncio/streams.pyi @@ -16,43 +16,71 @@ if sys.version_info < (3, 8): consumed: int def __init__(self, message: str, consumed: int) -> None: ... -async def open_connection( - host: str | None = ..., - port: int | str | None = ..., - *, - loop: events.AbstractEventLoop | None = ..., - limit: int = ..., - ssl_handshake_timeout: float | None = ..., - **kwds: Any, -) -> tuple[StreamReader, StreamWriter]: ... -async def start_server( - client_connected_cb: _ClientConnectedCallback, - host: str | None = ..., - port: int | str | None = ..., - *, - loop: events.AbstractEventLoop | None = ..., - limit: int = ..., - ssl_handshake_timeout: float | None = ..., - **kwds: Any, -) -> Server: ... +if sys.version_info >= (3, 10): + async def open_connection( + host: str | None = ..., + port: int | str | None = ..., + *, + limit: int = ..., + ssl_handshake_timeout: float | None = ..., + **kwds: Any, + ) -> tuple[StreamReader, StreamWriter]: ... + async def start_server( + client_connected_cb: _ClientConnectedCallback, + host: str | None = ..., + port: int | str | None = ..., + *, + limit: int = ..., + ssl_handshake_timeout: float | None = ..., + **kwds: Any, + ) -> Server: ... -if sys.platform != "win32": - if sys.version_info >= (3, 7): - _PathType = StrPath - else: - _PathType = str - async def open_unix_connection( - path: _PathType | None = ..., *, loop: events.AbstractEventLoop | None = ..., limit: int = ..., **kwds: Any +else: + async def open_connection( + host: str | None = ..., + port: int | str | None = ..., + *, + loop: events.AbstractEventLoop | None = ..., + limit: int = ..., + ssl_handshake_timeout: float | None = ..., + **kwds: Any, ) -> tuple[StreamReader, StreamWriter]: ... - async def start_unix_server( + async def start_server( client_connected_cb: _ClientConnectedCallback, - path: _PathType | None = ..., + host: str | None = ..., + port: int | str | None = ..., *, loop: events.AbstractEventLoop | None = ..., limit: int = ..., + ssl_handshake_timeout: float | None = ..., **kwds: Any, ) -> Server: ... +if sys.platform != "win32": + if sys.version_info >= (3, 7): + _PathType = StrPath + else: + _PathType = str + if sys.version_info >= (3, 10): + async def open_unix_connection( + path: _PathType | None = ..., *, limit: int = ..., **kwds: Any + ) -> tuple[StreamReader, StreamWriter]: ... + async def start_unix_server( + client_connected_cb: _ClientConnectedCallback, path: _PathType | None = ..., *, limit: int = ..., **kwds: Any + ) -> Server: ... + else: + async def open_unix_connection( + path: _PathType | None = ..., *, loop: events.AbstractEventLoop | None = ..., limit: int = ..., **kwds: Any + ) -> tuple[StreamReader, StreamWriter]: ... + async def start_unix_server( + client_connected_cb: _ClientConnectedCallback, + path: _PathType | None = ..., + *, + loop: events.AbstractEventLoop | None = ..., + limit: int = ..., + **kwds: Any, + ) -> Server: ... + class FlowControlMixin(protocols.Protocol): def __init__(self, loop: events.AbstractEventLoop | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/tasks.pyi b/mypy/typeshed/stdlib/asyncio/tasks.pyi index 15c12909f3c3..71f9741cb33b 100644 --- a/mypy/typeshed/stdlib/asyncio/tasks.pyi +++ b/mypy/typeshed/stdlib/asyncio/tasks.pyi @@ -21,9 +21,9 @@ _FT = TypeVar("_FT", bound=Future[Any]) _FutureT = Union[Future[_T], Generator[Any, None, _T], Awaitable[_T]] _TaskYieldType = Optional[Future[object]] -FIRST_EXCEPTION: str -FIRST_COMPLETED: str -ALL_COMPLETED: str +FIRST_COMPLETED = concurrent.futures.FIRST_COMPLETED +FIRST_EXCEPTION = concurrent.futures.FIRST_EXCEPTION +ALL_COMPLETED = concurrent.futures.ALL_COMPLETED if sys.version_info >= (3, 10): def as_completed(fs: Iterable[_FutureT[_T]], *, timeout: float | None = ...) -> Iterator[Future[_T]]: ... @@ -34,7 +34,7 @@ else: ) -> Iterator[Future[_T]]: ... @overload -def ensure_future(coro_or_future: _FT, *, loop: AbstractEventLoop | None = ...) -> _FT: ... # type: ignore +def ensure_future(coro_or_future: _FT, *, loop: AbstractEventLoop | None = ...) -> _FT: ... # type: ignore[misc] @overload def ensure_future(coro_or_future: Awaitable[_T], *, loop: AbstractEventLoop | None = ...) -> Task[_T]: ... @@ -230,25 +230,27 @@ def run_coroutine_threadsafe(coro: _FutureT[_T], loop: AbstractEventLoop) -> con if sys.version_info >= (3, 10): def shield(arg: _FutureT[_T]) -> Future[_T]: ... - def sleep(delay: float, result: _T = ...) -> Future[_T]: ... + async def sleep(delay: float, result: _T = ...) -> _T: ... @overload - def wait(fs: Iterable[_FT], *, timeout: float | None = ..., return_when: str = ...) -> Future[tuple[set[_FT], set[_FT]]]: ... # type: ignore + async def wait(fs: Iterable[_FT], *, timeout: float | None = ..., return_when: str = ...) -> tuple[set[_FT], set[_FT]]: ... # type: ignore[misc] @overload - def wait( + async def wait( fs: Iterable[Awaitable[_T]], *, timeout: float | None = ..., return_when: str = ... - ) -> Future[tuple[set[Task[_T]], set[Task[_T]]]]: ... - def wait_for(fut: _FutureT[_T], timeout: float | None) -> Future[_T]: ... + ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... + async def wait_for(fut: _FutureT[_T], timeout: float | None) -> _T: ... else: def shield(arg: _FutureT[_T], *, loop: AbstractEventLoop | None = ...) -> Future[_T]: ... - def sleep(delay: float, result: _T = ..., *, loop: AbstractEventLoop | None = ...) -> Future[_T]: ... + async def sleep(delay: float, result: _T = ..., *, loop: AbstractEventLoop | None = ...) -> _T: ... @overload - def wait(fs: Iterable[_FT], *, loop: AbstractEventLoop | None = ..., timeout: float | None = ..., return_when: str = ...) -> Future[tuple[set[_FT], set[_FT]]]: ... # type: ignore + async def wait( # type: ignore[misc] + fs: Iterable[_FT], *, loop: AbstractEventLoop | None = ..., timeout: float | None = ..., return_when: str = ... + ) -> tuple[set[_FT], set[_FT]]: ... @overload - def wait( + async def wait( fs: Iterable[Awaitable[_T]], *, loop: AbstractEventLoop | None = ..., timeout: float | None = ..., return_when: str = ... - ) -> Future[tuple[set[Task[_T]], set[Task[_T]]]]: ... - def wait_for(fut: _FutureT[_T], timeout: float | None, *, loop: AbstractEventLoop | None = ...) -> Future[_T]: ... + ) -> tuple[set[Task[_T]], set[Task[_T]]]: ... + async def wait_for(fut: _FutureT[_T], timeout: float | None, *, loop: AbstractEventLoop | None = ...) -> _T: ... class Task(Future[_T], Generic[_T]): if sys.version_info >= (3, 8): @@ -291,3 +293,7 @@ if sys.version_info >= (3, 7): else: def create_task(coro: Generator[_TaskYieldType, None, _T] | Awaitable[_T]) -> Task[_T]: ... def current_task(loop: AbstractEventLoop | None = ...) -> Task[Any] | None: ... + def _enter_task(loop: AbstractEventLoop, task: Task[Any]) -> None: ... + def _leave_task(loop: AbstractEventLoop, task: Task[Any]) -> None: ... + def _register_task(task: Task[Any]) -> None: ... + def _unregister_task(task: Task[Any]) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/threads.pyi b/mypy/typeshed/stdlib/asyncio/threads.pyi index 3f798d8ac862..c13c0c6d1194 100644 --- a/mypy/typeshed/stdlib/asyncio/threads.pyi +++ b/mypy/typeshed/stdlib/asyncio/threads.pyi @@ -1,7 +1,9 @@ import sys -from typing import Any, Callable, TypeVar +from typing import Callable, TypeVar +from typing_extensions import ParamSpec -_T = TypeVar("_T") +_P = ParamSpec("_P") +_R = TypeVar("_R") if sys.version_info >= (3, 9): - async def to_thread(__func: Callable[..., _T], *args: Any, **kwargs: Any) -> _T: ... + 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 33ec5d67aaf9..55147f4fddd5 100644 --- a/mypy/typeshed/stdlib/asyncio/trsock.pyi +++ b/mypy/typeshed/stdlib/asyncio/trsock.pyi @@ -1,14 +1,14 @@ import socket import sys from types import TracebackType -from typing import Any, BinaryIO, Iterable, NoReturn, Tuple, Type, Union, overload +from typing import Any, BinaryIO, Iterable, NoReturn, Type, Union, overload if sys.version_info >= (3, 8): # These are based in socket, maybe move them out into _typeshed.pyi or such - _Address = Union[Tuple[Any, ...], str] + _Address = Union[tuple[Any, ...], str] _RetAddress = Any _WriteBuffer = Union[bytearray, memoryview] - _CMSG = Tuple[int, int, bytes] + _CMSG = tuple[int, int, bytes] class TransportSocket: def __init__(self, sock: socket.socket) -> None: ... def _na(self, what: str) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/unix_events.pyi b/mypy/typeshed/stdlib/asyncio/unix_events.pyi index e8e57a20a765..de3b320a4e24 100644 --- a/mypy/typeshed/stdlib/asyncio/unix_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/unix_events.pyi @@ -8,6 +8,9 @@ from .base_events import Server from .events import AbstractEventLoop, BaseDefaultEventLoopPolicy, _ProtocolFactory, _SSLContext from .selector_events import BaseSelectorEventLoop +# This is also technically not available on Win, +# but other parts of typeshed need this defintion. +# So, it is special cased. class AbstractChildWatcher: def add_child_handler(self, pid: int, callback: Callable[..., Any], *args: Any) -> None: ... def remove_child_handler(self, pid: int) -> bool: ... @@ -18,44 +21,40 @@ class AbstractChildWatcher: if sys.version_info >= (3, 8): def is_active(self) -> bool: ... -class BaseChildWatcher(AbstractChildWatcher): - def __init__(self) -> None: ... - -class SafeChildWatcher(BaseChildWatcher): - def __enter__(self: Self) -> Self: ... - -class FastChildWatcher(BaseChildWatcher): - def __enter__(self: Self) -> Self: ... - -class _UnixSelectorEventLoop(BaseSelectorEventLoop): - if sys.version_info < (3, 7): - async def create_unix_server( - self, - protocol_factory: _ProtocolFactory, - path: str | None = ..., - *, - sock: socket | None = ..., - backlog: int = ..., - ssl: _SSLContext = ..., - ) -> Server: ... - -class _UnixDefaultEventLoopPolicy(BaseDefaultEventLoopPolicy): - 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): - - from typing import Protocol - class _Warn(Protocol): - def __call__( - self, message: str, category: Type[Warning] | None = ..., stacklevel: int = ..., source: Any | None = ... - ) -> None: ... - class MultiLoopChildWatcher(AbstractChildWatcher): +if sys.platform != "win32": + class BaseChildWatcher(AbstractChildWatcher): + def __init__(self) -> None: ... + class SafeChildWatcher(BaseChildWatcher): def __enter__(self: Self) -> Self: ... - class ThreadedChildWatcher(AbstractChildWatcher): + class FastChildWatcher(BaseChildWatcher): def __enter__(self: Self) -> Self: ... - def __del__(self, _warn: _Warn = ...) -> None: ... + class _UnixSelectorEventLoop(BaseSelectorEventLoop): + if sys.version_info < (3, 7): + async def create_unix_server( + self, + protocol_factory: _ProtocolFactory, + path: str | None = ..., + *, + sock: socket | None = ..., + backlog: int = ..., + ssl: _SSLContext = ..., + ) -> Server: ... + class _UnixDefaultEventLoopPolicy(BaseDefaultEventLoopPolicy): + 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): + + from typing import Protocol + class _Warn(Protocol): + def __call__( + self, message: str, category: Type[Warning] | None = ..., stacklevel: int = ..., source: Any | None = ... + ) -> None: ... + class MultiLoopChildWatcher(AbstractChildWatcher): + def __enter__(self: Self) -> Self: ... + class ThreadedChildWatcher(AbstractChildWatcher): + def __enter__(self: Self) -> Self: ... + def __del__(self, _warn: _Warn = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncio/windows_events.pyi b/mypy/typeshed/stdlib/asyncio/windows_events.pyi index f0a206a4e139..d86b6af91a29 100644 --- a/mypy/typeshed/stdlib/asyncio/windows_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/windows_events.pyi @@ -2,76 +2,76 @@ import socket import sys from _typeshed import WriteableBuffer from typing import IO, Any, Callable, ClassVar, NoReturn, Type +from typing_extensions import Literal from . import events, futures, proactor_events, selector_events, streams, windows_utils -__all__ = [ - "SelectorEventLoop", - "ProactorEventLoop", - "IocpProactor", - "DefaultEventLoopPolicy", - "WindowsSelectorEventLoopPolicy", - "WindowsProactorEventLoopPolicy", -] - -NULL: int -INFINITE: int -ERROR_CONNECTION_REFUSED: int -ERROR_CONNECTION_ABORTED: int -CONNECT_PIPE_INIT_DELAY: float -CONNECT_PIPE_MAX_DELAY: float - -class PipeServer: - def __init__(self, address: str) -> None: ... - def __del__(self) -> None: ... - def closed(self) -> bool: ... - def close(self) -> None: ... - -class _WindowsSelectorEventLoop(selector_events.BaseSelectorEventLoop): ... - -class ProactorEventLoop(proactor_events.BaseProactorEventLoop): - def __init__(self, proactor: IocpProactor | None = ...) -> None: ... - async def create_pipe_connection( - self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str - ) -> tuple[proactor_events._ProactorDuplexPipeTransport, streams.StreamReaderProtocol]: ... - async def start_serving_pipe( - self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str - ) -> list[PipeServer]: ... - -class IocpProactor: - def __init__(self, concurrency: int = ...) -> None: ... - def __repr__(self) -> str: ... - def __del__(self) -> None: ... - def set_loop(self, loop: events.AbstractEventLoop) -> None: ... - def select(self, timeout: int | None = ...) -> list[futures.Future[Any]]: ... - def recv(self, conn: socket.socket, nbytes: int, flags: int = ...) -> futures.Future[bytes]: ... - if sys.version_info >= (3, 7): - def recv_into(self, conn: socket.socket, buf: WriteableBuffer, flags: int = ...) -> futures.Future[Any]: ... - def send(self, conn: socket.socket, buf: WriteableBuffer, flags: int = ...) -> futures.Future[Any]: ... - def accept(self, listener: socket.socket) -> futures.Future[Any]: ... - def connect(self, conn: socket.socket, address: bytes) -> futures.Future[Any]: ... +if sys.platform == "win32": if sys.version_info >= (3, 7): - def sendfile(self, sock: socket.socket, file: IO[bytes], offset: int, count: int) -> futures.Future[Any]: ... - def accept_pipe(self, pipe: socket.socket) -> futures.Future[Any]: ... - async def connect_pipe(self, address: bytes) -> windows_utils.PipeHandle: ... - def wait_for_handle(self, handle: windows_utils.PipeHandle, timeout: int | None = ...) -> bool: ... - def close(self) -> None: ... + __all__ = ( + "SelectorEventLoop", + "ProactorEventLoop", + "IocpProactor", + "DefaultEventLoopPolicy", + "WindowsSelectorEventLoopPolicy", + "WindowsProactorEventLoopPolicy", + ) + else: + __all__ = ["SelectorEventLoop", "ProactorEventLoop", "IocpProactor", "DefaultEventLoopPolicy"] -SelectorEventLoop = _WindowsSelectorEventLoop + NULL: Literal[0] + INFINITE: Literal[0xFFFFFFFF] + ERROR_CONNECTION_REFUSED: Literal[1225] + ERROR_CONNECTION_ABORTED: Literal[1236] + CONNECT_PIPE_INIT_DELAY: float + CONNECT_PIPE_MAX_DELAY: float + class PipeServer: + def __init__(self, address: str) -> None: ... + def __del__(self) -> None: ... + def closed(self) -> bool: ... + def close(self) -> None: ... + class _WindowsSelectorEventLoop(selector_events.BaseSelectorEventLoop): ... + class ProactorEventLoop(proactor_events.BaseProactorEventLoop): + def __init__(self, proactor: IocpProactor | None = ...) -> None: ... + async def create_pipe_connection( + self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str + ) -> tuple[proactor_events._ProactorDuplexPipeTransport, streams.StreamReaderProtocol]: ... + async def start_serving_pipe( + self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str + ) -> list[PipeServer]: ... + class IocpProactor: + def __init__(self, concurrency: int = ...) -> None: ... + def __repr__(self) -> str: ... + def __del__(self) -> None: ... + def set_loop(self, loop: events.AbstractEventLoop) -> None: ... + def select(self, timeout: int | None = ...) -> list[futures.Future[Any]]: ... + def recv(self, conn: socket.socket, nbytes: int, flags: int = ...) -> futures.Future[bytes]: ... + if sys.version_info >= (3, 7): + def recv_into(self, conn: socket.socket, buf: WriteableBuffer, flags: int = ...) -> futures.Future[Any]: ... + def send(self, conn: socket.socket, buf: WriteableBuffer, flags: int = ...) -> futures.Future[Any]: ... + def accept(self, listener: socket.socket) -> futures.Future[Any]: ... + def connect(self, conn: socket.socket, address: bytes) -> futures.Future[Any]: ... + if sys.version_info >= (3, 7): + def sendfile(self, sock: socket.socket, file: IO[bytes], offset: int, count: int) -> futures.Future[Any]: ... + def accept_pipe(self, pipe: socket.socket) -> futures.Future[Any]: ... + async def connect_pipe(self, address: bytes) -> windows_utils.PipeHandle: ... + def wait_for_handle(self, handle: windows_utils.PipeHandle, timeout: int | None = ...) -> bool: ... + def close(self) -> None: ... + SelectorEventLoop = _WindowsSelectorEventLoop -if sys.version_info >= (3, 7): - class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): - _loop_factory: ClassVar[Type[SelectorEventLoop]] - def get_child_watcher(self) -> NoReturn: ... - def set_child_watcher(self, watcher: Any) -> NoReturn: ... - class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): - _loop_factory: ClassVar[Type[ProactorEventLoop]] - def get_child_watcher(self) -> NoReturn: ... - def set_child_watcher(self, watcher: Any) -> NoReturn: ... - DefaultEventLoopPolicy = WindowsSelectorEventLoopPolicy -else: - class _WindowsDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): - _loop_factory: ClassVar[Type[SelectorEventLoop]] - def get_child_watcher(self) -> NoReturn: ... - def set_child_watcher(self, watcher: Any) -> NoReturn: ... - DefaultEventLoopPolicy = _WindowsDefaultEventLoopPolicy + if sys.version_info >= (3, 7): + class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): + _loop_factory: ClassVar[Type[SelectorEventLoop]] + def get_child_watcher(self) -> NoReturn: ... + def set_child_watcher(self, watcher: Any) -> NoReturn: ... + class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy): + _loop_factory: ClassVar[Type[ProactorEventLoop]] + def get_child_watcher(self) -> NoReturn: ... + def set_child_watcher(self, watcher: Any) -> NoReturn: ... + DefaultEventLoopPolicy = WindowsSelectorEventLoopPolicy + else: + class _WindowsDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): + _loop_factory: ClassVar[Type[SelectorEventLoop]] + def get_child_watcher(self) -> NoReturn: ... + def set_child_watcher(self, watcher: Any) -> NoReturn: ... + DefaultEventLoopPolicy = _WindowsDefaultEventLoopPolicy diff --git a/mypy/typeshed/stdlib/asyncio/windows_utils.pyi b/mypy/typeshed/stdlib/asyncio/windows_utils.pyi index bf9cdde25a78..c387fc40f211 100644 --- a/mypy/typeshed/stdlib/asyncio/windows_utils.pyi +++ b/mypy/typeshed/stdlib/asyncio/windows_utils.pyi @@ -1,27 +1,29 @@ +import subprocess import sys from _typeshed import Self from types import TracebackType from typing import Callable, Protocol, Type +from typing_extensions import Literal -class _WarnFunction(Protocol): - def __call__(self, message: str, category: Type[Warning] = ..., stacklevel: int = ..., source: PipeHandle = ...) -> None: ... - -BUFSIZE: int -PIPE: int -STDOUT: int - -def pipe(*, duplex: bool = ..., overlapped: tuple[bool, bool] = ..., bufsize: int = ...) -> tuple[int, int]: ... - -class PipeHandle: - def __init__(self, handle: int) -> None: ... - def __repr__(self) -> str: ... - if sys.version_info >= (3, 8): - def __del__(self, _warn: _WarnFunction = ...) -> None: ... - else: - def __del__(self) -> None: ... - def __enter__(self: Self) -> Self: ... - def __exit__(self, t: type | None, v: BaseException | None, tb: TracebackType | None) -> None: ... - @property - def handle(self) -> int: ... - def fileno(self) -> int: ... - def close(self, *, CloseHandle: Callable[[int], None] = ...) -> None: ... +if sys.platform == "win32": + class _WarnFunction(Protocol): + def __call__( + self, message: str, category: Type[Warning] = ..., stacklevel: int = ..., source: PipeHandle = ... + ) -> None: ... + BUFSIZE: Literal[8192] + PIPE = subprocess.PIPE + STDOUT = subprocess.STDOUT + def pipe(*, duplex: bool = ..., overlapped: tuple[bool, bool] = ..., bufsize: int = ...) -> tuple[int, int]: ... + class PipeHandle: + def __init__(self, handle: int) -> None: ... + def __repr__(self) -> str: ... + if sys.version_info >= (3, 8): + def __del__(self, _warn: _WarnFunction = ...) -> None: ... + else: + def __del__(self) -> None: ... + def __enter__(self: Self) -> Self: ... + def __exit__(self, t: type | None, v: BaseException | None, tb: TracebackType | None) -> None: ... + @property + def handle(self) -> int: ... + def fileno(self) -> int: ... + def close(self, *, CloseHandle: Callable[[int], None] = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/asyncore.pyi b/mypy/typeshed/stdlib/asyncore.pyi index e135221134a5..123da2677a7e 100644 --- a/mypy/typeshed/stdlib/asyncore.pyi +++ b/mypy/typeshed/stdlib/asyncore.pyi @@ -1,10 +1,10 @@ import sys from _typeshed import FileDescriptorLike from socket import socket -from typing import Any, Dict, Tuple, overload +from typing import Any, overload # cyclic dependence with asynchat -_maptype = Dict[int, Any] +_maptype = dict[int, Any] _socket = socket socket_map: _maptype # undocumented @@ -41,8 +41,8 @@ class dispatcher: def readable(self) -> bool: ... def writable(self) -> bool: ... def listen(self, num: int) -> None: ... - def bind(self, addr: Tuple[Any, ...] | str) -> None: ... - def connect(self, address: Tuple[Any, ...] | str) -> None: ... + def bind(self, addr: tuple[Any, ...] | str) -> None: ... + def connect(self, address: tuple[Any, ...] | str) -> None: ... def accept(self) -> tuple[_socket, Any] | None: ... def send(self, data: bytes) -> int: ... def recv(self, buffer_size: int) -> bytes: ... diff --git a/mypy/typeshed/stdlib/atexit.pyi b/mypy/typeshed/stdlib/atexit.pyi index 9395c60678b8..ba0c7dfaf6b1 100644 --- a/mypy/typeshed/stdlib/atexit.pyi +++ b/mypy/typeshed/stdlib/atexit.pyi @@ -7,5 +7,5 @@ _P = ParamSpec("_P") def _clear() -> None: ... def _ncallbacks() -> int: ... def _run_exitfuncs() -> None: ... -def register(func: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> Callable[_P, _T]: ... # type: ignore +def register(func: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> Callable[_P, _T]: ... def unregister(func: Callable[..., Any]) -> None: ... diff --git a/mypy/typeshed/stdlib/audioop.pyi b/mypy/typeshed/stdlib/audioop.pyi index 321bfe55c4b0..b08731b85b0b 100644 --- a/mypy/typeshed/stdlib/audioop.pyi +++ b/mypy/typeshed/stdlib/audioop.pyi @@ -1,7 +1,5 @@ -from typing import Tuple - -AdpcmState = Tuple[int, int] -RatecvState = Tuple[int, Tuple[Tuple[int, int], ...]] +AdpcmState = tuple[int, int] +RatecvState = tuple[int, tuple[tuple[int, int], ...]] class error(Exception): ... diff --git a/mypy/typeshed/stdlib/bdb.pyi b/mypy/typeshed/stdlib/bdb.pyi index 1d03ddf19a0e..3f6b6d3d8b7b 100644 --- a/mypy/typeshed/stdlib/bdb.pyi +++ b/mypy/typeshed/stdlib/bdb.pyi @@ -1,9 +1,9 @@ from types import CodeType, FrameType, TracebackType -from typing import IO, Any, Callable, Iterable, Mapping, SupportsInt, Tuple, Type, TypeVar +from typing import IO, Any, Callable, Iterable, Mapping, SupportsInt, Type, TypeVar _T = TypeVar("_T") _TraceDispatch = Callable[[FrameType, str, Any], Any] # TODO: Recursive type -_ExcInfo = Tuple[Type[BaseException], BaseException, FrameType] +_ExcInfo = tuple[Type[BaseException], BaseException, FrameType] GENERATOR_AND_COROUTINE_FLAGS: int diff --git a/mypy/typeshed/stdlib/binascii.pyi b/mypy/typeshed/stdlib/binascii.pyi index 962f5666b284..317bb9979b92 100644 --- a/mypy/typeshed/stdlib/binascii.pyi +++ b/mypy/typeshed/stdlib/binascii.pyi @@ -12,10 +12,13 @@ def a2b_base64(__data: str | bytes) -> bytes: ... def b2a_base64(__data: bytes, *, newline: bool = ...) -> bytes: ... def a2b_qp(data: str | bytes, header: bool = ...) -> bytes: ... def b2a_qp(data: bytes, quotetabs: bool = ..., istext: bool = ..., header: bool = ...) -> bytes: ... -def a2b_hqx(__data: str | bytes) -> bytes: ... -def rledecode_hqx(__data: bytes) -> bytes: ... -def rlecode_hqx(__data: bytes) -> bytes: ... -def b2a_hqx(__data: bytes) -> bytes: ... + +if sys.version_info < (3, 11): + def a2b_hqx(__data: str | bytes) -> bytes: ... + def rledecode_hqx(__data: bytes) -> bytes: ... + def rlecode_hqx(__data: bytes) -> bytes: ... + def b2a_hqx(__data: bytes) -> bytes: ... + def crc_hqx(__data: bytes, __crc: int) -> int: ... def crc32(__data: bytes, __crc: int = ...) -> int: ... def b2a_hex(__data: bytes) -> bytes: ... diff --git a/mypy/typeshed/stdlib/binhex.pyi b/mypy/typeshed/stdlib/binhex.pyi index 02d094faf923..4e295b8ed903 100644 --- a/mypy/typeshed/stdlib/binhex.pyi +++ b/mypy/typeshed/stdlib/binhex.pyi @@ -1,4 +1,4 @@ -from typing import IO, Any, Tuple, Union +from typing import IO, Any, Union class Error(Exception): ... @@ -12,7 +12,7 @@ class FInfo: Creator: str Flags: int -_FileInfoTuple = Tuple[str, FInfo, int, int] +_FileInfoTuple = tuple[str, FInfo, int, int] _FileHandleUnion = Union[str, IO[bytes]] def getfileinfo(name: str) -> _FileInfoTuple: ... diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 1b2d3db12c3f..5547afc217f6 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -23,13 +23,11 @@ from _typeshed import ( SupportsWrite, ) from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from types import CodeType, TracebackType +from types import CodeType, TracebackType, _Cell from typing import ( IO, AbstractSet, Any, - AsyncIterable, - AsyncIterator, BinaryIO, ByteString, Callable, @@ -51,7 +49,6 @@ from typing import ( SupportsFloat, SupportsInt, SupportsRound, - Tuple, Type, TypeVar, Union, @@ -76,6 +73,14 @@ _T5 = TypeVar("_T5") _TT = TypeVar("_TT", bound="type") _TBE = TypeVar("_TBE", bound="BaseException") _R = TypeVar("_R") # Return-type TypeVar +_SupportsNextT = TypeVar("_SupportsNextT", bound=SupportsNext[Any], covariant=True) +_SupportsAnextT = TypeVar("_SupportsAnextT", bound=SupportsAnext[Any], covariant=True) + +class _SupportsIter(Protocol[_T_co]): + def __iter__(self) -> _T_co: ... + +class _SupportsAiter(Protocol[_T_co]): + def __aiter__(self) -> _T_co: ... class object: __doc__: str | None @@ -102,11 +107,11 @@ class object: 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__(self) -> str | tuple[Any, ...]: ... if sys.version_info >= (3, 8): - def __reduce_ex__(self, __protocol: SupportsIndex) -> str | Tuple[Any, ...]: ... + def __reduce_ex__(self, __protocol: SupportsIndex) -> str | tuple[Any, ...]: ... else: - def __reduce_ex__(self, __protocol: int) -> str | Tuple[Any, ...]: ... + def __reduce_ex__(self, __protocol: int) -> str | tuple[Any, ...]: ... def __dir__(self) -> Iterable[str]: ... def __init_subclass__(cls) -> None: ... @@ -133,16 +138,16 @@ class classmethod(Generic[_R]): # Special, only valid as a decorator. __qualname__: str __wrapped__: Callable[..., _R] -class type(object): +class type: __base__: type - __bases__: Tuple[type, ...] + __bases__: tuple[type, ...] __basicsize__: int __dict__: dict[str, Any] __dictoffset__: int __flags__: int __itemsize__: int __module__: str - __mro__: Tuple[type, ...] + __mro__: tuple[type, ...] __name__: str __qualname__: str __text_signature__: str | None @@ -150,11 +155,11 @@ class type(object): @overload 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: ... @overload - def __new__(cls: Type[_TT], __name: str, __bases: Tuple[type, ...], __namespace: dict[str, Any], **kwds: Any) -> _TT: ... + def __new__(cls: Type[_TT], __name: str, __bases: tuple[type, ...], __namespace: dict[str, Any], **kwds: Any) -> _TT: ... def __call__(self, *args: Any, **kwds: Any) -> Any: ... def __subclasses__(self: _TT) -> list[_TT]: ... # Note: the documentation doesn't specify what the return type is, the standard @@ -163,12 +168,12 @@ class type(object): 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) -> Mapping[str, object]: ... if sys.version_info >= (3, 10): def __or__(self, __t: Any) -> types.UnionType: ... def __ror__(self, __t: Any) -> types.UnionType: ... -class super(object): +class super: @overload def __init__(self, __t: Any, __obj: Any) -> None: ... @overload @@ -347,6 +352,8 @@ class complex: def __abs__(self) -> float: ... def __hash__(self) -> int: ... def __bool__(self) -> bool: ... + if sys.version_info >= (3, 11): + def __complex__(self) -> complex: ... class _FormatMapMapping(Protocol): def __getitem__(self, __key: str) -> Any: ... @@ -362,7 +369,7 @@ class str(Sequence[str]): def count(self, x: str, __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ...) -> int: ... def encode(self, encoding: str = ..., errors: str = ...) -> 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: ... if sys.version_info >= (3, 8): def expandtabs(self, tabsize: SupportsIndex = ...) -> str: ... @@ -403,7 +410,7 @@ class str(Sequence[str]): def split(self, sep: str | None = ..., maxsplit: SupportsIndex = ...) -> list[str]: ... def splitlines(self, keepends: bool = ...) -> list[str]: ... 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 = ...) -> str: ... def swapcase(self) -> str: ... @@ -422,7 +429,7 @@ class str(Sequence[str]): def __contains__(self, __o: str) -> bool: ... # type: ignore[override] def __eq__(self, __x: object) -> bool: ... def __ge__(self, __x: str) -> bool: ... - def __getitem__(self, __i: int | slice) -> str: ... + def __getitem__(self, __i: SupportsIndex | slice) -> str: ... def __gt__(self, __x: str) -> bool: ... def __hash__(self) -> int: ... def __iter__(self) -> Iterator[str]: ... @@ -455,7 +462,7 @@ class bytes(ByteString): ) -> int: ... def decode(self, encoding: str = ..., errors: str = ...) -> str: ... def endswith( - self, __suffix: bytes | Tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, __suffix: bytes | tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... if sys.version_info >= (3, 8): def expandtabs(self, tabsize: SupportsIndex = ...) -> bytes: ... @@ -502,7 +509,7 @@ class bytes(ByteString): def split(self, sep: bytes | None = ..., maxsplit: SupportsIndex = ...) -> list[bytes]: ... def splitlines(self, keepends: bool = ...) -> list[bytes]: ... def startswith( - self, __prefix: bytes | Tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, __prefix: bytes | tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... def strip(self, __bytes: bytes | None = ...) -> bytes: ... def swapcase(self) -> bytes: ... @@ -536,6 +543,8 @@ class bytes(ByteString): def __gt__(self, __x: bytes) -> bool: ... def __ge__(self, __x: bytes) -> bool: ... def __getnewargs__(self) -> tuple[bytes]: ... + if sys.version_info >= (3, 11): + def __bytes__(self) -> bytes: ... class bytearray(MutableSequence[int], ByteString): @overload @@ -555,7 +564,7 @@ class bytearray(MutableSequence[int], ByteString): def copy(self) -> bytearray: ... def decode(self, encoding: str = ..., errors: str = ...) -> str: ... def endswith( - self, __suffix: bytes | Tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, __suffix: bytes | tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... if sys.version_info >= (3, 8): def expandtabs(self, tabsize: SupportsIndex = ...) -> bytearray: ... @@ -604,7 +613,7 @@ class bytearray(MutableSequence[int], ByteString): def split(self, sep: bytes | None = ..., maxsplit: SupportsIndex = ...) -> list[bytearray]: ... def splitlines(self, keepends: bool = ...) -> list[bytearray]: ... def startswith( - self, __prefix: bytes | Tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... + self, __prefix: bytes | tuple[bytes, ...], __start: SupportsIndex | None = ..., __end: SupportsIndex | None = ... ) -> bool: ... def strip(self, __bytes: bytes | None = ...) -> bytearray: ... def swapcase(self) -> bytearray: ... @@ -649,9 +658,9 @@ class bytearray(MutableSequence[int], ByteString): class memoryview(Sized, Sequence[int]): format: str itemsize: int - shape: Tuple[int, ...] | None - strides: Tuple[int, ...] | None - suboffsets: Tuple[int, ...] | None + shape: tuple[int, ...] | None + strides: tuple[int, ...] | None + suboffsets: tuple[int, ...] | None readonly: bool ndim: int @@ -665,7 +674,7 @@ class memoryview(Sized, Sequence[int]): def __exit__( 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: ... + def cast(self, format: str, shape: list[int] | tuple[int, ...] = ...) -> memoryview: ... @overload def __getitem__(self, __i: SupportsIndex) -> int: ... @overload @@ -720,7 +729,7 @@ class bool(int): def __getnewargs__(self) -> tuple[int]: ... @final -class slice(object): +class slice: start: Any step: Any stop: Any @@ -736,48 +745,57 @@ class tuple(Sequence[_T_co], Generic[_T_co]): def __len__(self) -> int: ... def __contains__(self, __x: object) -> bool: ... @overload - def __getitem__(self, __x: int) -> _T_co: ... + def __getitem__(self, __x: SupportsIndex) -> _T_co: ... @overload - def __getitem__(self, __x: slice) -> Tuple[_T_co, ...]: ... + def __getitem__(self, __x: slice) -> tuple[_T_co, ...]: ... def __iter__(self) -> Iterator[_T_co]: ... - def __lt__(self, __x: Tuple[_T_co, ...]) -> bool: ... - def __le__(self, __x: Tuple[_T_co, ...]) -> bool: ... - def __gt__(self, __x: Tuple[_T_co, ...]) -> bool: ... - def __ge__(self, __x: Tuple[_T_co, ...]) -> bool: ... + def __lt__(self, __x: tuple[_T_co, ...]) -> bool: ... + def __le__(self, __x: tuple[_T_co, ...]) -> bool: ... + def __gt__(self, __x: tuple[_T_co, ...]) -> bool: ... + def __ge__(self, __x: tuple[_T_co, ...]) -> bool: ... @overload - def __add__(self, __x: Tuple[_T_co, ...]) -> Tuple[_T_co, ...]: ... + def __add__(self, __x: tuple[_T_co, ...]) -> tuple[_T_co, ...]: ... @overload - def __add__(self, __x: Tuple[_T, ...]) -> Tuple[_T_co | _T, ...]: ... - def __mul__(self, __n: SupportsIndex) -> Tuple[_T_co, ...]: ... - def __rmul__(self, __n: SupportsIndex) -> Tuple[_T_co, ...]: ... + def __add__(self, __x: tuple[_T, ...]) -> tuple[_T_co | _T, ...]: ... + def __mul__(self, __n: SupportsIndex) -> tuple[_T_co, ...]: ... + def __rmul__(self, __n: SupportsIndex) -> tuple[_T_co, ...]: ... def count(self, __value: Any) -> int: ... def index(self, __value: Any, __start: SupportsIndex = ..., __stop: SupportsIndex = ...) -> int: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... +# Doesn't exist at runtime, but deleting this breaks mypy. See #2999 +@final class function: - # TODO not defined in builtins! - __name__: str - __module__: str + # Make sure this class definition stays roughly in line with `types.FunctionType` + __closure__: tuple[_Cell, ...] | None __code__: CodeType + __defaults__: tuple[Any, ...] | None + __dict__: dict[str, Any] + __globals__: dict[str, Any] + __name__: str __qualname__: str __annotations__: dict[str, Any] + __kwdefaults__: dict[str, Any] + __module__: str + # mypy uses `builtins.function.__get__` to represent methods, properties, and getset_descriptors so we type the return as Any. + def __get__(self, obj: object | None, type: type | None = ...) -> Any: ... class list(MutableSequence[_T], Generic[_T]): @overload def __init__(self) -> None: ... @overload def __init__(self, __iterable: Iterable[_T]) -> None: ... - def clear(self) -> None: ... def copy(self) -> list[_T]: ... def append(self, __object: _T) -> None: ... def extend(self, __iterable: Iterable[_T]) -> None: ... def pop(self, __index: SupportsIndex = ...) -> _T: ... + # Signature of `list.index` should be kept in line with `collections.UserList.index()` 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 reverse(self) -> None: ... + # Signature of `list.sort` should be kept inline with `collections.UserList.sort()` @overload def sort(self: list[SupportsRichComparisonT], *, key: None = ..., reverse: bool = ...) -> None: ... @overload @@ -810,6 +828,7 @@ class list(MutableSequence[_T], Generic[_T]): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): + # __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics @overload def __init__(self: dict[_KT, _VT]) -> None: ... @overload @@ -823,19 +842,13 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): @overload def __init__(self: dict[str, str], __iterable: Iterable[list[str]]) -> None: ... def __new__(cls: Type[_T1], *args: Any, **kwargs: Any) -> _T1: ... - def clear(self) -> None: ... def copy(self) -> dict[_KT, _VT]: ... - def popitem(self) -> tuple[_KT, _VT]: ... - def setdefault(self, __key: _KT, __default: _VT = ...) -> _VT: ... - @overload - def update(self, __m: Mapping[_KT, _VT], **kwargs: _VT) -> None: ... - @overload - def update(self, __m: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ... - @overload - def update(self, **kwargs: _VT) -> None: ... def keys(self) -> dict_keys[_KT, _VT]: ... def values(self) -> dict_values[_KT, _VT]: ... def items(self) -> dict_items[_KT, _VT]: ... + # Signature of `dict.fromkeys` should be kept identical to `fromkeys` methods of `OrderedDict`/`ChainMap`/`UserDict` in `collections` + # TODO: the true signature of `dict.fromkeys` is not expressable in the current type system. + # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. @classmethod @overload def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> dict[_T, Any | None]: ... @@ -860,7 +873,6 @@ class dict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): class set(MutableSet[_T], Generic[_T]): def __init__(self, __iterable: Iterable[_T] = ...) -> None: ... def add(self, __element: _T) -> None: ... - def clear(self) -> None: ... def copy(self) -> set[_T]: ... def difference(self, *s: Iterable[Any]) -> set[_T]: ... def difference_update(self, *s: Iterable[Any]) -> None: ... @@ -870,7 +882,6 @@ class set(MutableSet[_T], Generic[_T]): def isdisjoint(self, __s: Iterable[Any]) -> bool: ... def issubset(self, __s: Iterable[Any]) -> bool: ... def issuperset(self, __s: Iterable[Any]) -> bool: ... - def pop(self) -> _T: ... def remove(self, __element: _T) -> None: ... def symmetric_difference(self, __s: Iterable[_T]) -> set[_T]: ... def symmetric_difference_update(self, __s: Iterable[_T]) -> None: ... @@ -921,7 +932,7 @@ class frozenset(AbstractSet[_T_co], Generic[_T_co]): if sys.version_info >= (3, 9): def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class enumerate(Iterator[Tuple[int, _T]], Generic[_T]): +class enumerate(Iterator[tuple[int, _T]], Generic[_T]): def __init__(self, iterable: Iterable[_T], start: int = ...) -> None: ... def __iter__(self) -> Iterator[tuple[int, _T]]: ... def __next__(self) -> tuple[int, _T]: ... @@ -949,7 +960,7 @@ class range(Sequence[int]): def __repr__(self) -> str: ... def __reversed__(self) -> Iterator[int]: ... -class property(object): +class property: fget: Callable[[Any], Any] | None fset: Callable[[Any, Any], None] | None fdel: Callable[[Any], None] | None @@ -995,7 +1006,7 @@ class _PathLike(Protocol[_AnyStr_co]): def __fspath__(self) -> _AnyStr_co: ... if sys.version_info >= (3, 10): - def aiter(__iterable: AsyncIterable[_T]) -> AsyncIterator[_T]: ... + def aiter(__async_iterable: _SupportsAiter[_SupportsAnextT]) -> _SupportsAnextT: ... @overload async def anext(__i: SupportsAnext[_T]) -> _T: ... @overload @@ -1073,12 +1084,12 @@ 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 help(*args: Any, **kwds: Any) -> None: ... +def help(request: object = ...) -> None: ... def hex(__number: int | SupportsIndex) -> str: ... def id(__obj: object) -> int: ... def input(__prompt: object = ...) -> str: ... @overload -def iter(__iterable: Iterable[_T]) -> Iterator[_T]: ... +def iter(__iterable: _SupportsIter[_SupportsNextT]) -> _SupportsNextT: ... @overload def iter(__function: Callable[[], _T | None], __sentinel: None) -> Iterator[_T]: ... @overload @@ -1087,15 +1098,15 @@ def iter(__function: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... # We need recursive types to express the type of the second argument to `isinstance` properly, hence the use of `Any` if sys.version_info >= (3, 10): def isinstance( - __obj: object, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] + __obj: object, __class_or_tuple: type | types.UnionType | tuple[type | types.UnionType | tuple[Any, ...], ...] ) -> bool: ... def issubclass( - __cls: type, __class_or_tuple: type | types.UnionType | Tuple[type | types.UnionType | Tuple[Any, ...], ...] + __cls: type, __class_or_tuple: type | types.UnionType | tuple[type | types.UnionType | tuple[Any, ...], ...] ) -> bool: ... else: - def isinstance(__obj: object, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... - def issubclass(__cls: type, __class_or_tuple: type | Tuple[type | Tuple[Any, ...], ...]) -> bool: ... + def isinstance(__obj: object, __class_or_tuple: type | tuple[type | tuple[Any, ...], ...]) -> bool: ... + def issubclass(__cls: type, __class_or_tuple: type | tuple[type | tuple[Any, ...], ...]) -> bool: ... def len(__obj: Sized) -> int: ... def license() -> None: ... @@ -1382,19 +1393,21 @@ def round(number: SupportsRound[_T], ndigits: SupportsIndex) -> _T: ... # for why arg 3 of `setattr` should be annotated with `Any` and not `object` def setattr(__obj: object, __name: str, __value: Any) -> None: ... @overload -def sorted(__iterable: Iterable[SupportsRichComparisonT], *, key: None = ..., reverse: bool = ...) -> list[SupportsRichComparisonT]: ... +def sorted( + __iterable: Iterable[SupportsRichComparisonT], *, key: None = ..., reverse: bool = ... +) -> list[SupportsRichComparisonT]: ... @overload def sorted(__iterable: Iterable[_T], *, key: Callable[[_T], SupportsRichComparison], reverse: bool = ...) -> list[_T]: ... if sys.version_info >= (3, 8): @overload - def sum(__iterable: Iterable[_T]) -> _T | int: ... + def sum(__iterable: Iterable[_T]) -> _T | Literal[0]: ... @overload def sum(__iterable: Iterable[_T], start: _S) -> _T | _S: ... else: @overload - def sum(__iterable: Iterable[_T]) -> _T | int: ... + def sum(__iterable: Iterable[_T]) -> _T | Literal[0]: ... @overload def sum(__iterable: Iterable[_T], __start: _S) -> _T | _S: ... @@ -1444,7 +1457,7 @@ class zip(Iterator[_T_co], Generic[_T_co]): __iter6: Iterable[Any], *iterables: Iterable[Any], strict: bool = ..., - ) -> zip[Tuple[Any, ...]]: ... + ) -> zip[tuple[Any, ...]]: ... else: @overload def __new__(cls, __iter1: Iterable[_T1]) -> zip[tuple[_T1]]: ... @@ -1475,7 +1488,7 @@ class zip(Iterator[_T_co], Generic[_T_co]): __iter5: Iterable[Any], __iter6: Iterable[Any], *iterables: Iterable[Any], - ) -> zip[Tuple[Any, ...]]: ... + ) -> zip[tuple[Any, ...]]: ... def __iter__(self) -> Iterator[_T_co]: ... def __next__(self) -> _T_co: ... @@ -1496,12 +1509,14 @@ class ellipsis: ... Ellipsis: ellipsis -class BaseException(object): - args: Tuple[Any, ...] +class BaseException: + args: tuple[Any, ...] __cause__: BaseException | None __context__: BaseException | None __suppress_context__: bool __traceback__: TracebackType | None + if sys.version_info >= (3, 11): + __note__: str | None def __init__(self, *args: object) -> None: ... def __str__(self) -> str: ... def __repr__(self) -> str: ... @@ -1624,7 +1639,14 @@ class UnicodeEncodeError(UnicodeError): reason: str def __init__(self, __encoding: str, __object: str, __start: int, __end: int, __reason: str) -> None: ... -class UnicodeTranslateError(UnicodeError): ... +class UnicodeTranslateError(UnicodeError): + encoding: None + object: str + start: int + end: int + reason: str + def __init__(self, __object: str, __start: int, __end: int, __reason: str) -> None: ... + class Warning(Exception): ... class UserWarning(Warning): ... class DeprecationWarning(Warning): ... @@ -1639,3 +1661,19 @@ class ResourceWarning(Warning): ... if sys.version_info >= (3, 10): class EncodingWarning(Warning): ... + +if sys.version_info >= (3, 11): + _SplitCondition = type[BaseException] | tuple[type[BaseException, ...]] | Callable[[BaseException], bool] + class BaseExceptionGroup(BaseException): + def __new__(cls, __message: str, __exceptions: Sequence[BaseException]) -> BaseExceptionGroup | ExceptionGroup: ... + @property + def message(self) -> str: ... + @property + def exceptions(self) -> Sequence[BaseException]: ... + def subgroup(self: Self, __condition: _SplitCondition) -> Self | None: ... + def split(self: Self, __condition: _SplitCondition) -> tuple[Self | None, Self | None]: ... + def derive(self: Self, __excs: Sequence[BaseException]) -> Self: ... + class ExceptionGroup(BaseExceptionGroup, Exception): + def __new__(cls, __message: str, exceptions: Sequence[Exception]) -> ExceptionGroup: ... + @property + def exceptions(self) -> Sequence[Exception]: ... diff --git a/mypy/typeshed/stdlib/bz2.pyi b/mypy/typeshed/stdlib/bz2.pyi index c49832759fa8..6aeaa3da4c60 100644 --- a/mypy/typeshed/stdlib/bz2.pyi +++ b/mypy/typeshed/stdlib/bz2.pyi @@ -80,6 +80,15 @@ def open( errors: str | None = ..., newline: str | None = ..., ) -> TextIO: ... +@overload +def open( + filename: StrOrBytesPath | _ReadableFileobj | _WritableFileobj, + mode: str, + compresslevel: int = ..., + encoding: str | None = ..., + errors: str | None = ..., + newline: str | None = ..., +) -> BZ2File | TextIO: ... class BZ2File(BaseStream, IO[bytes]): def __enter__(self: Self) -> Self: ... @@ -111,7 +120,7 @@ class BZ2File(BaseStream, IO[bytes]): ) -> None: ... def read(self, size: int | None = ...) -> bytes: ... def read1(self, size: int = ...) -> bytes: ... - def readline(self, size: SupportsIndex = ...) -> bytes: ... # type: ignore + def readline(self, size: SupportsIndex = ...) -> bytes: ... # type: ignore[override] def readinto(self, b: WriteableBuffer) -> int: ... def readlines(self, size: SupportsIndex = ...) -> list[bytes]: ... def seek(self, offset: int, whence: int = ...) -> int: ... @@ -119,13 +128,13 @@ class BZ2File(BaseStream, IO[bytes]): def writelines(self, seq: Iterable[ReadableBuffer]) -> None: ... @final -class BZ2Compressor(object): +class BZ2Compressor: def __init__(self, compresslevel: int = ...) -> None: ... def compress(self, __data: bytes) -> bytes: ... def flush(self) -> bytes: ... @final -class BZ2Decompressor(object): +class BZ2Decompressor: def decompress(self, data: bytes, max_length: int = ...) -> bytes: ... @property def eof(self) -> bool: ... diff --git a/mypy/typeshed/stdlib/cProfile.pyi b/mypy/typeshed/stdlib/cProfile.pyi index f4a7ab50cc11..e79524aa793e 100644 --- a/mypy/typeshed/stdlib/cProfile.pyi +++ b/mypy/typeshed/stdlib/cProfile.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import Self, StrOrBytesPath from types import CodeType -from typing import Any, Callable, Tuple, TypeVar +from typing import Any, Callable, TypeVar def run(statement: str, filename: str | None = ..., sort: str | int = ...) -> None: ... def runctx( @@ -9,7 +9,7 @@ def runctx( ) -> None: ... _T = TypeVar("_T") -_Label = Tuple[str, int, str] +_Label = tuple[str, int, str] class Profile: stats: dict[_Label, tuple[int, int, int, int, dict[_Label, tuple[int, int, int, int]]]] # undocumented diff --git a/mypy/typeshed/stdlib/calendar.pyi b/mypy/typeshed/stdlib/calendar.pyi index 26073fb7281b..aa37928b87b1 100644 --- a/mypy/typeshed/stdlib/calendar.pyi +++ b/mypy/typeshed/stdlib/calendar.pyi @@ -1,9 +1,9 @@ import datetime import sys from time import struct_time -from typing import Any, Iterable, Optional, Sequence, Tuple +from typing import Any, Iterable, Optional, Sequence -_LocaleType = Tuple[Optional[str], Optional[str]] +_LocaleType = tuple[Optional[str], Optional[str]] class IllegalMonthError(ValueError): def __init__(self, month: int) -> None: ... @@ -97,7 +97,7 @@ c: TextCalendar def setfirstweekday(firstweekday: int) -> None: ... def format(cols: int, colwidth: int = ..., spacing: int = ...) -> str: ... def formatstring(cols: int, colwidth: int = ..., spacing: int = ...) -> str: ... -def timegm(tuple: Tuple[int, ...] | struct_time) -> int: ... +def timegm(tuple: tuple[int, ...] | struct_time) -> int: ... # Data attributes day_name: Sequence[str] diff --git a/mypy/typeshed/stdlib/cgi.pyi b/mypy/typeshed/stdlib/cgi.pyi index 3821de46ed75..c2c3ac261010 100644 --- a/mypy/typeshed/stdlib/cgi.pyi +++ b/mypy/typeshed/stdlib/cgi.pyi @@ -57,7 +57,7 @@ class MiniFieldStorage: _list = list -class FieldStorage(object): +class FieldStorage: FieldStorageClass: _type | None keep_blank_values: int strict_parsing: int diff --git a/mypy/typeshed/stdlib/cgitb.pyi b/mypy/typeshed/stdlib/cgitb.pyi index 7576740fc1c0..a8f3912aa04c 100644 --- a/mypy/typeshed/stdlib/cgitb.pyi +++ b/mypy/typeshed/stdlib/cgitb.pyi @@ -1,8 +1,8 @@ from _typeshed import StrOrBytesPath from types import FrameType, TracebackType -from typing import IO, Any, Callable, Optional, Tuple, Type +from typing import IO, Any, Callable, Optional, Type -_ExcInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] +_ExcInfo = tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] def reset() -> str: ... # undocumented def small(text: str) -> str: ... # undocumented diff --git a/mypy/typeshed/stdlib/codecs.pyi b/mypy/typeshed/stdlib/codecs.pyi index ebd6911c3e63..e08672e51428 100644 --- a/mypy/typeshed/stdlib/codecs.pyi +++ b/mypy/typeshed/stdlib/codecs.pyi @@ -2,9 +2,14 @@ import sys import types from _typeshed import Self from abc import abstractmethod -from typing import IO, Any, BinaryIO, Callable, Generator, Iterable, Iterator, Protocol, TextIO, Tuple, Type, TypeVar, overload +from typing import IO, Any, BinaryIO, Callable, Generator, Iterable, Iterator, Protocol, TextIO, Type, TypeVar, overload from typing_extensions import Literal +BOM32_BE: bytes +BOM32_LE: bytes +BOM64_BE: bytes +BOM64_LE: bytes + # TODO: this only satisfies the most common interface, where # bytes is the raw form and str is the cooked form. # In the long run, both should become template parameters maybe? @@ -53,11 +58,11 @@ _BytesToBytesEncodingT = Literal[ @overload def encode(obj: bytes, encoding: _BytesToBytesEncodingT, errors: str = ...) -> bytes: ... @overload -def encode(obj: str, encoding: Literal["rot13", "rot_13"] = ..., errors: str = ...) -> str: ... # type: ignore +def encode(obj: str, encoding: Literal["rot13", "rot_13"] = ..., errors: str = ...) -> str: ... # type: ignore[misc] @overload def encode(obj: str, encoding: str = ..., errors: str = ...) -> bytes: ... @overload -def decode(obj: bytes, encoding: _BytesToBytesEncodingT, errors: str = ...) -> bytes: ... # type: ignore +def decode(obj: bytes, encoding: _BytesToBytesEncodingT, errors: str = ...) -> bytes: ... # type: ignore[misc] @overload def decode(obj: str, encoding: Literal["rot13", "rot_13"] = ..., errors: str = ...) -> str: ... @overload @@ -66,7 +71,7 @@ def lookup(__encoding: str) -> CodecInfo: ... def utf_16_be_decode(__data: bytes, __errors: str | None = ..., __final: bool = ...) -> tuple[str, int]: ... # undocumented def utf_16_be_encode(__str: str, __errors: str | None = ...) -> tuple[bytes, int]: ... # undocumented -class CodecInfo(Tuple[_Encoder, _Decoder, _StreamReader, _StreamWriter]): +class CodecInfo(tuple[_Encoder, _Decoder, _StreamReader, _StreamWriter]): @property def encode(self) -> _Encoder: ... @property diff --git a/mypy/typeshed/stdlib/collections/__init__.pyi b/mypy/typeshed/stdlib/collections/__init__.pyi index 66a76941beee..adcdf29fa690 100644 --- a/mypy/typeshed/stdlib/collections/__init__.pyi +++ b/mypy/typeshed/stdlib/collections/__init__.pyi @@ -1,8 +1,11 @@ import sys from _collections_abc import dict_items, dict_keys, dict_values -from _typeshed import Self -from typing import Any, Dict, Generic, NoReturn, Tuple, Type, TypeVar, overload -from typing_extensions import final +from _typeshed import Self, SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT +from typing import Any, Generic, NoReturn, Type, TypeVar, overload +from typing_extensions import SupportsIndex, final + +if sys.version_info >= (3, 9): + from types import GenericAlias if sys.version_info >= (3, 10): from typing import Callable, Iterable, Iterator, Mapping, MutableMapping, MutableSequence, Reversible, Sequence @@ -25,16 +28,26 @@ if sys.version_info >= (3, 7): rename: bool = ..., module: str | None = ..., defaults: Iterable[Any] | None = ..., - ) -> Type[Tuple[Any, ...]]: ... + ) -> Type[tuple[Any, ...]]: ... else: def namedtuple( typename: str, field_names: str | Iterable[str], *, verbose: bool = ..., rename: bool = ..., module: str | None = ... - ) -> Type[Tuple[Any, ...]]: ... + ) -> Type[tuple[Any, ...]]: ... -class UserDict(MutableMapping[_KT, _VT]): +class UserDict(MutableMapping[_KT, _VT], Generic[_KT, _VT]): data: dict[_KT, _VT] - def __init__(self, __dict: Mapping[_KT, _VT] | None = ..., **kwargs: _VT) -> None: ... + # __init__ should be kept roughly in line with `dict.__init__`, which has the same semantics + @overload + def __init__(self: UserDict[_KT, _VT], __dict: None = ...) -> None: ... + @overload + def __init__(self: UserDict[str, _VT], __dict: None = ..., **kwargs: _VT) -> None: ... + @overload + def __init__(self, __dict: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ... + @overload + def __init__(self, __iterable: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ... + @overload + def __init__(self: UserDict[str, str], __iterable: Iterable[list[str]]) -> None: ... def __len__(self) -> int: ... def __getitem__(self, key: _KT) -> _VT: ... def __setitem__(self, key: _KT, item: _VT) -> None: ... @@ -42,27 +55,34 @@ class UserDict(MutableMapping[_KT, _VT]): def __iter__(self) -> Iterator[_KT]: ... def __contains__(self, key: object) -> bool: ... def copy(self: Self) -> Self: ... + # `UserDict.fromkeys` has the same semantics as `dict.fromkeys`, so should be kept in line with `dict.fromkeys`. + # TODO: Much like `dict.fromkeys`, the true signature of `UserDict.fromkeys` is inexpressable in the current type system. + # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. + @classmethod + @overload + def fromkeys(cls, iterable: Iterable[_T], value: None = ...) -> UserDict[_T, Any | None]: ... @classmethod - def fromkeys(cls: Type[Self], iterable: Iterable[_KT], value: _VT | None = ...) -> Self: ... + @overload + def fromkeys(cls, iterable: Iterable[_T], value: _S) -> UserDict[_T, _S]: ... class UserList(MutableSequence[_T]): data: list[_T] def __init__(self, initlist: Iterable[_T] | None = ...) -> None: ... - def __lt__(self, other: object) -> bool: ... - def __le__(self, other: object) -> bool: ... - def __gt__(self, other: object) -> bool: ... - def __ge__(self, other: object) -> bool: ... + def __lt__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __le__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __gt__(self, other: list[_T] | UserList[_T]) -> bool: ... + def __ge__(self, other: list[_T] | UserList[_T]) -> bool: ... def __contains__(self, item: object) -> bool: ... def __len__(self) -> int: ... @overload - def __getitem__(self, i: int) -> _T: ... + def __getitem__(self, i: SupportsIndex) -> _T: ... @overload def __getitem__(self: Self, i: slice) -> Self: ... @overload - def __setitem__(self, i: int, o: _T) -> None: ... + def __setitem__(self, i: SupportsIndex, o: _T) -> None: ... @overload def __setitem__(self, i: slice, o: Iterable[_T]) -> None: ... - def __delitem__(self, i: int | slice) -> None: ... + def __delitem__(self, i: SupportsIndex | slice) -> None: ... def __add__(self: _S, other: Iterable[_T]) -> _S: ... def __iadd__(self: _S, other: Iterable[_T]) -> _S: ... def __mul__(self: _S, n: int) -> _S: ... @@ -71,12 +91,15 @@ class UserList(MutableSequence[_T]): def insert(self, i: int, item: _T) -> None: ... def pop(self, i: int = ...) -> _T: ... def remove(self, item: _T) -> None: ... - def clear(self) -> None: ... def copy(self: _S) -> _S: ... def count(self, item: _T) -> int: ... - def index(self, item: _T, *args: Any) -> int: ... - def reverse(self) -> None: ... - def sort(self, *args: Any, **kwds: Any) -> None: ... + # 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 = ..., __stop: SupportsIndex = ...) -> 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 = ..., reverse: bool = ...) -> None: ... + @overload + def sort(self, *, key: Callable[[_T], SupportsRichComparison], reverse: bool = ...) -> None: ... def extend(self, other: Iterable[_T]) -> None: ... _UserStringT = TypeVar("_UserStringT", bound=UserString) @@ -95,9 +118,9 @@ class UserString(Sequence[str]): def __contains__(self, char: object) -> bool: ... def __len__(self) -> int: ... # It should return a str to implement Sequence correctly, but it doesn't. - def __getitem__(self: _UserStringT, i: int | slice) -> _UserStringT: ... # type: ignore - def __iter__(self: _UserStringT) -> Iterator[_UserStringT]: ... # type: ignore - def __reversed__(self: _UserStringT) -> Iterator[_UserStringT]: ... # type: ignore + def __getitem__(self: _UserStringT, i: SupportsIndex | slice) -> _UserStringT: ... # type: ignore[override] + def __iter__(self: _UserStringT) -> Iterator[_UserStringT]: ... # type: ignore[override] + def __reversed__(self: _UserStringT) -> Iterator[_UserStringT]: ... # type: ignore[override] def __add__(self: _UserStringT, other: object) -> _UserStringT: ... def __mul__(self: _UserStringT, n: int) -> _UserStringT: ... def __mod__(self: _UserStringT, args: Any) -> _UserStringT: ... @@ -109,7 +132,7 @@ class UserString(Sequence[str]): def encode(self: UserString, encoding: str | None = ..., errors: str | None = ...) -> bytes: ... else: def encode(self: _UserStringT, encoding: str | None = ..., errors: str | None = ...) -> _UserStringT: ... - def endswith(self, suffix: str | Tuple[str, ...], start: int | None = ..., end: int | None = ...) -> bool: ... + def endswith(self, suffix: str | tuple[str, ...], start: int | None = ..., end: int | None = ...) -> bool: ... def expandtabs(self: _UserStringT, tabsize: int = ...) -> _UserStringT: ... def find(self, sub: str | UserString, start: int = ..., end: int = ...) -> int: ... def format(self, *args: Any, **kwds: Any) -> str: ... @@ -126,6 +149,8 @@ class UserString(Sequence[str]): def isspace(self) -> bool: ... def istitle(self) -> bool: ... def isupper(self) -> bool: ... + if sys.version_info >= (3, 7): + def isascii(self) -> bool: ... def join(self, seq: Iterable[str]) -> str: ... def ljust(self: _UserStringT, width: int, *args: Any) -> _UserStringT: ... def lower(self: _UserStringT) -> _UserStringT: ... @@ -149,7 +174,7 @@ class UserString(Sequence[str]): def split(self, sep: str | None = ..., maxsplit: int = ...) -> list[str]: ... def rsplit(self, sep: str | None = ..., maxsplit: int = ...) -> list[str]: ... def splitlines(self, keepends: bool = ...) -> list[str]: ... - def startswith(self, prefix: str | Tuple[str, ...], start: int | None = ..., end: int | None = ...) -> bool: ... + def startswith(self, prefix: str | tuple[str, ...], start: int | None = ..., end: int | None = ...) -> bool: ... def strip(self: _UserStringT, chars: str | None = ...) -> _UserStringT: ... def swapcase(self: _UserStringT) -> _UserStringT: ... def title(self: _UserStringT) -> _UserStringT: ... @@ -163,56 +188,44 @@ class deque(MutableSequence[_T], Generic[_T]): def __init__(self, iterable: Iterable[_T] = ..., maxlen: int | None = ...) -> None: ... def append(self, __x: _T) -> None: ... def appendleft(self, __x: _T) -> None: ... - def clear(self) -> None: ... def copy(self: _S) -> _S: ... 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 = ..., __stop: int = ...) -> int: ... - def pop(self) -> _T: ... # type: ignore + def pop(self) -> _T: ... # type: ignore[override] def popleft(self) -> _T: ... def remove(self, __value: _T) -> None: ... - def reverse(self) -> None: ... def rotate(self, __n: int = ...) -> None: ... def __copy__(self: _S) -> _S: ... def __len__(self) -> int: ... - def __iter__(self) -> Iterator[_T]: ... def __str__(self) -> str: ... - # These methods of deque don't really take slices, but we need to - # define them as taking a slice to satisfy MutableSequence. - @overload - def __getitem__(self, __index: int) -> _T: ... - @overload - def __getitem__(self, __s: slice) -> MutableSequence[_T]: ... - @overload - def __setitem__(self, __i: int, __x: _T) -> None: ... - @overload - def __setitem__(self, __s: slice, __o: Iterable[_T]) -> None: ... - @overload - def __delitem__(self, __i: int) -> None: ... - @overload - def __delitem__(self, __s: slice) -> None: ... + # These methods of deque don't take slices, unlike MutableSequence, hence the type: ignores + def __getitem__(self, __index: SupportsIndex) -> _T: ... # type: ignore[override] + def __setitem__(self, __i: SupportsIndex, __x: _T) -> None: ... # type: ignore[override] + def __delitem__(self, __i: SupportsIndex) -> None: ... # type: ignore[override] def __contains__(self, __o: object) -> bool: ... def __reduce__(self: Self) -> tuple[Type[Self], tuple[()], None, Iterator[_T]]: ... - def __reversed__(self) -> Iterator[_T]: ... def __iadd__(self: _S, __iterable: Iterable[_T]) -> _S: ... def __add__(self: _S, __other: _S) -> _S: ... def __mul__(self: _S, __other: int) -> _S: ... def __imul__(self: _S, __other: int) -> _S: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, __item: Any) -> GenericAlias: ... -class Counter(Dict[_T, int], Generic[_T]): +class Counter(dict[_T, int], Generic[_T]): @overload def __init__(self, __iterable: None = ..., **kwargs: int) -> None: ... @overload - def __init__(self, __mapping: Mapping[_T, int]) -> None: ... + def __init__(self, __mapping: SupportsKeysAndGetItem[_T, int]) -> None: ... @overload def __init__(self, __iterable: Iterable[_T]) -> None: ... def copy(self: Self) -> Self: ... def elements(self) -> Iterator[_T]: ... def most_common(self, n: int | None = ...) -> list[tuple[_T, int]]: ... @classmethod - def fromkeys(cls, iterable: Any, v: int | None = ...) -> NoReturn: ... # type: ignore + def fromkeys(cls, iterable: Any, v: int | None = ...) -> NoReturn: ... # type: ignore[override] @overload def subtract(self, __iterable: None = ...) -> None: ... @overload @@ -225,7 +238,7 @@ class Counter(Dict[_T, int], Generic[_T]): # Dict.update. Not sure if we should use '# type: ignore' instead # and omit the type from the union. @overload - def update(self, __m: Mapping[_T, int], **kwargs: int) -> None: ... + def update(self, __m: SupportsKeysAndGetItem[_T, int], **kwargs: int) -> None: ... @overload def update(self, __m: Iterable[_T] | Iterable[tuple[_T, int]], **kwargs: int) -> None: ... @overload @@ -233,27 +246,29 @@ class Counter(Dict[_T, int], Generic[_T]): def __add__(self, other: Counter[_T]) -> Counter[_T]: ... def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... def __and__(self, other: Counter[_T]) -> Counter[_T]: ... - def __or__(self, other: Counter[_T]) -> Counter[_T]: ... # type: ignore + def __or__(self, other: Counter[_T]) -> Counter[_T]: ... # type: ignore[override] def __pos__(self) -> Counter[_T]: ... def __neg__(self) -> Counter[_T]: ... def __iadd__(self, other: Counter[_T]) -> Counter[_T]: ... def __isub__(self, other: Counter[_T]) -> Counter[_T]: ... def __iand__(self, other: Counter[_T]) -> Counter[_T]: ... - def __ior__(self, other: Counter[_T]) -> Counter[_T]: ... # type: ignore + def __ior__(self, other: Counter[_T]) -> Counter[_T]: ... # type: ignore[override] + if sys.version_info >= (3, 10): + def total(self) -> int: ... @final class _OrderedDictKeysView(dict_keys[_KT_co, _VT_co], Reversible[_KT_co]): # type: ignore[misc] def __reversed__(self) -> Iterator[_KT_co]: ... @final -class _OrderedDictItemsView(dict_items[_KT_co, _VT_co], Reversible[Tuple[_KT_co, _VT_co]]): # type: ignore[misc] +class _OrderedDictItemsView(dict_items[_KT_co, _VT_co], Reversible[tuple[_KT_co, _VT_co]]): # type: ignore[misc] def __reversed__(self) -> Iterator[tuple[_KT_co, _VT_co]]: ... @final class _OrderedDictValuesView(dict_values[_KT_co, _VT_co], Reversible[_VT_co], Generic[_KT_co, _VT_co]): # type: ignore[misc] def __reversed__(self) -> Iterator[_VT_co]: ... -class OrderedDict(Dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): +class OrderedDict(dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): def popitem(self, last: bool = ...) -> tuple[_KT, _VT]: ... def move_to_end(self, key: _KT, last: bool = ...) -> None: ... def copy(self: Self) -> Self: ... @@ -261,8 +276,17 @@ class OrderedDict(Dict[_KT, _VT], Reversible[_KT], Generic[_KT, _VT]): def keys(self) -> _OrderedDictKeysView[_KT, _VT]: ... def items(self) -> _OrderedDictItemsView[_KT, _VT]: ... def values(self) -> _OrderedDictValuesView[_KT, _VT]: ... + # `fromkeys` is actually inherited from `dict` at runtime, so the signature should be kept in line with `dict.fromkeys`. + # Ideally we would not redefine it here, but the true signature of `dict.fromkeys` is not expressable in the current type system. + # See #3800 & https://github.com/python/typing/issues/548#issuecomment-683336963. + @classmethod + @overload + def fromkeys(cls, __iterable: Iterable[_T], __value: None = ...) -> OrderedDict[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> OrderedDict[_T, _S]: ... -class defaultdict(Dict[_KT, _VT], Generic[_KT, _VT]): +class defaultdict(dict[_KT, _VT], Generic[_KT, _VT]): default_factory: Callable[[], _VT] | None @overload def __init__(self, **kwargs: _VT) -> None: ... @@ -271,9 +295,11 @@ class defaultdict(Dict[_KT, _VT], Generic[_KT, _VT]): @overload def __init__(self, __default_factory: Callable[[], _VT] | None, **kwargs: _VT) -> None: ... @overload - def __init__(self, __default_factory: Callable[[], _VT] | None, __map: Mapping[_KT, _VT]) -> None: ... + def __init__(self, __default_factory: Callable[[], _VT] | None, __map: SupportsKeysAndGetItem[_KT, _VT]) -> None: ... @overload - def __init__(self, __default_factory: Callable[[], _VT] | None, __map: Mapping[_KT, _VT], **kwargs: _VT) -> None: ... + def __init__( + self, __default_factory: Callable[[], _VT] | None, __map: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT + ) -> None: ... @overload def __init__(self, __default_factory: Callable[[], _VT] | None, __iterable: Iterable[tuple[_KT, _VT]]) -> None: ... @overload @@ -301,3 +327,11 @@ class ChainMap(MutableMapping[_KT, _VT], Generic[_KT, _VT]): def pop(self, key: _KT) -> _VT: ... @overload def pop(self, key: _KT, default: _VT | _T = ...) -> _VT | _T: ... + def copy(self: Self) -> Self: ... + # 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 = ...) -> ChainMap[_T, Any | None]: ... + @classmethod + @overload + def fromkeys(cls, __iterable: Iterable[_T], __value: _S) -> ChainMap[_T, _S]: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi index fd7333420b39..b55351aacc6f 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/_base.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/_base.pyi @@ -4,19 +4,20 @@ from _typeshed import Self from abc import abstractmethod from collections.abc import Container, Iterable, Iterator, Sequence from logging import Logger -from typing import Any, Callable, Generic, Protocol, Set, TypeVar, overload +from typing import Any, Callable, Generic, Protocol, TypeVar, overload +from typing_extensions import Literal, SupportsIndex if sys.version_info >= (3, 9): from types import GenericAlias -FIRST_COMPLETED: str -FIRST_EXCEPTION: str -ALL_COMPLETED: str -PENDING: str -RUNNING: str -CANCELLED: str -CANCELLED_AND_NOTIFIED: str -FINISHED: str +FIRST_COMPLETED: Literal["FIRST_COMPLETED"] +FIRST_EXCEPTION: Literal["FIRST_EXCEPTION"] +ALL_COMPLETED: Literal["ALL_COMPLETED"] +PENDING: Literal["PENDING"] +RUNNING: Literal["RUNNING"] +CANCELLED: Literal["CANCELLED"] +CANCELLED_AND_NOTIFIED: Literal["CANCELLED_AND_NOTIFIED"] +FINISHED: Literal["FINISHED"] _FUTURE_STATES: list[str] _STATE_TO_DESCRIPTION_MAP: dict[str, str] LOGGER: Logger @@ -75,13 +76,13 @@ class Executor: def as_completed(fs: Iterable[Future[_T]], timeout: float | None = ...) -> Iterator[Future[_T]]: ... # Ideally this would be a namedtuple, but mypy doesn't support generic tuple types. See #1976 -class DoneAndNotDoneFutures(Sequence[Set[Future[_T]]]): +class DoneAndNotDoneFutures(Sequence[set[Future[_T]]]): done: set[Future[_T]] not_done: set[Future[_T]] def __new__(_cls, done: set[Future[_T]], not_done: set[Future[_T]]) -> DoneAndNotDoneFutures[_T]: ... def __len__(self) -> int: ... @overload - def __getitem__(self, i: int) -> set[Future[_T]]: ... + def __getitem__(self, i: SupportsIndex) -> set[Future[_T]]: ... @overload def __getitem__(self, s: slice) -> DoneAndNotDoneFutures[_T]: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/process.pyi b/mypy/typeshed/stdlib/concurrent/futures/process.pyi index cc48f48f0023..6435901a8f13 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/process.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/process.pyi @@ -5,7 +5,7 @@ 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, Callable, Generic, Tuple, TypeVar +from typing import Any, Callable, Generic, TypeVar from weakref import ref from ._base import Executor, Future @@ -37,7 +37,7 @@ class _ExceptionWithTraceback: exc: BaseException tb: TracebackType def __init__(self, exc: BaseException, tb: TracebackType) -> None: ... - def __reduce__(self) -> str | Tuple[Any, ...]: ... + def __reduce__(self) -> str | tuple[Any, ...]: ... def _rebuild_exc(exc: Exception, tb: str) -> Exception: ... @@ -84,7 +84,7 @@ if sys.version_info >= (3, 7): ) -> None: ... def _on_queue_feeder_error(self, e: Exception, obj: _CallItem) -> None: ... -def _get_chunks(*iterables: Any, chunksize: int) -> Generator[Tuple[Any, ...], None, None]: ... +def _get_chunks(*iterables: Any, chunksize: int) -> Generator[tuple[Any, ...], None, None]: ... def _process_chunk(fn: Callable[..., Any], chunk: tuple[Any, None, None]) -> Generator[Any, None, None]: ... def _sendback_result( result_queue: SimpleQueue[_WorkItem[Any]], work_id: int, result: Any | None = ..., exception: Exception | None = ... @@ -95,7 +95,7 @@ if sys.version_info >= (3, 7): call_queue: Queue[_CallItem], result_queue: SimpleQueue[_ResultItem], initializer: Callable[..., None] | None, - initargs: Tuple[Any, ...], + initargs: tuple[Any, ...], ) -> None: ... else: @@ -139,7 +139,7 @@ else: class ProcessPoolExecutor(Executor): _mp_context: BaseContext | None = ... _initializer: Callable[..., None] | None = ... - _initargs: Tuple[Any, ...] = ... + _initargs: tuple[Any, ...] = ... _executor_manager_thread: _ThreadWakeup _processes: MutableMapping[int, Process] _shutdown_thread: bool @@ -158,7 +158,7 @@ class ProcessPoolExecutor(Executor): max_workers: int | None = ..., mp_context: BaseContext | None = ..., initializer: Callable[..., None] | None = ..., - initargs: Tuple[Any, ...] = ..., + initargs: tuple[Any, ...] = ..., ) -> None: ... else: def __init__(self, max_workers: int | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/concurrent/futures/thread.pyi b/mypy/typeshed/stdlib/concurrent/futures/thread.pyi index 5ad5b65d3bec..f27c43c3403c 100644 --- a/mypy/typeshed/stdlib/concurrent/futures/thread.pyi +++ b/mypy/typeshed/stdlib/concurrent/futures/thread.pyi @@ -1,8 +1,8 @@ import queue import sys -from collections.abc import Iterable, Mapping, Set # equivalent to typing.AbstractSet, not builtins.set +from collections.abc import Iterable, Mapping, Set as AbstractSet from threading import Lock, Semaphore, Thread -from typing import Any, Callable, Generic, Tuple, TypeVar +from typing import Any, Callable, Generic, TypeVar from weakref import ref from ._base import Executor, Future @@ -33,7 +33,7 @@ if sys.version_info >= (3, 7): executor_reference: ref[Any], work_queue: queue.SimpleQueue[Any], initializer: Callable[..., None], - initargs: Tuple[Any, ...], + initargs: tuple[Any, ...], ) -> None: ... else: @@ -46,13 +46,13 @@ if sys.version_info >= (3, 7): class ThreadPoolExecutor(Executor): _max_workers: int _idle_semaphore: Semaphore - _threads: Set[Thread] + _threads: AbstractSet[Thread] _broken: bool _shutdown: bool _shutdown_lock: Lock _thread_name_prefix: str | None = ... _initializer: Callable[..., None] | None = ... - _initargs: Tuple[Any, ...] = ... + _initargs: tuple[Any, ...] = ... if sys.version_info >= (3, 7): _work_queue: queue.SimpleQueue[_WorkItem[Any]] else: @@ -63,7 +63,7 @@ class ThreadPoolExecutor(Executor): max_workers: int | None = ..., thread_name_prefix: str = ..., initializer: Callable[..., None] | None = ..., - initargs: Tuple[Any, ...] = ..., + initargs: tuple[Any, ...] = ..., ) -> None: ... else: def __init__(self, max_workers: int | None = ..., thread_name_prefix: str = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/configparser.pyi b/mypy/typeshed/stdlib/configparser.pyi index a0efa30416dd..dc81cb78577a 100644 --- a/mypy/typeshed/stdlib/configparser.pyi +++ b/mypy/typeshed/stdlib/configparser.pyi @@ -1,14 +1,14 @@ import sys from _typeshed import StrOrBytesPath, StrPath, SupportsWrite from collections.abc import Callable, ItemsView, Iterable, Iterator, Mapping, MutableMapping, Sequence -from typing import Any, ClassVar, Dict, Optional, Pattern, Type, TypeVar, overload +from typing import Any, ClassVar, Optional, Pattern, Type, TypeVar, overload from typing_extensions import Literal # Internal type aliases _section = Mapping[str, str] _parser = MutableMapping[str, _section] _converter = Callable[[str], Any] -_converters = Dict[str, _converter] +_converters = dict[str, _converter] _T = TypeVar("_T") if sys.version_info >= (3, 7): @@ -122,7 +122,7 @@ class RawConfigParser(_parser): fallback: _T = ..., ) -> _T: ... # This is incompatible with MutableMapping so we ignore the type - @overload # type: ignore + @overload # type: ignore[override] def get(self, section: str, option: str, *, raw: bool = ..., vars: _section | None = ...) -> str: ... @overload def get(self, section: str, option: str, *, raw: bool = ..., vars: _section | None = ..., fallback: _T) -> str | _T: ... @@ -137,7 +137,9 @@ class RawConfigParser(_parser): def optionxform(self, optionstr: str) -> str: ... class ConfigParser(RawConfigParser): ... -class SafeConfigParser(ConfigParser): ... + +if sys.version_info < (3, 11): + class SafeConfigParser(ConfigParser): ... class SectionProxy(MutableMapping[str, str]): def __init__(self, parser: RawConfigParser, name: str) -> None: ... @@ -151,7 +153,16 @@ class SectionProxy(MutableMapping[str, str]): def parser(self) -> RawConfigParser: ... @property def name(self) -> str: ... - def get(self, option: str, fallback: str | None = ..., *, raw: bool = ..., vars: _section | None = ..., _impl: Any | None = ..., **kwargs: Any) -> str: ... # type: ignore + def get( # type: ignore[override] + self, + option: str, + fallback: str | None = ..., + *, + raw: bool = ..., + vars: _section | None = ..., + _impl: Any | None = ..., + **kwargs: Any, + ) -> str: ... # These are partially-applied version of the methods with the same names in # RawConfigParser; the stubs should be kept updated together @overload diff --git a/mypy/typeshed/stdlib/contextlib.pyi b/mypy/typeshed/stdlib/contextlib.pyi index 9d968e092ca5..b536c36678a2 100644 --- a/mypy/typeshed/stdlib/contextlib.pyi +++ b/mypy/typeshed/stdlib/contextlib.pyi @@ -4,18 +4,21 @@ from types import TracebackType from typing import ( IO, Any, + AsyncGenerator, AsyncIterator, Awaitable, Callable, ContextManager, + Generator, Generic, Iterator, Optional, + Protocol, Type, TypeVar, overload, ) -from typing_extensions import ParamSpec, Protocol +from typing_extensions import ParamSpec AbstractContextManager = ContextManager if sys.version_info >= (3, 7): @@ -32,14 +35,44 @@ _P = ParamSpec("_P") _ExitFunc = Callable[[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]], bool] _CM_EF = TypeVar("_CM_EF", AbstractContextManager[Any], _ExitFunc) -class _GeneratorContextManager(AbstractContextManager[_T_co]): +class ContextDecorator: def __call__(self, func: _F) -> _F: ... -# type ignore to deal with incomplete ParamSpec support in mypy -def contextmanager(func: Callable[_P, Iterator[_T]]) -> Callable[_P, _GeneratorContextManager[_T]]: ... # type: ignore +class _GeneratorContextManager(AbstractContextManager[_T_co], ContextDecorator, Generic[_T_co]): + # In Python <= 3.6, __init__ and all instance attributes are defined directly on this class. + # In Python >= 3.7, __init__ and all instance attributes are 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: ... + gen: Generator[_T_co, Any, Any] + func: Callable[..., Generator[_T_co, Any, Any]] + args: tuple[Any, ...] + kwds: dict[str, Any] + +def contextmanager(func: Callable[_P, Iterator[_T_co]]) -> Callable[_P, _GeneratorContextManager[_T_co]]: ... + +if sys.version_info >= (3, 10): + _AF = TypeVar("_AF", bound=Callable[..., Awaitable[Any]]) + class AsyncContextDecorator: + def __call__(self, func: _AF) -> _AF: ... + class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co], AsyncContextDecorator, Generic[_T_co]): + # __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: ... + gen: AsyncGenerator[_T_co, Any] + func: Callable[..., AsyncGenerator[_T_co, Any]] + args: tuple[Any, ...] + kwds: dict[str, Any] + +elif sys.version_info >= (3, 7): + class _AsyncGeneratorContextManager(AbstractAsyncContextManager[_T_co], Generic[_T_co]): + 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]] + args: tuple[Any, ...] + kwds: dict[str, Any] if sys.version_info >= (3, 7): - def asynccontextmanager(func: Callable[_P, AsyncIterator[_T]]) -> Callable[_P, AbstractAsyncContextManager[_T]]: ... # type: ignore + def asynccontextmanager(func: Callable[_P, AsyncIterator[_T_co]]) -> Callable[_P, _AsyncGeneratorContextManager[_T_co]]: ... class _SupportsClose(Protocol): def close(self) -> object: ... @@ -55,9 +88,6 @@ if sys.version_info >= (3, 10): _SupportsAcloseT = TypeVar("_SupportsAcloseT", bound=_SupportsAclose) class aclosing(AbstractAsyncContextManager[_SupportsAcloseT]): def __init__(self, thing: _SupportsAcloseT) -> None: ... - _AF = TypeVar("_AF", bound=Callable[..., Awaitable[Any]]) - class AsyncContextDecorator: - def __call__(self, func: _AF) -> _AF: ... class suppress(AbstractContextManager[None]): def __init__(self, *exceptions: Type[BaseException]) -> None: ... @@ -71,9 +101,6 @@ class redirect_stdout(AbstractContextManager[_T_io]): class redirect_stderr(AbstractContextManager[_T_io]): def __init__(self, new_target: _T_io) -> None: ... -class ContextDecorator: - def __call__(self, func: _F) -> _F: ... - class ExitStack(AbstractContextManager[ExitStack]): def __init__(self) -> None: ... def enter_context(self, cm: AbstractContextManager[_T]) -> _T: ... diff --git a/mypy/typeshed/stdlib/copyreg.pyi b/mypy/typeshed/stdlib/copyreg.pyi index 320097b3a204..6097670833c0 100644 --- a/mypy/typeshed/stdlib/copyreg.pyi +++ b/mypy/typeshed/stdlib/copyreg.pyi @@ -1,7 +1,7 @@ -from typing import Any, Callable, Hashable, Optional, SupportsInt, Tuple, TypeVar, Union +from typing import Any, Callable, Hashable, Optional, SupportsInt, TypeVar, Union _TypeT = TypeVar("_TypeT", bound=type) -_Reduce = Union[Tuple[Callable[..., _TypeT], Tuple[Any, ...]], Tuple[Callable[..., _TypeT], Tuple[Any, ...], Optional[Any]]] +_Reduce = Union[tuple[Callable[..., _TypeT], tuple[Any, ...]], tuple[Callable[..., _TypeT], tuple[Any, ...], Optional[Any]]] __all__: list[str] diff --git a/mypy/typeshed/stdlib/crypt.pyi b/mypy/typeshed/stdlib/crypt.pyi index 27e30433f702..a8342859e770 100644 --- a/mypy/typeshed/stdlib/crypt.pyi +++ b/mypy/typeshed/stdlib/crypt.pyi @@ -1,20 +1,18 @@ import sys -class _Method: ... +if sys.platform != "win32": + class _Method: ... + METHOD_CRYPT: _Method + METHOD_MD5: _Method + METHOD_SHA256: _Method + METHOD_SHA512: _Method + if sys.version_info >= (3, 7): + METHOD_BLOWFISH: _Method -METHOD_CRYPT: _Method -METHOD_MD5: _Method -METHOD_SHA256: _Method -METHOD_SHA512: _Method -if sys.version_info >= (3, 7): - METHOD_BLOWFISH: _Method + methods: list[_Method] -methods: list[_Method] - -if sys.version_info >= (3, 7): - def mksalt(method: _Method | None = ..., *, rounds: int | None = ...) -> str: ... - -else: - def mksalt(method: _Method | None = ...) -> str: ... - -def crypt(word: str, salt: str | _Method | None = ...) -> str: ... + if sys.version_info >= (3, 7): + def mksalt(method: _Method | None = ..., *, rounds: int | None = ...) -> str: ... + else: + def mksalt(method: _Method | None = ...) -> str: ... + def crypt(word: str, salt: str | _Method | None = ...) -> str: ... diff --git a/mypy/typeshed/stdlib/csv.pyi b/mypy/typeshed/stdlib/csv.pyi index 0b69cb2272d3..63999be059f6 100644 --- a/mypy/typeshed/stdlib/csv.pyi +++ b/mypy/typeshed/stdlib/csv.pyi @@ -21,7 +21,7 @@ from collections.abc import Collection, Iterable, Iterator, Mapping, Sequence from typing import Any, Generic, Type, TypeVar, overload if sys.version_info >= (3, 8): - from typing import Dict as _DictReadMapping + from builtins import dict as _DictReadMapping else: from collections import OrderedDict as _DictReadMapping @@ -100,7 +100,7 @@ class DictWriter(Generic[_T]): def writerow(self, rowdict: Mapping[_T, Any]) -> Any: ... def writerows(self, rowdicts: Iterable[Mapping[_T, Any]]) -> None: ... -class Sniffer(object): +class Sniffer: preferred: list[str] def __init__(self) -> None: ... def sniff(self, sample: str, delimiters: str | None = ...) -> Type[Dialect]: ... diff --git a/mypy/typeshed/stdlib/ctypes/__init__.pyi b/mypy/typeshed/stdlib/ctypes/__init__.pyi index bbe083f5d4c4..7f2eba011d0f 100644 --- a/mypy/typeshed/stdlib/ctypes/__init__.pyi +++ b/mypy/typeshed/stdlib/ctypes/__init__.pyi @@ -1,5 +1,6 @@ import sys from _typeshed import ReadableBuffer, WriteableBuffer +from abc import abstractmethod from typing import ( Any, Callable, @@ -10,7 +11,6 @@ from typing import ( Mapping, Optional, Sequence, - Tuple, Type, TypeVar, Union as _UnionT, @@ -28,7 +28,7 @@ RTLD_GLOBAL: int RTLD_LOCAL: int DEFAULT_MODE: int -class CDLL(object): +class CDLL: _func_flags_: ClassVar[int] _func_restype_: ClassVar[_CData] _name: str @@ -76,8 +76,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 - def __rmul__(cls: Type[_CT], other: int) -> Type[Array[_CT]]: ... # type: ignore + 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 @@ -97,8 +97,8 @@ class _CData(metaclass=_CDataMeta): class _CanCastTo(_CData): ... class _PointerLike(_CanCastTo): ... -_ECT = Callable[[Optional[Type[_CData]], _FuncPointer, Tuple[_CData, ...]], _CData] -_PF = _UnionT[Tuple[int], Tuple[int, str], Tuple[int, str, Any]] +_ECT = Callable[[Optional[Type[_CData]], _FuncPointer, tuple[_CData, ...]], _CData] +_PF = _UnionT[tuple[int], tuple[int, str], tuple[int, str, Any]] class _FuncPointer(_PointerLike, _CData): restype: Type[_CData] | Callable[[int], Any] | None @@ -109,9 +109,9 @@ class _FuncPointer(_PointerLike, _CData): @overload def __init__(self, callable: Callable[..., Any]) -> None: ... @overload - def __init__(self, func_spec: tuple[str | int, CDLL], paramflags: Tuple[_PF, ...] = ...) -> None: ... + def __init__(self, func_spec: tuple[str | int, CDLL], paramflags: tuple[_PF, ...] = ...) -> None: ... @overload - def __init__(self, vtlb_index: int, name: str, paramflags: Tuple[_PF, ...] = ..., iid: pointer[c_int] = ...) -> None: ... + def __init__(self, vtlb_index: int, name: str, paramflags: tuple[_PF, ...] = ..., iid: pointer[c_int] = ...) -> None: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... class _NamedFuncPointer(_FuncPointer): @@ -157,7 +157,7 @@ def create_unicode_buffer(init: int | str, size: int | None = ...) -> Array[c_wc if sys.platform == "win32": def DllCanUnloadNow() -> int: ... def DllGetClassObject(rclsid: Any, riid: Any, ppv: Any) -> int: ... # TODO not documented - def FormatError(code: int) -> str: ... + def FormatError(code: int = ...) -> str: ... def GetLastError() -> int: ... def get_errno() -> int: ... @@ -268,8 +268,16 @@ class BigEndianStructure(Structure): ... class LittleEndianStructure(Structure): ... class Array(Generic[_CT], _CData): - _length_: int - _type_: Type[_CT] + @property + @abstractmethod + def _length_(self) -> int: ... + @_length_.setter + def _length_(self, value: int) -> None: ... + @property + @abstractmethod + def _type_(self) -> Type[_CT]: ... + @_type_.setter + def _type_(self, value: Type[_CT]) -> 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. diff --git a/mypy/typeshed/stdlib/curses/__init__.pyi b/mypy/typeshed/stdlib/curses/__init__.pyi index 73e84fba3763..aef2d9b95ed5 100644 --- a/mypy/typeshed/stdlib/curses/__init__.pyi +++ b/mypy/typeshed/stdlib/curses/__init__.pyi @@ -1,15 +1,17 @@ -from _curses import * # noqa: F403 -from _curses import _CursesWindow as _CursesWindow +import sys from typing import Any, Callable, TypeVar -_T = TypeVar("_T") +if sys.platform != "win32": + from _curses import * # noqa: F403 + from _curses import _CursesWindow as _CursesWindow -# available after calling `curses.initscr()` -LINES: int -COLS: int + _T = TypeVar("_T") -# available after calling `curses.start_color()` -COLORS: int -COLOR_PAIRS: int + # available after calling `curses.initscr()` + LINES: int + COLS: int -def wrapper(__func: Callable[..., _T], *arg: Any, **kwds: Any) -> _T: ... + # available after calling `curses.start_color()` + COLORS: int + COLOR_PAIRS: int + def wrapper(__func: Callable[..., _T], *arg: Any, **kwds: Any) -> _T: ... diff --git a/mypy/typeshed/stdlib/curses/ascii.pyi b/mypy/typeshed/stdlib/curses/ascii.pyi index 66efbe36a7df..25de8f605bda 100644 --- a/mypy/typeshed/stdlib/curses/ascii.pyi +++ b/mypy/typeshed/stdlib/curses/ascii.pyi @@ -1,62 +1,63 @@ +import sys from typing import TypeVar -_CharT = TypeVar("_CharT", str, int) +if sys.platform != "win32": + _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/panel.pyi b/mypy/typeshed/stdlib/curses/panel.pyi index 138e4a9f727e..ed13a6e050e9 100644 --- a/mypy/typeshed/stdlib/curses/panel.pyi +++ b/mypy/typeshed/stdlib/curses/panel.pyi @@ -1,20 +1,23 @@ -from _curses import _CursesWindow +import sys -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: ... +if sys.platform != "win32": + from _curses import _CursesWindow -def bottom_panel() -> _Curses_Panel: ... -def new_panel(__win: _CursesWindow) -> _Curses_Panel: ... -def top_panel() -> _Curses_Panel: ... -def update_panels() -> _Curses_Panel: ... + 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: ... + 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 578a579fda38..eb6879603853 100644 --- a/mypy/typeshed/stdlib/curses/textpad.pyi +++ b/mypy/typeshed/stdlib/curses/textpad.pyi @@ -1,11 +1,12 @@ -from _curses import _CursesWindow +import sys from typing import Callable -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 = ...) -> None: ... - def edit(self, validate: Callable[[int], int] | None = ...) -> str: ... - def do_command(self, ch: str | int) -> None: ... - def gather(self) -> str: ... +if sys.platform != "win32": + from _curses import _CursesWindow + 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 = ...) -> None: ... + def edit(self, validate: Callable[[int], int] | None = ...) -> str: ... + def do_command(self, ch: str | int) -> None: ... + def gather(self) -> str: ... diff --git a/mypy/typeshed/stdlib/dataclasses.pyi b/mypy/typeshed/stdlib/dataclasses.pyi index 59efbe77aed6..885facb9c0db 100644 --- a/mypy/typeshed/stdlib/dataclasses.pyi +++ b/mypy/typeshed/stdlib/dataclasses.pyi @@ -1,7 +1,6 @@ import sys import types -from typing import Any, Callable, Generic, Iterable, Mapping, Tuple, Type, TypeVar, overload -from typing_extensions import Protocol +from typing import Any, Callable, Generic, Iterable, Mapping, Protocol, Type, TypeVar, overload if sys.version_info >= (3, 9): from types import GenericAlias @@ -21,7 +20,7 @@ def asdict(obj: Any) -> dict[str, Any]: ... @overload def asdict(obj: Any, *, dict_factory: Callable[[list[tuple[str, Any]]], _T]) -> _T: ... @overload -def astuple(obj: Any) -> Tuple[Any, ...]: ... +def astuple(obj: Any) -> tuple[Any, ...]: ... @overload def astuple(obj: Any, *, tuple_factory: Callable[[list[Any]], _T]) -> _T: ... @@ -173,7 +172,7 @@ else: metadata: Mapping[Any, Any] | None = ..., ) -> Any: ... -def fields(class_or_instance: Any) -> Tuple[Field[Any], ...]: ... +def fields(class_or_instance: Any) -> tuple[Field[Any], ...]: ... def is_dataclass(obj: Any) -> bool: ... class FrozenInstanceError(AttributeError): ... @@ -192,7 +191,7 @@ if sys.version_info >= (3, 10): cls_name: str, fields: Iterable[str | tuple[str, type] | tuple[str, type, Field[Any]]], *, - bases: Tuple[type, ...] = ..., + bases: tuple[type, ...] = ..., namespace: dict[str, Any] | None = ..., init: bool = ..., repr: bool = ..., @@ -201,6 +200,7 @@ if sys.version_info >= (3, 10): unsafe_hash: bool = ..., frozen: bool = ..., match_args: bool = ..., + kw_only: bool = ..., slots: bool = ..., ) -> type: ... @@ -209,7 +209,7 @@ else: cls_name: str, fields: Iterable[str | tuple[str, type] | tuple[str, type, Field[Any]]], *, - bases: Tuple[type, ...] = ..., + bases: tuple[type, ...] = ..., namespace: dict[str, Any] | None = ..., init: bool = ..., repr: bool = ..., diff --git a/mypy/typeshed/stdlib/datetime.pyi b/mypy/typeshed/stdlib/datetime.pyi index bd4d47e051ec..e0ce085c2967 100644 --- a/mypy/typeshed/stdlib/datetime.pyi +++ b/mypy/typeshed/stdlib/datetime.pyi @@ -56,7 +56,7 @@ class date: @property def day(self) -> int: ... def ctime(self) -> str: ... - def strftime(self, fmt: str) -> str: ... + def strftime(self, __format: str) -> str: ... def __format__(self, __fmt: str) -> str: ... def isoformat(self) -> str: ... def timetuple(self) -> struct_time: ... @@ -128,7 +128,7 @@ class time: if sys.version_info >= (3, 7): @classmethod def fromisoformat(cls: Type[_S], __time_string: str) -> _S: ... - def strftime(self, fmt: str) -> str: ... + def strftime(self, __format: str) -> str: ... def __format__(self, __fmt: str) -> str: ... def utcoffset(self) -> timedelta | None: ... def tzname(self) -> str | None: ... @@ -276,10 +276,10 @@ class datetime(date): def utcoffset(self) -> timedelta | None: ... def tzname(self) -> str | None: ... def dst(self) -> timedelta | None: ... - def __le__(self, __other: datetime) -> bool: ... # type: ignore - def __lt__(self, __other: datetime) -> bool: ... # type: ignore - def __ge__(self, __other: datetime) -> bool: ... # type: ignore - def __gt__(self, __other: datetime) -> bool: ... # type: ignore + def __le__(self, __other: datetime) -> bool: ... # type: ignore[override] + def __lt__(self, __other: datetime) -> bool: ... # type: ignore[override] + def __ge__(self, __other: datetime) -> bool: ... # type: ignore[override] + def __gt__(self, __other: datetime) -> bool: ... # type: ignore[override] if sys.version_info >= (3, 8): @overload # type: ignore[override] def __sub__(self: _D, __other: timedelta) -> _D: ... diff --git a/mypy/typeshed/stdlib/dbm/__init__.pyi b/mypy/typeshed/stdlib/dbm/__init__.pyi index 9b9f92ccaa86..5ecacd91b4ed 100644 --- a/mypy/typeshed/stdlib/dbm/__init__.pyi +++ b/mypy/typeshed/stdlib/dbm/__init__.pyi @@ -1,6 +1,6 @@ from _typeshed import Self from types import TracebackType -from typing import Iterator, MutableMapping, Tuple, Type, Union +from typing import Iterator, MutableMapping, Type, Union from typing_extensions import Literal _KeyType = Union[str, bytes] @@ -87,7 +87,7 @@ class _Database(MutableMapping[_KeyType, bytes]): class _error(Exception): ... -error = Tuple[Type[_error], Type[OSError]] +error: tuple[Type[_error], Type[OSError]] def whichdb(filename: str) -> str: ... def open(file: str, flag: _TFlags = ..., mode: int = ...) -> _Database: ... diff --git a/mypy/typeshed/stdlib/dbm/gnu.pyi b/mypy/typeshed/stdlib/dbm/gnu.pyi index 7cec827e8992..702f62d11b75 100644 --- a/mypy/typeshed/stdlib/dbm/gnu.pyi +++ b/mypy/typeshed/stdlib/dbm/gnu.pyi @@ -6,6 +6,8 @@ _T = TypeVar("_T") _KeyType = Union[str, bytes] _ValueType = Union[str, bytes] +open_flags: str + class error(OSError): ... # Actual typename gdbm, not exposed by the implementation @@ -31,7 +33,7 @@ class _gdbm: def keys(self) -> list[bytes]: ... def setdefault(self, k: _KeyType, default: _ValueType = ...) -> bytes: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] def open(__filename: str, __flags: str = ..., __mode: int = ...) -> _gdbm: ... diff --git a/mypy/typeshed/stdlib/dbm/ndbm.pyi b/mypy/typeshed/stdlib/dbm/ndbm.pyi index a4b35a309dbd..7b04c5385dbe 100644 --- a/mypy/typeshed/stdlib/dbm/ndbm.pyi +++ b/mypy/typeshed/stdlib/dbm/ndbm.pyi @@ -29,7 +29,7 @@ class _dbm: def keys(self) -> list[bytes]: ... def setdefault(self, k: _KeyType, default: _ValueType = ...) -> bytes: ... # Don't exist at runtime - __new__: None # type: ignore - __init__: None # type: ignore + __new__: None # type: ignore[assignment] + __init__: None # type: ignore[assignment] def open(__filename: str, __flags: str = ..., __mode: int = ...) -> _dbm: ... diff --git a/mypy/typeshed/stdlib/decimal.pyi b/mypy/typeshed/stdlib/decimal.pyi index 30c8e973348d..07f9ca1bfdf0 100644 --- a/mypy/typeshed/stdlib/decimal.pyi +++ b/mypy/typeshed/stdlib/decimal.pyi @@ -1,15 +1,16 @@ import numbers +import sys from types import TracebackType -from typing import Any, Container, NamedTuple, Sequence, Tuple, Type, TypeVar, Union, overload +from typing import Any, Container, NamedTuple, Sequence, Type, TypeVar, Union, overload _Decimal = Union[Decimal, int] -_DecimalNew = Union[Decimal, float, str, Tuple[int, Sequence[int], int]] +_DecimalNew = Union[Decimal, float, str, tuple[int, Sequence[int], int]] _ComparableNum = Union[Decimal, float, numbers.Rational] _DecimalT = TypeVar("_DecimalT", bound=Decimal) class DecimalTuple(NamedTuple): sign: int - digits: Tuple[int, ...] + digits: tuple[int, ...] exponent: int ROUND_DOWN: str @@ -21,6 +22,8 @@ ROUND_UP: str ROUND_HALF_DOWN: str ROUND_05UP: str +if sys.version_info >= (3, 7): + HAVE_CONTEXTVAR: bool HAVE_THREADS: bool MAX_EMAX: int MAX_PREC: int @@ -46,7 +49,7 @@ def setcontext(__context: Context) -> None: ... def getcontext() -> Context: ... def localcontext(ctx: Context | None = ...) -> _ContextManager: ... -class Decimal(object): +class Decimal: def __new__(cls: Type[_DecimalT], value: _DecimalNew = ..., context: Context | None = ...) -> _DecimalT: ... @classmethod def from_float(cls, __f: float) -> Decimal: ... @@ -148,7 +151,7 @@ class Decimal(object): def __deepcopy__(self, __memo: Any) -> Decimal: ... def __format__(self, __specifier: str, __context: Context | None = ...) -> str: ... -class _ContextManager(object): +class _ContextManager: new_context: Context saved_context: Context def __init__(self, new_context: Context) -> None: ... @@ -157,7 +160,7 @@ class _ContextManager(object): _TrapType = Type[DecimalException] -class Context(object): +class Context: prec: int rounding: str Emin: int @@ -181,7 +184,7 @@ class Context(object): # __setattr__() only allows to set a specific set of attributes, # already defined above. def __delattr__(self, __name: str) -> None: ... - def __reduce__(self) -> tuple[Type[Context], Tuple[Any, ...]]: ... + def __reduce__(self) -> tuple[Type[Context], tuple[Any, ...]]: ... def clear_flags(self) -> None: ... def clear_traps(self) -> None: ... def copy(self) -> Context: ... diff --git a/mypy/typeshed/stdlib/difflib.pyi b/mypy/typeshed/stdlib/difflib.pyi index 7c4ae8e2f246..d259e77dfe8c 100644 --- a/mypy/typeshed/stdlib/difflib.pyi +++ b/mypy/typeshed/stdlib/difflib.pyi @@ -34,9 +34,7 @@ class SequenceMatcher(Generic[_T]): # mypy thinks the signatures of the overloads overlap, but the types still work fine @overload -def get_close_matches( # type: ignore - word: AnyStr, possibilities: Iterable[AnyStr], n: int = ..., cutoff: float = ... -) -> list[AnyStr]: ... +def get_close_matches(word: AnyStr, possibilities: Iterable[AnyStr], n: int = ..., cutoff: float = ...) -> list[AnyStr]: ... # type: ignore[misc] @overload def get_close_matches( word: Sequence[_T], possibilities: Iterable[Sequence[_T]], n: int = ..., cutoff: float = ... @@ -72,7 +70,7 @@ def ndiff( a: Sequence[str], b: Sequence[str], linejunk: _JunkCallback | None = ..., charjunk: _JunkCallback | None = ... ) -> Iterator[str]: ... -class HtmlDiff(object): +class HtmlDiff: def __init__( self, tabsize: int = ..., diff --git a/mypy/typeshed/stdlib/dis.pyi b/mypy/typeshed/stdlib/dis.pyi index a6ea3e950b95..ac0632d25c9c 100644 --- a/mypy/typeshed/stdlib/dis.pyi +++ b/mypy/typeshed/stdlib/dis.pyi @@ -20,8 +20,8 @@ from typing import IO, Any, Callable, Iterator, NamedTuple, Union # Strictly this should not have to include Callable, but mypy doesn't use FunctionType # for functions (python/mypy#3171) -_have_code = Union[types.MethodType, types.FunctionType, types.CodeType, type, Callable[..., Any]] -_have_code_or_string = Union[_have_code, str, bytes] +_HaveCodeType = Union[types.MethodType, types.FunctionType, types.CodeType, type, Callable[..., Any]] +_HaveCodeOrStringType = Union[_HaveCodeType, str, bytes] class Instruction(NamedTuple): opname: str @@ -36,7 +36,7 @@ class Instruction(NamedTuple): class Bytecode: codeobj: types.CodeType first_line: int - def __init__(self, x: _have_code_or_string, *, first_line: int | None = ..., current_offset: int | None = ...) -> None: ... + def __init__(self, x: _HaveCodeOrStringType, *, first_line: int | None = ..., current_offset: int | None = ...) -> None: ... def __iter__(self) -> Iterator[Instruction]: ... def __repr__(self) -> str: ... def info(self) -> str: ... @@ -46,19 +46,19 @@ class Bytecode: COMPILER_FLAG_NAMES: dict[int, str] -def findlabels(code: _have_code) -> list[int]: ... -def findlinestarts(code: _have_code) -> Iterator[tuple[int, int]]: ... +def findlabels(code: _HaveCodeType) -> list[int]: ... +def findlinestarts(code: _HaveCodeType) -> Iterator[tuple[int, int]]: ... def pretty_flags(flags: int) -> str: ... -def code_info(x: _have_code_or_string) -> str: ... +def code_info(x: _HaveCodeOrStringType) -> str: ... if sys.version_info >= (3, 7): - def dis(x: _have_code_or_string | None = ..., *, file: IO[str] | None = ..., depth: int | None = ...) -> None: ... + def dis(x: _HaveCodeOrStringType | None = ..., *, file: IO[str] | None = ..., depth: int | None = ...) -> None: ... else: - def dis(x: _have_code_or_string | None = ..., *, file: IO[str] | None = ...) -> None: ... + def dis(x: _HaveCodeOrStringType | None = ..., *, file: IO[str] | None = ...) -> None: ... def distb(tb: types.TracebackType | None = ..., *, file: IO[str] | None = ...) -> None: ... -def disassemble(co: _have_code, lasti: int = ..., *, file: IO[str] | None = ...) -> None: ... -def disco(co: _have_code, lasti: int = ..., *, file: IO[str] | None = ...) -> None: ... -def show_code(co: _have_code, *, file: IO[str] | None = ...) -> None: ... -def get_instructions(x: _have_code, *, first_line: int | None = ...) -> Iterator[Instruction]: ... +def disassemble(co: _HaveCodeType, lasti: int = ..., *, file: IO[str] | None = ...) -> None: ... +def disco(co: _HaveCodeType, lasti: int = ..., *, file: IO[str] | None = ...) -> None: ... +def show_code(co: _HaveCodeType, *, file: IO[str] | None = ...) -> None: ... +def get_instructions(x: _HaveCodeType, *, first_line: int | None = ...) -> Iterator[Instruction]: ... diff --git a/mypy/typeshed/stdlib/distutils/ccompiler.pyi b/mypy/typeshed/stdlib/distutils/ccompiler.pyi index d21de4691503..7c7023ed0b65 100644 --- a/mypy/typeshed/stdlib/distutils/ccompiler.pyi +++ b/mypy/typeshed/stdlib/distutils/ccompiler.pyi @@ -1,6 +1,6 @@ -from typing import Any, Callable, Optional, Tuple, Union +from typing import Any, Callable, Optional, Union -_Macro = Union[Tuple[str], Tuple[str, Optional[str]]] +_Macro = Union[tuple[str], tuple[str, Optional[str]]] def gen_lib_options( compiler: CCompiler, library_dirs: list[str], runtime_library_dirs: list[str], libraries: list[str] @@ -141,7 +141,7 @@ class CCompiler: def library_filename(self, libname: str, lib_type: str = ..., strip_dir: int = ..., output_dir: str = ...) -> str: ... def object_filenames(self, source_filenames: list[str], strip_dir: int = ..., output_dir: str = ...) -> list[str]: ... def shared_object_filename(self, basename: str, strip_dir: int = ..., output_dir: str = ...) -> str: ... - def execute(self, func: Callable[..., None], args: Tuple[Any, ...], msg: str | None = ..., level: int = ...) -> None: ... + def execute(self, func: Callable[..., None], args: tuple[Any, ...], msg: str | None = ..., level: int = ...) -> None: ... def spawn(self, cmd: list[str]) -> None: ... def mkpath(self, name: str, mode: int = ...) -> None: ... def move_file(self, src: str, dst: str) -> str: ... diff --git a/mypy/typeshed/stdlib/distutils/command/__init__.pyi b/mypy/typeshed/stdlib/distutils/command/__init__.pyi index e69de29bb2d1..a4b9b1c2bd1b 100644 --- a/mypy/typeshed/stdlib/distutils/command/__init__.pyi +++ b/mypy/typeshed/stdlib/distutils/command/__init__.pyi @@ -0,0 +1,40 @@ +from . import ( + bdist_dumb as bdist_dumb, + bdist_rpm as bdist_rpm, + build as build, + build_clib as build_clib, + build_ext as build_ext, + build_py as build_py, + build_scripts as build_scripts, + check as check, + clean as clean, + install as install, + install_data as install_data, + install_headers as install_headers, + install_lib as install_lib, + register as register, + sdist as sdist, + upload as upload, +) + +__all__ = [ + "build", + "build_py", + "build_ext", + "build_clib", + "build_scripts", + "clean", + "install", + "install_lib", + "install_headers", + "install_scripts", + "install_data", + "sdist", + "register", + "bdist", + "bdist_dumb", + "bdist_rpm", + "bdist_wininst", + "check", + "upload", +] diff --git a/mypy/typeshed/stdlib/distutils/command/check.pyi b/mypy/typeshed/stdlib/distutils/command/check.pyi index 9149b540f715..36895d2c16f1 100644 --- a/mypy/typeshed/stdlib/distutils/command/check.pyi +++ b/mypy/typeshed/stdlib/distutils/command/check.pyi @@ -5,7 +5,7 @@ from ..cmd import Command _Reporter = Any # really docutils.utils.Reporter # Only defined if docutils is installed. -class SilentReporter(_Reporter): # type: ignore +class SilentReporter(_Reporter): messages: Any def __init__( self, diff --git a/mypy/typeshed/stdlib/distutils/command/install.pyi b/mypy/typeshed/stdlib/distutils/command/install.pyi index 47fa8b08d1b2..661d256e6f07 100644 --- a/mypy/typeshed/stdlib/distutils/command/install.pyi +++ b/mypy/typeshed/stdlib/distutils/command/install.pyi @@ -1,9 +1,9 @@ -from typing import Any, Tuple +from typing import Any from ..cmd import Command HAS_USER_SITE: bool -SCHEME_KEYS: Tuple[str, ...] +SCHEME_KEYS: tuple[str, ...] INSTALL_SCHEMES: dict[str, dict[Any, Any]] class install(Command): diff --git a/mypy/typeshed/stdlib/distutils/fancy_getopt.pyi b/mypy/typeshed/stdlib/distutils/fancy_getopt.pyi index 06a0847e4687..dce8394b6289 100644 --- a/mypy/typeshed/stdlib/distutils/fancy_getopt.pyi +++ b/mypy/typeshed/stdlib/distutils/fancy_getopt.pyi @@ -1,7 +1,7 @@ -from typing import Any, Iterable, List, Mapping, Optional, Tuple, overload +from typing import Any, Iterable, Mapping, Optional, overload -_Option = Tuple[str, Optional[str], str] -_GR = Tuple[List[str], OptionDummy] +_Option = tuple[str, Optional[str], str] +_GR = tuple[list[str], OptionDummy] def fancy_getopt( options: list[_Option], negative_opt: Mapping[_Option, _Option], object: Any, args: list[str] | None diff --git a/mypy/typeshed/stdlib/distutils/util.pyi b/mypy/typeshed/stdlib/distutils/util.pyi index 9b0915570ece..03ee0185cac4 100644 --- a/mypy/typeshed/stdlib/distutils/util.pyi +++ b/mypy/typeshed/stdlib/distutils/util.pyi @@ -1,6 +1,6 @@ from _typeshed import StrPath from collections.abc import Callable, Container, Iterable, Mapping -from typing import Any, Tuple +from typing import Any def get_platform() -> str: ... def convert_path(pathname: str) -> str: ... @@ -9,7 +9,7 @@ def check_environ() -> None: ... def subst_vars(s: str, local_vars: Mapping[str, str]) -> None: ... def split_quoted(s: str) -> list[str]: ... def execute( - func: Callable[..., None], args: Tuple[Any, ...], msg: str | None = ..., verbose: bool = ..., dry_run: bool = ... + func: Callable[..., None], args: tuple[Any, ...], msg: str | None = ..., verbose: bool = ..., dry_run: bool = ... ) -> None: ... def strtobool(val: str) -> bool: ... def byte_compile( diff --git a/mypy/typeshed/stdlib/distutils/version.pyi b/mypy/typeshed/stdlib/distutils/version.pyi index 9921dde39af6..1908cdeda97a 100644 --- a/mypy/typeshed/stdlib/distutils/version.pyi +++ b/mypy/typeshed/stdlib/distutils/version.pyi @@ -1,5 +1,5 @@ from abc import abstractmethod -from typing import Pattern, Tuple, TypeVar +from typing import Pattern, TypeVar _T = TypeVar("_T", bound=Version) @@ -31,7 +31,7 @@ class StrictVersion(Version): class LooseVersion(Version): component_re: Pattern[str] vstring: str - version: Tuple[str | int, ...] + version: tuple[str | int, ...] def __init__(self, vstring: str | None = ...) -> None: ... def parse(self: _T, vstring: str) -> _T: ... def __str__(self) -> str: ... diff --git a/mypy/typeshed/stdlib/doctest.pyi b/mypy/typeshed/stdlib/doctest.pyi index 9a9f83b0d8fe..611137740ac4 100644 --- a/mypy/typeshed/stdlib/doctest.pyi +++ b/mypy/typeshed/stdlib/doctest.pyi @@ -1,6 +1,6 @@ import types import unittest -from typing import Any, Callable, NamedTuple, Tuple, Type +from typing import Any, Callable, NamedTuple, Type class TestResults(NamedTuple): failed: int @@ -86,7 +86,7 @@ class DocTestFinder: ) -> list[DocTest]: ... _Out = Callable[[str], Any] -_ExcInfo = Tuple[Type[BaseException], BaseException, types.TracebackType] +_ExcInfo = tuple[Type[BaseException], BaseException, types.TracebackType] class DocTestRunner: DIVIDER: str diff --git a/mypy/typeshed/stdlib/email/_header_value_parser.pyi b/mypy/typeshed/stdlib/email/_header_value_parser.pyi index f1b08b5d5805..ddb9d9e45913 100644 --- a/mypy/typeshed/stdlib/email/_header_value_parser.pyi +++ b/mypy/typeshed/stdlib/email/_header_value_parser.pyi @@ -1,7 +1,7 @@ import sys from email.errors import HeaderParseError, MessageDefect from email.policy import Policy -from typing import Any, Iterable, Iterator, List, Pattern, Type, TypeVar, Union +from typing import Any, Iterable, Iterator, Pattern, Type, TypeVar, Union from typing_extensions import Final _T = TypeVar("_T") @@ -23,7 +23,7 @@ def quote_string(value: Any) -> str: ... if sys.version_info >= (3, 7): rfc2047_matcher: Pattern[str] -class TokenList(List[Union[TokenList, Terminal]]): +class TokenList(list[Union[TokenList, Terminal]]): token_type: str | None syntactic_break: bool ew_combine_allowed: bool @@ -334,7 +334,7 @@ class Terminal(str): def pop_trailing_ws(self) -> None: ... @property def comments(self) -> list[str]: ... - def __getnewargs__(self) -> tuple[str, str]: ... # type: ignore + def __getnewargs__(self) -> tuple[str, str]: ... # type: ignore[override] class WhiteSpaceTerminal(Terminal): @property diff --git a/mypy/typeshed/stdlib/email/base64mime.pyi b/mypy/typeshed/stdlib/email/base64mime.pyi new file mode 100644 index 000000000000..a8030a978923 --- /dev/null +++ b/mypy/typeshed/stdlib/email/base64mime.pyi @@ -0,0 +1,7 @@ +def header_length(bytearray: str | bytes) -> int: ... +def header_encode(header_bytes: str | bytes, charset: str = ...) -> str: ... +def body_encode(s: bytes, maxlinelen: int = ..., eol: str = ...) -> str: ... +def decode(string: str | bytes) -> bytes: ... + +body_decode = decode +decodestring = decode diff --git a/mypy/typeshed/stdlib/email/headerregistry.pyi b/mypy/typeshed/stdlib/email/headerregistry.pyi index 69e7bf315d9f..abf10ed4a4fd 100644 --- a/mypy/typeshed/stdlib/email/headerregistry.pyi +++ b/mypy/typeshed/stdlib/email/headerregistry.pyi @@ -1,5 +1,6 @@ import sys import types +from collections.abc import Iterable, Mapping from datetime import datetime as _datetime from email._header_value_parser import ( AddressList, @@ -12,28 +13,33 @@ from email._header_value_parser import ( ) from email.errors import MessageDefect from email.policy import Policy -from typing import Any, Iterable, Tuple, Type +from typing import Any, ClassVar, Type +from typing_extensions import Literal 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) + max_count: ClassVar[Literal[1] | None] @property def name(self) -> str: ... @property - def defects(self) -> Tuple[MessageDefect, ...]: ... - @property - def max_count(self) -> int | None: ... + def defects(self) -> tuple[MessageDefect, ...]: ... def __new__(cls, name: str, value: Any) -> BaseHeader: ... def init(self, name: str, *, parse_tree: TokenList, defects: Iterable[MessageDefect]) -> None: ... def fold(self, *, policy: Policy) -> str: ... class UnstructuredHeader: + max_count: ClassVar[Literal[1] | None] @staticmethod def value_parser(value: str) -> UnstructuredTokenList: ... @classmethod def parse(cls, value: str, kwds: dict[str, Any]) -> None: ... -class UniqueUnstructuredHeader(UnstructuredHeader): ... +class UniqueUnstructuredHeader(UnstructuredHeader): + max_count: ClassVar[Literal[1]] class DateHeader: + max_count: ClassVar[Literal[1] | None] + def init(self, name: str, *, parse_tree: TokenList, defects: Iterable[MessageDefect], datetime: _datetime) -> None: ... @property def datetime(self) -> _datetime: ... @staticmethod @@ -41,27 +47,43 @@ class DateHeader: @classmethod def parse(cls, value: str | _datetime, kwds: dict[str, Any]) -> None: ... -class UniqueDateHeader(DateHeader): ... +class UniqueDateHeader(DateHeader): + max_count: ClassVar[Literal[1]] class AddressHeader: + max_count: ClassVar[Literal[1] | None] + def init(self, name: str, *, parse_tree: TokenList, defects: Iterable[MessageDefect], groups: Iterable[Group]) -> None: ... @property - def groups(self) -> Tuple[Group, ...]: ... + def groups(self) -> tuple[Group, ...]: ... @property - def addresses(self) -> Tuple[Address, ...]: ... + def addresses(self) -> tuple[Address, ...]: ... @staticmethod def value_parser(value: str) -> AddressList: ... @classmethod def parse(cls, value: str, kwds: dict[str, Any]) -> None: ... -class UniqueAddressHeader(AddressHeader): ... +class UniqueAddressHeader(AddressHeader): + max_count: ClassVar[Literal[1]] class SingleAddressHeader(AddressHeader): @property def address(self) -> Address: ... -class UniqueSingleAddressHeader(SingleAddressHeader): ... +class UniqueSingleAddressHeader(SingleAddressHeader): + max_count: ClassVar[Literal[1]] class MIMEVersionHeader: + max_count: ClassVar[Literal[1]] + def init( + self, + name: str, + *, + parse_tree: TokenList, + defects: Iterable[MessageDefect], + version: str | None, + major: int | None, + minor: int | None, + ) -> None: ... @property def version(self) -> str | None: ... @property @@ -74,6 +96,8 @@ class MIMEVersionHeader: def parse(cls, value: str, kwds: dict[str, Any]) -> None: ... class ParameterizedMIMEHeader: + max_count: ClassVar[Literal[1]] + def init(self, name: str, *, parse_tree: TokenList, defects: Iterable[MessageDefect], params: Mapping[str, Any]) -> None: ... @property def params(self) -> types.MappingProxyType[str, Any]: ... @classmethod @@ -90,12 +114,15 @@ class ContentTypeHeader(ParameterizedMIMEHeader): def value_parser(value: str) -> ContentType: ... class ContentDispositionHeader(ParameterizedMIMEHeader): + # init is redefined but has the same signature as parent class, so is omitted from the stub @property - def content_disposition(self) -> str: ... + def content_disposition(self) -> str | None: ... @staticmethod def value_parser(value: str) -> ContentDisposition: ... class ContentTransferEncodingHeader: + max_count: ClassVar[Literal[1]] + def init(self, name: str, *, parse_tree: TokenList, defects: Iterable[MessageDefect]) -> None: ... @property def cte(self) -> str: ... @classmethod @@ -106,6 +133,7 @@ class ContentTransferEncodingHeader: 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 @@ -137,6 +165,6 @@ class Group: @property def display_name(self) -> str | None: ... @property - def addresses(self) -> Tuple[Address, ...]: ... + def addresses(self) -> tuple[Address, ...]: ... def __init__(self, display_name: str | None = ..., addresses: Iterable[Address] | None = ...) -> None: ... def __str__(self) -> str: ... diff --git a/mypy/typeshed/stdlib/email/message.pyi b/mypy/typeshed/stdlib/email/message.pyi index a1749a4cfc2e..b89c8f8ec167 100644 --- a/mypy/typeshed/stdlib/email/message.pyi +++ b/mypy/typeshed/stdlib/email/message.pyi @@ -2,15 +2,16 @@ from email.charset import Charset from email.contentmanager import ContentManager from email.errors import MessageDefect from email.policy import Policy -from typing import Any, Generator, Iterator, List, Optional, Sequence, Tuple, TypeVar, Union + +# using a type alias ("_HeaderType = Any") breaks mypy, who knows why +from typing import Any, Any as _HeaderType, Generator, Iterator, Optional, Sequence, TypeVar, Union _T = TypeVar("_T") -_PayloadType = Union[List[Message], str, bytes] +_PayloadType = Union[list[Message], str, bytes] _CharsetType = Union[Charset, str, None] -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] -_ParamType = Union[str, Tuple[Optional[str], Optional[str], str]] -_HeaderType = Any +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] +_ParamType = Union[str, tuple[Optional[str], Optional[str], str]] class Message: policy: Policy # undocumented @@ -69,6 +70,9 @@ class Message: replace: bool = ..., ) -> 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: str) -> None: ... + def raw_items(self) -> Iterator[tuple[str, str]]: ... class MIMEPart(Message): def __init__(self, policy: Policy | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/email/mime/application.pyi b/mypy/typeshed/stdlib/email/mime/application.pyi index 11fc470e9dd1..d176cd613e27 100644 --- a/mypy/typeshed/stdlib/email/mime/application.pyi +++ b/mypy/typeshed/stdlib/email/mime/application.pyi @@ -1,8 +1,8 @@ from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Optional, Union -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] class MIMEApplication(MIMENonMultipart): def __init__( diff --git a/mypy/typeshed/stdlib/email/mime/audio.pyi b/mypy/typeshed/stdlib/email/mime/audio.pyi index ee6de410bf53..38657c932e2f 100644 --- a/mypy/typeshed/stdlib/email/mime/audio.pyi +++ b/mypy/typeshed/stdlib/email/mime/audio.pyi @@ -1,8 +1,8 @@ from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Optional, Union -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] class MIMEAudio(MIMENonMultipart): def __init__( diff --git a/mypy/typeshed/stdlib/email/mime/base.pyi b/mypy/typeshed/stdlib/email/mime/base.pyi index b88dfd492554..cb655607b032 100644 --- a/mypy/typeshed/stdlib/email/mime/base.pyi +++ b/mypy/typeshed/stdlib/email/mime/base.pyi @@ -1,8 +1,8 @@ import email.message from email.policy import Policy -from typing import Optional, Tuple, Union +from typing import Optional, Union -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] class MIMEBase(email.message.Message): def __init__(self, _maintype: str, _subtype: str, *, policy: Policy | None = ..., **_params: _ParamsType) -> None: ... diff --git a/mypy/typeshed/stdlib/email/mime/image.pyi b/mypy/typeshed/stdlib/email/mime/image.pyi index 886aa74d5fe5..0325d9e594da 100644 --- a/mypy/typeshed/stdlib/email/mime/image.pyi +++ b/mypy/typeshed/stdlib/email/mime/image.pyi @@ -1,8 +1,8 @@ from email.mime.nonmultipart import MIMENonMultipart from email.policy import Policy -from typing import Callable, Optional, Tuple, Union +from typing import Callable, Optional, Union -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] class MIMEImage(MIMENonMultipart): def __init__( diff --git a/mypy/typeshed/stdlib/email/mime/multipart.pyi b/mypy/typeshed/stdlib/email/mime/multipart.pyi index 6259ddf5ab8f..6c316c055329 100644 --- a/mypy/typeshed/stdlib/email/mime/multipart.pyi +++ b/mypy/typeshed/stdlib/email/mime/multipart.pyi @@ -1,9 +1,9 @@ from email.message import Message from email.mime.base import MIMEBase from email.policy import Policy -from typing import Optional, Sequence, Tuple, Union +from typing import Optional, Sequence, Union -_ParamsType = Union[str, None, Tuple[str, Optional[str], str]] +_ParamsType = Union[str, None, tuple[str, Optional[str], str]] class MIMEMultipart(MIMEBase): def __init__( diff --git a/mypy/typeshed/stdlib/email/policy.pyi b/mypy/typeshed/stdlib/email/policy.pyi index 72a54bcfbf08..15991c7e084b 100644 --- a/mypy/typeshed/stdlib/email/policy.pyi +++ b/mypy/typeshed/stdlib/email/policy.pyi @@ -1,17 +1,27 @@ -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from email.contentmanager import ContentManager from email.errors import MessageDefect from email.header import Header from email.message import Message from typing import Any, Callable -class Policy: +class Policy(metaclass=ABCMeta): max_line_length: int | None linesep: str cte_type: str raise_on_defect: bool - mange_from: bool - def __init__(self, **kw: Any) -> None: ... + 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) -> Policy: ... def handle_defect(self, obj: Message, defect: MessageDefect) -> None: ... def register_defect(self, obj: Message, defect: MessageDefect) -> None: ... @@ -30,7 +40,7 @@ class Policy: 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 + 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: ... @@ -41,6 +51,20 @@ class EmailPolicy(Policy): refold_source: str header_factory: Callable[[str, str], str] content_manager: ContentManager + 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 = ..., + utf8: bool = ..., + refold_source: str = ..., + header_factory: Callable[[str, str], str] = ..., + content_manager: ContentManager = ..., + ) -> None: ... 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: ... diff --git a/mypy/typeshed/stdlib/email/quoprimime.pyi b/mypy/typeshed/stdlib/email/quoprimime.pyi new file mode 100644 index 000000000000..41c4bd8cca9e --- /dev/null +++ b/mypy/typeshed/stdlib/email/quoprimime.pyi @@ -0,0 +1,13 @@ +def header_check(octet: int) -> bool: ... +def body_check(octet: int) -> bool: ... +def header_length(bytearray: bytes) -> int: ... +def body_length(bytearray: bytes) -> int: ... +def unquote(s: str | bytes) -> str: ... +def quote(c: str | bytes) -> str: ... +def header_encode(header_bytes: bytes, charset: str = ...) -> str: ... +def body_encode(body: str, maxlinelen: int = ..., eol: str = ...) -> str: ... +def decode(encoded: str, eol: str = ...) -> str: ... +def header_decode(s: str) -> str: ... + +body_decode = decode +decodestring = decode diff --git a/mypy/typeshed/stdlib/email/utils.pyi b/mypy/typeshed/stdlib/email/utils.pyi index 3c07e98079fc..728a5a53f230 100644 --- a/mypy/typeshed/stdlib/email/utils.pyi +++ b/mypy/typeshed/stdlib/email/utils.pyi @@ -1,10 +1,10 @@ import datetime import sys from email.charset import Charset -from typing import Optional, Tuple, Union, overload +from typing import Optional, Union, overload -_ParamType = Union[str, Tuple[Optional[str], Optional[str], str]] -_PDTZ = Tuple[int, int, int, int, int, int, int, int, int, Optional[int]] +_ParamType = Union[str, tuple[Optional[str], Optional[str], str]] +_PDTZ = tuple[int, int, int, int, int, int, int, int, int, Optional[int]] def quote(str: str) -> str: ... def unquote(str: str) -> str: ... diff --git a/mypy/typeshed/stdlib/encodings/utf_8_sig.pyi b/mypy/typeshed/stdlib/encodings/utf_8_sig.pyi new file mode 100644 index 000000000000..bf52e8a6f3d3 --- /dev/null +++ b/mypy/typeshed/stdlib/encodings/utf_8_sig.pyi @@ -0,0 +1,27 @@ +import codecs + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors: str = ...) -> None: ... + def encode(self, input: str, final: bool = ...) -> bytes: ... + def reset(self) -> None: ... + def getstate(self) -> int: ... # type: ignore[override] + def setstate(self, state: int) -> None: ... # type: ignore[override] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def __init__(self, errors: str = ...) -> None: ... + def _buffer_decode(self, input: bytes, errors: str | None, final: bool) -> tuple[str, int]: ... + def reset(self) -> None: ... + def getstate(self) -> tuple[bytes, int]: ... + def setstate(self, state: tuple[bytes, int]) -> None: ... + +class StreamWriter(codecs.StreamWriter): + def reset(self) -> None: ... + def encode(self, input: str, errors: str | None = ...) -> tuple[bytes, int]: ... + +class StreamReader(codecs.StreamReader): + def reset(self) -> None: ... + def decode(self, input: bytes, errors: str | None = ...) -> tuple[str, int]: ... + +def getregentry() -> codecs.CodecInfo: ... +def encode(input: str, errors: str | None = ...) -> tuple[bytes, int]: ... +def decode(input: bytes, errors: str | None = ...) -> tuple[str, int]: ... diff --git a/mypy/typeshed/stdlib/enum.pyi b/mypy/typeshed/stdlib/enum.pyi index 07fea104cec7..a80a022ad6f5 100644 --- a/mypy/typeshed/stdlib/enum.pyi +++ b/mypy/typeshed/stdlib/enum.pyi @@ -2,17 +2,49 @@ import sys import types from abc import ABCMeta from builtins import property as _builtins_property -from typing import Any, Iterator, Type, TypeVar +from collections.abc import Iterable, Iterator, Mapping +from typing import Any, Type, TypeVar, Union, overload _T = TypeVar("_T") _S = TypeVar("_S", bound=Type[Enum]) +# The following all work: +# >>> from enum import Enum +# >>> from string import ascii_lowercase +# >>> Enum('Foo', names='RED YELLOW GREEN') +# +# >>> Enum('Foo', names=[('RED', 1), ('YELLOW, 2)]) +# +# >>> Enum('Foo', names=((x for x in (ascii_lowercase[i], i)) for i in range(5))) +# +# >>> Enum('Foo', names={'RED': 1, 'YELLOW': 2}) +# +_EnumNames = Union[str, Iterable[str], Iterable[Iterable[Union[str, Any]]], Mapping[str, Any]] + +class _EnumDict(dict[str, Any]): + def __init__(self) -> None: ... + # Note: EnumMeta actually subclasses type directly, not ABCMeta. # This is a temporary workaround to allow multiple creation of enums with builtins # such as str as mixins, which due to the handling of ABCs of builtin types, cause # spurious inconsistent metaclass structure. See #1595. # Structurally: Iterable[T], Reversible[T], Container[T] where T is the enum itself class EnumMeta(ABCMeta): + if sys.version_info >= (3, 11): + def __new__( + metacls: Type[_T], + cls: str, + bases: tuple[type, ...], + classdict: _EnumDict, + *, + boundary: FlagBoundary | None = ..., + _simple: bool = ..., + **kwds: Any, + ) -> _T: ... + elif sys.version_info >= (3, 9): + def __new__(metacls: Type[_T], cls: str, bases: tuple[type, ...], classdict: _EnumDict, **kwds: Any) -> _T: ... # type: ignore + else: + def __new__(metacls: Type[_T], cls: str, bases: tuple[type, ...], classdict: _EnumDict) -> _T: ... # type: ignore def __iter__(self: Type[_T]) -> Iterator[_T]: ... def __reversed__(self: Type[_T]) -> Iterator[_T]: ... def __contains__(self: Type[Any], member: object) -> bool: ... @@ -20,13 +52,56 @@ class EnumMeta(ABCMeta): @_builtins_property def __members__(self: Type[_T]) -> types.MappingProxyType[str, _T]: ... def __len__(self) -> int: ... + if sys.version_info >= (3, 11): + # Simple value lookup + @overload # type: ignore[override] + def __call__(cls: Type[_T], value: Any, names: None = ...) -> _T: ... + # Functional Enum API + @overload + def __call__( + cls, + value: str, + names: _EnumNames, + *, + module: str | None = ..., + qualname: str | None = ..., + type: type | None = ..., + start: int = ..., + boundary: FlagBoundary | None = ..., + ) -> Type[Enum]: ... + else: + @overload # type: ignore[override] + def __call__(cls: Type[_T], value: Any, names: None = ...) -> _T: ... + @overload + def __call__( + cls, + value: str, + names: _EnumNames, + *, + module: str | None = ..., + qualname: str | None = ..., + type: type | None = ..., + start: int = ..., + ) -> Type[Enum]: ... _member_names_: list[str] # undocumented _member_map_: dict[str, Enum] # undocumented _value2member_map_: dict[Any, Enum] # undocumented +if sys.version_info >= (3, 11): + # In 3.11 `EnumMeta` metaclass is renamed to `EnumType`, but old name also exists. + EnumType = EnumMeta + class Enum(metaclass=EnumMeta): - name: str - value: Any + if sys.version_info >= (3, 11): + @property + def name(self) -> str: ... + @property + def value(self) -> Any: ... + else: + @types.DynamicClassAttribute + def name(self) -> str: ... + @types.DynamicClassAttribute + def value(self) -> Any: ... _name_: str _value_: Any if sys.version_info >= (3, 7): @@ -46,7 +121,13 @@ class Enum(metaclass=EnumMeta): def __reduce_ex__(self, proto: object) -> Any: ... class IntEnum(int, Enum): - value: int + _value_: int + if sys.version_info >= (3, 11): + @property + def value(self) -> int: ... + else: + @types.DynamicClassAttribute + def value(self) -> int: ... def __new__(cls: Type[_T], value: int | _T) -> _T: ... def unique(enumeration: _S) -> _S: ... @@ -55,12 +136,28 @@ _auto_null: Any # subclassing IntFlag so it picks up all implemented base functions, best modeling behavior of enum.auto() class auto(IntFlag): - value: Any + _value_: Any + if sys.version_info >= (3, 11): + @property + def value(self) -> Any: ... + else: + @types.DynamicClassAttribute + def value(self) -> Any: ... def __new__(cls: Type[_T]) -> _T: ... class Flag(Enum): - name: str | None # type: ignore - value: int + _name_: str | None # type: ignore[assignment] + _value_: int + if sys.version_info >= (3, 11): + @property + def name(self) -> str | None: ... # type: ignore[override] + @property + def value(self) -> int: ... + else: + @types.DynamicClassAttribute + def name(self) -> str | None: ... # type: ignore[override] + @types.DynamicClassAttribute + def value(self) -> int: ... def __contains__(self: _T, other: _T) -> bool: ... def __repr__(self) -> str: ... def __str__(self) -> str: ... @@ -81,7 +178,10 @@ class IntFlag(int, Flag): if sys.version_info >= (3, 11): class StrEnum(str, Enum): - def __new__(cls: Type[_T], value: int | _T) -> _T: ... + def __new__(cls: Type[_T], value: str | _T) -> _T: ... + _value_: str + @property + def value(self) -> str: ... class FlagBoundary(StrEnum): STRICT: str CONFORM: str @@ -91,7 +191,10 @@ if sys.version_info >= (3, 11): CONFORM = FlagBoundary.CONFORM EJECT = FlagBoundary.EJECT KEEP = FlagBoundary.KEEP - class property(_builtins_property): ... + class property(types.DynamicClassAttribute): + def __set_name__(self, ownerclass: Type[Enum], name: str) -> None: ... + name: str + clsname: str def global_enum(cls: _S) -> _S: ... def global_enum_repr(self: Enum) -> str: ... def global_flag_repr(self: Flag) -> str: ... diff --git a/mypy/typeshed/stdlib/fcntl.pyi b/mypy/typeshed/stdlib/fcntl.pyi index 141f9ee9360a..47766357c83f 100644 --- a/mypy/typeshed/stdlib/fcntl.pyi +++ b/mypy/typeshed/stdlib/fcntl.pyi @@ -3,94 +3,94 @@ from _typeshed import FileDescriptorLike, ReadOnlyBuffer, WriteableBuffer from typing import Any, overload from typing_extensions import Literal -FASYNC: int -FD_CLOEXEC: int -DN_ACCESS: int -DN_ATTRIB: int -DN_CREATE: int -DN_DELETE: int -DN_MODIFY: int -DN_MULTISHOT: int -DN_RENAME: int -F_DUPFD: int -F_DUPFD_CLOEXEC: int -F_FULLFSYNC: int -F_EXLCK: int -F_GETFD: int -F_GETFL: int -F_GETLEASE: int -F_GETLK: int -F_GETLK64: int -F_GETOWN: int -F_NOCACHE: int -F_GETSIG: int -F_NOTIFY: int -F_RDLCK: int -F_SETFD: int -F_SETFL: int -F_SETLEASE: int -F_SETLK: int -F_SETLK64: int -F_SETLKW: int -F_SETLKW64: int -if sys.version_info >= (3, 9) and sys.platform == "linux": - F_OFD_GETLK: int - F_OFD_SETLK: int - F_OFD_SETLKW: int -F_SETOWN: int -F_SETSIG: int -F_SHLCK: int -F_UNLCK: int -F_WRLCK: int -I_ATMARK: int -I_CANPUT: int -I_CKBAND: int -I_FDINSERT: int -I_FIND: int -I_FLUSH: int -I_FLUSHBAND: int -I_GETBAND: int -I_GETCLTIME: int -I_GETSIG: int -I_GRDOPT: int -I_GWROPT: int -I_LINK: int -I_LIST: int -I_LOOK: int -I_NREAD: int -I_PEEK: int -I_PLINK: int -I_POP: int -I_PUNLINK: int -I_PUSH: int -I_RECVFD: int -I_SENDFD: int -I_SETCLTIME: int -I_SETSIG: int -I_SRDOPT: int -I_STR: int -I_SWROPT: int -I_UNLINK: int -LOCK_EX: int -LOCK_MAND: int -LOCK_NB: int -LOCK_READ: int -LOCK_RW: int -LOCK_SH: int -LOCK_UN: int -LOCK_WRITE: int - -@overload -def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: int = ...) -> int: ... -@overload -def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: bytes) -> bytes: ... -@overload -def ioctl(__fd: FileDescriptorLike, __request: int, __arg: int = ..., __mutate_flag: bool = ...) -> int: ... -@overload -def ioctl(__fd: FileDescriptorLike, __request: int, __arg: WriteableBuffer, __mutate_flag: Literal[True] = ...) -> int: ... -@overload -def ioctl(__fd: FileDescriptorLike, __request: int, __arg: WriteableBuffer, __mutate_flag: Literal[False]) -> bytes: ... -@overload -def ioctl(__fd: FileDescriptorLike, __request: int, __arg: ReadOnlyBuffer, __mutate_flag: bool = ...) -> bytes: ... -def flock(__fd: FileDescriptorLike, __operation: int) -> None: ... -def lockf(__fd: FileDescriptorLike, __cmd: int, __len: int = ..., __start: int = ..., __whence: int = ...) -> Any: ... +if sys.platform != "win32": + FASYNC: int + FD_CLOEXEC: int + DN_ACCESS: int + DN_ATTRIB: int + DN_CREATE: int + DN_DELETE: int + DN_MODIFY: int + DN_MULTISHOT: int + DN_RENAME: int + F_DUPFD: int + F_DUPFD_CLOEXEC: int + F_FULLFSYNC: int + F_EXLCK: int + F_GETFD: int + F_GETFL: int + F_GETLEASE: int + F_GETLK: int + F_GETLK64: int + F_GETOWN: int + F_NOCACHE: int + F_GETSIG: int + F_NOTIFY: int + F_RDLCK: int + F_SETFD: int + F_SETFL: int + F_SETLEASE: int + F_SETLK: int + F_SETLK64: int + F_SETLKW: int + F_SETLKW64: int + if sys.version_info >= (3, 9) and sys.platform == "linux": + F_OFD_GETLK: int + F_OFD_SETLK: int + F_OFD_SETLKW: int + F_SETOWN: int + F_SETSIG: int + F_SHLCK: int + F_UNLCK: int + F_WRLCK: int + I_ATMARK: int + I_CANPUT: int + I_CKBAND: int + I_FDINSERT: int + I_FIND: int + I_FLUSH: int + I_FLUSHBAND: int + I_GETBAND: int + I_GETCLTIME: int + I_GETSIG: int + I_GRDOPT: int + I_GWROPT: int + I_LINK: int + I_LIST: int + I_LOOK: int + I_NREAD: int + I_PEEK: int + I_PLINK: int + I_POP: int + I_PUNLINK: int + I_PUSH: int + I_RECVFD: int + I_SENDFD: int + I_SETCLTIME: int + I_SETSIG: int + I_SRDOPT: int + I_STR: int + I_SWROPT: int + I_UNLINK: int + LOCK_EX: int + LOCK_MAND: int + LOCK_NB: int + LOCK_READ: int + LOCK_RW: int + LOCK_SH: int + LOCK_UN: int + LOCK_WRITE: int + @overload + def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: int = ...) -> int: ... + @overload + def fcntl(__fd: FileDescriptorLike, __cmd: int, __arg: bytes) -> bytes: ... + @overload + def ioctl(__fd: FileDescriptorLike, __request: int, __arg: int = ..., __mutate_flag: bool = ...) -> int: ... + @overload + def ioctl(__fd: FileDescriptorLike, __request: int, __arg: WriteableBuffer, __mutate_flag: Literal[True] = ...) -> int: ... + @overload + def ioctl(__fd: FileDescriptorLike, __request: int, __arg: WriteableBuffer, __mutate_flag: Literal[False]) -> bytes: ... + @overload + def ioctl(__fd: FileDescriptorLike, __request: int, __arg: ReadOnlyBuffer, __mutate_flag: bool = ...) -> bytes: ... + def flock(__fd: FileDescriptorLike, __operation: int) -> None: ... + def lockf(__fd: FileDescriptorLike, __cmd: int, __len: int = ..., __start: int = ..., __whence: int = ...) -> Any: ... diff --git a/mypy/typeshed/stdlib/fileinput.pyi b/mypy/typeshed/stdlib/fileinput.pyi index 3c14b736ca50..576822059560 100644 --- a/mypy/typeshed/stdlib/fileinput.pyi +++ b/mypy/typeshed/stdlib/fileinput.pyi @@ -85,7 +85,8 @@ class FileInput(Iterable[AnyStr], Generic[AnyStr]): def __exit__(self, type: Any, value: Any, traceback: Any) -> None: ... def __iter__(self) -> Iterator[AnyStr]: ... def __next__(self) -> AnyStr: ... - def __getitem__(self, i: int) -> AnyStr: ... + if sys.version_info < (3, 11): + def __getitem__(self, i: int) -> AnyStr: ... def nextfile(self) -> None: ... def readline(self) -> AnyStr: ... def filename(self) -> str: ... diff --git a/mypy/typeshed/stdlib/formatter.pyi b/mypy/typeshed/stdlib/formatter.pyi index 7c3b97688dbd..f5d8348d08a1 100644 --- a/mypy/typeshed/stdlib/formatter.pyi +++ b/mypy/typeshed/stdlib/formatter.pyi @@ -1,8 +1,8 @@ -from typing import IO, Any, Iterable, Tuple +from typing import IO, Any, Iterable AS_IS: None -_FontType = Tuple[str, bool, bool, bool] -_StylesType = Tuple[Any, ...] +_FontType = tuple[str, bool, bool, bool] +_StylesType = tuple[Any, ...] class NullFormatter: writer: NullWriter | None @@ -68,7 +68,7 @@ class NullWriter: def new_font(self, font: _FontType) -> None: ... def new_margin(self, margin: int, level: int) -> None: ... def new_spacing(self, spacing: str | None) -> None: ... - def new_styles(self, styles: Tuple[Any, ...]) -> None: ... + def new_styles(self, styles: tuple[Any, ...]) -> None: ... def send_paragraph(self, blankline: int) -> None: ... def send_line_break(self) -> None: ... def send_hor_rule(self, *args: Any, **kw: Any) -> None: ... @@ -81,7 +81,7 @@ class AbstractWriter(NullWriter): def new_font(self, font: _FontType) -> None: ... def new_margin(self, margin: int, level: int) -> None: ... def new_spacing(self, spacing: str | None) -> None: ... - def new_styles(self, styles: Tuple[Any, ...]) -> None: ... + def new_styles(self, styles: tuple[Any, ...]) -> None: ... def send_paragraph(self, blankline: int) -> None: ... def send_line_break(self) -> None: ... def send_hor_rule(self, *args: Any, **kw: Any) -> None: ... diff --git a/mypy/typeshed/stdlib/fractions.pyi b/mypy/typeshed/stdlib/fractions.pyi index 3c6808651275..8de5ae20971c 100644 --- a/mypy/typeshed/stdlib/fractions.pyi +++ b/mypy/typeshed/stdlib/fractions.pyi @@ -134,6 +134,8 @@ class Fraction(Rational): def __le__(self, other: _ComparableNum) -> bool: ... def __ge__(self, other: _ComparableNum) -> bool: ... def __bool__(self) -> bool: ... + if sys.version_info >= (3, 11): + def __int__(self) -> int: ... # Not actually defined within fractions.py, but provides more useful # overrides @property diff --git a/mypy/typeshed/stdlib/ftplib.pyi b/mypy/typeshed/stdlib/ftplib.pyi index 3f4f892bb516..f84199c168e9 100644 --- a/mypy/typeshed/stdlib/ftplib.pyi +++ b/mypy/typeshed/stdlib/ftplib.pyi @@ -3,7 +3,7 @@ from _typeshed import Self, SupportsRead, SupportsReadline from socket import socket from ssl import SSLContext from types import TracebackType -from typing import Any, Callable, Iterable, Iterator, TextIO, Tuple, Type +from typing import Any, Callable, Iterable, Iterator, TextIO, Type from typing_extensions import Literal MSG_OOB: int @@ -18,7 +18,7 @@ class error_temp(Error): ... class error_perm(Error): ... class error_proto(Error): ... -all_errors: Tuple[Type[Exception], ...] +all_errors: tuple[Type[Exception], ...] class FTP: debugging: int @@ -33,10 +33,6 @@ class FTP: lastresp: str file: TextIO | None encoding: str - - # The following variable is intentionally left undocumented. - # See https://bugs.python.org/issue43285 for relevant discussion - # trust_server_pasv_ipv4_address: bool def __enter__(self: Self) -> Self: ... def __exit__( self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None diff --git a/mypy/typeshed/stdlib/functools.pyi b/mypy/typeshed/stdlib/functools.pyi index b5e52bf59920..990fed20d80d 100644 --- a/mypy/typeshed/stdlib/functools.pyi +++ b/mypy/typeshed/stdlib/functools.pyi @@ -1,7 +1,7 @@ import sys import types -from _typeshed import SupportsItems, SupportsLessThan -from typing import Any, Callable, Generic, Hashable, Iterable, NamedTuple, Sequence, Sized, Tuple, Type, TypeVar, overload +from _typeshed import SupportsAllComparisons, SupportsItems +from typing import Any, Callable, Generic, Hashable, Iterable, NamedTuple, Sequence, Sized, Type, TypeVar, overload from typing_extensions import final if sys.version_info >= (3, 9): @@ -45,13 +45,13 @@ WRAPPER_UPDATES: Sequence[str] def update_wrapper(wrapper: _T, wrapped: _AnyCallable, assigned: Sequence[str] = ..., updated: Sequence[str] = ...) -> _T: ... def wraps(wrapped: _AnyCallable, assigned: Sequence[str] = ..., updated: Sequence[str] = ...) -> Callable[[_T], _T]: ... def total_ordering(cls: Type[_T]) -> Type[_T]: ... -def cmp_to_key(mycmp: Callable[[_T, _T], int]) -> Callable[[_T], SupportsLessThan]: ... +def cmp_to_key(mycmp: Callable[[_T, _T], int]) -> Callable[[_T], SupportsAllComparisons]: ... class partial(Generic[_T]): func: Callable[..., _T] - args: Tuple[Any, ...] + args: tuple[Any, ...] keywords: dict[str, Any] - def __init__(self, func: Callable[..., _T], *args: Any, **kwargs: Any) -> None: ... + def __new__(cls: Type[_S], __func: Callable[..., _T], *args: Any, **kwargs: Any) -> _S: ... def __call__(self, *args: Any, **kwargs: Any) -> _T: ... if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... @@ -61,7 +61,7 @@ _Descriptor = Any class partialmethod(Generic[_T]): func: Callable[..., _T] | _Descriptor - args: Tuple[Any, ...] + args: tuple[Any, ...] keywords: dict[str, Any] @overload def __init__(self, __func: Callable[..., _T], *args: Any, **keywords: Any) -> None: ... @@ -120,10 +120,10 @@ if sys.version_info >= (3, 9): def cache(__user_function: Callable[..., _T]) -> _lru_cache_wrapper[_T]: ... def _make_key( - args: Tuple[Hashable, ...], + args: tuple[Hashable, ...], kwds: SupportsItems[Any, Any], typed: bool, - kwd_mark: Tuple[object, ...] = ..., + kwd_mark: tuple[object, ...] = ..., fasttypes: set[type] = ..., tuple: type = ..., type: Any = ..., diff --git a/mypy/typeshed/stdlib/genericpath.pyi b/mypy/typeshed/stdlib/genericpath.pyi index 56683e323178..f9518750d3f1 100644 --- a/mypy/typeshed/stdlib/genericpath.pyi +++ b/mypy/typeshed/stdlib/genericpath.pyi @@ -1,6 +1,6 @@ import os -from _typeshed import BytesPath, StrOrBytesPath, StrPath, SupportsLessThanT -from typing import Sequence, Tuple, overload +from _typeshed import BytesPath, StrOrBytesPath, StrPath, SupportsRichComparisonT +from typing import Sequence, overload from typing_extensions import Literal # All overloads can return empty string. Ideally, Literal[""] would be a valid @@ -11,9 +11,9 @@ def commonprefix(m: Sequence[StrPath]) -> str: ... @overload def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... @overload -def commonprefix(m: Sequence[list[SupportsLessThanT]]) -> Sequence[SupportsLessThanT]: ... +def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... @overload -def commonprefix(m: Sequence[Tuple[SupportsLessThanT, ...]]) -> Sequence[SupportsLessThanT]: ... +def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... def exists(path: StrOrBytesPath | int) -> bool: ... def getsize(filename: StrOrBytesPath | int) -> int: ... def isfile(path: StrOrBytesPath | int) -> bool: ... diff --git a/mypy/typeshed/stdlib/gettext.pyi b/mypy/typeshed/stdlib/gettext.pyi index b408d3f7485c..21be9fb1ff29 100644 --- a/mypy/typeshed/stdlib/gettext.pyi +++ b/mypy/typeshed/stdlib/gettext.pyi @@ -16,8 +16,9 @@ class NullTranslations: def npgettext(self, context: str, msgid1: str, msgid2: str, n: int) -> str: ... def info(self) -> Any: ... def charset(self) -> Any: ... - def output_charset(self) -> Any: ... - def set_output_charset(self, charset: str) -> None: ... + if sys.version_info < (3, 11): + def output_charset(self) -> Any: ... + def set_output_charset(self, charset: str) -> None: ... def install(self, names: Container[str] | None = ...) -> None: ... class GNUTranslations(NullTranslations): @@ -30,47 +31,71 @@ def find(domain: str, localedir: StrPath | None = ..., languages: Iterable[str] _T = TypeVar("_T") -@overload -def translation( - domain: str, - localedir: StrPath | None = ..., - languages: Iterable[str] | None = ..., - class_: None = ..., - fallback: bool = ..., - codeset: str | None = ..., -) -> NullTranslations: ... -@overload -def translation( - domain: str, - localedir: StrPath | None = ..., - languages: Iterable[str] | None = ..., - class_: Type[_T] = ..., - fallback: Literal[False] = ..., - codeset: str | None = ..., -) -> _T: ... -@overload -def translation( - domain: str, - localedir: StrPath | None = ..., - languages: Iterable[str] | None = ..., - class_: Type[Any] = ..., - fallback: Literal[True] = ..., - codeset: str | None = ..., -) -> Any: ... -def install( - domain: str, localedir: StrPath | None = ..., codeset: str | None = ..., names: Container[str] | None = ... -) -> None: ... +if sys.version_info >= (3, 11): + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: None = ..., + fallback: bool = ..., + ) -> NullTranslations: ... + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: Type[_T] = ..., + fallback: Literal[False] = ..., + ) -> _T: ... + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: Type[Any] = ..., + fallback: Literal[True] = ..., + ) -> Any: ... + def install(domain: str, localedir: StrPath | None = ..., names: Container[str] | None = ...) -> None: ... + +else: + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: None = ..., + fallback: bool = ..., + codeset: str | None = ..., + ) -> NullTranslations: ... + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: Type[_T] = ..., + fallback: Literal[False] = ..., + codeset: str | None = ..., + ) -> _T: ... + @overload + def translation( + domain: str, + localedir: StrPath | None = ..., + languages: Iterable[str] | None = ..., + class_: Type[Any] = ..., + fallback: Literal[True] = ..., + codeset: str | None = ..., + ) -> Any: ... + def install( + domain: str, localedir: StrPath | None = ..., codeset: str | None = ..., names: Container[str] | None = ... + ) -> None: ... + def textdomain(domain: str | None = ...) -> str: ... def bindtextdomain(domain: str, localedir: StrPath | None = ...) -> str: ... -def bind_textdomain_codeset(domain: str, codeset: str | None = ...) -> str: ... def dgettext(domain: str, message: str) -> str: ... -def ldgettext(domain: str, message: str) -> str: ... def dngettext(domain: str, msgid1: str, msgid2: str, n: int) -> str: ... -def ldngettext(domain: str, msgid1: str, msgid2: str, n: int) -> str: ... def gettext(message: str) -> str: ... -def lgettext(message: str) -> str: ... def ngettext(msgid1: str, msgid2: str, n: int) -> str: ... -def lngettext(msgid1: str, msgid2: str, n: int) -> str: ... if sys.version_info >= (3, 8): def pgettext(context: str, message: str) -> str: ... @@ -78,4 +103,11 @@ if sys.version_info >= (3, 8): 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: ... + def ldgettext(domain: str, message: str) -> str: ... + def lngettext(msgid1: str, msgid2: str, n: int) -> str: ... + def ldngettext(domain: str, msgid1: str, msgid2: str, n: int) -> str: ... + def bind_textdomain_codeset(domain: str, codeset: str | None = ...) -> str: ... + Catalog = translation diff --git a/mypy/typeshed/stdlib/graphlib.pyi b/mypy/typeshed/stdlib/graphlib.pyi index 0872af4a54a4..96d64cbce18c 100644 --- a/mypy/typeshed/stdlib/graphlib.pyi +++ b/mypy/typeshed/stdlib/graphlib.pyi @@ -1,5 +1,5 @@ from _typeshed import SupportsItems -from typing import Generic, Iterable, Tuple, TypeVar +from typing import Generic, Iterable, TypeVar _T = TypeVar("_T") @@ -10,7 +10,7 @@ class TopologicalSorter(Generic[_T]): def is_active(self) -> bool: ... def __bool__(self) -> bool: ... def done(self, *nodes: _T) -> None: ... - def get_ready(self) -> Tuple[_T, ...]: ... + def get_ready(self) -> tuple[_T, ...]: ... def static_order(self) -> Iterable[_T]: ... class CycleError(ValueError): ... diff --git a/mypy/typeshed/stdlib/grp.pyi b/mypy/typeshed/stdlib/grp.pyi index 08cbe6b86476..b416269921d6 100644 --- a/mypy/typeshed/stdlib/grp.pyi +++ b/mypy/typeshed/stdlib/grp.pyi @@ -1,11 +1,19 @@ -from typing import NamedTuple +import sys +from _typeshed import structseq +from typing import Any, Optional +from typing_extensions import final -class struct_group(NamedTuple): - gr_name: str - gr_passwd: str | None - gr_gid: int - gr_mem: list[str] - -def getgrall() -> list[struct_group]: ... -def getgrgid(id: int) -> struct_group: ... -def getgrnam(name: str) -> struct_group: ... +if sys.platform != "win32": + @final + class struct_group(structseq[Any], tuple[str, Optional[str], int, list[str]]): + @property + def gr_name(self) -> str: ... + @property + def gr_passwd(self) -> str | None: ... + @property + def gr_gid(self) -> int: ... + @property + def gr_mem(self) -> list[str]: ... + def getgrall() -> list[struct_group]: ... + def getgrgid(id: int) -> struct_group: ... + def getgrnam(name: str) -> struct_group: ... diff --git a/mypy/typeshed/stdlib/hashlib.pyi b/mypy/typeshed/stdlib/hashlib.pyi index e39f2f25326e..fad3c5aad457 100644 --- a/mypy/typeshed/stdlib/hashlib.pyi +++ b/mypy/typeshed/stdlib/hashlib.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import ReadableBuffer, Self from typing import AbstractSet -class _Hash(object): +class _Hash: @property def digest_size(self) -> int: ... @property @@ -49,7 +49,7 @@ def pbkdf2_hmac( hash_name: str, password: ReadableBuffer, salt: ReadableBuffer, iterations: int, dklen: int | None = ... ) -> bytes: ... -class _VarLenHash(object): +class _VarLenHash: digest_size: int block_size: int name: str diff --git a/mypy/typeshed/stdlib/heapq.pyi b/mypy/typeshed/stdlib/heapq.pyi index 81ee02582a6a..fd3c2db8ad66 100644 --- a/mypy/typeshed/stdlib/heapq.pyi +++ b/mypy/typeshed/stdlib/heapq.pyi @@ -1,4 +1,4 @@ -from _typeshed import SupportsLessThan +from _typeshed import SupportsRichComparison from typing import Any, Callable, Iterable, TypeVar _T = TypeVar("_T") @@ -9,6 +9,6 @@ def heappushpop(__heap: list[_T], __item: _T) -> _T: ... def heapify(__heap: list[Any]) -> None: ... def heapreplace(__heap: list[_T], __item: _T) -> _T: ... def merge(*iterables: Iterable[_T], key: Callable[[_T], Any] | None = ..., reverse: bool = ...) -> Iterable[_T]: ... -def nlargest(n: int, iterable: Iterable[_T], key: Callable[[_T], SupportsLessThan] | None = ...) -> list[_T]: ... -def nsmallest(n: int, iterable: Iterable[_T], key: Callable[[_T], SupportsLessThan] | None = ...) -> list[_T]: ... +def nlargest(n: int, iterable: Iterable[_T], key: Callable[[_T], SupportsRichComparison] | None = ...) -> list[_T]: ... +def nsmallest(n: int, iterable: Iterable[_T], key: Callable[[_T], SupportsRichComparison] | None = ...) -> list[_T]: ... def _heapify_max(__x: list[Any]) -> None: ... # undocumented diff --git a/mypy/typeshed/stdlib/hmac.pyi b/mypy/typeshed/stdlib/hmac.pyi index 440bddd7919c..88c88631f99a 100644 --- a/mypy/typeshed/stdlib/hmac.pyi +++ b/mypy/typeshed/stdlib/hmac.pyi @@ -7,6 +7,9 @@ from typing import Any, AnyStr, Callable, Union, overload _Hash = Any _DigestMod = Union[str, Callable[[], _Hash], ModuleType] +trans_5C: bytes +trans_36: bytes + digest_size: None if sys.version_info >= (3, 8): diff --git a/mypy/typeshed/stdlib/html/parser.pyi b/mypy/typeshed/stdlib/html/parser.pyi index fec3f3509522..60e0de51d3b8 100644 --- a/mypy/typeshed/stdlib/html/parser.pyi +++ b/mypy/typeshed/stdlib/html/parser.pyi @@ -1,5 +1,5 @@ from _markupbase import ParserBase -from typing import Tuple +from typing import Pattern class HTMLParser(ParserBase): def __init__(self, *, convert_charrefs: bool = ...) -> None: ... @@ -18,7 +18,7 @@ class HTMLParser(ParserBase): def handle_decl(self, decl: str) -> None: ... def handle_pi(self, data: str) -> None: ... def unknown_decl(self, data: str) -> None: ... - CDATA_CONTENT_ELEMENTS: Tuple[str, ...] + CDATA_CONTENT_ELEMENTS: tuple[str, ...] def check_for_whole_start_tag(self, i: int) -> int: ... # undocumented def clear_cdata_mode(self) -> None: ... # undocumented def goahead(self, end: bool) -> None: ... # undocumented @@ -28,3 +28,8 @@ class HTMLParser(ParserBase): def parse_pi(self, i: int) -> int: ... # undocumented def parse_starttag(self, i: int) -> int: ... # undocumented def set_cdata_mode(self, elem: str) -> None: ... # undocumented + rawdata: str # undocumented + cdata_elem: str | None # undocumented + convert_charrefs: bool # undocumented + interesting: Pattern[str] # undocumented + lasttag: str # undocumented diff --git a/mypy/typeshed/stdlib/http/client.pyi b/mypy/typeshed/stdlib/http/client.pyi index c450db587135..1558f6ff46e8 100644 --- a/mypy/typeshed/stdlib/http/client.pyi +++ b/mypy/typeshed/stdlib/http/client.pyi @@ -96,7 +96,7 @@ class HTTPResponse(io.BufferedIOBase, BinaryIO): def read(self, amt: int | None = ...) -> bytes: ... def read1(self, n: int = ...) -> bytes: ... def readinto(self, b: WriteableBuffer) -> int: ... - def readline(self, limit: int = ...) -> bytes: ... # type: ignore + def readline(self, limit: int = ...) -> bytes: ... # type: ignore[override] @overload def getheader(self, name: str) -> str | None: ... @overload diff --git a/mypy/typeshed/stdlib/http/cookiejar.pyi b/mypy/typeshed/stdlib/http/cookiejar.pyi index f37fb19cebe9..6bfa7f385e69 100644 --- a/mypy/typeshed/stdlib/http/cookiejar.pyi +++ b/mypy/typeshed/stdlib/http/cookiejar.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import StrPath from http.client import HTTPResponse -from typing import ClassVar, Iterable, Iterator, Pattern, Sequence, Tuple, TypeVar, overload +from typing import ClassVar, Iterable, Iterator, Pattern, Sequence, TypeVar, overload from urllib.request import Request _T = TypeVar("_T") @@ -102,10 +102,10 @@ class DefaultCookiePolicy(CookiePolicy): strict_ns_set_initial_dollar: bool = ..., strict_ns_set_path: bool = ..., ) -> None: ... - def blocked_domains(self) -> Tuple[str, ...]: ... + def blocked_domains(self) -> tuple[str, ...]: ... def set_blocked_domains(self, blocked_domains: Sequence[str]) -> None: ... def is_blocked(self, domain: str) -> bool: ... - def allowed_domains(self) -> Tuple[str, ...] | None: ... + def allowed_domains(self) -> tuple[str, ...] | None: ... def set_allowed_domains(self, allowed_domains: Sequence[str] | None) -> None: ... def is_not_allowed(self, domain: str) -> bool: ... def set_ok_version(self, cookie: Cookie, request: Request) -> bool: ... # undocumented diff --git a/mypy/typeshed/stdlib/http/cookies.pyi b/mypy/typeshed/stdlib/http/cookies.pyi index 7e9513adb1a1..211fd37662d4 100644 --- a/mypy/typeshed/stdlib/http/cookies.pyi +++ b/mypy/typeshed/stdlib/http/cookies.pyi @@ -1,5 +1,5 @@ import sys -from typing import Any, Dict, Generic, Iterable, Mapping, TypeVar, Union, overload +from typing import Any, Generic, Iterable, Mapping, TypeVar, Union, overload if sys.version_info >= (3, 9): from types import GenericAlias @@ -18,7 +18,7 @@ def _unquote(str: str) -> str: ... class CookieError(Exception): ... -class Morsel(Dict[str, Any], Generic[_T]): +class Morsel(dict[str, Any], Generic[_T]): value: str coded_value: _T key: str @@ -29,7 +29,7 @@ class Morsel(Dict[str, Any], Generic[_T]): def set(self, key: str, val: str, coded_val: _T, LegalChars: str = ...) -> None: ... def setdefault(self, key: str, val: str | None = ...) -> str: ... # The dict update can also get a keywords argument so this is incompatible - @overload # type: ignore + @overload # type: ignore[override] def update(self, values: Mapping[str, str]) -> None: ... @overload def update(self, values: Iterable[tuple[str, str]]) -> None: ... @@ -40,7 +40,7 @@ class Morsel(Dict[str, Any], Generic[_T]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... -class BaseCookie(Dict[str, Morsel[_T]], Generic[_T]): +class BaseCookie(dict[str, Morsel[_T]], Generic[_T]): def __init__(self, input: _DataType | None = ...) -> None: ... def value_decode(self, val: str) -> _T: ... def value_encode(self, val: _T) -> str: ... diff --git a/mypy/typeshed/stdlib/imaplib.pyi b/mypy/typeshed/stdlib/imaplib.pyi index a9f19048c9ae..1b2774d8fde0 100644 --- a/mypy/typeshed/stdlib/imaplib.pyi +++ b/mypy/typeshed/stdlib/imaplib.pyi @@ -5,14 +5,14 @@ from _typeshed import Self from socket import socket as _socket from ssl import SSLContext, SSLSocket from types import TracebackType -from typing import IO, Any, Callable, List, Pattern, Tuple, Type, Union +from typing import IO, Any, Callable, Pattern, Type, Union from typing_extensions import Literal # TODO: Commands should use their actual return types, not this type alias. # E.g. Tuple[Literal["OK"], List[bytes]] -_CommandResults = Tuple[str, List[Any]] +_CommandResults = tuple[str, list[Any]] -_AnyResponseData = Union[List[None], List[Union[bytes, Tuple[bytes, bytes]]]] +_AnyResponseData = Union[list[None], list[Union[bytes, tuple[bytes, bytes]]]] _list = list # conflicts with a method named "list" diff --git a/mypy/typeshed/stdlib/importlib/abc.pyi b/mypy/typeshed/stdlib/importlib/abc.pyi index 2e18f3f899a2..9bb370dfd7e8 100644 --- a/mypy/typeshed/stdlib/importlib/abc.pyi +++ b/mypy/typeshed/stdlib/importlib/abc.pyi @@ -12,8 +12,8 @@ from _typeshed import ( from abc import ABCMeta, abstractmethod from importlib.machinery import ModuleSpec from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from typing import IO, Any, BinaryIO, Iterator, Mapping, Protocol, Sequence, Union, overload -from typing_extensions import Literal, runtime_checkable +from typing import IO, Any, BinaryIO, Iterator, Mapping, NoReturn, Protocol, Sequence, Union, overload, runtime_checkable +from typing_extensions import Literal _Path = Union[bytes, str] @@ -85,8 +85,12 @@ if sys.version_info >= (3, 7): def open_resource(self, resource: StrOrBytesPath) -> IO[bytes]: ... @abstractmethod def resource_path(self, resource: StrOrBytesPath) -> str: ... - @abstractmethod - def is_resource(self, name: str) -> bool: ... + if sys.version_info >= (3, 10): + @abstractmethod + def is_resource(self, path: str) -> bool: ... + else: + @abstractmethod + def is_resource(self, name: str) -> bool: ... @abstractmethod def contents(self) -> Iterator[str]: ... @@ -169,3 +173,10 @@ if sys.version_info >= (3, 9): def read_bytes(self) -> bytes: ... @abstractmethod def read_text(self, encoding: str | None = ...) -> str: ... + class TraversableResources(ResourceReader): + @abstractmethod + def files(self) -> Traversable: ... + def open_resource(self, resource: StrPath) -> BufferedReader: ... # type: ignore[override] + def resource_path(self, resource: Any) -> NoReturn: ... + def is_resource(self, path: StrPath) -> bool: ... + def contents(self) -> Iterator[str]: ... diff --git a/mypy/typeshed/stdlib/importlib/machinery.pyi b/mypy/typeshed/stdlib/importlib/machinery.pyi index 432bec901161..b73f9c527583 100644 --- a/mypy/typeshed/stdlib/importlib/machinery.pyi +++ b/mypy/typeshed/stdlib/importlib/machinery.pyi @@ -1,6 +1,10 @@ import importlib.abc +import sys import types -from typing import Any, Callable, Sequence +from typing import Any, Callable, Iterable, Sequence + +if sys.version_info >= (3, 8): + from importlib.metadata import DistributionFinder, PathDistribution class ModuleSpec: def __init__( @@ -41,10 +45,16 @@ class BuiltinImporter(importlib.abc.MetaPathFinder, importlib.abc.InspectLoader) # Loader @staticmethod def module_repr(module: types.ModuleType) -> str: ... - @classmethod - def create_module(cls, spec: ModuleSpec) -> types.ModuleType | None: ... - @classmethod - def exec_module(cls, module: types.ModuleType) -> None: ... + if sys.version_info >= (3, 10): + @staticmethod + def create_module(spec: ModuleSpec) -> types.ModuleType | None: ... + @staticmethod + def exec_module(module: types.ModuleType) -> None: ... + else: + @classmethod + def create_module(cls, spec: ModuleSpec) -> types.ModuleType | None: ... + @classmethod + def exec_module(cls, module: types.ModuleType) -> None: ... class FrozenImporter(importlib.abc.MetaPathFinder, importlib.abc.InspectLoader): # MetaPathFinder @@ -66,8 +76,12 @@ class FrozenImporter(importlib.abc.MetaPathFinder, importlib.abc.InspectLoader): # Loader @staticmethod def module_repr(m: types.ModuleType) -> str: ... - @classmethod - def create_module(cls, spec: ModuleSpec) -> types.ModuleType | None: ... + if sys.version_info >= (3, 10): + @staticmethod + def create_module(spec: ModuleSpec) -> types.ModuleType | None: ... + else: + @classmethod + def create_module(cls, spec: ModuleSpec) -> types.ModuleType | None: ... @staticmethod def exec_module(module: types.ModuleType) -> None: ... @@ -80,8 +94,18 @@ class WindowsRegistryFinder(importlib.abc.MetaPathFinder): ) -> ModuleSpec | None: ... class PathFinder: - @classmethod - def invalidate_caches(cls) -> None: ... + if sys.version_info >= (3, 10): + @staticmethod + def invalidate_caches() -> None: ... + else: + @classmethod + def invalidate_caches(cls) -> None: ... + if sys.version_info >= (3, 10): + @staticmethod + def find_distributions(context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... + elif sys.version_info >= (3, 8): + @classmethod + def find_distributions(cls, context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... @classmethod def find_spec( cls, fullname: str, path: Sequence[bytes | str] | None = ..., target: types.ModuleType | None = ... diff --git a/mypy/typeshed/stdlib/importlib/metadata.pyi b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi similarity index 80% rename from mypy/typeshed/stdlib/importlib/metadata.pyi rename to mypy/typeshed/stdlib/importlib/metadata/__init__.pyi index 2c1041b76503..a9e223149b52 100644 --- a/mypy/typeshed/stdlib/importlib/metadata.pyi +++ b/mypy/typeshed/stdlib/importlib/metadata/__init__.pyi @@ -7,9 +7,10 @@ from email.message import Message from importlib.abc import MetaPathFinder from os import PathLike from pathlib import Path -from typing import Any, Iterable, NamedTuple, Tuple, overload +from typing import Any, ClassVar, Iterable, NamedTuple, Pattern, overload if sys.version_info >= (3, 10): + from importlib.metadata._meta import PackageMetadata as PackageMetadata def packages_distributions() -> Mapping[str, list[str]]: ... if sys.version_info >= (3, 8): @@ -19,9 +20,18 @@ if sys.version_info >= (3, 8): value: str group: str class EntryPoint(_EntryPointBase): + pattern: ClassVar[Pattern[str]] def load(self) -> Any: ... # Callable[[], Any] or an importable module @property def extras(self) -> list[str]: ... + if sys.version_info >= (3, 9): + @property + def module(self) -> str: ... + @property + def attr(self) -> str: ... + if sys.version_info >= (3, 10): + dist: ClassVar[Distribution | None] + def matches(self, **params: Any) -> bool: ... # undocumented class PackagePath(pathlib.PurePosixPath): def read_text(self, encoding: str = ...) -> str: ... def read_binary(self) -> bytes: ... @@ -61,6 +71,9 @@ if sys.version_info >= (3, 8): def files(self) -> list[PackagePath] | None: ... @property def requires(self) -> list[str] | None: ... + if sys.version_info >= (3, 10): + @property + def name(self) -> str: ... class DistributionFinder(MetaPathFinder): class Context: name: str | None @@ -72,6 +85,9 @@ if sys.version_info >= (3, 8): 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" + def invalidate_caches(cls) -> None: ... # type: ignore class PathDistribution(Distribution): def __init__(self, path: Path) -> None: ... def read_text(self, filename: StrPath) -> str: ... @@ -85,6 +101,6 @@ if sys.version_info >= (3, 8): ) -> Iterable[Distribution]: ... def metadata(distribution_name: str) -> Message: ... def version(distribution_name: str) -> str: ... - def entry_points() -> dict[str, Tuple[EntryPoint, ...]]: ... + def entry_points() -> dict[str, tuple[EntryPoint, ...]]: ... def files(distribution_name: str) -> list[PackagePath] | None: ... def requires(distribution_name: str) -> list[str] | None: ... diff --git a/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi b/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi new file mode 100644 index 000000000000..a5e5733396d7 --- /dev/null +++ b/mypy/typeshed/stdlib/importlib/metadata/_meta.pyi @@ -0,0 +1,18 @@ +from typing import Any, Iterator, Protocol, TypeVar + +_T = TypeVar("_T") + +class PackageMetadata(Protocol): + def __len__(self) -> int: ... + def __contains__(self, item: str) -> bool: ... + def __getitem__(self, key: str) -> str: ... + def __iter__(self) -> Iterator[str]: ... + def get_all(self, name: str, failobj: _T = ...) -> list[Any] | _T: ... + @property + def json(self) -> dict[str, str | list[str]]: ... + +class SimplePath(Protocol): + def joinpath(self) -> SimplePath: ... + def __div__(self) -> SimplePath: ... + def parent(self) -> SimplePath: ... + def read_text(self) -> str: ... diff --git a/mypy/typeshed/stdlib/importlib/resources.pyi b/mypy/typeshed/stdlib/importlib/resources.pyi index 194c0bac2b6a..b484d7126b21 100644 --- a/mypy/typeshed/stdlib/importlib/resources.pyi +++ b/mypy/typeshed/stdlib/importlib/resources.pyi @@ -23,3 +23,6 @@ if sys.version_info >= (3, 9): from importlib.abc import Traversable def files(package: Package) -> Traversable: ... def as_file(path: Traversable) -> AbstractContextManager[Path]: ... + +if sys.version_info >= (3, 10): + from importlib.abc import ResourceReader as ResourceReader diff --git a/mypy/typeshed/stdlib/importlib/util.pyi b/mypy/typeshed/stdlib/importlib/util.pyi index 30b8765fad04..c759d7def5be 100644 --- a/mypy/typeshed/stdlib/importlib/util.pyi +++ b/mypy/typeshed/stdlib/importlib/util.pyi @@ -1,5 +1,6 @@ import importlib.abc import importlib.machinery +import sys import types from _typeshed import StrOrBytesPath from typing import Any, Callable @@ -7,9 +8,9 @@ from typing_extensions import ParamSpec _P = ParamSpec("_P") -def module_for_loader(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... # type: ignore -def set_loader(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... # type: ignore -def set_package(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... # type: ignore +def module_for_loader(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... +def set_loader(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... +def set_package(fxn: Callable[_P, types.ModuleType]) -> Callable[_P, types.ModuleType]: ... def resolve_name(name: str, package: str | None) -> str: ... MAGIC_NUMBER: bytes @@ -36,3 +37,6 @@ class LazyLoader(importlib.abc.Loader): def factory(cls, loader: importlib.abc.Loader) -> Callable[..., LazyLoader]: ... def create_module(self, spec: importlib.machinery.ModuleSpec) -> types.ModuleType | None: ... def exec_module(self, module: types.ModuleType) -> None: ... + +if sys.version_info >= (3, 7): + def source_hash(source_bytes: bytes) -> int: ... diff --git a/mypy/typeshed/stdlib/inspect.pyi b/mypy/typeshed/stdlib/inspect.pyi index 88002cf205b1..a96e30865a59 100644 --- a/mypy/typeshed/stdlib/inspect.pyi +++ b/mypy/typeshed/stdlib/inspect.pyi @@ -23,7 +23,7 @@ from types import ( if sys.version_info >= (3, 7): from types import ClassMethodDescriptorType, WrapperDescriptorType, MemberDescriptorType, MethodDescriptorType -from typing import Any, ClassVar, NamedTuple, Protocol, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Coroutine, NamedTuple, Protocol, Type, TypeVar, Union from typing_extensions import Literal, TypeGuard # @@ -41,17 +41,19 @@ class BlockFinder: last: int def tokeneater(self, type: int, token: str, srowcol: tuple[int, int], erowcol: tuple[int, int], line: str) -> None: ... -CO_OPTIMIZED: int -CO_NEWLOCALS: int -CO_VARARGS: int -CO_VARKEYWORDS: int -CO_NESTED: int -CO_GENERATOR: int -CO_NOFREE: int -CO_COROUTINE: int -CO_ITERABLE_COROUTINE: int -CO_ASYNC_GENERATOR: int -TPFLAGS_IS_ABSTRACT: int +CO_OPTIMIZED: Literal[1] +CO_NEWLOCALS: Literal[2] +CO_VARARGS: Literal[4] +CO_VARKEYWORDS: Literal[8] +CO_NESTED: Literal[16] +CO_GENERATOR: Literal[32] +CO_NOFREE: Literal[64] +CO_COROUTINE: Literal[128] +CO_ITERABLE_COROUTINE: Literal[256] +CO_ASYNC_GENERATOR: Literal[512] +TPFLAGS_IS_ABSTRACT: Literal[1048576] + +modulesbyfile: dict[str, Any] def getmembers(object: object, predicate: Callable[[Any], bool] | None = ...) -> list[tuple[str, Any]]: ... def getmodulename(path: str) -> str | None: ... @@ -93,14 +95,7 @@ def isframe(object: object) -> TypeGuard[FrameType]: ... def iscode(object: object) -> TypeGuard[CodeType]: ... def isbuiltin(object: object) -> TypeGuard[BuiltinFunctionType]: ... -if sys.version_info < (3, 7): - def isroutine( - object: object, - ) -> TypeGuard[FunctionType | LambdaType | MethodType | BuiltinFunctionType | BuiltinMethodType]: ... - def ismethoddescriptor(object: object) -> bool: ... - def ismemberdescriptor(object: object) -> bool: ... - -else: +if sys.version_info >= (3, 7): def isroutine( object: object, ) -> TypeGuard[ @@ -116,6 +111,13 @@ else: def ismethoddescriptor(object: object) -> TypeGuard[MethodDescriptorType]: ... def ismemberdescriptor(object: object) -> TypeGuard[MemberDescriptorType]: ... +else: + def isroutine( + object: object, + ) -> TypeGuard[FunctionType | LambdaType | MethodType | BuiltinFunctionType | BuiltinMethodType]: ... + def ismethoddescriptor(object: object) -> bool: ... + def ismemberdescriptor(object: object) -> bool: ... + def isabstract(object: object) -> bool: ... def isgetsetdescriptor(object: object) -> TypeGuard[GetSetDescriptorType]: ... def isdatadescriptor(object: object) -> TypeGuard[_SupportsSet[Any, Any] | _SupportsDelete[Any]]: ... @@ -205,21 +207,26 @@ class _ParameterKind(enum.IntEnum): VAR_KEYWORD: int if sys.version_info >= (3, 8): - description: str + @property + def description(self) -> str: ... class Parameter: def __init__(self, name: str, kind: _ParameterKind, *, default: Any = ..., annotation: Any = ...) -> None: ... empty = _empty - name: str - default: Any - annotation: Any - kind: _ParameterKind POSITIONAL_ONLY: ClassVar[Literal[_ParameterKind.POSITIONAL_ONLY]] POSITIONAL_OR_KEYWORD: ClassVar[Literal[_ParameterKind.POSITIONAL_OR_KEYWORD]] VAR_POSITIONAL: ClassVar[Literal[_ParameterKind.VAR_POSITIONAL]] KEYWORD_ONLY: ClassVar[Literal[_ParameterKind.KEYWORD_ONLY]] VAR_KEYWORD: ClassVar[Literal[_ParameterKind.VAR_KEYWORD]] + @property + def name(self) -> str: ... + @property + def default(self) -> Any: ... + @property + def kind(self) -> _ParameterKind: ... + @property + def annotation(self) -> Any: ... def replace( self: Self, *, @@ -231,7 +238,7 @@ class Parameter: class BoundArguments: arguments: OrderedDict[str, Any] - args: Tuple[Any, ...] + args: tuple[Any, ...] kwargs: dict[str, Any] signature: Signature def __init__(self, signature: Signature, arguments: OrderedDict[str, Any]) -> None: ... @@ -247,25 +254,26 @@ class BoundArguments: def getclasstree(classes: list[type], unique: bool = ...) -> list[Any]: ... def walktree(classes: list[type], children: dict[Type[Any], list[type]], parent: Type[Any] | None) -> list[Any]: ... -class ArgSpec(NamedTuple): - args: list[str] - varargs: str | None - keywords: str | None - defaults: Tuple[Any, ...] - class Arguments(NamedTuple): args: list[str] varargs: str | None varkw: str | None def getargs(co: CodeType) -> Arguments: ... -def getargspec(func: object) -> ArgSpec: ... + +if sys.version_info < (3, 11): + class ArgSpec(NamedTuple): + args: list[str] + varargs: str | None + keywords: str | None + defaults: tuple[Any, ...] + def getargspec(func: object) -> ArgSpec: ... class FullArgSpec(NamedTuple): args: list[str] varargs: str | None varkw: str | None - defaults: Tuple[Any, ...] | None + defaults: tuple[Any, ...] | None kwonlyargs: list[str] kwonlydefaults: dict[str, Any] | None annotations: dict[str, Any] @@ -281,21 +289,24 @@ class ArgInfo(NamedTuple): def getargvalues(frame: FrameType) -> ArgInfo: ... def formatannotation(annotation: object, base_module: str | None = ...) -> str: ... def formatannotationrelativeto(object: object) -> Callable[[object], str]: ... -def formatargspec( - args: list[str], - varargs: str | None = ..., - varkw: str | None = ..., - defaults: Tuple[Any, ...] | None = ..., - kwonlyargs: Sequence[str] | None = ..., - kwonlydefaults: dict[str, Any] | None = ..., - annotations: dict[str, Any] = ..., - formatarg: Callable[[str], str] = ..., - formatvarargs: Callable[[str], str] = ..., - formatvarkw: Callable[[str], str] = ..., - formatvalue: Callable[[Any], str] = ..., - formatreturns: Callable[[Any], str] = ..., - formatannotation: Callable[[Any], str] = ..., -) -> str: ... + +if sys.version_info < (3, 11): + def formatargspec( + args: list[str], + varargs: str | None = ..., + varkw: str | None = ..., + defaults: tuple[Any, ...] | None = ..., + kwonlyargs: Sequence[str] | None = ..., + kwonlydefaults: dict[str, Any] | None = ..., + annotations: dict[str, Any] = ..., + formatarg: Callable[[str], str] = ..., + formatvarargs: Callable[[str], str] = ..., + formatvarkw: Callable[[str], str] = ..., + formatvalue: Callable[[Any], str] = ..., + formatreturns: Callable[[Any], str] = ..., + formatannotation: Callable[[Any], str] = ..., + ) -> str: ... + def formatargvalues( args: list[str], varargs: str | None, @@ -306,7 +317,7 @@ def formatargvalues( formatvarkw: Callable[[str], str] | None = ..., formatvalue: Callable[[Any], str] | None = ..., ) -> str: ... -def getmro(cls: type) -> Tuple[type, ...]: ... +def getmro(cls: type) -> tuple[type, ...]: ... def getcallargs(__func: Callable[..., Any], *args: Any, **kwds: Any) -> dict[str, Any]: ... class ClosureVars(NamedTuple): @@ -327,7 +338,7 @@ class Traceback(NamedTuple): lineno: int function: str code_context: list[str] | None - index: int | None # type: ignore + index: int | None # type: ignore[assignment] class FrameInfo(NamedTuple): frame: FrameType @@ -335,7 +346,7 @@ class FrameInfo(NamedTuple): lineno: int function: str code_context: list[str] | None - index: int | None # type: ignore + index: int | None # type: ignore[assignment] def getframeinfo(frame: FrameType | TracebackType, context: int = ...) -> Traceback: ... def getouterframes(frame: Any, context: int = ...) -> list[FrameInfo]: ... @@ -355,26 +366,25 @@ def getattr_static(obj: object, attr: str, default: Any | None = ...) -> Any: .. # Current State of Generators and Coroutines # -# TODO In the next two blocks of code, can we be more specific regarding the -# type of the "enums"? +GEN_CREATED: Literal["GEN_CREATED"] +GEN_RUNNING: Literal["GEN_RUNNING"] +GEN_SUSPENDED: Literal["GEN_SUSPENDED"] +GEN_CLOSED: Literal["GEN_CLOSED"] -GEN_CREATED: str -GEN_RUNNING: str -GEN_SUSPENDED: str -GEN_CLOSED: str +def getgeneratorstate( + generator: Generator[Any, Any, Any] +) -> Literal["GEN_CREATED", "GEN_RUNNING", "GEN_SUSPENDED", "GEN_CLOSED"]: ... -def getgeneratorstate(generator: Generator[Any, Any, Any]) -> str: ... +CORO_CREATED: Literal["CORO_CREATED"] +CORO_RUNNING: Literal["CORO_RUNNING"] +CORO_SUSPENDED: Literal["CORO_SUSPENDED"] +CORO_CLOSED: Literal["CORO_CLOSED"] -CORO_CREATED: str -CORO_RUNNING: str -CORO_SUSPENDED: str -CORO_CLOSED: str -# TODO can we be more specific than "object"? -def getcoroutinestate(coroutine: object) -> str: ... +def getcoroutinestate( + coroutine: Coroutine[Any, Any, Any] +) -> Literal["CORO_CREATED", "CORO_RUNNING", "CORO_SUSPENDED", "CORO_CLOSED"]: ... def getgeneratorlocals(generator: Generator[Any, Any, Any]) -> dict[str, Any]: ... - -# TODO can we be more specific than "object"? -def getcoroutinelocals(coroutine: object) -> dict[str, Any]: ... +def getcoroutinelocals(coroutine: Coroutine[Any, Any, Any]) -> dict[str, Any]: ... # Create private type alias to avoid conflict with symbol of same # name created in Attribute class. diff --git a/mypy/typeshed/stdlib/io.pyi b/mypy/typeshed/stdlib/io.pyi index 6342907004d5..50452917c6f3 100644 --- a/mypy/typeshed/stdlib/io.pyi +++ b/mypy/typeshed/stdlib/io.pyi @@ -4,7 +4,7 @@ import sys from _typeshed import ReadableBuffer, Self, StrOrBytesPath, WriteableBuffer from os import _Opener from types import TracebackType -from typing import IO, Any, BinaryIO, Callable, Iterable, Iterator, TextIO, Tuple, Type +from typing import IO, Any, BinaryIO, Callable, Iterable, Iterator, TextIO, Type DEFAULT_BUFFER_SIZE: int @@ -65,7 +65,7 @@ class BufferedIOBase(IOBase): class FileIO(RawIOBase, BinaryIO): mode: str - name: StrOrBytesPath | int # type: ignore + name: StrOrBytesPath | int # type: ignore[assignment] def __init__( self, file: StrOrBytesPath | int, mode: str = ..., closefd: bool = ..., opener: _Opener | None = ... ) -> None: ... @@ -87,7 +87,7 @@ class BytesIO(BufferedIOBase, BinaryIO): if sys.version_info >= (3, 7): def read1(self, __size: int | None = ...) -> bytes: ... else: - def read1(self, __size: int | None) -> bytes: ... # type: ignore + def read1(self, __size: int | None) -> bytes: ... # type: ignore[override] class BufferedReader(BufferedIOBase, BinaryIO): def __enter__(self: Self) -> Self: ... @@ -96,7 +96,7 @@ class BufferedReader(BufferedIOBase, BinaryIO): if sys.version_info >= (3, 7): def read1(self, __size: int = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... # type: ignore + def read1(self, __size: int) -> bytes: ... # type: ignore[override] class BufferedWriter(BufferedIOBase, BinaryIO): def __enter__(self: Self) -> Self: ... @@ -110,7 +110,7 @@ class BufferedRandom(BufferedReader, BufferedWriter): if sys.version_info >= (3, 7): def read1(self, __size: int = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... # type: ignore + def read1(self, __size: int) -> bytes: ... # type: ignore[override] class BufferedRWPair(BufferedIOBase): def __init__(self, reader: RawIOBase, writer: RawIOBase, buffer_size: int = ...) -> None: ... @@ -119,14 +119,14 @@ class BufferedRWPair(BufferedIOBase): class TextIOBase(IOBase): encoding: str errors: str | None - newlines: str | Tuple[str, ...] | None - def __iter__(self) -> Iterator[str]: ... # type: ignore - def __next__(self) -> str: ... # type: ignore + newlines: str | tuple[str, ...] | None + 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 - def readline(self, __size: int = ...) -> str: ... # type: ignore - def readlines(self, __hint: int = ...) -> list[str]: ... # type: ignore + def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore[override] + def readline(self, __size: int = ...) -> str: ... # type: ignore[override] + def readlines(self, __hint: int = ...) -> list[str]: ... # type: ignore[override] def read(self, __size: int | None = ...) -> str: ... def tell(self) -> int: ... @@ -160,11 +160,11 @@ class TextIOWrapper(TextIOBase, TextIO): ) -> None: ... # These are inherited from TextIOBase, but must exist in the stub to satisfy mypy. def __enter__(self: Self) -> Self: ... - def __iter__(self) -> Iterator[str]: ... # type: ignore - def __next__(self) -> str: ... # type: ignore - def writelines(self, __lines: Iterable[str]) -> None: ... # type: ignore - def readline(self, __size: int = ...) -> str: ... # type: ignore - def readlines(self, __hint: int = ...) -> list[str]: ... # type: ignore + 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 = ...) -> str: ... # type: ignore[override] + def readlines(self, __hint: int = ...) -> list[str]: ... # type: ignore[override] def seek(self, __cookie: int, __whence: int = ...) -> int: ... class StringIO(TextIOWrapper): @@ -179,4 +179,4 @@ class IncrementalNewlineDecoder(codecs.IncrementalDecoder): def __init__(self, decoder: codecs.IncrementalDecoder | None, translate: bool, errors: str = ...) -> None: ... def decode(self, input: bytes | str, final: bool = ...) -> str: ... @property - def newlines(self) -> str | Tuple[str, ...] | None: ... + def newlines(self) -> str | tuple[str, ...] | None: ... diff --git a/mypy/typeshed/stdlib/ipaddress.pyi b/mypy/typeshed/stdlib/ipaddress.pyi index 0ded1ef19b47..1cfd9a7c9378 100644 --- a/mypy/typeshed/stdlib/ipaddress.pyi +++ b/mypy/typeshed/stdlib/ipaddress.pyi @@ -9,9 +9,9 @@ _A = TypeVar("_A", IPv4Address, IPv6Address) _N = TypeVar("_N", IPv4Network, IPv6Network) _T = TypeVar("_T") -def ip_address(address: object) -> Any: ... # morally IPv4Address | IPv6Address -def ip_network(address: object, strict: bool = ...) -> Any: ... # morally IPv4Network | IPv6Network -def ip_interface(address: object) -> Any: ... # morally IPv4Interface | IPv6Interface +def ip_address(address: object) -> IPv4Address | IPv6Address: ... +def ip_network(address: object, strict: bool = ...) -> IPv4Network | IPv6Network: ... +def ip_interface(address: object) -> IPv4Interface | IPv6Interface: ... class _IPAddressBase: def __eq__(self, other: Any) -> bool: ... @@ -84,7 +84,7 @@ class _BaseNetwork(_IPAddressBase, Container[_A], Iterable[_A], Generic[_A]): def max_prefixlen(self) -> int: ... @property def num_addresses(self) -> int: ... - def overlaps(self, other: _BaseNetwork[_A]) -> bool: ... + def overlaps(self, other: _BaseNetwork[IPv4Address] | _BaseNetwork[IPv6Address]) -> bool: ... @property def prefixlen(self) -> int: ... if sys.version_info >= (3, 7): @@ -127,6 +127,9 @@ class IPv6Address(_BaseAddress): def sixtofour(self) -> IPv4Address | None: ... @property def teredo(self) -> tuple[IPv4Address, IPv4Address] | None: ... + if sys.version_info >= (3, 9): + @property + def scope_id(self) -> str | None: ... class IPv6Network(_BaseNetwork[IPv6Address]): @property @@ -136,10 +139,16 @@ class IPv6Interface(IPv6Address, _BaseInterface[IPv6Address, IPv6Network]): ... def v4_int_to_packed(address: int) -> bytes: ... def v6_int_to_packed(address: int) -> bytes: ... + +# Third overload is technically incorrect, but convenient when first and last are return values of ip_address() @overload def summarize_address_range(first: IPv4Address, last: IPv4Address) -> Iterator[IPv4Network]: ... @overload def summarize_address_range(first: IPv6Address, last: IPv6Address) -> Iterator[IPv6Network]: ... +@overload +def summarize_address_range( + first: IPv4Address | IPv6Address, last: IPv4Address | IPv6Address +) -> Iterator[IPv4Network] | Iterator[IPv6Network]: ... def collapse_addresses(addresses: Iterable[_N]) -> Iterator[_N]: ... @overload def get_mixed_type_key(obj: _A) -> tuple[int, _A]: ... diff --git a/mypy/typeshed/stdlib/itertools.pyi b/mypy/typeshed/stdlib/itertools.pyi index 9d666d681781..a5a7f4f1b62f 100644 --- a/mypy/typeshed/stdlib/itertools.pyi +++ b/mypy/typeshed/stdlib/itertools.pyi @@ -9,7 +9,6 @@ from typing import ( SupportsComplex, SupportsFloat, SupportsInt, - Tuple, Type, TypeVar, Union, @@ -17,6 +16,9 @@ from typing import ( ) from typing_extensions import Literal, SupportsIndex +if sys.version_info >= (3, 9): + from types import GenericAlias + _T = TypeVar("_T") _S = TypeVar("_S") _N = TypeVar("_N", int, float, SupportsFloat, SupportsInt, SupportsIndex, SupportsComplex) @@ -67,6 +69,8 @@ class chain(Iterator[_T], Generic[_T]): @classmethod # We use Type and not Type[_S] to not lose the type inference from __iterable def from_iterable(cls: Type[Any], __iterable: Iterable[Iterable[_S]]) -> Iterator[_S]: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, __item: Any) -> GenericAlias: ... class compress(Iterator[_T], Generic[_T]): def __init__(self, data: Iterable[_T], selectors: Iterable[Any]) -> None: ... @@ -86,7 +90,7 @@ class filterfalse(Iterator[_T], Generic[_T]): _T1 = TypeVar("_T1") _T2 = TypeVar("_T2") -class groupby(Iterator[Tuple[_T, Iterator[_S]]], Generic[_T, _S]): +class groupby(Iterator[tuple[_T, Iterator[_S]]], Generic[_T, _S]): @overload def __new__(cls, iterable: Iterable[_T1], key: None = ...) -> groupby[_T1, _T1]: ... @overload @@ -112,7 +116,7 @@ class takewhile(Iterator[_T], Generic[_T]): def __iter__(self) -> Iterator[_T]: ... def __next__(self) -> _T: ... -def tee(__iterable: Iterable[_T], __n: int = ...) -> Tuple[Iterator[_T], ...]: ... +def tee(__iterable: Iterable[_T], __n: int = ...) -> tuple[Iterator[_T], ...]: ... class zip_longest(Iterator[Any]): def __init__(self, *p: Iterable[Any], fillvalue: Any = ...) -> None: ... @@ -165,18 +169,18 @@ class product(Iterator[_T_co], Generic[_T_co]): __iter6: Iterable[Any], __iter7: Iterable[Any], *iterables: Iterable[Any], - ) -> product[Tuple[Any, ...]]: ... + ) -> product[tuple[Any, ...]]: ... @overload - def __new__(cls, *iterables: Iterable[_T1], repeat: int) -> product[Tuple[_T1, ...]]: ... + 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[Any], repeat: int = ...) -> product[tuple[Any, ...]]: ... def __iter__(self) -> Iterator[_T_co]: ... def __next__(self) -> _T_co: ... -class permutations(Iterator[Tuple[_T, ...]], Generic[_T]): +class permutations(Iterator[tuple[_T, ...]], Generic[_T]): def __init__(self, iterable: Iterable[_T], r: int | None = ...) -> None: ... - def __iter__(self) -> Iterator[Tuple[_T, ...]]: ... - def __next__(self) -> Tuple[_T, ...]: ... + def __iter__(self) -> Iterator[tuple[_T, ...]]: ... + def __next__(self) -> tuple[_T, ...]: ... class combinations(Iterator[_T_co], Generic[_T_co]): @overload @@ -188,14 +192,14 @@ class combinations(Iterator[_T_co], Generic[_T_co]): @overload def __new__(cls, iterable: Iterable[_T], r: Literal[5]) -> combinations[tuple[_T, _T, _T, _T, _T]]: ... @overload - def __new__(cls, iterable: Iterable[_T], r: int) -> combinations[Tuple[_T, ...]]: ... + def __new__(cls, iterable: Iterable[_T], r: int) -> combinations[tuple[_T, ...]]: ... def __iter__(self) -> Iterator[_T_co]: ... def __next__(self) -> _T_co: ... -class combinations_with_replacement(Iterator[Tuple[_T, ...]], Generic[_T]): +class combinations_with_replacement(Iterator[tuple[_T, ...]], Generic[_T]): def __init__(self, iterable: Iterable[_T], r: int) -> None: ... - def __iter__(self) -> Iterator[Tuple[_T, ...]]: ... - def __next__(self) -> Tuple[_T, ...]: ... + def __iter__(self) -> Iterator[tuple[_T, ...]]: ... + def __next__(self) -> tuple[_T, ...]: ... if sys.version_info >= (3, 10): class pairwise(Iterator[_T_co], Generic[_T_co]): diff --git a/mypy/typeshed/stdlib/json/encoder.pyi b/mypy/typeshed/stdlib/json/encoder.pyi index 9557a96eee78..6dd74896e5a0 100644 --- a/mypy/typeshed/stdlib/json/encoder.pyi +++ b/mypy/typeshed/stdlib/json/encoder.pyi @@ -1,4 +1,10 @@ -from typing import Any, Callable, Iterator +from typing import Any, Callable, Iterator, Pattern + +ESCAPE: Pattern[str] +ESCAPE_ASCII: Pattern[str] +HAS_UTF8: Pattern[bytes] +ESCAPE_DCT: dict[str, str] +INFINITY: float def py_encode_basestring(s: str) -> str: ... # undocumented def py_encode_basestring_ascii(s: str) -> str: ... # undocumented diff --git a/mypy/typeshed/stdlib/lib2to3/pgen2/grammar.pyi b/mypy/typeshed/stdlib/lib2to3/pgen2/grammar.pyi index 48cb4eae916c..77cc6aec3d67 100644 --- a/mypy/typeshed/stdlib/lib2to3/pgen2/grammar.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pgen2/grammar.pyi @@ -1,10 +1,10 @@ from _typeshed import StrPath -from typing import Dict, List, Optional, Tuple, TypeVar +from typing import Optional, TypeVar _P = TypeVar("_P") -_Label = Tuple[int, Optional[str]] -_DFA = List[List[Tuple[int, int]]] -_DFAS = Tuple[_DFA, Dict[int, int]] +_Label = tuple[int, Optional[str]] +_DFA = list[list[tuple[int, int]]] +_DFAS = tuple[_DFA, dict[int, int]] class Grammar: symbol2number: dict[str, int] diff --git a/mypy/typeshed/stdlib/lib2to3/pgen2/token.pyi b/mypy/typeshed/stdlib/lib2to3/pgen2/token.pyi index c4ab376eca64..2f944c40a02c 100644 --- a/mypy/typeshed/stdlib/lib2to3/pgen2/token.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pgen2/token.pyi @@ -1,3 +1,5 @@ +import sys + ENDMARKER: int NAME: int NUMBER: int @@ -57,6 +59,8 @@ ATEQUAL: int AWAIT: int ASYNC: int ERRORTOKEN: int +if sys.version_info >= (3, 7): + COLONEQUAL: int N_TOKENS: int NT_OFFSET: int tok_name: dict[int, str] diff --git a/mypy/typeshed/stdlib/lib2to3/pgen2/tokenize.pyi b/mypy/typeshed/stdlib/lib2to3/pgen2/tokenize.pyi index e96a0d8c8eb3..3679caee9314 100644 --- a/mypy/typeshed/stdlib/lib2to3/pgen2/tokenize.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pgen2/tokenize.pyi @@ -1,9 +1,9 @@ from lib2to3.pgen2.token import * # noqa -from typing import Callable, Iterable, Iterator, Tuple +from typing import Callable, Iterable, Iterator -_Coord = Tuple[int, int] +_Coord = tuple[int, int] _TokenEater = Callable[[int, str, _Coord, _Coord, str], None] -_TokenInfo = Tuple[int, str, _Coord, _Coord, str] +_TokenInfo = tuple[int, str, _Coord, _Coord, str] class TokenError(Exception): ... class StopTokenizing(Exception): ... diff --git a/mypy/typeshed/stdlib/lib2to3/pytree.pyi b/mypy/typeshed/stdlib/lib2to3/pytree.pyi index eab82cbc200d..2ed9a2788d84 100644 --- a/mypy/typeshed/stdlib/lib2to3/pytree.pyi +++ b/mypy/typeshed/stdlib/lib2to3/pytree.pyi @@ -1,11 +1,11 @@ from lib2to3.pgen2.grammar import Grammar -from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, TypeVar, Union +from typing import Any, Callable, Iterator, Optional, TypeVar, Union _P = TypeVar("_P") _NL = Union[Node, Leaf] -_Context = Tuple[str, int, int] -_Results = Dict[str, _NL] -_RawNode = Tuple[int, str, _Context, Optional[List[_NL]]] +_Context = tuple[str, int, int] +_Results = dict[str, _NL] +_RawNode = tuple[int, str, _Context, Optional[list[_NL]]] _Convert = Callable[[Grammar, _RawNode], Any] HUGE: int diff --git a/mypy/typeshed/stdlib/linecache.pyi b/mypy/typeshed/stdlib/linecache.pyi index a66614bf6b37..e53d3efea5b2 100644 --- a/mypy/typeshed/stdlib/linecache.pyi +++ b/mypy/typeshed/stdlib/linecache.pyi @@ -1,7 +1,7 @@ -from typing import Any, Dict, List, Protocol, Tuple +from typing import Any, Protocol -_ModuleGlobals = Dict[str, Any] -_ModuleMetadata = Tuple[int, float, List[str], str] +_ModuleGlobals = dict[str, Any] +_ModuleMetadata = tuple[int, float, list[str], str] class _SourceLoader(Protocol): def __call__(self) -> str | None: ... diff --git a/mypy/typeshed/stdlib/locale.pyi b/mypy/typeshed/stdlib/locale.pyi index 1f80c8a62483..f3942102716a 100644 --- a/mypy/typeshed/stdlib/locale.pyi +++ b/mypy/typeshed/stdlib/locale.pyi @@ -4,7 +4,7 @@ import sys # as a type annotation or type alias. from builtins import str as _str from decimal import Decimal -from typing import Any, Callable, Iterable, Mapping, Sequence, Tuple +from typing import Any, Callable, Iterable, Mapping, Sequence CODESET: int D_T_FMT: int @@ -82,13 +82,13 @@ class Error(Exception): ... def setlocale(category: int, locale: _str | Iterable[_str] | None = ...) -> _str: ... def localeconv() -> Mapping[_str, int | _str | list[int]]: ... def nl_langinfo(__key: int) -> _str: ... -def getdefaultlocale(envvars: Tuple[_str, ...] = ...) -> tuple[_str | None, _str | None]: ... +def getdefaultlocale(envvars: tuple[_str, ...] = ...) -> tuple[_str | None, _str | None]: ... def getlocale(category: int = ...) -> Sequence[_str]: ... def getpreferredencoding(do_setlocale: bool = ...) -> _str: ... def normalize(localename: _str) -> _str: ... def resetlocale(category: int = ...) -> None: ... -def strcoll(string1: _str, string2: _str) -> int: ... -def strxfrm(string: _str) -> _str: ... +def strcoll(__os1: _str, __os2: _str) -> int: ... +def strxfrm(__string: _str) -> _str: ... def format(percent: _str, value: float | Decimal, grouping: bool = ..., monetary: bool = ..., *additional: Any) -> _str: ... if sys.version_info >= (3, 7): diff --git a/mypy/typeshed/stdlib/logging/__init__.pyi b/mypy/typeshed/stdlib/logging/__init__.pyi index c972559c9b60..442e79a9c6f3 100644 --- a/mypy/typeshed/stdlib/logging/__init__.pyi +++ b/mypy/typeshed/stdlib/logging/__init__.pyi @@ -1,17 +1,17 @@ import sys import threading -from _typeshed import StrPath, SupportsWrite +from _typeshed import Self, StrPath, SupportsWrite from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence from io import TextIOWrapper from string import Template from time import struct_time from types import FrameType, TracebackType -from typing import Any, ClassVar, Generic, Optional, Pattern, TextIO, Tuple, Type, TypeVar, Union, overload +from typing import Any, ClassVar, Generic, Optional, Pattern, TextIO, Type, TypeVar, Union, overload from typing_extensions import Literal -_SysExcInfoType = Union[Tuple[Type[BaseException], BaseException, Optional[TracebackType]], Tuple[None, None, None]] +_SysExcInfoType = Union[tuple[Type[BaseException], BaseException, Optional[TracebackType]], tuple[None, None, None]] _ExcInfoType = Union[None, bool, _SysExcInfoType, BaseException] -_ArgsType = Union[Tuple[object, ...], Mapping[str, object]] +_ArgsType = Union[tuple[object, ...], Mapping[str, object]] _FilterType = Union[Filter, Callable[[LogRecord], int]] _Level = Union[int, str] _FormatStyle = Literal["%", "{", "$"] @@ -27,14 +27,14 @@ def currentframe() -> FrameType: ... _levelToName: dict[int, str] _nameToLevel: dict[str, int] -class Filterer(object): +class Filterer: filters: list[Filter] def __init__(self) -> None: ... def addFilter(self, filter: _FilterType) -> None: ... def removeFilter(self, filter: _FilterType) -> None: ... def filter(self, record: LogRecord) -> bool: ... -class Manager(object): # undocumented +class Manager: # undocumented root: RootLogger disable: int emittedNoHandlerWarning: bool @@ -59,7 +59,7 @@ class Logger(Filterer): def setLevel(self, level: _Level) -> None: ... def isEnabledFor(self, level: int) -> bool: ... def getEffectiveLevel(self) -> int: ... - def getChild(self, suffix: str) -> Logger: ... + def getChild(self: Self, suffix: str) -> Self: ... # see python/typing#980 if sys.version_info >= (3, 8): def debug( self, @@ -285,7 +285,17 @@ class Formatter: else: default_msec_format: str - if sys.version_info >= (3, 8): + if sys.version_info >= (3, 10): + def __init__( + self, + fmt: str | None = ..., + datefmt: str | None = ..., + style: _FormatStyle = ..., + validate: bool = ..., + *, + defaults: Mapping[str, Any] | None = ..., + ) -> None: ... + elif sys.version_info >= (3, 8): def __init__( self, fmt: str | None = ..., datefmt: str | None = ..., style: _FormatStyle = ..., validate: bool = ... ) -> None: ... @@ -326,6 +336,7 @@ class LogRecord: lineno: int module: str msecs: float + # Only created when logging.Formatter.format is called. See #6132. message: str msg: str name: str @@ -357,7 +368,7 @@ class LoggerAdapter(Generic[_L]): manager: Manager # undocumented if sys.version_info >= (3, 10): extra: Mapping[str, object] | None - def __init__(self, logger: _L, extra: Mapping[str, object] | None) -> None: ... + def __init__(self, logger: _L, extra: Mapping[str, object] | None = ...) -> None: ... else: extra: Mapping[str, object] def __init__(self, logger: _L, extra: Mapping[str, object]) -> None: ... @@ -738,14 +749,17 @@ class RootLogger(Logger): root: RootLogger -class PercentStyle(object): # undocumented +class PercentStyle: # undocumented default_format: str asctime_format: str asctime_search: str if sys.version_info >= (3, 8): validation_pattern: Pattern[str] _fmt: str - def __init__(self, fmt: str) -> None: ... + if sys.version_info >= (3, 10): + def __init__(self, fmt: str, *, defaults: Mapping[str, Any] | None = ...) -> None: ... + else: + def __init__(self, fmt: str) -> None: ... def usesTime(self) -> bool: ... if sys.version_info >= (3, 8): def validate(self) -> None: ... diff --git a/mypy/typeshed/stdlib/logging/handlers.pyi b/mypy/typeshed/stdlib/logging/handlers.pyi index 5be624872a14..50d6d0583556 100644 --- a/mypy/typeshed/stdlib/logging/handlers.pyi +++ b/mypy/typeshed/stdlib/logging/handlers.pyi @@ -128,7 +128,7 @@ class SocketHandler(Handler): def createSocket(self) -> None: ... class DatagramHandler(SocketHandler): - def makeSocket(self) -> socket: ... # type: ignore + def makeSocket(self) -> socket: ... # type: ignore[override] class SysLogHandler(Handler): LOG_EMERG: int diff --git a/mypy/typeshed/stdlib/lzma.pyi b/mypy/typeshed/stdlib/lzma.pyi index e1da3024c4ac..e4bd977d7eab 100644 --- a/mypy/typeshed/stdlib/lzma.pyi +++ b/mypy/typeshed/stdlib/lzma.pyi @@ -41,7 +41,7 @@ PRESET_EXTREME: int # from _lzma.c @final -class LZMADecompressor(object): +class LZMADecompressor: def __init__(self, format: int | None = ..., memlimit: int | None = ..., filters: _FilterChain | None = ...) -> None: ... def decompress(self, data: bytes, max_length: int = ...) -> bytes: ... @property @@ -55,7 +55,7 @@ class LZMADecompressor(object): # from _lzma.c @final -class LZMACompressor(object): +class LZMACompressor: def __init__( self, format: int | None = ..., check: int = ..., preset: int | None = ..., filters: _FilterChain | None = ... ) -> None: ... diff --git a/mypy/typeshed/stdlib/mailcap.pyi b/mypy/typeshed/stdlib/mailcap.pyi index 9eaa771ed3d3..56218d1370fe 100644 --- a/mypy/typeshed/stdlib/mailcap.pyi +++ b/mypy/typeshed/stdlib/mailcap.pyi @@ -1,6 +1,6 @@ -from typing import Dict, Mapping, Sequence, Union +from typing import Mapping, Sequence, Union -_Cap = Dict[str, Union[str, int]] +_Cap = dict[str, Union[str, int]] def findmatch( caps: Mapping[str, list[_Cap]], MIMEtype: str, key: str = ..., filename: str = ..., plist: Sequence[str] = ... diff --git a/mypy/typeshed/stdlib/math.pyi b/mypy/typeshed/stdlib/math.pyi index f92a3d94f978..d5e6f99dfa68 100644 --- a/mypy/typeshed/stdlib/math.pyi +++ b/mypy/typeshed/stdlib/math.pyi @@ -21,6 +21,10 @@ 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 ceil(__x: _SupportsFloatOrIndex) -> int: ... if sys.version_info >= (3, 8): @@ -99,7 +103,7 @@ def pow(__x: _SupportsFloatOrIndex, __y: _SupportsFloatOrIndex) -> float: ... if sys.version_info >= (3, 8): @overload - def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = ...) -> int: ... # type: ignore + def prod(__iterable: Iterable[SupportsIndex], *, start: SupportsIndex = ...) -> int: ... # type: ignore[misc] @overload def prod(__iterable: Iterable[_SupportsFloatOrIndex], *, start: _SupportsFloatOrIndex = ...) -> float: ... diff --git a/mypy/typeshed/stdlib/mimetypes.pyi b/mypy/typeshed/stdlib/mimetypes.pyi index 90c87d2cf385..8f51c1580eec 100644 --- a/mypy/typeshed/stdlib/mimetypes.pyi +++ b/mypy/typeshed/stdlib/mimetypes.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import StrPath -from typing import IO, Sequence, Tuple +from typing import IO, Sequence if sys.version_info >= (3, 8): def guess_type(url: StrPath, strict: bool = ...) -> tuple[str | None, str | None]: ... @@ -26,9 +26,12 @@ class MimeTypes: encodings_map: dict[str, str] types_map: tuple[dict[str, str], dict[str, str]] types_map_inv: tuple[dict[str, str], dict[str, str]] - def __init__(self, filenames: Tuple[str, ...] = ..., strict: bool = ...) -> None: ... + def __init__(self, filenames: tuple[str, ...] = ..., strict: bool = ...) -> None: ... def guess_extension(self, type: str, strict: bool = ...) -> str | None: ... - def guess_type(self, url: str, strict: bool = ...) -> tuple[str | None, str | None]: ... + if sys.version_info >= (3, 8): + def guess_type(self, url: StrPath, strict: bool = ...) -> tuple[str | None, str | None]: ... + else: + def guess_type(self, url: str, strict: bool = ...) -> tuple[str | None, str | None]: ... def guess_all_extensions(self, type: str, strict: bool = ...) -> list[str]: ... def read(self, filename: str, strict: bool = ...) -> None: ... def readfp(self, fp: IO[str], strict: bool = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/mmap.pyi b/mypy/typeshed/stdlib/mmap.pyi index 4dd8f8cd2cdd..b79ab92f0c87 100644 --- a/mypy/typeshed/stdlib/mmap.pyi +++ b/mypy/typeshed/stdlib/mmap.pyi @@ -1,6 +1,7 @@ import sys from _typeshed import ReadableBuffer -from typing import ContextManager, Iterable, Iterator, NoReturn, Sized, overload +from contextlib import AbstractContextManager +from typing import Iterable, Iterator, NoReturn, Sized, overload ACCESS_DEFAULT: int ACCESS_READ: int @@ -24,7 +25,7 @@ if sys.platform != "win32": PAGESIZE: int -class mmap(ContextManager[mmap], Iterable[int], Sized): +class mmap(AbstractContextManager[mmap], Iterable[int], Sized): if sys.platform == "win32": def __init__(self, fileno: int, length: int, tagname: str | None = ..., access: int = ..., offset: int = ...) -> None: ... else: diff --git a/mypy/typeshed/stdlib/modulefinder.pyi b/mypy/typeshed/stdlib/modulefinder.pyi index e77a108e9525..3e7694ccffc9 100644 --- a/mypy/typeshed/stdlib/modulefinder.pyi +++ b/mypy/typeshed/stdlib/modulefinder.pyi @@ -1,6 +1,6 @@ import sys from types import CodeType -from typing import IO, Any, Container, Iterable, Iterator, Sequence, Tuple +from typing import IO, Any, Container, Iterable, Iterator, Sequence LOAD_CONST: int # undocumented IMPORT_NAME: int # undocumented @@ -62,7 +62,7 @@ class ModuleFinder: def find_all_submodules(self, m: Module) -> Iterable[str]: ... # undocumented def import_module(self, partname: str, fqname: str, parent: Module) -> Module | None: ... # undocumented def load_module(self, fqname: str, fp: IO[str], pathname: str, file_info: tuple[str, str, str]) -> Module: ... # undocumented - def scan_opcodes(self, co: CodeType) -> Iterator[tuple[str, Tuple[Any, ...]]]: ... # undocumented + def scan_opcodes(self, co: CodeType) -> Iterator[tuple[str, tuple[Any, ...]]]: ... # undocumented def scan_code(self, co: CodeType, m: Module) -> None: ... # undocumented def load_package(self, fqname: str, pathname: str) -> Module: ... # undocumented def add_module(self, fqname: str) -> Module: ... # undocumented diff --git a/mypy/typeshed/stdlib/msilib/__init__.pyi b/mypy/typeshed/stdlib/msilib/__init__.pyi index 4e1a7e6a7c02..b5866492a097 100644 --- a/mypy/typeshed/stdlib/msilib/__init__.pyi +++ b/mypy/typeshed/stdlib/msilib/__init__.pyi @@ -1,6 +1,6 @@ import sys from types import ModuleType -from typing import Any, Container, Iterable, Sequence, Tuple, Type +from typing import Any, Container, Iterable, Sequence, Type from typing_extensions import Literal if sys.platform == "win32": @@ -37,7 +37,7 @@ if sys.platform == "win32": seqno: int | Type[_Unspecified] = ..., cond: str | Type[_Unspecified] = ..., ) -> None: ... - def add_data(db: _Database, table: str, values: Iterable[Tuple[Any, ...]]) -> None: ... + def add_data(db: _Database, table: str, values: Iterable[tuple[Any, ...]]) -> None: ... def add_stream(db: _Database, name: str, path: str) -> None: ... def init_database( name: str, schema: ModuleType, ProductName: str, ProductCode: str, ProductVersion: str, Manufacturer: str diff --git a/mypy/typeshed/stdlib/msilib/sequence.pyi b/mypy/typeshed/stdlib/msilib/sequence.pyi index 123d232886f7..87dff754009d 100644 --- a/mypy/typeshed/stdlib/msilib/sequence.pyi +++ b/mypy/typeshed/stdlib/msilib/sequence.pyi @@ -1,9 +1,9 @@ import sys -from typing import List, Optional, Tuple +from typing import Optional if sys.platform == "win32": - _SequenceType = List[Tuple[str, Optional[str], int]] + _SequenceType = list[tuple[str, Optional[str], int]] AdminExecuteSequence: _SequenceType AdminUISequence: _SequenceType diff --git a/mypy/typeshed/stdlib/multiprocessing/connection.pyi b/mypy/typeshed/stdlib/multiprocessing/connection.pyi index 56ea5c7c0b0b..56db4594edc0 100644 --- a/mypy/typeshed/stdlib/multiprocessing/connection.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/connection.pyi @@ -2,13 +2,13 @@ import socket import sys import types from _typeshed import Self -from typing import Any, Iterable, Tuple, Type, Union +from typing import Any, Iterable, Type, Union if sys.version_info >= (3, 8): from typing import SupportsIndex # https://docs.python.org/3/library/multiprocessing.html#address-formats -_Address = Union[str, Tuple[str, int]] +_Address = Union[str, tuple[str, int]] class _ConnectionBase: if sys.version_info >= (3, 8): diff --git a/mypy/typeshed/stdlib/multiprocessing/context.pyi b/mypy/typeshed/stdlib/multiprocessing/context.pyi index e65a387819bc..83e1b7884efc 100644 --- a/mypy/typeshed/stdlib/multiprocessing/context.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/context.pyi @@ -19,7 +19,7 @@ class BufferTooShort(ProcessError): ... class TimeoutError(ProcessError): ... class AuthenticationError(ProcessError): ... -class BaseContext(object): +class BaseContext: Process: Type[BaseProcess] ProcessError: Type[Exception] BufferTooShort: Type[Exception] diff --git a/mypy/typeshed/stdlib/multiprocessing/dummy/connection.pyi b/mypy/typeshed/stdlib/multiprocessing/dummy/connection.pyi index 4ef3d095911f..9500a38364f0 100644 --- a/mypy/typeshed/stdlib/multiprocessing/dummy/connection.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/dummy/connection.pyi @@ -1,13 +1,13 @@ from _typeshed import Self from queue import Queue from types import TracebackType -from typing import Any, Tuple, Type, Union +from typing import Any, Type, Union families: list[None] -_Address = Union[str, Tuple[str, int]] +_Address = Union[str, tuple[str, int]] -class Connection(object): +class Connection: _in: Any _out: Any recv: Any @@ -22,7 +22,7 @@ class Connection(object): def close(self) -> None: ... def poll(self, timeout: float = ...) -> bool: ... -class Listener(object): +class Listener: _backlog_queue: Queue[Any] | None @property def address(self) -> Queue[Any] | None: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/managers.pyi b/mypy/typeshed/stdlib/multiprocessing/managers.pyi index 22a33f226c0b..79310614efc1 100644 --- a/mypy/typeshed/stdlib/multiprocessing/managers.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/managers.pyi @@ -1,9 +1,8 @@ -# NOTE: These are incomplete! - import queue import sys import threading -from typing import Any, AnyStr, Callable, ContextManager, Generic, Iterable, Mapping, Sequence, Tuple, TypeVar +from contextlib import AbstractContextManager +from typing import Any, AnyStr, Callable, Generic, Iterable, Mapping, Sequence, TypeVar from .connection import Connection from .context import BaseContext @@ -28,7 +27,7 @@ class Namespace: _Namespace = Namespace -class Token(object): +class Token: typeid: str | bytes | None address: tuple[str | bytes, int] id: str | bytes | int | None @@ -37,7 +36,7 @@ class Token(object): def __getstate__(self) -> tuple[str | bytes | None, tuple[str | bytes, int], str | bytes | int | None]: ... def __setstate__(self, state: tuple[str | bytes | None, tuple[str | bytes, int], str | bytes | int | None]) -> None: ... -class BaseProxy(object): +class BaseProxy: _address_to_local: dict[Any, Any] _mutex: Any def __init__( @@ -51,7 +50,7 @@ class BaseProxy(object): manager_owned: bool = ..., ) -> None: ... def __deepcopy__(self, memo: Any | None) -> Any: ... - def _callmethod(self, methodname: str, args: Tuple[Any, ...] = ..., kwds: dict[Any, Any] = ...) -> None: ... + def _callmethod(self, methodname: str, args: tuple[Any, ...] = ..., kwds: dict[Any, Any] = ...) -> None: ... def _getvalue(self) -> Any: ... def __reduce__(self) -> tuple[Any, tuple[Any, Any, str, dict[Any, Any]]]: ... @@ -71,7 +70,7 @@ class Server: def serve_forever(self) -> None: ... def accept_connection(self, c: Connection, name: str) -> None: ... -class BaseManager(ContextManager[BaseManager]): +class BaseManager(AbstractContextManager[BaseManager]): def __init__( self, address: Any | None = ..., authkey: bytes | None = ..., serializer: str = ..., ctx: BaseContext | None = ... ) -> None: ... @@ -97,7 +96,7 @@ class BaseManager(ContextManager[BaseManager]): _dict = dict _list = list -class SyncManager(BaseManager, ContextManager[SyncManager]): +class SyncManager(BaseManager, AbstractContextManager[SyncManager]): def BoundedSemaphore(self, value: Any = ...) -> threading.BoundedSemaphore: ... def Condition(self, lock: Any = ...) -> threading.Condition: ... def Event(self) -> threading.Event: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/pool.pyi b/mypy/typeshed/stdlib/multiprocessing/pool.pyi index 75583aae8012..518e4b7364d7 100644 --- a/mypy/typeshed/stdlib/multiprocessing/pool.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/pool.pyi @@ -1,10 +1,14 @@ import sys from _typeshed import Self -from typing import Any, Callable, ContextManager, Generic, Iterable, Iterator, List, Mapping, TypeVar +from contextlib import AbstractContextManager +from typing import Any, Callable, Generic, Iterable, Iterator, Mapping, TypeVar +from typing_extensions import Literal if sys.version_info >= (3, 9): from types import GenericAlias +__all__ = ["Pool", "ThreadPool"] + _PT = TypeVar("_PT", bound=Pool) _S = TypeVar("_S") _T = TypeVar("_T") @@ -31,7 +35,7 @@ class ApplyResult(Generic[_T]): # alias created during issue #17805 AsyncResult = ApplyResult -class MapResult(ApplyResult[List[_T]]): +class MapResult(ApplyResult[list[_T]]): if sys.version_info >= (3, 8): def __init__( self, @@ -62,7 +66,7 @@ class IMapIterator(Iterator[_T]): class IMapUnorderedIterator(IMapIterator[_T]): ... -class Pool(ContextManager[Pool]): +class Pool(AbstractContextManager[Pool]): def __init__( self, processes: int | None = ..., @@ -107,18 +111,18 @@ class Pool(ContextManager[Pool]): def join(self) -> None: ... def __enter__(self: Self) -> Self: ... -class ThreadPool(Pool, ContextManager[ThreadPool]): +class ThreadPool(Pool, AbstractContextManager[ThreadPool]): def __init__( self, processes: int | None = ..., initializer: Callable[..., Any] | None = ..., initargs: Iterable[Any] = ... ) -> None: ... # undocumented if sys.version_info >= (3, 8): - INIT: str - RUN: str - CLOSE: str - TERMINATE: str + INIT: Literal["INIT"] + RUN: Literal["RUN"] + CLOSE: Literal["CLOSE"] + TERMINATE: Literal["TERMINATE"] else: - RUN: int - CLOSE: int - TERMINATE: int + RUN: Literal[0] + CLOSE: Literal[1] + TERMINATE: Literal[2] diff --git a/mypy/typeshed/stdlib/multiprocessing/process.pyi b/mypy/typeshed/stdlib/multiprocessing/process.pyi index 32c22d19f6e5..4746c78b1b4d 100644 --- a/mypy/typeshed/stdlib/multiprocessing/process.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/process.pyi @@ -1,17 +1,17 @@ import sys -from typing import Any, Callable, Mapping, Tuple +from typing import Any, Callable, Mapping class BaseProcess: name: str daemon: bool authkey: bytes - _identity: Tuple[int, ...] # undocumented + _identity: tuple[int, ...] # undocumented def __init__( self, group: None = ..., target: Callable[..., Any] | None = ..., name: str | None = ..., - args: Tuple[Any, ...] = ..., + args: tuple[Any, ...] = ..., kwargs: Mapping[str, Any] = ..., *, daemon: bool | None = ..., diff --git a/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi b/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi index 6ffc2542087a..1b51da38bc43 100644 --- a/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/shared_memory.pyi @@ -1,5 +1,5 @@ import sys -from typing import Any, Generic, Iterable, Tuple, TypeVar +from typing import Any, Generic, Iterable, TypeVar if sys.version_info >= (3, 9): from types import GenericAlias @@ -23,7 +23,7 @@ if sys.version_info >= (3, 8): def __init__(self, sequence: Iterable[_SLT] | None = ..., *, name: str | None = ...) -> None: ... def __getitem__(self, position: int) -> _SLT: ... def __setitem__(self, position: int, value: _SLT) -> None: ... - def __reduce__(self: _S) -> tuple[_S, Tuple[_SLT, ...]]: ... + def __reduce__(self: _S) -> tuple[_S, tuple[_SLT, ...]]: ... def __len__(self) -> int: ... @property def format(self) -> str: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi index 1741885f13bf..c32c9aafe9a4 100644 --- a/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/synchronize.pyi @@ -1,7 +1,8 @@ import sys import threading +from contextlib import AbstractContextManager from multiprocessing.context import BaseContext -from typing import Any, Callable, ContextManager, Union +from typing import Any, Callable, Union _LockLike = Union[Lock, RLock] @@ -13,7 +14,7 @@ class Barrier(threading.Barrier): class BoundedSemaphore(Semaphore): def __init__(self, value: int = ..., *, ctx: BaseContext) -> None: ... -class Condition(ContextManager[bool]): +class Condition(AbstractContextManager[bool]): def __init__(self, lock: _LockLike | None = ..., *, ctx: BaseContext) -> None: ... if sys.version_info >= (3, 7): def notify(self, n: int = ...) -> None: ... @@ -25,7 +26,7 @@ class Condition(ContextManager[bool]): def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... def release(self) -> None: ... -class Event(ContextManager[bool]): +class Event(AbstractContextManager[bool]): def __init__(self, lock: _LockLike | None = ..., *, ctx: BaseContext) -> None: ... def is_set(self) -> bool: ... def set(self) -> None: ... @@ -42,6 +43,6 @@ class Semaphore(SemLock): def __init__(self, value: int = ..., *, ctx: BaseContext) -> None: ... # Not part of public API -class SemLock(ContextManager[bool]): +class SemLock(AbstractContextManager[bool]): def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... def release(self) -> None: ... diff --git a/mypy/typeshed/stdlib/netrc.pyi b/mypy/typeshed/stdlib/netrc.pyi index b8eac307740a..7c1c2068aff6 100644 --- a/mypy/typeshed/stdlib/netrc.pyi +++ b/mypy/typeshed/stdlib/netrc.pyi @@ -1,5 +1,5 @@ from _typeshed import StrOrBytesPath -from typing import Optional, Tuple +from typing import Optional class NetrcParseError(Exception): filename: str | None @@ -8,7 +8,7 @@ class NetrcParseError(Exception): def __init__(self, msg: str, filename: StrOrBytesPath | None = ..., lineno: int | None = ...) -> None: ... # (login, account, password) tuple -_NetrcTuple = Tuple[str, Optional[str], Optional[str]] +_NetrcTuple = tuple[str, Optional[str], Optional[str]] class netrc: hosts: dict[str, _NetrcTuple] diff --git a/mypy/typeshed/stdlib/nntplib.pyi b/mypy/typeshed/stdlib/nntplib.pyi index 508b5f679bc3..f0a0fb42da5c 100644 --- a/mypy/typeshed/stdlib/nntplib.pyi +++ b/mypy/typeshed/stdlib/nntplib.pyi @@ -3,7 +3,7 @@ import socket import ssl import sys from _typeshed import Self -from typing import IO, Any, Iterable, NamedTuple, Tuple, Union +from typing import IO, Any, Iterable, NamedTuple, Union _File = Union[IO[bytes], bytes, str, None] @@ -72,7 +72,7 @@ class _NNTPBase: def xhdr(self, hdr: str, str: Any, *, file: _File = ...) -> tuple[str, _list[str]]: ... def xover(self, start: int, end: int, *, file: _File = ...) -> tuple[str, _list[tuple[int, dict[str, str]]]]: ... def over( - self, message_spec: None | str | _list[Any] | Tuple[Any, ...], *, file: _File = ... + self, message_spec: None | str | _list[Any] | tuple[Any, ...], *, file: _File = ... ) -> tuple[str, _list[tuple[int, dict[str, str]]]]: ... if sys.version_info < (3, 9): def xgtitle(self, group: str, *, file: _File = ...) -> tuple[str, _list[tuple[str, str]]]: ... diff --git a/mypy/typeshed/stdlib/ntpath.pyi b/mypy/typeshed/stdlib/ntpath.pyi index 45d715704157..f691356cb702 100644 --- a/mypy/typeshed/stdlib/ntpath.pyi +++ b/mypy/typeshed/stdlib/ntpath.pyi @@ -48,11 +48,13 @@ altsep: str if sys.version_info < (3, 7) and sys.platform == "win32": def splitunc(p: AnyStr) -> tuple[AnyStr, AnyStr]: ... # deprecated -# Similar to posixpath, but have slightly different argument names +# 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, +# as the parameter name is different in posixpath.join() @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/operator.pyi b/mypy/typeshed/stdlib/operator.pyi index bb8e23733f87..180bd161c045 100644 --- a/mypy/typeshed/stdlib/operator.pyi +++ b/mypy/typeshed/stdlib/operator.pyi @@ -1,179 +1,51 @@ -from typing import ( - Any, - Container, - Generic, - Mapping, - MutableMapping, - MutableSequence, - Sequence, - SupportsAbs, - Tuple, - TypeVar, - overload, -) -from typing_extensions import final +import sys -_T = TypeVar("_T") -_T_co = TypeVar("_T_co", covariant=True) -_K = TypeVar("_K") -_V = TypeVar("_V") +from _operator import * -def lt(__a: Any, __b: Any) -> Any: ... -def le(__a: Any, __b: Any) -> Any: ... -def eq(__a: Any, __b: Any) -> Any: ... -def ne(__a: Any, __b: Any) -> Any: ... -def ge(__a: Any, __b: Any) -> Any: ... -def gt(__a: Any, __b: Any) -> Any: ... -def __lt__(a: Any, b: Any) -> Any: ... -def __le__(a: Any, b: Any) -> Any: ... -def __eq__(a: Any, b: Any) -> Any: ... -def __ne__(a: Any, b: Any) -> Any: ... -def __ge__(a: Any, b: Any) -> Any: ... -def __gt__(a: Any, b: Any) -> Any: ... -def not_(__a: Any) -> bool: ... -def __not__(a: Any) -> bool: ... -def truth(__a: Any) -> bool: ... -def is_(__a: Any, __b: Any) -> bool: ... -def is_not(__a: Any, __b: Any) -> bool: ... -def abs(__a: SupportsAbs[_T]) -> _T: ... -def __abs__(a: SupportsAbs[_T]) -> _T: ... -def add(__a: Any, __b: Any) -> Any: ... -def __add__(a: Any, b: Any) -> Any: ... -def and_(__a: Any, __b: Any) -> Any: ... -def __and__(a: Any, b: Any) -> Any: ... -def floordiv(__a: Any, __b: Any) -> Any: ... -def __floordiv__(a: Any, b: Any) -> Any: ... -def index(__a: Any) -> int: ... -def __index__(a: Any) -> int: ... -def inv(__a: Any) -> Any: ... -def invert(__a: Any) -> Any: ... -def __inv__(a: Any) -> Any: ... -def __invert__(a: Any) -> Any: ... -def lshift(__a: Any, __b: Any) -> Any: ... -def __lshift__(a: Any, b: Any) -> Any: ... -def mod(__a: Any, __b: Any) -> Any: ... -def __mod__(a: Any, b: Any) -> Any: ... -def mul(__a: Any, __b: Any) -> Any: ... -def __mul__(a: Any, b: Any) -> Any: ... -def matmul(__a: Any, __b: Any) -> Any: ... -def __matmul__(a: Any, b: Any) -> Any: ... -def neg(__a: Any) -> Any: ... -def __neg__(a: Any) -> Any: ... -def or_(__a: Any, __b: Any) -> Any: ... -def __or__(a: Any, b: Any) -> Any: ... -def pos(__a: Any) -> Any: ... -def __pos__(a: Any) -> Any: ... -def pow(__a: Any, __b: Any) -> Any: ... -def __pow__(a: Any, b: Any) -> Any: ... -def rshift(__a: Any, __b: Any) -> Any: ... -def __rshift__(a: Any, b: Any) -> Any: ... -def sub(__a: Any, __b: Any) -> Any: ... -def __sub__(a: Any, b: Any) -> Any: ... -def truediv(__a: Any, __b: Any) -> Any: ... -def __truediv__(a: Any, b: Any) -> Any: ... -def xor(__a: Any, __b: Any) -> Any: ... -def __xor__(a: Any, b: Any) -> Any: ... -def concat(__a: Sequence[_T], __b: Sequence[_T]) -> Sequence[_T]: ... -def __concat__(a: Sequence[_T], b: Sequence[_T]) -> Sequence[_T]: ... -def contains(__a: Container[Any], __b: Any) -> bool: ... -def __contains__(a: Container[Any], b: Any) -> bool: ... -def countOf(__a: Container[Any], __b: Any) -> int: ... -@overload -def delitem(__a: MutableSequence[Any], __b: int) -> None: ... -@overload -def delitem(__a: MutableSequence[Any], __b: slice) -> None: ... -@overload -def delitem(__a: MutableMapping[_K, Any], __b: _K) -> None: ... -@overload -def __delitem__(a: MutableSequence[Any], b: int) -> None: ... -@overload -def __delitem__(a: MutableSequence[Any], b: slice) -> None: ... -@overload -def __delitem__(a: MutableMapping[_K, Any], b: _K) -> None: ... -@overload -def getitem(__a: Sequence[_T], __b: int) -> _T: ... -@overload -def getitem(__a: Sequence[_T], __b: slice) -> Sequence[_T]: ... -@overload -def getitem(__a: Mapping[_K, _V], __b: _K) -> _V: ... -@overload -def __getitem__(a: Sequence[_T], b: int) -> _T: ... -@overload -def __getitem__(a: Sequence[_T], b: slice) -> Sequence[_T]: ... -@overload -def __getitem__(a: Mapping[_K, _V], b: _K) -> _V: ... -def indexOf(__a: Sequence[_T], __b: _T) -> int: ... -@overload -def setitem(__a: MutableSequence[_T], __b: int, __c: _T) -> None: ... -@overload -def setitem(__a: MutableSequence[_T], __b: slice, __c: Sequence[_T]) -> None: ... -@overload -def setitem(__a: MutableMapping[_K, _V], __b: _K, __c: _V) -> None: ... -@overload -def __setitem__(a: MutableSequence[_T], b: int, c: _T) -> None: ... -@overload -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: Any, __default: int = ...) -> int: ... -@final -class attrgetter(Generic[_T_co]): - @overload - def __new__(cls, attr: str) -> attrgetter[Any]: ... - @overload - 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]]: ... - @overload - 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: ... - -@final -class itemgetter(Generic[_T_co]): - @overload - def __new__(cls, item: Any) -> itemgetter[Any]: ... - @overload - def __new__(cls, item: Any, __item2: Any) -> itemgetter[tuple[Any, Any]]: ... - @overload - def __new__(cls, item: Any, __item2: Any, __item3: Any) -> itemgetter[tuple[Any, Any, Any]]: ... - @overload - def __new__(cls, item: Any, __item2: Any, __item3: Any, __item4: Any) -> itemgetter[tuple[Any, Any, Any, Any]]: ... - @overload - def __new__(cls, item: Any, *items: Any) -> itemgetter[Tuple[Any, ...]]: ... - def __call__(self, obj: Any) -> _T_co: ... - -@final -class methodcaller: - def __init__(self, __name: str, *args: Any, **kwargs: Any) -> None: ... - def __call__(self, obj: Any) -> Any: ... - -def iadd(__a: Any, __b: Any) -> Any: ... -def __iadd__(a: Any, b: Any) -> Any: ... -def iand(__a: Any, __b: Any) -> Any: ... -def __iand__(a: Any, b: Any) -> Any: ... -def iconcat(__a: Any, __b: Any) -> Any: ... -def __iconcat__(a: Any, b: Any) -> Any: ... -def ifloordiv(__a: Any, __b: Any) -> Any: ... -def __ifloordiv__(a: Any, b: Any) -> Any: ... -def ilshift(__a: Any, __b: Any) -> Any: ... -def __ilshift__(a: Any, b: Any) -> Any: ... -def imod(__a: Any, __b: Any) -> Any: ... -def __imod__(a: Any, b: Any) -> Any: ... -def imul(__a: Any, __b: Any) -> Any: ... -def __imul__(a: Any, b: Any) -> Any: ... -def imatmul(__a: Any, __b: Any) -> Any: ... -def __imatmul__(a: Any, b: Any) -> Any: ... -def ior(__a: Any, __b: Any) -> Any: ... -def __ior__(a: Any, b: Any) -> Any: ... -def ipow(__a: Any, __b: Any) -> Any: ... -def __ipow__(a: Any, b: Any) -> Any: ... -def irshift(__a: Any, __b: Any) -> Any: ... -def __irshift__(a: Any, b: Any) -> Any: ... -def isub(__a: Any, __b: Any) -> Any: ... -def __isub__(a: Any, b: Any) -> Any: ... -def itruediv(__a: Any, __b: Any) -> Any: ... -def __itruediv__(a: Any, b: Any) -> Any: ... -def ixor(__a: Any, __b: Any) -> Any: ... -def __ixor__(a: Any, b: Any) -> Any: ... +__lt__ = lt +__le__ = le +__eq__ = eq +__ne__ = ne +__ge__ = ge +__gt__ = gt +__not__ = not_ +__abs__ = abs +__add__ = add +__and__ = and_ +__floordiv__ = floordiv +__index__ = index +__inv__ = inv +__invert__ = invert +__lshift__ = lshift +__mod__ = mod +__mul__ = mul +__matmul__ = matmul +__neg__ = neg +__or__ = or_ +__pos__ = pos +__pow__ = pow +__rshift__ = rshift +__sub__ = sub +__truediv__ = truediv +__xor__ = xor +__concat__ = concat +__contains__ = contains +__delitem__ = delitem +__getitem__ = getitem +__setitem__ = setitem +__iadd__ = iadd +__iand__ = iand +__iconcat__ = iconcat +__ifloordiv__ = ifloordiv +__ilshift__ = ilshift +__imod__ = imod +__imul__ = imul +__imatmul__ = imatmul +__ior__ = ior +__ipow__ = ipow +__irshift__ = irshift +__isub__ = isub +__itruediv__ = itruediv +__ixor__ = ixor +if sys.version_info >= (3, 11): + __call__ = call diff --git a/mypy/typeshed/stdlib/optparse.pyi b/mypy/typeshed/stdlib/optparse.pyi index b8ea9d2fff38..416bc5446cc5 100644 --- a/mypy/typeshed/stdlib/optparse.pyi +++ b/mypy/typeshed/stdlib/optparse.pyi @@ -1,6 +1,6 @@ -from typing import IO, Any, AnyStr, Callable, Iterable, Mapping, Sequence, Tuple, Type, overload +from typing import IO, Any, AnyStr, Callable, Iterable, Mapping, Sequence, Type, overload -NO_DEFAULT: Tuple[str, ...] +NO_DEFAULT: tuple[str, ...] SUPPRESS_HELP: str SUPPRESS_USAGE: str @@ -72,14 +72,14 @@ class TitledHelpFormatter(HelpFormatter): def format_usage(self, usage: str) -> str: ... class Option: - ACTIONS: Tuple[str, ...] - ALWAYS_TYPED_ACTIONS: Tuple[str, ...] + ACTIONS: tuple[str, ...] + ALWAYS_TYPED_ACTIONS: tuple[str, ...] ATTRS: list[str] CHECK_METHODS: list[Callable[..., Any]] | None - CONST_ACTIONS: Tuple[str, ...] - STORE_ACTIONS: Tuple[str, ...] - TYPED_ACTIONS: Tuple[str, ...] - TYPES: Tuple[str, ...] + CONST_ACTIONS: tuple[str, ...] + STORE_ACTIONS: tuple[str, ...] + TYPED_ACTIONS: tuple[str, ...] + TYPES: tuple[str, ...] TYPE_CHECKER: dict[str, Callable[..., Any]] _long_opts: list[str] _short_opts: list[str] @@ -89,7 +89,7 @@ class Option: nargs: int type: Any callback: Callable[..., Any] | None - callback_args: Tuple[Any, ...] | None + callback_args: tuple[Any, ...] | None callback_kwargs: dict[str, Any] | None help: str | None metavar: str | None diff --git a/mypy/typeshed/stdlib/os/__init__.pyi b/mypy/typeshed/stdlib/os/__init__.pyi index b432f6931a3f..5308416adff4 100644 --- a/mypy/typeshed/stdlib/os/__init__.pyi +++ b/mypy/typeshed/stdlib/os/__init__.pyi @@ -9,10 +9,11 @@ from _typeshed import ( Self, StrOrBytesPath, StrPath, + structseq, ) from builtins import OSError +from contextlib import AbstractContextManager from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper as _TextIOWrapper -from posix import listdir as listdir, times_result from subprocess import Popen from typing import ( IO, @@ -20,17 +21,14 @@ from typing import ( AnyStr, BinaryIO, Callable, - ContextManager, Generic, Iterable, Iterator, - List, Mapping, MutableMapping, NoReturn, Protocol, Sequence, - Tuple, TypeVar, Union, overload, @@ -92,6 +90,9 @@ if sys.platform != "win32": P_PGID: int P_ALL: int + if sys.platform == "linux" and sys.version_info >= (3, 9): + P_PIDFD: int + WEXITED: int WSTOPPED: int WNOWAIT: int @@ -101,6 +102,12 @@ if sys.platform != "win32": CLD_TRAPPED: int CLD_CONTINUED: int + if sys.version_info >= (3, 9): + CLD_KILLED: int + CLD_STOPPED: int + + # TODO: SCHED_RESET_ON_FORK not available on darwin? + # TODO: SCHED_BATCH and SCHED_IDLE are linux only? SCHED_OTHER: int # some flavors of Unix SCHED_BATCH: int # some flavors of Unix SCHED_IDLE: int # some flavors of Unix @@ -119,6 +126,8 @@ if sys.platform != "win32": if sys.platform == "linux": RTLD_DEEPBIND: int + GRND_NONBLOCK: int + GRND_RANDOM: int SEEK_SET: int SEEK_CUR: int @@ -161,6 +170,24 @@ O_NOATIME: int # Gnu extension if in C library O_PATH: int # Gnu extension if in C library O_TMPFILE: int # Gnu extension if in C library O_LARGEFILE: int # Gnu extension if in C library +O_ACCMODE: int # TODO: when does this exist? + +if sys.platform != "win32" and sys.platform != "darwin": + # posix, but apparently missing on macos + ST_APPEND: int + ST_MANDLOCK: int + ST_NOATIME: int + ST_NODEV: int + ST_NODIRATIME: int + ST_NOEXEC: int + ST_RELATIME: int + ST_SYNCHRONOUS: int + ST_WRITE: int + +if sys.platform != "win32": + NGROUPS_MAX: int + ST_NOSUID: int + ST_RDONLY: int curdir: str pardir: str @@ -210,7 +237,7 @@ class _Environ(MutableMapping[AnyStr, AnyStr], Generic[AnyStr]): putenv: Callable[[AnyStr, AnyStr], None], unsetenv: Callable[[AnyStr, AnyStr], None], ) -> None: ... - def setdefault(self, key: AnyStr, value: AnyStr) -> AnyStr: ... # type: ignore + def setdefault(self, key: AnyStr, value: AnyStr) -> AnyStr: ... # type: ignore[override] def copy(self) -> dict[AnyStr, AnyStr]: ... def __delitem__(self, key: AnyStr) -> None: ... def __getitem__(self, key: AnyStr) -> AnyStr: ... @@ -262,55 +289,84 @@ TMP_MAX: int # Undocumented, but used by tempfile # ----- os classes (structures) ----- @final -class stat_result: - # For backward compatibility, the return value of stat() is also - # accessible as a tuple of at least 10 integers giving the most important - # (and portable) members of the stat structure, in the order st_mode, - # st_ino, st_dev, st_nlink, st_uid, st_gid, st_size, st_atime, st_mtime, - # st_ctime. More items may be added at the end by some implementations. - - st_mode: int # protection bits, - st_ino: int # inode number, - st_dev: int # device, - st_nlink: int # number of hard links, - st_uid: int # user id of owner, - st_gid: int # group id of owner, - st_size: int # size of file, in bytes, - st_atime: float # time of most recent access, - st_mtime: float # time of most recent content modification, - st_ctime: float # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows) - st_atime_ns: int # time of most recent access, in nanoseconds - st_mtime_ns: int # time of most recent content modification in nanoseconds - st_ctime_ns: int # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows) in nanoseconds - if sys.version_info >= (3, 8) and sys.platform == "win32": - st_reparse_tag: int +class stat_result(structseq[float], tuple[int, int, int, int, int, int, int, float, float, float]): + # The constructor of this class takes an iterable of variable length (though it must be at least 10). + # + # However, this class behaves like a tuple of 10 elements, + # no matter how long the iterable supplied to the constructor is. + # https://github.com/python/typeshed/pull/6560#discussion_r767162532 + # + # The 10 elements always present are st_mode, st_ino, st_dev, st_nlink, + # st_uid, st_gid, st_size, st_atime, st_mtime, st_ctime. + # + # More items may be added at the end by some implementations. + @property + def st_mode(self) -> int: ... # protection bits, + @property + def st_ino(self) -> int: ... # inode number, + @property + def st_dev(self) -> int: ... # device, + @property + def st_nlink(self) -> int: ... # number of hard links, + @property + def st_uid(self) -> int: ... # user id of owner, + @property + def st_gid(self) -> int: ... # group id of owner, + @property + def st_size(self) -> int: ... # size of file, in bytes, + @property + def st_atime(self) -> float: ... # time of most recent access, + @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: ... + @property + def st_atime_ns(self) -> int: ... # time of most recent access, in nanoseconds + @property + def st_mtime_ns(self) -> int: ... # time of most recent content modification in nanoseconds + # platform dependent (time of most recent metadata change on Unix, or the time of creation on Windows) in nanoseconds + @property + def st_ctime_ns(self) -> int: ... if sys.platform == "win32": - st_file_attributes: int - def __getitem__(self, i: int) -> int: ... - # not documented - def __init__(self, tuple: Tuple[int, ...]) -> None: ... - # On some Unix systems (such as Linux), the following attributes may also - # be available: - st_blocks: int # number of blocks allocated for file - st_blksize: int # filesystem blocksize - st_rdev: int # type of device if an inode device - st_flags: int # user defined flags for file - - # On other Unix systems (such as FreeBSD), the following attributes may be - # available (but may be only filled out if root tries to use them): - st_gen: int # file generation number - st_birthtime: int # time of file creation - - # On Mac OS systems, the following attributes may also be available: - st_rsize: int - st_creator: int - st_type: int + @property + def st_file_attributes(self) -> int: ... + if sys.version_info >= (3, 8): + @property + def st_reparse_tag(self) -> int: ... + else: + @property + def st_blocks(self) -> int: ... # number of blocks allocated for file + @property + def st_blksize(self) -> int: ... # filesystem blocksize + @property + def st_rdev(self) -> int: ... # type of device if an inode device + if sys.platform != "linux": + # These properties are available on MacOS, but not on Windows or Ubuntu. + # On other Unix systems (such as FreeBSD), the following attributes may be + # available (but may be only filled out if root tries to use them): + @property + def st_gen(self) -> int: ... # file generation number + @property + def st_birthtime(self) -> int: ... # time of file creation + if sys.platform == "darwin": + @property + def st_flags(self) -> int: ... # user defined flags for file + # Atributes documented as sometimes appearing, but deliberately omitted from the stub: `st_creator`, `st_rsize`, `st_type`. + # See https://github.com/python/typeshed/pull/6560#issuecomment-991253327 @runtime_checkable class PathLike(Protocol[_AnyStr_co]): def __fspath__(self) -> _AnyStr_co: ... - if sys.version_info >= (3, 9): - def __class_getitem__(cls, item: Any) -> GenericAlias: ... + +@overload +def listdir(path: str | None = ...) -> list[str]: ... +@overload +def listdir(path: bytes) -> list[bytes]: ... +@overload +def listdir(path: int) -> list[str]: ... +@overload +def listdir(path: PathLike[str]) -> list[str]: ... _FdOrAnyPath = Union[int, StrOrBytesPath] @@ -330,45 +386,55 @@ class DirEntry(Generic[AnyStr]): if sys.version_info >= (3, 9): def __class_getitem__(cls, item: Any) -> GenericAlias: ... -if sys.platform != "win32": - _Tuple10Int = Tuple[int, int, int, int, int, int, int, int, int, int] - _Tuple11Int = Tuple[int, int, int, int, int, int, int, int, int, int, int] - if sys.version_info >= (3, 7): - # f_fsid was added in https://github.com/python/cpython/pull/4571 - @final - class statvfs_result(_Tuple10Int): # Unix only - def __new__(cls, seq: _Tuple10Int | _Tuple11Int, dict: dict[str, int] = ...) -> statvfs_result: ... - n_fields: int - n_sequence_fields: int - n_unnamed_fields: int - - f_bsize: int - f_frsize: int - f_blocks: int - f_bfree: int - f_bavail: int - f_files: int - f_ffree: int - f_favail: int - f_flag: int - f_namemax: int - f_fsid: int - else: - class statvfs_result(_Tuple10Int): # Unix only - n_fields: int - n_sequence_fields: int - n_unnamed_fields: int - - f_bsize: int - f_frsize: int - f_blocks: int - f_bfree: int - f_bavail: int - f_files: int - f_ffree: int - f_favail: int - f_flag: int - f_namemax: int +if sys.version_info >= (3, 7): + @final + class statvfs_result(structseq[int], tuple[int, int, int, int, int, int, int, int, int, int, int]): + @property + def f_bsize(self) -> int: ... + @property + def f_frsize(self) -> int: ... + @property + def f_blocks(self) -> int: ... + @property + def f_bfree(self) -> int: ... + @property + def f_bavail(self) -> int: ... + @property + def f_files(self) -> int: ... + @property + def f_ffree(self) -> int: ... + @property + def f_favail(self) -> int: ... + @property + def f_flag(self) -> int: ... + @property + def f_namemax(self) -> int: ... + @property + def f_fsid(self) -> int: ... + +else: + @final + class statvfs_result(structseq[int], tuple[int, int, int, int, int, int, int, int, int, int]): + @property + def f_bsize(self) -> int: ... + @property + def f_frsize(self) -> int: ... + @property + def f_blocks(self) -> int: ... + @property + def f_bfree(self) -> int: ... + @property + def f_bavail(self) -> int: ... + @property + def f_files(self) -> int: ... + @property + def f_ffree(self) -> int: ... + @property + def f_favail(self) -> int: ... + @property + def f_flag(self) -> int: ... + @property + def f_namemax(self) -> int: ... # ----- os function stubs ----- def fsencode(filename: StrOrBytesPath) -> bytes: ... @@ -385,9 +451,20 @@ def getpid() -> int: ... def getppid() -> int: ... def strerror(__code: int) -> str: ... def umask(__mask: int) -> int: ... +@final +class uname_result(structseq[str], tuple[str, str, str, str, str]): + @property + def sysname(self) -> str: ... + @property + def nodename(self) -> str: ... + @property + def release(self) -> str: ... + @property + def version(self) -> str: ... + @property + def machine(self) -> str: ... if sys.platform != "win32": - # Unix only def ctermid() -> str: ... def getegid() -> int: ... def geteuid() -> int: ... @@ -417,7 +494,6 @@ if sys.platform != "win32": def getsid(__pid: int) -> int: ... def setsid() -> None: ... def setuid(__uid: int) -> None: ... - from posix import uname_result def uname() -> uname_result: ... @overload @@ -433,7 +509,7 @@ if sys.platform != "win32": def putenv(__name: bytes | str, __value: bytes | str) -> None: ... -if sys.platform != "win32": +if sys.platform != "win32" or sys.version_info >= (3, 9): def unsetenv(__name: bytes | str) -> None: ... _Opener = Callable[[str, int], int] @@ -527,7 +603,9 @@ else: def dup2(fd: int, fd2: int, inheritable: bool = ...) -> None: ... def fstat(fd: int) -> stat_result: ... +def ftruncate(__fd: int, __length: int) -> None: ... def fsync(fd: FileDescriptorLike) -> None: ... +def isatty(__fd: int) -> bool: ... def lseek(__fd: int, __position: int, __how: int) -> int: ... def open(path: StrOrBytesPath, flags: int, mode: int = ..., *, dir_fd: int | None = ...) -> int: ... def pipe() -> tuple[int, int]: ... @@ -537,22 +615,29 @@ if sys.platform != "win32": # Unix only def fchmod(fd: int, mode: int) -> None: ... def fchown(fd: int, uid: int, gid: int) -> None: ... - if sys.platform != "darwin": - def fdatasync(fd: FileDescriptorLike) -> None: ... # Unix only, not Mac def fpathconf(__fd: int, __name: str | int) -> int: ... def fstatvfs(__fd: int) -> statvfs_result: ... - def ftruncate(__fd: int, __length: int) -> None: ... def get_blocking(__fd: int) -> bool: ... def set_blocking(__fd: int, __blocking: bool) -> None: ... - def isatty(__fd: int) -> bool: ... def lockf(__fd: int, __command: int, __length: int) -> None: ... def openpty() -> tuple[int, int]: ... # some flavors of Unix if sys.platform != "darwin": - def pipe2(flags: int) -> tuple[int, int]: ... # some flavors of Unix + 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 pread(__fd: int, __length: int, __offset: int) -> bytes: ... def pwrite(__fd: int, __buffer: bytes, __offset: int) -> int: ... + if sys.platform != "darwin": + if sys.version_info >= (3, 10): + RWF_APPEND: int # docs say available on 3.7+, stubtest says otherwise + if sys.version_info >= (3, 7): + def preadv(__fd: int, __buffers: Iterable[bytes], __offset: int, __flags: int = ...) -> int: ... + def pwritev(__fd: int, __buffers: Iterable[bytes], __offset: int, __flags: int = ...) -> int: ... + RWF_DSYNC: int + RWF_SYNC: int + RWF_HIPRI: int + RWF_NOWAIT: int @overload def sendfile(out_fd: int, in_fd: int, offset: int | None, count: int) -> int: ... @overload @@ -569,9 +654,11 @@ if sys.platform != "win32": def writev(__fd: int, __buffers: Sequence[bytes]) -> int: ... @final -class terminal_size(Tuple[int, int]): - columns: int - lines: int +class terminal_size(structseq[int], tuple[int, int]): + @property + def columns(self) -> int: ... + @property + def lines(self) -> int: ... def get_terminal_size(fd: int = ...) -> terminal_size: ... def get_inheritable(__fd: int) -> bool: ... @@ -596,17 +683,14 @@ def getcwd() -> str: ... def getcwdb() -> bytes: ... def chmod(path: _FdOrAnyPath, mode: int, *, dir_fd: int | None = ..., follow_symlinks: bool = ...) -> None: ... -if sys.platform != "win32": +if sys.platform != "win32" and sys.platform != "linux": def chflags(path: StrOrBytesPath, flags: int, follow_symlinks: bool = ...) -> None: ... # some flavors of Unix - def chown( - path: _FdOrAnyPath, uid: int, gid: int, *, dir_fd: int | None = ..., follow_symlinks: bool = ... - ) -> None: ... # Unix only + def lchflags(path: StrOrBytesPath, flags: int) -> None: ... + def lchmod(path: StrOrBytesPath, mode: int) -> None: ... if sys.platform != "win32": - # Unix only def chroot(path: StrOrBytesPath) -> None: ... - def lchflags(path: StrOrBytesPath, flags: int) -> None: ... - def lchmod(path: StrOrBytesPath, mode: int) -> None: ... + def chown(path: _FdOrAnyPath, uid: int, gid: int, *, dir_fd: int | None = ..., follow_symlinks: bool = ...) -> None: ... def lchown(path: StrOrBytesPath, uid: int, gid: int) -> None: ... def link( @@ -640,7 +724,7 @@ def renames(old: StrOrBytesPath, new: StrOrBytesPath) -> None: ... def replace(src: StrOrBytesPath, dst: StrOrBytesPath, *, src_dir_fd: int | None = ..., dst_dir_fd: int | None = ...) -> None: ... def rmdir(path: StrOrBytesPath, *, dir_fd: int | None = ...) -> None: ... -class _ScandirIterator(Iterator[DirEntry[AnyStr]], ContextManager[_ScandirIterator[AnyStr]]): +class _ScandirIterator(Iterator[DirEntry[AnyStr]], AbstractContextManager[_ScandirIterator[AnyStr]]): def __next__(self) -> DirEntry[AnyStr]: ... def close(self) -> None: ... @@ -744,14 +828,14 @@ def execlpe(file: StrOrBytesPath, __arg0: StrOrBytesPath, *args: Any) -> NoRetur # in practice, and doing so would explode the number of combinations in this already long union. # All these combinations are necessary due to list being invariant. _ExecVArgs = Union[ - Tuple[StrOrBytesPath, ...], - List[bytes], - List[str], - List[PathLike[Any]], - List[Union[bytes, str]], - List[Union[bytes, PathLike[Any]]], - List[Union[str, PathLike[Any]]], - List[Union[bytes, str, PathLike[Any]]], + tuple[StrOrBytesPath, ...], + list[bytes], + list[str], + list[PathLike[Any]], + list[Union[bytes, str]], + list[Union[bytes, PathLike[Any]]], + list[Union[str, PathLike[Any]]], + list[Union[bytes, str, PathLike[Any]]], ] _ExecEnv = Union[Mapping[bytes, Union[bytes, str]], Mapping[str, Union[bytes, str]]] @@ -773,7 +857,7 @@ if sys.platform != "win32": class _wrap_close(_TextIOWrapper): def __init__(self, stream: _TextIOWrapper, proc: Popen[str]) -> None: ... - def close(self) -> int | None: ... # type: ignore + def close(self) -> int | None: ... # type: ignore[override] def popen(cmd: str, mode: str = ..., buffering: int = ...) -> _wrap_close: ... def spawnl(mode: int, file: StrOrBytesPath, arg0: StrOrBytesPath, *args: StrOrBytesPath) -> int: ... @@ -788,6 +872,19 @@ else: def spawnve(__mode: int, __path: StrOrBytesPath, __argv: _ExecVArgs, __env: _ExecEnv) -> int: ... def system(command: StrOrBytesPath) -> int: ... +@final +class times_result(structseq[float], tuple[float, float, float, float, float]): + @property + def user(self) -> float: ... + @property + def system(self) -> float: ... + @property + def children_user(self) -> float: ... + @property + def children_system(self) -> float: ... + @property + def elapsed(self) -> float: ... + def times() -> times_result: ... def waitpid(__pid: int, __options: int) -> tuple[int, int]: ... @@ -795,14 +892,24 @@ if sys.platform == "win32": def startfile(path: StrOrBytesPath, operation: str | None = ...) -> None: ... else: - # Unix only def spawnlp(mode: int, file: StrOrBytesPath, arg0: StrOrBytesPath, *args: StrOrBytesPath) -> int: ... def spawnlpe(mode: int, file: StrOrBytesPath, arg0: StrOrBytesPath, *args: Any) -> int: ... # Imprecise signature def spawnvp(mode: int, file: StrOrBytesPath, args: _ExecVArgs) -> int: ... def spawnvpe(mode: int, file: StrOrBytesPath, args: _ExecVArgs, env: _ExecEnv) -> int: ... def wait() -> tuple[int, int]: ... # Unix only if sys.platform != "darwin": - from posix import waitid_result + @final + class waitid_result(structseq[int], tuple[int, int, int, int, int]): + @property + def si_pid(self) -> int: ... + @property + def si_uid(self) -> int: ... + @property + def si_signo(self) -> int: ... + @property + def si_status(self) -> int: ... + @property + def si_code(self) -> int: ... def waitid(idtype: int, ident: int, options: int) -> waitid_result: ... def wait3(options: int) -> tuple[int, int, Any]: ... def wait4(pid: int, options: int) -> tuple[int, int, Any]: ... @@ -815,10 +922,42 @@ else: def WSTOPSIG(status: int) -> int: ... def WTERMSIG(status: int) -> int: ... if sys.version_info >= (3, 8): - from posix import posix_spawn as posix_spawn, posix_spawnp as posix_spawnp + 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": - from posix import sched_param + @final + class sched_param(structseq[int], tuple[int]): + def __new__(cls, sched_priority: int) -> sched_param: ... + @property + def sched_priority(self) -> int: ... def sched_get_priority_min(policy: int) -> int: ... # some flavors of Unix def sched_get_priority_max(policy: int) -> int: ... # some flavors of Unix def sched_yield() -> None: ... # some flavors of Unix @@ -880,3 +1019,6 @@ if sys.version_info >= (3, 8): MFD_HUGE_2GB: int MFD_HUGE_16GB: int def memfd_create(name: str, flags: int = ...) -> int: ... + +if sys.version_info >= (3, 9): + def waitstatus_to_exitcode(status: int) -> int: ... diff --git a/mypy/typeshed/stdlib/parser.pyi b/mypy/typeshed/stdlib/parser.pyi index aecf3244ca8d..ab819a71a15f 100644 --- a/mypy/typeshed/stdlib/parser.pyi +++ b/mypy/typeshed/stdlib/parser.pyi @@ -1,13 +1,13 @@ from _typeshed import StrOrBytesPath from types import CodeType -from typing import Any, Sequence, Tuple +from typing import Any, Sequence def expr(source: str) -> STType: ... def suite(source: str) -> STType: ... def sequence2st(sequence: Sequence[Any]) -> STType: ... def tuple2st(sequence: Sequence[Any]) -> STType: ... def st2list(st: STType, line_info: bool = ..., col_info: bool = ...) -> list[Any]: ... -def st2tuple(st: STType, line_info: bool = ..., col_info: bool = ...) -> Tuple[Any, ...]: ... +def st2tuple(st: STType, line_info: bool = ..., col_info: bool = ...) -> tuple[Any, ...]: ... def compilest(st: STType, filename: StrOrBytesPath = ...) -> CodeType: ... def isexpr(st: STType) -> bool: ... def issuite(st: STType) -> bool: ... @@ -19,4 +19,4 @@ class STType: def isexpr(self) -> bool: ... def issuite(self) -> bool: ... def tolist(self, line_info: bool = ..., col_info: bool = ...) -> list[Any]: ... - def totuple(self, line_info: bool = ..., col_info: bool = ...) -> Tuple[Any, ...]: ... + def totuple(self, line_info: bool = ..., col_info: bool = ...) -> tuple[Any, ...]: ... diff --git a/mypy/typeshed/stdlib/pathlib.pyi b/mypy/typeshed/stdlib/pathlib.pyi index 7d5f7ff2dba8..b541345c06d4 100644 --- a/mypy/typeshed/stdlib/pathlib.pyi +++ b/mypy/typeshed/stdlib/pathlib.pyi @@ -11,7 +11,7 @@ from _typeshed import ( from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper from os import PathLike, stat_result from types import TracebackType -from typing import IO, Any, BinaryIO, Generator, Sequence, Tuple, Type, TypeVar, overload +from typing import IO, Any, BinaryIO, Generator, Sequence, Type, TypeVar, overload from typing_extensions import Literal if sys.version_info >= (3, 9): @@ -20,7 +20,7 @@ if sys.version_info >= (3, 9): _P = TypeVar("_P", bound=PurePath) class PurePath(PathLike[str]): - parts: Tuple[str, ...] + parts: tuple[str, ...] drive: str root: str anchor: str diff --git a/mypy/typeshed/stdlib/pickle.pyi b/mypy/typeshed/stdlib/pickle.pyi index cef1ffe9eb9b..46c349137459 100644 --- a/mypy/typeshed/stdlib/pickle.pyi +++ b/mypy/typeshed/stdlib/pickle.pyi @@ -1,11 +1,11 @@ import sys -from typing import Any, Callable, ClassVar, Iterable, Iterator, Mapping, Optional, Protocol, Tuple, Type, Union +from typing import Any, Callable, ClassVar, Iterable, Iterator, Mapping, Optional, Protocol, Type, Union from typing_extensions import final HIGHEST_PROTOCOL: int DEFAULT_PROTOCOL: int -bytes_types: Tuple[Type[Any], ...] # undocumented +bytes_types: tuple[Type[Any], ...] # undocumented class _ReadableFileobj(Protocol): def read(self, __n: int) -> bytes: ... @@ -58,10 +58,10 @@ class UnpicklingError(PickleError): ... _reducedtype = Union[ str, - Tuple[Callable[..., Any], Tuple[Any, ...]], - Tuple[Callable[..., Any], Tuple[Any, ...], Any], - Tuple[Callable[..., Any], Tuple[Any, ...], Any, Optional[Iterator[Any]]], - Tuple[Callable[..., Any], Tuple[Any, ...], Any, Optional[Iterator[Any]], Optional[Iterator[Any]]], + tuple[Callable[..., Any], tuple[Any, ...]], + tuple[Callable[..., Any], tuple[Any, ...], Any], + tuple[Callable[..., Any], tuple[Any, ...], Any, Optional[Iterator[Any]]], + tuple[Callable[..., Any], tuple[Any, ...], Any, Optional[Iterator[Any]], Optional[Iterator[Any]]], ] class Pickler: diff --git a/mypy/typeshed/stdlib/pickletools.pyi b/mypy/typeshed/stdlib/pickletools.pyi index 9fa51a3848ee..04a695f5f103 100644 --- a/mypy/typeshed/stdlib/pickletools.pyi +++ b/mypy/typeshed/stdlib/pickletools.pyi @@ -1,7 +1,7 @@ -from typing import IO, Any, Callable, Iterator, MutableMapping, Tuple, Type +from typing import IO, Any, Callable, Iterator, MutableMapping, Type _Reader = Callable[[IO[bytes]], Any] -bytes_types: Tuple[Type[Any], ...] +bytes_types: tuple[Type[Any], ...] UP_TO_NEWLINE: int TAKEN_FROM_ARGUMENT1: int @@ -9,7 +9,7 @@ TAKEN_FROM_ARGUMENT4: int TAKEN_FROM_ARGUMENT4U: int TAKEN_FROM_ARGUMENT8U: int -class ArgumentDescriptor(object): +class ArgumentDescriptor: name: str n: int reader: _Reader @@ -106,11 +106,11 @@ def read_long4(f: IO[bytes]) -> int: ... long4: ArgumentDescriptor -class StackObject(object): +class StackObject: name: str - obtype: Type[Any] | Tuple[Type[Any], ...] + obtype: Type[Any] | tuple[Type[Any], ...] doc: str - def __init__(self, name: str, obtype: Type[Any] | Tuple[Type[Any], ...], doc: str) -> None: ... + def __init__(self, name: str, obtype: Type[Any] | tuple[Type[Any], ...], doc: str) -> None: ... pyint: StackObject pylong: StackObject @@ -131,7 +131,7 @@ anyobject: StackObject markobject: StackObject stackslice: StackObject -class OpcodeInfo(object): +class OpcodeInfo: name: str code: str arg: ArgumentDescriptor | None diff --git a/mypy/typeshed/stdlib/platform.pyi b/mypy/typeshed/stdlib/platform.pyi index 7db2d59ff7ea..765a7a5ea5f9 100644 --- a/mypy/typeshed/stdlib/platform.pyi +++ b/mypy/typeshed/stdlib/platform.pyi @@ -4,7 +4,7 @@ if sys.version_info < (3, 8): import os DEV_NULL = os.devnull -from typing import NamedTuple, Tuple +from typing import NamedTuple if sys.version_info >= (3, 8): def libc_ver(executable: str | None = ..., lib: str = ..., version: str = ..., chunksize: int = ...) -> tuple[str, str]: ... @@ -17,11 +17,11 @@ if sys.version_info < (3, 8): distname: str = ..., version: str = ..., id: str = ..., - supported_dists: Tuple[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, ...] = ... + distname: str = ..., version: str = ..., id: str = ..., supported_dists: tuple[str, ...] = ... ) -> tuple[str, str, str]: ... def win32_ver(release: str = ..., version: str = ..., csd: str = ..., ptype: str = ...) -> tuple[str, str, str, str]: ... @@ -62,3 +62,6 @@ def python_revision() -> str: ... def python_build() -> tuple[str, str]: ... def python_compiler() -> str: ... def platform(aliased: bool = ..., terse: bool = ...) -> str: ... + +if sys.version_info >= (3, 10): + def freedesktop_os_release() -> dict[str, str]: ... diff --git a/mypy/typeshed/stdlib/plistlib.pyi b/mypy/typeshed/stdlib/plistlib.pyi index 07b6963746be..7abe9dd2942b 100644 --- a/mypy/typeshed/stdlib/plistlib.pyi +++ b/mypy/typeshed/stdlib/plistlib.pyi @@ -1,7 +1,7 @@ import sys from datetime import datetime from enum import Enum -from typing import IO, Any, Dict as _Dict, Mapping, MutableMapping, Tuple, Type +from typing import IO, Any, Mapping, MutableMapping, Type class PlistFormat(Enum): FMT_XML: int @@ -31,7 +31,7 @@ else: ) -> Any: ... def dump( - value: Mapping[str, Any] | list[Any] | Tuple[Any, ...] | str | bool | float | bytes | datetime, + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | datetime, fp: IO[bytes], *, fmt: PlistFormat = ..., @@ -39,7 +39,7 @@ def dump( skipkeys: bool = ..., ) -> None: ... def dumps( - value: Mapping[str, Any] | list[Any] | Tuple[Any, ...] | str | bool | float | bytes | datetime, + value: Mapping[str, Any] | list[Any] | tuple[Any, ...] | str | bool | float | bytes | datetime, *, fmt: PlistFormat = ..., skipkeys: bool = ..., @@ -53,7 +53,7 @@ if sys.version_info < (3, 9): def writePlistToBytes(value: Mapping[str, Any]) -> bytes: ... if sys.version_info < (3, 7): - class Dict(_Dict[str, Any]): + class Dict(dict[str, Any]): def __getattr__(self, attr: str) -> Any: ... def __setattr__(self, attr: str, value: Any) -> None: ... def __delattr__(self, attr: str) -> None: ... diff --git a/mypy/typeshed/stdlib/poplib.pyi b/mypy/typeshed/stdlib/poplib.pyi index 28fba4ce951f..028af412847b 100644 --- a/mypy/typeshed/stdlib/poplib.pyi +++ b/mypy/typeshed/stdlib/poplib.pyi @@ -1,8 +1,8 @@ import socket import ssl -from typing import Any, BinaryIO, List, Pattern, Tuple, overload +from typing import Any, BinaryIO, Pattern, overload -_LongResp = Tuple[bytes, List[bytes], int] +_LongResp = tuple[bytes, list[bytes], int] class error_proto(Exception): ... diff --git a/mypy/typeshed/stdlib/posix.pyi b/mypy/typeshed/stdlib/posix.pyi index 14cea87cde29..9f658039bcf2 100644 --- a/mypy/typeshed/stdlib/posix.pyi +++ b/mypy/typeshed/stdlib/posix.pyi @@ -1,204 +1,322 @@ import sys -from _typeshed import StrOrBytesPath -from os import PathLike, _ExecEnv, _ExecVArgs, stat_result as stat_result -from typing import Any, Iterable, NamedTuple, Sequence, Tuple, overload -from typing_extensions import final -@final -class uname_result(NamedTuple): - sysname: str - nodename: str - release: str - version: str - machine: str +if sys.platform != "win32": + # Actually defined here, but defining in os allows sharing code with windows + from os import ( + CLD_CONTINUED as CLD_CONTINUED, + CLD_DUMPED as CLD_DUMPED, + CLD_EXITED as CLD_EXITED, + CLD_TRAPPED as CLD_TRAPPED, + EX_CANTCREAT as EX_CANTCREAT, + EX_CONFIG as EX_CONFIG, + EX_DATAERR as EX_DATAERR, + EX_IOERR as EX_IOERR, + EX_NOHOST as EX_NOHOST, + EX_NOINPUT as EX_NOINPUT, + EX_NOPERM as EX_NOPERM, + EX_NOTFOUND as EX_NOTFOUND, + EX_NOUSER as EX_NOUSER, + EX_OK as EX_OK, + EX_OSERR as EX_OSERR, + EX_OSFILE as EX_OSFILE, + EX_PROTOCOL as EX_PROTOCOL, + EX_SOFTWARE as EX_SOFTWARE, + EX_TEMPFAIL as EX_TEMPFAIL, + EX_UNAVAILABLE as EX_UNAVAILABLE, + EX_USAGE as EX_USAGE, + F_LOCK as F_LOCK, + F_OK as F_OK, + F_TEST as F_TEST, + F_TLOCK as F_TLOCK, + F_ULOCK as F_ULOCK, + O_APPEND as O_APPEND, + O_ASYNC as O_ASYNC, + O_CREAT as O_CREAT, + O_DIRECT as O_DIRECT, + O_DIRECTORY as O_DIRECTORY, + O_DSYNC as O_DSYNC, + O_EXCL as O_EXCL, + O_LARGEFILE as O_LARGEFILE, + O_NDELAY as O_NDELAY, + O_NOATIME as O_NOATIME, + O_NOCTTY as O_NOCTTY, + O_NOFOLLOW as O_NOFOLLOW, + O_NONBLOCK as O_NONBLOCK, + O_RDONLY as O_RDONLY, + O_RDWR as O_RDWR, + O_RSYNC as O_RSYNC, + O_SYNC as O_SYNC, + O_TRUNC as O_TRUNC, + O_WRONLY as O_WRONLY, + P_ALL as P_ALL, + P_PGID as P_PGID, + P_PID as P_PID, + PRIO_PGRP as PRIO_PGRP, + PRIO_PROCESS as PRIO_PROCESS, + PRIO_USER as PRIO_USER, + R_OK as R_OK, + RTLD_GLOBAL as RTLD_GLOBAL, + RTLD_LAZY as RTLD_LAZY, + RTLD_LOCAL as RTLD_LOCAL, + RTLD_NODELETE as RTLD_NODELETE, + RTLD_NOLOAD as RTLD_NOLOAD, + RTLD_NOW as RTLD_NOW, + SCHED_BATCH as SCHED_BATCH, + SCHED_FIFO as SCHED_FIFO, + SCHED_IDLE as SCHED_IDLE, + SCHED_OTHER as SCHED_OTHER, + SCHED_RESET_ON_FORK as SCHED_RESET_ON_FORK, + SCHED_RR as SCHED_RR, + SCHED_SPORADIC as SCHED_SPORADIC, + SEEK_DATA as SEEK_DATA, + SEEK_HOLE as SEEK_HOLE, + ST_NOSUID as ST_NOSUID, + ST_RDONLY as ST_RDONLY, + TMP_MAX as TMP_MAX, + W_OK as W_OK, + WCONTINUED as WCONTINUED, + WCOREDUMP as WCOREDUMP, + WEXITED as WEXITED, + WEXITSTATUS as WEXITSTATUS, + WIFCONTINUED as WIFCONTINUED, + WIFEXITED as WIFEXITED, + WIFSIGNALED as WIFSIGNALED, + WIFSTOPPED as WIFSTOPPED, + WNOHANG as WNOHANG, + WNOWAIT as WNOWAIT, + WSTOPPED as WSTOPPED, + WSTOPSIG as WSTOPSIG, + WTERMSIG as WTERMSIG, + WUNTRACED as WUNTRACED, + X_OK as X_OK, + DirEntry as DirEntry, + _exit as _exit, + abort as abort, + access as access, + chdir as chdir, + chmod as chmod, + chown as chown, + chroot as chroot, + close as close, + closerange as closerange, + confstr as confstr, + confstr_names as confstr_names, + cpu_count as cpu_count, + ctermid as ctermid, + device_encoding as device_encoding, + dup as dup, + dup2 as dup2, + error as error, + execv as execv, + execve as execve, + fchdir as fchdir, + fchmod as fchmod, + fchown as fchown, + fork as fork, + forkpty as forkpty, + fpathconf as fpathconf, + fspath as fspath, + fstat as fstat, + fstatvfs as fstatvfs, + fsync as fsync, + ftruncate as ftruncate, + get_blocking as get_blocking, + get_inheritable as get_inheritable, + get_terminal_size as get_terminal_size, + getcwd as getcwd, + getcwdb as getcwdb, + getegid as getegid, + geteuid as geteuid, + getgid as getgid, + getgrouplist as getgrouplist, + getgroups as getgroups, + getloadavg as getloadavg, + getlogin as getlogin, + getpgid as getpgid, + getpgrp as getpgrp, + getpid as getpid, + getppid as getppid, + getpriority as getpriority, + getsid as getsid, + getuid as getuid, + initgroups as initgroups, + isatty as isatty, + kill as kill, + killpg as killpg, + lchown as lchown, + link as link, + listdir as listdir, + lockf as lockf, + lseek as lseek, + lstat as lstat, + major as major, + makedev as makedev, + minor as minor, + mkdir as mkdir, + mkfifo as mkfifo, + mknod as mknod, + nice as nice, + open as open, + openpty as openpty, + pathconf as pathconf, + pathconf_names as pathconf_names, + pipe as pipe, + pread as pread, + putenv as putenv, + pwrite as pwrite, + read as read, + readlink as readlink, + readv as readv, + remove as remove, + rename as rename, + replace as replace, + rmdir as rmdir, + scandir as scandir, + sched_get_priority_max as sched_get_priority_max, + sched_get_priority_min as sched_get_priority_min, + sched_param as sched_param, + sched_yield as sched_yield, + sendfile as sendfile, + set_blocking as set_blocking, + set_inheritable as set_inheritable, + setegid as setegid, + seteuid as seteuid, + setgid as setgid, + setgroups as setgroups, + setpgid as setpgid, + setpgrp as setpgrp, + setpriority as setpriority, + setregid as setregid, + setreuid as setreuid, + setsid as setsid, + setuid as setuid, + stat as stat, + stat_result as stat_result, + statvfs as statvfs, + statvfs_result as statvfs_result, + strerror as strerror, + symlink as symlink, + sync as sync, + sysconf as sysconf, + sysconf_names as sysconf_names, + system as system, + tcgetpgrp as tcgetpgrp, + tcsetpgrp as tcsetpgrp, + terminal_size as terminal_size, + times as times, + times_result as times_result, + truncate as truncate, + ttyname as ttyname, + umask as umask, + uname as uname, + uname_result as uname_result, + unlink as unlink, + unsetenv as unsetenv, + urandom as urandom, + utime as utime, + wait as wait, + wait3 as wait3, + wait4 as wait4, + waitpid as waitpid, + write as write, + writev as writev, + ) -@final -class times_result(NamedTuple): - user: float - system: float - children_user: float - children_system: float - elapsed: float + 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, + ) + else: + from os import chflags as chflags, lchflags as lchflags, lchmod as lchmod -if sys.platform != "darwin": - class waitid_result(NamedTuple): - si_pid: int - si_uid: int - si_signo: int - si_status: int - si_code: int + if sys.platform != "darwin": + from os import ( + 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, + fdatasync as fdatasync, + getresgid as getresgid, + getresuid as getresuid, + pipe2 as pipe2, + posix_fadvise as posix_fadvise, + posix_fallocate as posix_fallocate, + sched_getaffinity as sched_getaffinity, + sched_getparam as sched_getparam, + sched_getscheduler as sched_getscheduler, + sched_rr_get_interval as sched_rr_get_interval, + sched_setaffinity as sched_setaffinity, + sched_setparam as sched_setparam, + sched_setscheduler as sched_setscheduler, + setresgid as setresgid, + setresuid as setresuid, + waitid as waitid, + waitid_result as waitid_result, + ) -class sched_param(NamedTuple): - sched_priority: int + if sys.version_info >= (3, 10): + from os import RWF_APPEND as RWF_APPEND -CLD_CONTINUED: int -CLD_DUMPED: int -CLD_EXITED: int -CLD_TRAPPED: int + 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 -EX_CANTCREAT: int -EX_CONFIG: int -EX_DATAERR: int -EX_IOERR: int -EX_NOHOST: int -EX_NOINPUT: int -EX_NOPERM: int -EX_NOTFOUND: int -EX_NOUSER: int -EX_OK: int -EX_OSERR: int -EX_OSFILE: int -EX_PROTOCOL: int -EX_SOFTWARE: int -EX_TEMPFAIL: int -EX_UNAVAILABLE: int -EX_USAGE: int + if sys.platform == "linux": + from os import P_PIDFD as P_PIDFD + if sys.version_info >= (3, 8): + 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, + ) -F_OK: int -R_OK: int -W_OK: int -X_OK: int + if sys.platform == "linux": + 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, + memfd_create as memfd_create, + ) + if sys.version_info >= (3, 7): + from os import register_at_fork as register_at_fork -F_LOCK: int -F_TEST: int -F_TLOCK: int -F_ULOCK: int + 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, + preadv as preadv, + pwritev as pwritev, + ) -if sys.platform == "linux": - GRND_NONBLOCK: int - GRND_RANDOM: int -NGROUPS_MAX: int - -O_APPEND: int -O_ACCMODE: int -O_ASYNC: int -O_CREAT: int -O_DIRECT: int -O_DIRECTORY: int -O_DSYNC: int -O_EXCL: int -O_LARGEFILE: int -O_NDELAY: int -O_NOATIME: int -O_NOCTTY: int -O_NOFOLLOW: int -O_NONBLOCK: int -O_RDONLY: int -O_RDWR: int -O_RSYNC: int -O_SYNC: int -O_TRUNC: int -O_WRONLY: int - -if sys.platform != "darwin": - POSIX_FADV_DONTNEED: int - POSIX_FADV_NOREUSE: int - POSIX_FADV_NORMAL: int - POSIX_FADV_RANDOM: int - POSIX_FADV_SEQUENTIAL: int - POSIX_FADV_WILLNEED: int - -PRIO_PGRP: int -PRIO_PROCESS: int -PRIO_USER: int - -P_ALL: int -P_PGID: int -P_PID: int - -if sys.platform == "linux": - RTLD_DEEPBIND: int -RTLD_GLOBAL: int -RTLD_LAZY: int -RTLD_LOCAL: int -RTLD_NODELETE: int -RTLD_NOLOAD: int -RTLD_NOW: int - -SCHED_FIFO: int -SCHED_OTHER: int -SCHED_RR: int - -if sys.platform == "linux": - SCHED_BATCH: int - SCHED_IDLE: int -if sys.platform != "darwin": - SCHED_RESET_ON_FORK: int - -SEEK_DATA: int -SEEK_HOLE: int - -ST_APPEND: int -ST_MANDLOCK: int -ST_NOATIME: int -ST_NODEV: int -ST_NODIRATIME: int -ST_NOEXEC: int -ST_NOSUID: int -ST_RDONLY: int -ST_RELATIME: int -ST_SYNCHRONOUS: int -ST_WRITE: int - -TMP_MAX: int -WCONTINUED: int - -def WCOREDUMP(__status: int) -> bool: ... -def WEXITSTATUS(status: int) -> int: ... -def WIFCONTINUED(status: int) -> bool: ... -def WIFEXITED(status: int) -> bool: ... -def WIFSIGNALED(status: int) -> bool: ... -def WIFSTOPPED(status: int) -> bool: ... - -WNOHANG: int - -def WSTOPSIG(status: int) -> int: ... -def WTERMSIG(status: int) -> int: ... - -WUNTRACED: int - -XATTR_CREATE: int -XATTR_REPLACE: int -XATTR_SIZE_MAX: int - -@overload -def listdir(path: str | None = ...) -> list[str]: ... -@overload -def listdir(path: bytes) -> list[bytes]: ... -@overload -def listdir(path: int) -> list[str]: ... -@overload -def listdir(path: PathLike[str]) -> list[str]: ... - -if sys.platform != "win32" and 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: ... - -if sys.platform == "win32": - environ: dict[str, str] -else: + # Not same as os.environ or os.environb + # Because of this variable, we can't do "from posix import *" in os/__init__.pyi environ: dict[bytes, bytes] diff --git a/mypy/typeshed/stdlib/posixpath.pyi b/mypy/typeshed/stdlib/posixpath.pyi index ae3d0d5cc65f..58cadb4de03c 100644 --- a/mypy/typeshed/stdlib/posixpath.pyi +++ b/mypy/typeshed/stdlib/posixpath.pyi @@ -60,10 +60,14 @@ def normpath(path: AnyStr) -> AnyStr: ... def commonpath(paths: Sequence[StrPath]) -> str: ... @overload def commonpath(paths: Sequence[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, +# as the parameter name is different in ntpath.join() @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 cb0cbf7c9388..7581c0122c9c 100644 --- a/mypy/typeshed/stdlib/profile.pyi +++ b/mypy/typeshed/stdlib/profile.pyi @@ -1,5 +1,5 @@ from _typeshed import StrOrBytesPath -from typing import Any, Callable, Tuple, TypeVar +from typing import Any, Callable, TypeVar def run(statement: str, filename: str | None = ..., sort: str | int = ...) -> None: ... def runctx( @@ -8,7 +8,7 @@ def runctx( _SelfT = TypeVar("_SelfT", bound=Profile) _T = TypeVar("_T") -_Label = Tuple[str, int, str] +_Label = tuple[str, int, str] class Profile: bias: int diff --git a/mypy/typeshed/stdlib/pstats.pyi b/mypy/typeshed/stdlib/pstats.pyi index e8256f9f98ab..6e008c823ff2 100644 --- a/mypy/typeshed/stdlib/pstats.pyi +++ b/mypy/typeshed/stdlib/pstats.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import StrOrBytesPath from cProfile import Profile as _cProfile from profile import Profile -from typing import IO, Any, Iterable, Tuple, TypeVar, Union, overload +from typing import IO, Any, Iterable, TypeVar, Union, overload _Selector = Union[str, float, int] _T = TypeVar("_T", bound=Stats) @@ -33,7 +33,7 @@ class Stats: def get_top_level_stats(self) -> None: ... def add(self: _T, *arg_list: None | str | Profile | _cProfile | _T) -> _T: ... def dump_stats(self, filename: StrOrBytesPath) -> None: ... - def get_sort_arg_defs(self) -> dict[str, tuple[Tuple[tuple[int, int], ...], str]]: ... + def get_sort_arg_defs(self) -> dict[str, tuple[tuple[tuple[int, int], ...], str]]: ... @overload def sort_stats(self: _T, field: int) -> _T: ... @overload diff --git a/mypy/typeshed/stdlib/pty.pyi b/mypy/typeshed/stdlib/pty.pyi index f943cebdb157..73c6ddfbd0c4 100644 --- a/mypy/typeshed/stdlib/pty.pyi +++ b/mypy/typeshed/stdlib/pty.pyi @@ -1,15 +1,18 @@ +import sys from typing import Callable, Iterable +from typing_extensions import Literal -_Reader = Callable[[int], bytes] +if sys.platform != "win32": + __all__ = ["openpty", "fork", "spawn"] + _Reader = Callable[[int], bytes] -STDIN_FILENO: int -STDOUT_FILENO: int -STDERR_FILENO: int + STDIN_FILENO: Literal[0] + STDOUT_FILENO: Literal[1] + STDERR_FILENO: Literal[2] -CHILD: int - -def openpty() -> tuple[int, int]: ... -def master_open() -> tuple[int, str]: ... -def slave_open(tty_name: str) -> int: ... -def fork() -> tuple[int, int]: ... -def spawn(argv: str | Iterable[str], master_read: _Reader = ..., stdin_read: _Reader = ...) -> int: ... + CHILD: Literal[0] + def openpty() -> tuple[int, int]: ... + def master_open() -> tuple[int, str]: ... # deprecated, use openpty() + def slave_open(tty_name: str) -> int: ... # deprecated, use openpty() + def fork() -> tuple[int, int]: ... + def spawn(argv: str | Iterable[str], master_read: _Reader = ..., stdin_read: _Reader = ...) -> int: ... diff --git a/mypy/typeshed/stdlib/pwd.pyi b/mypy/typeshed/stdlib/pwd.pyi index 2b931248edda..08a9facf642e 100644 --- a/mypy/typeshed/stdlib/pwd.pyi +++ b/mypy/typeshed/stdlib/pwd.pyi @@ -1,18 +1,25 @@ -from typing import ClassVar, Tuple +import sys +from _typeshed import structseq +from typing import Any +from typing_extensions import final -class struct_passwd(Tuple[str, str, int, int, str, str, str]): - pw_name: str - pw_passwd: str - pw_uid: int - pw_gid: int - pw_gecos: str - pw_dir: str - pw_shell: str - - n_fields: ClassVar[int] - n_sequence_fields: ClassVar[int] - n_unnamed_fields: ClassVar[int] - -def getpwall() -> list[struct_passwd]: ... -def getpwuid(__uid: int) -> struct_passwd: ... -def getpwnam(__name: str) -> struct_passwd: ... +if sys.platform != "win32": + @final + class struct_passwd(structseq[Any], tuple[str, str, int, int, str, str, str]): + @property + def pw_name(self) -> str: ... + @property + def pw_passwd(self) -> str: ... + @property + def pw_uid(self) -> int: ... + @property + def pw_gid(self) -> int: ... + @property + def pw_gecos(self) -> str: ... + @property + def pw_dir(self) -> str: ... + @property + def pw_shell(self) -> str: ... + def getpwall() -> list[struct_passwd]: ... + def getpwuid(__uid: int) -> struct_passwd: ... + def getpwnam(__name: str) -> struct_passwd: ... diff --git a/mypy/typeshed/stdlib/pydoc.pyi b/mypy/typeshed/stdlib/pydoc.pyi index 97e71f389616..a1d4359d28fc 100644 --- a/mypy/typeshed/stdlib/pydoc.pyi +++ b/mypy/typeshed/stdlib/pydoc.pyi @@ -1,10 +1,10 @@ from _typeshed import SupportsWrite from reprlib import Repr from types import MethodType, ModuleType, TracebackType -from typing import IO, Any, AnyStr, Callable, Container, Mapping, MutableMapping, NoReturn, Optional, Tuple, Type +from typing import IO, Any, AnyStr, Callable, Container, Mapping, MutableMapping, NoReturn, Optional, Type # the return type of sys.exc_info(), used by ErrorDuringImport.__init__ -_Exc_Info = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] +_Exc_Info = tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] __author__: str __date__: str @@ -96,7 +96,7 @@ class HTMLDoc(Doc): methods: Mapping[str, str] = ..., ) -> str: ... def formattree( - self, tree: list[tuple[type, Tuple[type, ...]] | list[Any]], modname: str, parent: type | None = ... + self, tree: list[tuple[type, tuple[type, ...]] | list[Any]], modname: str, parent: type | None = ... ) -> str: ... def docmodule(self, object: object, name: str | None = ..., mod: str | None = ..., *ignored: Any) -> str: ... def docclass( @@ -109,7 +109,7 @@ class HTMLDoc(Doc): *ignored: Any, ) -> str: ... def formatvalue(self, object: object) -> str: ... - def docroutine( + def docroutine( # type: ignore[override] self, object: object, name: str | None = ..., @@ -118,15 +118,10 @@ class HTMLDoc(Doc): classes: Mapping[str, str] = ..., methods: Mapping[str, str] = ..., cl: type | None = ..., - *ignored: Any, - ) -> str: ... - def docproperty( - self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ..., *ignored: Any ) -> str: ... + def docproperty(self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ...) -> str: ... # type: ignore[override] def docother(self, object: object, name: str | None = ..., mod: Any | None = ..., *ignored: Any) -> str: ... - def docdata( - self, object: object, name: str | None = ..., mod: Any | None = ..., cl: Any | None = ..., *ignored: Any - ) -> str: ... + def docdata(self, object: object, name: str | None = ..., mod: Any | None = ..., cl: Any | None = ...) -> str: ... # type: ignore[override] def index(self, dir: str, shadowed: MutableMapping[str, bool] | None = ...) -> str: ... def filelink(self, url: str, path: str) -> str: ... @@ -148,21 +143,15 @@ class TextDoc(Doc): def indent(self, text: str, prefix: str = ...) -> str: ... def section(self, title: str, contents: str) -> str: ... def formattree( - self, tree: list[tuple[type, Tuple[type, ...]] | list[Any]], modname: str, parent: type | None = ..., prefix: str = ... + self, tree: list[tuple[type, tuple[type, ...]] | list[Any]], modname: str, parent: type | None = ..., prefix: str = ... ) -> str: ... - def docmodule(self, object: object, name: str | None = ..., mod: Any | None = ..., *ignored: Any) -> str: ... + def docmodule(self, object: object, name: str | None = ..., mod: Any | None = ...) -> str: ... # type: ignore[override] def docclass(self, object: object, name: str | None = ..., mod: str | None = ..., *ignored: Any) -> str: ... def formatvalue(self, object: object) -> str: ... - def docroutine( - self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ..., *ignored: Any - ) -> str: ... - def docproperty( - self, object: object, name: str | None = ..., mod: Any | None = ..., cl: Any | None = ..., *ignored: Any - ) -> str: ... - def docdata( - self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ..., *ignored: Any - ) -> str: ... - def docother( + def docroutine(self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ...) -> str: ... # type: ignore[override] + def docproperty(self, object: object, name: str | None = ..., mod: Any | None = ..., cl: Any | None = ...) -> str: ... # type: ignore[override] + def docdata(self, object: object, name: str | None = ..., mod: str | None = ..., cl: Any | None = ...) -> str: ... # type: ignore[override] + def docother( # type: ignore[override] self, object: object, name: str | None = ..., @@ -170,7 +159,6 @@ class TextDoc(Doc): parent: str | None = ..., maxlen: int | None = ..., doc: Any | None = ..., - *ignored: Any, ) -> str: ... def pager(text: str) -> None: ... @@ -199,7 +187,7 @@ _list = list # "list" conflicts with method name class Helper: keywords: dict[str, str | tuple[str, str]] symbols: dict[str, str] - topics: dict[str, str | Tuple[str, ...]] + topics: dict[str, str | tuple[str, ...]] def __init__(self, input: IO[str] | None = ..., output: IO[str] | None = ...) -> None: ... input: IO[str] output: IO[str] diff --git a/mypy/typeshed/stdlib/pyexpat/__init__.pyi b/mypy/typeshed/stdlib/pyexpat/__init__.pyi index 6a3d6cd56791..5aca55c2b813 100644 --- a/mypy/typeshed/stdlib/pyexpat/__init__.pyi +++ b/mypy/typeshed/stdlib/pyexpat/__init__.pyi @@ -1,7 +1,7 @@ import pyexpat.errors as errors import pyexpat.model as model from _typeshed import SupportsRead -from typing import Any, Callable, Optional, Tuple +from typing import Any, Callable, Optional from typing_extensions import final EXPAT_VERSION: str # undocumented @@ -20,10 +20,10 @@ XML_PARAM_ENTITY_PARSING_NEVER: int XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE: int XML_PARAM_ENTITY_PARSING_ALWAYS: int -_Model = Tuple[int, int, Optional[str], Tuple[Any, ...]] +_Model = tuple[int, int, Optional[str], tuple[Any, ...]] @final -class XMLParserType(object): +class XMLParserType: def Parse(self, __data: str | bytes, __isfinal: bool = ...) -> int: ... def ParseFile(self, __file: SupportsRead[bytes]) -> int: ... def SetBase(self, __base: str) -> None: ... diff --git a/mypy/typeshed/stdlib/random.pyi b/mypy/typeshed/stdlib/random.pyi index 73c29d2f78c3..ffa866ef9aa0 100644 --- a/mypy/typeshed/stdlib/random.pyi +++ b/mypy/typeshed/stdlib/random.pyi @@ -1,25 +1,27 @@ import _random import sys +from _typeshed import SupportsLenAndGetItem from collections.abc import Callable, Iterable, MutableSequence, Sequence, Set as AbstractSet from fractions import Fraction -from typing import Any, NoReturn, Tuple, TypeVar +from typing import Any, ClassVar, NoReturn, TypeVar _T = TypeVar("_T") class Random(_random.Random): + VERSION: ClassVar[int] def __init__(self, x: Any = ...) -> None: ... def seed(self, a: Any = ..., version: int = ...) -> None: ... - def getstate(self) -> Tuple[Any, ...]: ... - def setstate(self, state: Tuple[Any, ...]) -> None: ... + def getstate(self) -> tuple[Any, ...]: ... + def setstate(self, state: tuple[Any, ...]) -> None: ... def getrandbits(self, __k: int) -> int: ... def randrange(self, start: int, stop: int | None = ..., step: int = ...) -> int: ... def randint(self, a: int, b: int) -> int: ... if sys.version_info >= (3, 9): def randbytes(self, n: int) -> bytes: ... - def choice(self, seq: Sequence[_T]) -> _T: ... + def choice(self, seq: SupportsLenAndGetItem[_T]) -> _T: ... def choices( self, - population: Sequence[_T], + population: SupportsLenAndGetItem[_T], weights: Sequence[float | Fraction] | None = ..., *, cum_weights: Sequence[float | Fraction] | None = ..., @@ -27,7 +29,9 @@ class Random(_random.Random): ) -> list[_T]: ... def shuffle(self, x: MutableSequence[Any], random: Callable[[], float] | None = ...) -> None: ... if sys.version_info >= (3, 9): - def sample(self, population: Sequence[_T] | AbstractSet[_T], k: int, *, counts: Iterable[_T] | None = ...) -> list[_T]: ... + def sample( + self, population: Sequence[_T] | AbstractSet[_T], k: int, *, counts: Iterable[_T] | None = ... + ) -> list[_T]: ... else: def sample(self, population: Sequence[_T] | AbstractSet[_T], k: int) -> list[_T]: ... def random(self) -> float: ... @@ -45,6 +49,7 @@ class Random(_random.Random): # SystemRandom is not implemented for all OS's; good on Windows & Linux class SystemRandom(Random): + def getrandbits(self, k: int) -> int: ... # k can be passed by keyword def getstate(self, *args: Any, **kwds: Any) -> NoReturn: ... def setstate(self, *args: Any, **kwds: Any) -> NoReturn: ... @@ -59,9 +64,13 @@ def randint(a: int, b: int) -> int: ... if sys.version_info >= (3, 9): def randbytes(n: int) -> bytes: ... -def choice(seq: Sequence[_T]) -> _T: ... +def choice(seq: SupportsLenAndGetItem[_T]) -> _T: ... def choices( - population: Sequence[_T], weights: Sequence[float] | None = ..., *, cum_weights: Sequence[float] | None = ..., k: int = ... + population: SupportsLenAndGetItem[_T], + weights: Sequence[float] | None = ..., + *, + cum_weights: Sequence[float] | None = ..., + k: int = ..., ) -> list[_T]: ... def shuffle(x: MutableSequence[Any], random: Callable[[], float] | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/readline.pyi b/mypy/typeshed/stdlib/readline.pyi index 2de749b2c216..fd3a4b1dcc65 100644 --- a/mypy/typeshed/stdlib/readline.pyi +++ b/mypy/typeshed/stdlib/readline.pyi @@ -1,33 +1,34 @@ +import sys from _typeshed import StrOrBytesPath from typing import Callable, Optional, Sequence -_CompleterT = Optional[Callable[[str, int], Optional[str]]] -_CompDispT = Optional[Callable[[str, Sequence[str], int], None]] - -def parse_and_bind(__string: str) -> None: ... -def read_init_file(__filename: StrOrBytesPath | None = ...) -> None: ... -def get_line_buffer() -> str: ... -def insert_text(__string: str) -> None: ... -def redisplay() -> None: ... -def read_history_file(__filename: StrOrBytesPath | None = ...) -> None: ... -def write_history_file(__filename: StrOrBytesPath | None = ...) -> None: ... -def append_history_file(__nelements: int, __filename: StrOrBytesPath | None = ...) -> None: ... -def get_history_length() -> int: ... -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[[], None] | None = ...) -> None: ... -def set_pre_input_hook(__function: Callable[[], None] | None = ...) -> None: ... -def set_completer(__function: _CompleterT = ...) -> None: ... -def get_completer() -> _CompleterT: ... -def get_completion_type() -> int: ... -def get_begidx() -> int: ... -def get_endidx() -> int: ... -def set_completer_delims(__string: str) -> None: ... -def get_completer_delims() -> str: ... -def set_completion_display_matches_hook(__function: _CompDispT = ...) -> None: ... +if sys.platform != "win32": + _CompleterT = Optional[Callable[[str, int], Optional[str]]] + _CompDispT = Optional[Callable[[str, Sequence[str], int], None]] + def parse_and_bind(__string: str) -> None: ... + def read_init_file(__filename: StrOrBytesPath | None = ...) -> None: ... + def get_line_buffer() -> str: ... + def insert_text(__string: str) -> None: ... + def redisplay() -> None: ... + def read_history_file(__filename: StrOrBytesPath | None = ...) -> None: ... + def write_history_file(__filename: StrOrBytesPath | None = ...) -> None: ... + def append_history_file(__nelements: int, __filename: StrOrBytesPath | None = ...) -> None: ... + def get_history_length() -> int: ... + 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[[], None] | None = ...) -> None: ... + def set_pre_input_hook(__function: Callable[[], None] | None = ...) -> None: ... + def set_completer(__function: _CompleterT = ...) -> None: ... + def get_completer() -> _CompleterT: ... + def get_completion_type() -> int: ... + def get_begidx() -> int: ... + def get_endidx() -> int: ... + def set_completer_delims(__string: str) -> None: ... + def get_completer_delims() -> str: ... + def set_completion_display_matches_hook(__function: _CompDispT = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/reprlib.pyi b/mypy/typeshed/stdlib/reprlib.pyi index 4d400554a4ff..2095c0af6983 100644 --- a/mypy/typeshed/stdlib/reprlib.pyi +++ b/mypy/typeshed/stdlib/reprlib.pyi @@ -1,6 +1,6 @@ from array import array from collections import deque -from typing import Any, Callable, Tuple +from typing import Any, Callable _ReprFunc = Callable[[Any], str] @@ -21,7 +21,7 @@ class Repr: def __init__(self) -> None: ... def repr(self, x: Any) -> str: ... def repr1(self, x: Any, level: int) -> str: ... - def repr_tuple(self, x: Tuple[Any, ...], level: int) -> str: ... + def repr_tuple(self, x: tuple[Any, ...], level: int) -> str: ... def repr_list(self, x: list[Any], level: int) -> str: ... def repr_array(self, x: array[Any], level: int) -> str: ... def repr_set(self, x: set[Any], level: int) -> str: ... diff --git a/mypy/typeshed/stdlib/resource.pyi b/mypy/typeshed/stdlib/resource.pyi index d7124edcc2fa..19a6f470b775 100644 --- a/mypy/typeshed/stdlib/resource.pyi +++ b/mypy/typeshed/stdlib/resource.pyi @@ -1,58 +1,73 @@ import sys -from typing import Any, Tuple, overload +from _typeshed import structseq +from typing import overload +from typing_extensions import final -RLIMIT_AS: int -RLIMIT_CORE: int -RLIMIT_CPU: int -RLIMIT_DATA: int -RLIMIT_FSIZE: int -RLIMIT_MEMLOCK: int -RLIMIT_NOFILE: int -RLIMIT_NPROC: int -RLIMIT_RSS: int -RLIMIT_STACK: int -RLIM_INFINITY: int -RUSAGE_CHILDREN: int -RUSAGE_SELF: int -if sys.platform == "linux": - RLIMIT_MSGQUEUE: int - RLIMIT_NICE: int - RLIMIT_OFILE: int - RLIMIT_RTPRIO: int - RLIMIT_RTTIME: int - RLIMIT_SIGPENDING: int - RUSAGE_THREAD: int - -_Tuple16 = Tuple[float, float, int, int, int, int, int, int, int, int, int, int, int, int, int, int] - -class struct_rusage(_Tuple16): - def __new__(cls, sequence: _Tuple16, dict: dict[str, Any] = ...) -> struct_rusage: ... - ru_utime: float - ru_stime: float - ru_maxrss: int - ru_ixrss: int - ru_idrss: int - ru_isrss: int - ru_minflt: int - ru_majflt: int - ru_nswap: int - ru_inblock: int - ru_oublock: int - ru_msgsnd: int - ru_msgrcv: int - ru_nsignals: int - ru_nvcsw: int - ru_nivcsw: 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: ... - -if sys.platform == "linux": - @overload - def prlimit(pid: int, resource: int, limits: tuple[int, int]) -> tuple[int, int]: ... - @overload - def prlimit(pid: int, resource: int) -> tuple[int, int]: ... - -error = OSError +if sys.platform != "win32": + RLIMIT_AS: int + RLIMIT_CORE: int + RLIMIT_CPU: int + RLIMIT_DATA: int + RLIMIT_FSIZE: int + RLIMIT_MEMLOCK: int + RLIMIT_NOFILE: int + RLIMIT_NPROC: int + RLIMIT_RSS: int + RLIMIT_STACK: int + RLIM_INFINITY: int + RUSAGE_CHILDREN: int + RUSAGE_SELF: int + if sys.platform == "linux": + RLIMIT_MSGQUEUE: int + RLIMIT_NICE: int + RLIMIT_OFILE: int + RLIMIT_RTPRIO: int + 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] + ): + @property + def ru_utime(self) -> float: ... + @property + def ru_stime(self) -> float: ... + @property + def ru_maxrss(self) -> int: ... + @property + def ru_ixrss(self) -> int: ... + @property + def ru_idrss(self) -> int: ... + @property + def ru_isrss(self) -> int: ... + @property + def ru_minflt(self) -> int: ... + @property + def ru_majflt(self) -> int: ... + @property + def ru_nswap(self) -> int: ... + @property + def ru_inblock(self) -> int: ... + @property + def ru_oublock(self) -> int: ... + @property + def ru_msgsnd(self) -> int: ... + @property + def ru_msgrcv(self) -> int: ... + @property + def ru_nsignals(self) -> int: ... + @property + def ru_nvcsw(self) -> int: ... + @property + 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: ... + if sys.platform == "linux": + @overload + def prlimit(pid: int, resource: int, limits: tuple[int, int]) -> tuple[int, int]: ... + @overload + def prlimit(pid: int, resource: int) -> tuple[int, int]: ... + error = OSError diff --git a/mypy/typeshed/stdlib/sched.pyi b/mypy/typeshed/stdlib/sched.pyi index cb96dc2bbf4a..71aacc5c2610 100644 --- a/mypy/typeshed/stdlib/sched.pyi +++ b/mypy/typeshed/stdlib/sched.pyi @@ -1,10 +1,10 @@ -from typing import Any, Callable, NamedTuple, Tuple +from typing import Any, Callable, NamedTuple class Event(NamedTuple): time: float priority: Any action: Callable[..., Any] - argument: Tuple[Any, ...] + argument: tuple[Any, ...] kwargs: dict[str, Any] class scheduler: @@ -14,7 +14,7 @@ class scheduler: time: float, priority: Any, action: Callable[..., Any], - argument: Tuple[Any, ...] = ..., + argument: tuple[Any, ...] = ..., kwargs: dict[str, Any] = ..., ) -> Event: ... def enter( @@ -22,7 +22,7 @@ class scheduler: delay: float, priority: Any, action: Callable[..., Any], - argument: Tuple[Any, ...] = ..., + argument: tuple[Any, ...] = ..., kwargs: dict[str, Any] = ..., ) -> Event: ... def run(self, blocking: bool = ...) -> float | None: ... diff --git a/mypy/typeshed/stdlib/secrets.pyi b/mypy/typeshed/stdlib/secrets.pyi index 6752a30f431e..f57eef8492d7 100644 --- a/mypy/typeshed/stdlib/secrets.pyi +++ b/mypy/typeshed/stdlib/secrets.pyi @@ -1,12 +1,13 @@ +from _typeshed import SupportsLenAndGetItem from hmac import compare_digest as compare_digest from random import SystemRandom as SystemRandom -from typing import Sequence, TypeVar +from typing import TypeVar _T = TypeVar("_T") def randbelow(exclusive_upper_bound: int) -> int: ... def randbits(k: int) -> int: ... -def choice(seq: Sequence[_T]) -> _T: ... +def choice(seq: SupportsLenAndGetItem[_T]) -> _T: ... def token_bytes(nbytes: int | None = ...) -> bytes: ... def token_hex(nbytes: int | None = ...) -> str: ... def token_urlsafe(nbytes: int | None = ...) -> str: ... diff --git a/mypy/typeshed/stdlib/select.pyi b/mypy/typeshed/stdlib/select.pyi index 0329dbaa2c11..e57504b5b447 100644 --- a/mypy/typeshed/stdlib/select.pyi +++ b/mypy/typeshed/stdlib/select.pyi @@ -13,6 +13,7 @@ if sys.platform != "win32": POLLOUT: int POLLPRI: int POLLRDBAND: int + POLLRDHUP: int POLLRDNORM: int POLLWRBAND: int POLLWRNORM: int @@ -32,7 +33,7 @@ error = OSError if sys.platform != "linux" and sys.platform != "win32": # BSD only - class kevent(object): + class kevent: data: Any fflags: int filter: int @@ -49,7 +50,7 @@ if sys.platform != "linux" and sys.platform != "win32": udata: Any = ..., ) -> None: ... # BSD only - class kqueue(object): + class kqueue: closed: bool def __init__(self) -> None: ... def close(self) -> None: ... @@ -99,7 +100,7 @@ if sys.platform != "linux" and sys.platform != "win32": KQ_NOTE_WRITE: int if sys.platform == "linux": - class epoll(object): + class epoll: def __init__(self, sizehint: int = ..., flags: int = ...) -> None: ... def __enter__(self: Self) -> Self: ... def __exit__( @@ -118,6 +119,7 @@ if sys.platform == "linux": @classmethod def fromfd(cls, __fd: FileDescriptorLike) -> epoll: ... EPOLLERR: int + EPOLLEXCLUSIVE: int EPOLLET: int EPOLLHUP: int EPOLLIN: int @@ -126,10 +128,12 @@ if sys.platform == "linux": EPOLLOUT: int EPOLLPRI: int EPOLLRDBAND: int + EPOLLRDHUP: int EPOLLRDNORM: int EPOLLWRBAND: int EPOLLWRNORM: int EPOLL_RDHUP: int + EPOLL_CLOEXEC: int if sys.platform != "linux" and sys.platform != "darwin" and sys.platform != "win32": # Solaris only diff --git a/mypy/typeshed/stdlib/signal.pyi b/mypy/typeshed/stdlib/signal.pyi index d617e24f227f..777391662aa3 100644 --- a/mypy/typeshed/stdlib/signal.pyi +++ b/mypy/typeshed/stdlib/signal.pyi @@ -1,56 +1,40 @@ import sys +from _typeshed import structseq from enum import IntEnum from types import FrameType -from typing import Any, Callable, Iterable, Optional, Tuple, Union - -if sys.platform != "win32": - class ItimerError(IOError): ... - ITIMER_PROF: int - ITIMER_REAL: int - ITIMER_VIRTUAL: int +from typing import Any, Callable, Iterable, Optional, Union +from typing_extensions import final NSIG: int class Signals(IntEnum): SIGABRT: int - if sys.platform != "win32": - SIGALRM: int + SIGEMT: int + SIGFPE: int + SIGILL: int + SIGINFO: int + SIGINT: int + SIGSEGV: int + SIGTERM: int + if sys.platform == "win32": SIGBREAK: int - if sys.platform != "win32": + CTRL_C_EVENT: int + CTRL_BREAK_EVENT: int + else: + SIGALRM: int SIGBUS: int SIGCHLD: int - if sys.platform != "darwin" and sys.platform != "win32": - SIGCLD: int - if sys.platform != "win32": SIGCONT: int - SIGEMT: int - SIGFPE: int - if sys.platform != "win32": SIGHUP: int - SIGILL: int - SIGINFO: int - SIGINT: int - if sys.platform != "win32": SIGIO: int SIGIOT: int SIGKILL: int SIGPIPE: int - if sys.platform != "darwin" and sys.platform != "win32": - SIGPOLL: int - SIGPWR: int - if sys.platform != "win32": SIGPROF: int SIGQUIT: int - if sys.platform != "darwin" and sys.platform != "win32": - SIGRTMAX: int - SIGRTMIN: int - SIGSEGV: int - if sys.platform != "win32": SIGSTOP: int SIGSYS: int - SIGTERM: int - if sys.platform != "win32": SIGTRAP: int SIGTSTP: int SIGTTIN: int @@ -62,65 +46,54 @@ class Signals(IntEnum): SIGWINCH: int SIGXCPU: int SIGXFSZ: int + if sys.platform != "darwin": + SIGCLD: int + SIGPOLL: int + SIGPWR: int + SIGRTMAX: int + SIGRTMIN: int class Handlers(IntEnum): SIG_DFL: int SIG_IGN: int -SIG_DFL = Handlers.SIG_DFL -SIG_IGN = Handlers.SIG_IGN - -if sys.platform != "win32": - class Sigmasks(IntEnum): - SIG_BLOCK: int - SIG_UNBLOCK: int - SIG_SETMASK: int - SIG_BLOCK = Sigmasks.SIG_BLOCK - SIG_UNBLOCK = Sigmasks.SIG_UNBLOCK - SIG_SETMASK = Sigmasks.SIG_SETMASK +SIG_DFL: Handlers +SIG_IGN: Handlers _SIGNUM = Union[int, Signals] _HANDLER = Union[Callable[[int, Optional[FrameType]], Any], int, Handlers, None] +def default_int_handler(signum: int, frame: FrameType | None) -> None: ... +def getsignal(__signalnum: _SIGNUM) -> _HANDLER: ... +def signal(__signalnum: _SIGNUM, __handler: _HANDLER) -> _HANDLER: ... + SIGABRT: Signals -if sys.platform != "win32": - SIGALRM: Signals +SIGEMT: Signals +SIGFPE: Signals +SIGILL: Signals +SIGINFO: Signals +SIGINT: Signals +SIGSEGV: Signals +SIGTERM: Signals + if sys.platform == "win32": SIGBREAK: Signals -if sys.platform != "win32": + CTRL_C_EVENT: Signals + CTRL_BREAK_EVENT: Signals +else: + SIGALRM: Signals SIGBUS: Signals SIGCHLD: Signals -if sys.platform != "darwin" and sys.platform != "win32": - SIGCLD: Signals -if sys.platform != "win32": SIGCONT: Signals -SIGEMT: Signals -SIGFPE: Signals -if sys.platform != "win32": SIGHUP: Signals -SIGILL: Signals -SIGINFO: Signals -SIGINT: Signals -if sys.platform != "win32": SIGIO: Signals SIGIOT: Signals SIGKILL: Signals SIGPIPE: Signals -if sys.platform != "darwin" and sys.platform != "win32": - SIGPOLL: Signals - SIGPWR: Signals -if sys.platform != "win32": SIGPROF: Signals SIGQUIT: Signals -if sys.platform != "darwin" and sys.platform != "win32": - SIGRTMAX: Signals - SIGRTMIN: Signals -SIGSEGV: Signals -if sys.platform != "win32": SIGSTOP: Signals SIGSYS: Signals -SIGTERM: Signals -if sys.platform != "win32": SIGTRAP: Signals SIGTSTP: Signals SIGTTIN: Signals @@ -132,64 +105,58 @@ if sys.platform != "win32": SIGWINCH: Signals SIGXCPU: Signals SIGXFSZ: Signals - -if sys.platform == "win32": - CTRL_C_EVENT: int - CTRL_BREAK_EVENT: int - -if sys.platform != "win32" and sys.platform != "darwin": - class struct_siginfo(Tuple[int, int, int, int, int, int, int]): - def __init__(self, sequence: Iterable[int]) -> None: ... - @property - def si_signo(self) -> int: ... - @property - def si_code(self) -> int: ... - @property - def si_errno(self) -> int: ... - @property - def si_pid(self) -> int: ... - @property - def si_uid(self) -> int: ... - @property - def si_status(self) -> int: ... - @property - def si_band(self) -> int: ... - -if sys.platform != "win32": + class ItimerError(IOError): ... + ITIMER_PROF: int + ITIMER_REAL: int + ITIMER_VIRTUAL: int + class Sigmasks(IntEnum): + SIG_BLOCK: int + SIG_UNBLOCK: int + SIG_SETMASK: int + SIG_BLOCK = Sigmasks.SIG_BLOCK + SIG_UNBLOCK = Sigmasks.SIG_UNBLOCK + SIG_SETMASK = Sigmasks.SIG_SETMASK def alarm(__seconds: int) -> int: ... - -def default_int_handler(signum: int, frame: FrameType) -> None: ... - -if sys.platform != "win32": def getitimer(__which: int) -> tuple[float, float]: ... - -def getsignal(__signalnum: _SIGNUM) -> _HANDLER: ... + def pause() -> None: ... + def pthread_kill(__thread_id: int, __signalnum: int) -> None: ... + def pthread_sigmask(__how: int, __mask: Iterable[int]) -> set[_SIGNUM]: ... + def setitimer(__which: int, __seconds: float, __interval: float = ...) -> tuple[float, float]: ... + def siginterrupt(__signalnum: int, __flag: bool) -> None: ... + def sigpending() -> Any: ... + def sigwait(__sigset: Iterable[int]) -> _SIGNUM: ... + if sys.platform != "darwin": + SIGCLD: Signals + SIGPOLL: Signals + SIGPWR: Signals + SIGRTMAX: Signals + SIGRTMIN: Signals + @final + class struct_siginfo(structseq[int], tuple[int, int, int, int, int, int, int]): + @property + def si_signo(self) -> int: ... + @property + def si_code(self) -> int: ... + @property + def si_errno(self) -> int: ... + @property + def si_pid(self) -> int: ... + @property + def si_uid(self) -> int: ... + @property + def si_status(self) -> int: ... + @property + def si_band(self) -> int: ... + 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: ... -if sys.platform != "win32": - def pause() -> None: ... - def pthread_kill(__thread_id: int, __signalnum: int) -> None: ... - def pthread_sigmask(__how: int, __mask: Iterable[int]) -> set[_SIGNUM]: ... - if sys.version_info >= (3, 7): def set_wakeup_fd(fd: int, *, warn_on_full_buffer: bool = ...) -> int: ... else: def set_wakeup_fd(fd: int) -> int: ... - -if sys.platform != "win32": - def setitimer(__which: int, __seconds: float, __interval: float = ...) -> tuple[float, float]: ... - def siginterrupt(__signalnum: int, __flag: bool) -> None: ... - -def signal(__signalnum: _SIGNUM, __handler: _HANDLER) -> _HANDLER: ... - -if sys.platform != "win32": - def sigpending() -> Any: ... - def sigwait(__sigset: Iterable[int]) -> _SIGNUM: ... - if sys.platform != "darwin": - def sigtimedwait(sigset: Iterable[int], timeout: float) -> struct_siginfo | None: ... - def sigwaitinfo(sigset: Iterable[int]) -> struct_siginfo: ... diff --git a/mypy/typeshed/stdlib/smtpd.pyi b/mypy/typeshed/stdlib/smtpd.pyi index 2b6020524827..e5401552caae 100644 --- a/mypy/typeshed/stdlib/smtpd.pyi +++ b/mypy/typeshed/stdlib/smtpd.pyi @@ -2,9 +2,9 @@ import asynchat import asyncore import socket from collections import defaultdict -from typing import Any, Tuple, Type +from typing import Any, Type -_Address = Tuple[str, int] # (host, port) +_Address = tuple[str, int] # (host, port) class SMTPChannel(asynchat.async_chat): COMMAND: int @@ -40,7 +40,7 @@ class SMTPChannel(asynchat.async_chat): decode_data: bool = ..., ) -> None: ... # base asynchat.async_chat.push() accepts bytes - def push(self, msg: str) -> None: ... # type: ignore + def push(self, msg: str) -> None: ... # type: ignore[override] def collect_incoming_data(self, data: bytes) -> None: ... def found_terminator(self) -> None: ... def smtp_HELO(self, arg: str) -> None: ... @@ -77,11 +77,7 @@ class SMTPServer(asyncore.dispatcher): class DebuggingServer(SMTPServer): ... class PureProxy(SMTPServer): - def process_message( # type: ignore - self, peer: _Address, mailfrom: str, rcpttos: list[str], data: bytes | str - ) -> str | None: ... + def process_message(self, peer: _Address, mailfrom: str, rcpttos: list[str], data: bytes | str) -> str | None: ... # type: ignore[override] class MailmanProxy(PureProxy): - def process_message( # type: ignore - self, peer: _Address, mailfrom: str, rcpttos: list[str], data: bytes | str - ) -> str | None: ... + def process_message(self, peer: _Address, mailfrom: str, rcpttos: list[str], data: bytes | str) -> str | None: ... # type: ignore[override] diff --git a/mypy/typeshed/stdlib/smtplib.pyi b/mypy/typeshed/stdlib/smtplib.pyi index 5dbdf5d44c29..0a57f1f5d2de 100644 --- a/mypy/typeshed/stdlib/smtplib.pyi +++ b/mypy/typeshed/stdlib/smtplib.pyi @@ -1,14 +1,15 @@ +import sys from _typeshed import Self from email.message import Message as _Message from socket import socket from ssl import SSLContext from types import TracebackType -from typing import Any, Dict, Pattern, Protocol, Sequence, Tuple, Type, Union, overload +from typing import Any, Pattern, Protocol, Sequence, Type, Union, overload -_Reply = Tuple[int, bytes] -_SendErrs = Dict[str, _Reply] +_Reply = tuple[int, bytes] +_SendErrs = dict[str, _Reply] # Should match source_address for socket.create_connection -_SourceAddress = Tuple[Union[bytearray, bytes, str], int] +_SourceAddress = tuple[Union[bytearray, bytes, str], int] SMTP_PORT: int SMTP_SSL_PORT: int @@ -149,6 +150,16 @@ class SMTP_SSL(SMTP): LMTP_PORT: int class LMTP(SMTP): - def __init__( - self, host: str = ..., port: int = ..., local_hostname: str | None = ..., source_address: _SourceAddress | None = ... - ) -> None: ... + if sys.version_info >= (3, 9): + def __init__( + self, + host: str = ..., + port: int = ..., + local_hostname: str | None = ..., + source_address: _SourceAddress | None = ..., + timeout: float = ..., + ) -> None: ... + else: + def __init__( + self, host: str = ..., port: int = ..., local_hostname: str | None = ..., source_address: _SourceAddress | None = ... + ) -> None: ... diff --git a/mypy/typeshed/stdlib/socket.pyi b/mypy/typeshed/stdlib/socket.pyi index 1f5ae6eb76c8..430fef4ff344 100644 --- a/mypy/typeshed/stdlib/socket.pyi +++ b/mypy/typeshed/stdlib/socket.pyi @@ -570,9 +570,9 @@ class socket(_socket.socket): ) -> BinaryIO: ... def sendfile(self, file: BinaryIO, offset: int = ..., count: int | None = ...) -> int: ... @property - def family(self) -> AddressFamily: ... # type: ignore + def family(self) -> AddressFamily: ... # type: ignore[override] @property - def type(self) -> SocketKind: ... # type: ignore + def type(self) -> SocketKind: ... # type: ignore[override] def get_inheritable(self) -> bool: ... def set_inheritable(self, inheritable: bool) -> None: ... @@ -593,7 +593,7 @@ if sys.platform == "win32": def socketpair(family: int = ..., type: int = ..., proto: int = ...) -> tuple[socket, socket]: ... else: - def socketpair( # type: ignore + def socketpair( family: int | AddressFamily | None = ..., type: SocketType | int = ..., proto: int = ... ) -> tuple[socket, socket]: ... diff --git a/mypy/typeshed/stdlib/socketserver.pyi b/mypy/typeshed/stdlib/socketserver.pyi index 6f5eeefb84fd..c663e73bef50 100644 --- a/mypy/typeshed/stdlib/socketserver.pyi +++ b/mypy/typeshed/stdlib/socketserver.pyi @@ -2,11 +2,11 @@ import sys import types from _typeshed import Self from socket import socket as _socket -from typing import Any, BinaryIO, Callable, ClassVar, Tuple, Type, TypeVar, Union +from typing import Any, BinaryIO, Callable, ClassVar, Type, TypeVar, Union _T = TypeVar("_T") -_RequestType = Union[_socket, Tuple[bytes, _socket]] -_AddressType = Union[Tuple[str, int], str] +_RequestType = Union[_socket, tuple[bytes, _socket]] +_AddressType = Union[tuple[str, int], str] class BaseServer: address_family: int @@ -55,6 +55,7 @@ class TCPServer(BaseServer): def close_request(self, request: _RequestType) -> None: ... # undocumented class UDPServer(BaseServer): + max_packet_size: ClassVar[int] def __init__( self, server_address: tuple[str, int], diff --git a/mypy/typeshed/stdlib/spwd.pyi b/mypy/typeshed/stdlib/spwd.pyi index 0f8d36fee945..7a62d62523f5 100644 --- a/mypy/typeshed/stdlib/spwd.pyi +++ b/mypy/typeshed/stdlib/spwd.pyi @@ -1,15 +1,28 @@ -from typing import NamedTuple +import sys +from _typeshed import structseq +from typing import Any +from typing_extensions import final -class struct_spwd(NamedTuple): - sp_namp: str - sp_pwdp: str - sp_lstchg: int - sp_min: int - sp_max: int - sp_warn: int - sp_inact: int - sp_expire: int - sp_flag: int - -def getspall() -> list[struct_spwd]: ... -def getspnam(__arg: str) -> struct_spwd: ... +if sys.platform != "win32": + @final + class struct_spwd(structseq[Any], tuple[str, str, int, int, int, int, int, int, int]): + @property + def sp_namp(self) -> str: ... + @property + def sp_pwdp(self) -> str: ... + @property + def sp_lstchg(self) -> int: ... + @property + def sp_min(self) -> int: ... + @property + def sp_max(self) -> int: ... + @property + def sp_warn(self) -> int: ... + @property + def sp_inact(self) -> int: ... + @property + def sp_expire(self) -> int: ... + @property + def sp_flag(self) -> int: ... + def getspall() -> list[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 e2e45d538da9..ea9098940d4b 100644 --- a/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi +++ b/mypy/typeshed/stdlib/sqlite3/dbapi2.pyi @@ -40,6 +40,8 @@ if sys.version_info >= (3, 7): SQLITE_DELETE: int SQLITE_DENY: int SQLITE_DETACH: int +if sys.version_info >= (3, 7): + SQLITE_DONE: int SQLITE_DROP_INDEX: int SQLITE_DROP_TABLE: int SQLITE_DROP_TEMP_INDEX: int @@ -83,7 +85,7 @@ version: str # TODO: adapt needs to get probed def adapt(obj, protocol, alternate): ... -def complete_statement(sql: str) -> bool: ... +def complete_statement(statement: str) -> bool: ... if sys.version_info >= (3, 7): def connect( @@ -115,7 +117,7 @@ def register_adapter(__type: Type[_T], __caster: Callable[[_T], int | float | st def register_converter(__name: str, __converter: Callable[[bytes], Any]) -> None: ... if sys.version_info < (3, 8): - class Cache(object): + class Cache: def __init__(self, *args, **kwargs) -> None: ... def display(self, *args, **kwargs) -> None: ... def get(self, *args, **kwargs) -> None: ... @@ -124,7 +126,7 @@ class _AggregateProtocol(Protocol): def step(self, value: int) -> None: ... def finalize(self) -> int: ... -class Connection(object): +class Connection: DataError: Any DatabaseError: Any Error: Any @@ -154,16 +156,14 @@ class Connection(object): # TODO: please check in executemany() if seq_of_parameters type is possible like this def executemany(self, __sql: str, __parameters: Iterable[Iterable[Any]]) -> Cursor: ... def executescript(self, __sql_script: bytes | str) -> Cursor: ... - def interrupt(self, *args: Any, **kwargs: Any) -> None: ... - def iterdump(self, *args: Any, **kwargs: Any) -> Generator[str, None, None]: ... - def rollback(self, *args: Any, **kwargs: Any) -> None: ... - # TODO: set_authorizer(authorzer_callback) - # see https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.set_authorizer - # returns [SQLITE_OK, SQLITE_DENY, SQLITE_IGNORE] so perhaps int - def set_authorizer(self, *args: Any, **kwargs: Any) -> None: ... - # set_progress_handler(handler, n) -> see https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.set_progress_handler - def set_progress_handler(self, *args: Any, **kwargs: Any) -> None: ... - def set_trace_callback(self, *args: Any, **kwargs: Any) -> None: ... + def interrupt(self) -> None: ... + def iterdump(self) -> Generator[str, None, None]: ... + def rollback(self) -> None: ... + def set_authorizer( + self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None + ) -> None: ... + def set_progress_handler(self, progress_handler: Callable[[], bool | None] | None, n: int) -> None: ... + 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, enabled: bool) -> None: ... @@ -193,21 +193,26 @@ class Cursor(Iterator[Any]): # required type is sqlite3.Connection (which is imported as _Connection) # however, the name of the __init__ variable is unknown def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def close(self, *args: Any, **kwargs: Any) -> None: ... + def close(self) -> None: ... def execute(self, __sql: str, __parameters: Iterable[Any] = ...) -> Cursor: ... def executemany(self, __sql: str, __seq_of_parameters: Iterable[Iterable[Any]]) -> Cursor: ... def executescript(self, __sql_script: bytes | str) -> Cursor: ... def fetchall(self) -> list[Any]: ... def fetchmany(self, size: int | None = ...) -> list[Any]: ... def fetchone(self) -> Any: ... - def setinputsizes(self, *args: Any, **kwargs: Any) -> None: ... - def setoutputsize(self, *args: Any, **kwargs: Any) -> None: ... + def setinputsizes(self, __sizes: object) -> None: ... # does nothing + def setoutputsize(self, __size: object, __column: object = ...) -> None: ... # does nothing def __iter__(self) -> Cursor: ... def __next__(self) -> Any: ... class DataError(DatabaseError): ... class DatabaseError(Error): ... -class Error(Exception): ... + +class Error(Exception): + if sys.version_info >= (3, 11): + sqlite_errorcode: int + sqlite_errorname: str + class IntegrityError(DatabaseError): ... class InterfaceError(Error): ... class InternalError(DatabaseError): ... @@ -216,14 +221,14 @@ class OperationalError(DatabaseError): ... OptimizedUnicode = str -class PrepareProtocol(object): +class PrepareProtocol: def __init__(self, *args: Any, **kwargs: Any) -> None: ... class ProgrammingError(DatabaseError): ... -class Row(object): +class Row: def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def keys(self, *args: Any, **kwargs: Any): ... + def keys(self): ... def __eq__(self, other): ... def __ge__(self, other): ... def __getitem__(self, index): ... @@ -236,7 +241,7 @@ class Row(object): def __ne__(self, other): ... if sys.version_info < (3, 8): - class Statement(object): + class Statement: def __init__(self, *args, **kwargs): ... class Warning(Exception): ... diff --git a/mypy/typeshed/stdlib/sre_compile.pyi b/mypy/typeshed/stdlib/sre_compile.pyi index aac8c0242764..98a9f4dad008 100644 --- a/mypy/typeshed/stdlib/sre_compile.pyi +++ b/mypy/typeshed/stdlib/sre_compile.pyi @@ -1,18 +1,5 @@ -from sre_constants import ( - SRE_FLAG_ASCII as SRE_FLAG_ASCII, - SRE_FLAG_DEBUG as SRE_FLAG_DEBUG, - SRE_FLAG_DOTALL as SRE_FLAG_DOTALL, - SRE_FLAG_IGNORECASE as SRE_FLAG_IGNORECASE, - SRE_FLAG_LOCALE as SRE_FLAG_LOCALE, - SRE_FLAG_MULTILINE as SRE_FLAG_MULTILINE, - SRE_FLAG_TEMPLATE as SRE_FLAG_TEMPLATE, - SRE_FLAG_UNICODE as SRE_FLAG_UNICODE, - SRE_FLAG_VERBOSE as SRE_FLAG_VERBOSE, - SRE_INFO_CHARSET as SRE_INFO_CHARSET, - SRE_INFO_LITERAL as SRE_INFO_LITERAL, - SRE_INFO_PREFIX as SRE_INFO_PREFIX, - _NamedIntConstant, -) +from sre_constants import * +from sre_constants import _NamedIntConstant from sre_parse import SubPattern from typing import Any, Pattern diff --git a/mypy/typeshed/stdlib/sre_constants.pyi b/mypy/typeshed/stdlib/sre_constants.pyi index 4658d0e4b175..df7e1a28007b 100644 --- a/mypy/typeshed/stdlib/sre_constants.pyi +++ b/mypy/typeshed/stdlib/sre_constants.pyi @@ -1,6 +1,8 @@ import sys from typing import Any +MAXGROUPS: int + MAGIC: int class error(Exception): @@ -20,6 +22,9 @@ OPCODES: list[_NamedIntConstant] ATCODES: list[_NamedIntConstant] CHCODES: list[_NamedIntConstant] OP_IGNORE: dict[_NamedIntConstant, _NamedIntConstant] +if sys.version_info >= (3, 7): + OP_LOCALE_IGNORE: dict[_NamedIntConstant, _NamedIntConstant] + OP_UNICODE_IGNORE: dict[_NamedIntConstant, _NamedIntConstant] AT_MULTILINE: dict[_NamedIntConstant, _NamedIntConstant] AT_LOCALE: dict[_NamedIntConstant, _NamedIntConstant] AT_UNICODE: dict[_NamedIntConstant, _NamedIntConstant] @@ -75,6 +80,14 @@ SUBPATTERN: _NamedIntConstant MIN_REPEAT_ONE: _NamedIntConstant if sys.version_info >= (3, 7): RANGE_UNI_IGNORE: _NamedIntConstant + GROUPREF_LOC_IGNORE: _NamedIntConstant + GROUPREF_UNI_IGNORE: _NamedIntConstant + IN_LOC_IGNORE: _NamedIntConstant + IN_UNI_IGNORE: _NamedIntConstant + LITERAL_LOC_IGNORE: _NamedIntConstant + LITERAL_UNI_IGNORE: _NamedIntConstant + NOT_LITERAL_LOC_IGNORE: _NamedIntConstant + NOT_LITERAL_UNI_IGNORE: _NamedIntConstant else: RANGE_IGNORE: _NamedIntConstant MIN_REPEAT: _NamedIntConstant diff --git a/mypy/typeshed/stdlib/sre_parse.pyi b/mypy/typeshed/stdlib/sre_parse.pyi index 2d00bedc2c81..c4de55bcbf7e 100644 --- a/mypy/typeshed/stdlib/sre_parse.pyi +++ b/mypy/typeshed/stdlib/sre_parse.pyi @@ -1,6 +1,7 @@ import sys +from sre_constants import * from sre_constants import _NamedIntConstant as _NIC, error as _Error -from typing import Any, Iterable, List, Match, Optional, Pattern as _Pattern, Tuple, Union, overload +from typing import Any, Iterable, Match, Optional, Pattern as _Pattern, Union, overload SPECIAL_CHARS: str REPEAT_CHARS: str @@ -12,6 +13,8 @@ WHITESPACE: frozenset[str] ESCAPES: dict[str, tuple[_NIC, int]] CATEGORIES: dict[str, tuple[_NIC, _NIC] | tuple[_NIC, list[tuple[_NIC, _NIC]]]] FLAGS: dict[str, int] +if sys.version_info >= (3, 7): + TYPE_FLAGS: int GLOBAL_FLAGS: int class Verbose(Exception): ... @@ -24,7 +27,7 @@ class _State: def __init__(self) -> None: ... @property def groups(self) -> int: ... - def opengroup(self, name: str = ...) -> int: ... + def opengroup(self, name: str | None = ...) -> int: ... def closegroup(self, gid: int, p: SubPattern) -> None: ... def checkgroup(self, gid: int) -> bool: ... def checklookbehindgroup(self, gid: int, source: Tokenizer) -> None: ... @@ -34,12 +37,12 @@ if sys.version_info >= (3, 8): else: Pattern = _State -_OpSubpatternType = Tuple[Optional[int], int, int, SubPattern] -_OpGroupRefExistsType = Tuple[int, SubPattern, SubPattern] -_OpInType = List[Tuple[_NIC, int]] -_OpBranchType = Tuple[None, List[SubPattern]] +_OpSubpatternType = tuple[Optional[int], int, int, SubPattern] +_OpGroupRefExistsType = tuple[int, SubPattern, SubPattern] +_OpInType = list[tuple[_NIC, int]] +_OpBranchType = tuple[None, list[SubPattern]] _AvType = Union[_OpInType, _OpBranchType, Iterable[SubPattern], _OpGroupRefExistsType, _OpSubpatternType] -_CodeType = Tuple[_NIC, _AvType] +_CodeType = tuple[_NIC, _AvType] class SubPattern: data: list[_CodeType] @@ -82,8 +85,8 @@ class Tokenizer: def fix_flags(src: str | bytes, flags: int) -> int: ... -_TemplateType = Tuple[List[Tuple[int, int]], List[Optional[str]]] -_TemplateByteType = Tuple[List[Tuple[int, int]], List[Optional[bytes]]] +_TemplateType = tuple[list[tuple[int, int]], list[Optional[str]]] +_TemplateByteType = tuple[list[tuple[int, int]], list[Optional[bytes]]] if sys.version_info >= (3, 8): def parse(str: str, flags: int = ..., state: State | None = ...) -> SubPattern: ... @overload diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index 689b083d764c..cdb727285647 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -2,14 +2,14 @@ import enum import socket import sys from _typeshed import ReadableBuffer, Self, StrOrBytesPath, WriteableBuffer -from typing import Any, Callable, ClassVar, Dict, Iterable, List, NamedTuple, Optional, Set, Tuple, Type, Union, overload +from typing import Any, Callable, ClassVar, Iterable, NamedTuple, Optional, Type, Union, overload from typing_extensions import Literal, TypedDict -_PCTRTT = Tuple[Tuple[str, str], ...] -_PCTRTTT = Tuple[_PCTRTT, ...] -_PeerCertRetDictType = Dict[str, Union[str, _PCTRTTT, _PCTRTT]] +_PCTRTT = tuple[tuple[str, str], ...] +_PCTRTTT = tuple[_PCTRTT, ...] +_PeerCertRetDictType = dict[str, Union[str, _PCTRTTT, _PCTRTT]] _PeerCertRetType = Union[_PeerCertRetDictType, bytes, None] -_EnumRetType = List[Tuple[bytes, str, Union[Set[str], bool]]] +_EnumRetType = list[tuple[bytes, str, Union[set[str], bool]]] _PasswordType = Union[Callable[[], Union[str, bytes]], str, bytes] _SrvnmeCbType = Callable[[Union[SSLSocket, SSLObject], Optional[str], SSLSocket], Optional[int]] @@ -102,7 +102,15 @@ def RAND_egd(path: str) -> None: ... def RAND_add(__s: bytes, __entropy: float) -> None: ... def match_hostname(cert: _PeerCertRetType, hostname: str) -> None: ... def cert_time_to_seconds(cert_time: str) -> int: ... -def get_server_certificate(addr: tuple[str, int], ssl_version: int = ..., ca_certs: str | None = ...) -> str: ... + +if sys.version_info >= (3, 10): + def get_server_certificate( + addr: tuple[str, int], ssl_version: int = ..., ca_certs: str | None = ..., timeout: float = ... + ) -> str: ... + +else: + def get_server_certificate(addr: tuple[str, int], ssl_version: int = ..., ca_certs: str | None = ...) -> str: ... + def DER_cert_to_PEM_cert(der_cert_bytes: bytes) -> str: ... def PEM_cert_to_DER_cert(pem_cert_string: str) -> bytes: ... @@ -135,6 +143,9 @@ class VerifyFlags(enum.IntFlag): VERIFY_CRL_CHECK_CHAIN: int VERIFY_X509_STRICT: int VERIFY_X509_TRUSTED_FIRST: int + if sys.version_info >= (3, 10): + VERIFY_ALLOW_PROXY_CERTS: int + VERIFY_X509_PARTIAL_CHAIN: int VERIFY_DEFAULT: VerifyFlags VERIFY_CRL_CHECK_LEAF: VerifyFlags @@ -142,6 +153,10 @@ VERIFY_CRL_CHECK_CHAIN: VerifyFlags VERIFY_X509_STRICT: VerifyFlags VERIFY_X509_TRUSTED_FIRST: VerifyFlags +if sys.version_info >= (3, 10): + VERIFY_ALLOW_PROXY_CERTS: VerifyFlags + VERIFY_X509_PARTIAL_CHAIN: VerifyFlags + class _SSLMethod(enum.IntEnum): PROTOCOL_SSLv23: int PROTOCOL_SSLv2: int @@ -205,7 +220,7 @@ if sys.version_info >= (3, 7): HAS_TLSv1: bool HAS_TLSv1_1: bool HAS_TLSv1_2: bool - HAS_TLSv1_3: bool +HAS_TLSv1_3: bool HAS_ALPN: bool HAS_ECDH: bool HAS_SNI: bool @@ -293,7 +308,9 @@ class SSLSocket(socket.socket): server_hostname: str | None session: SSLSession | None session_reused: bool | None - if sys.version_info < (3, 7): + if sys.version_info >= (3, 7): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + else: def __init__( self, sock: socket.socket | None = ..., @@ -315,8 +332,6 @@ class SSLSocket(socket.socket): _context: SSLContext | None = ..., _session: Any | None = ..., ) -> None: ... - else: - def __init__(self, *args: Any, **kwargs: Any) -> None: ... def connect(self, addr: socket._Address | bytes) -> None: ... def connect_ex(self, addr: socket._Address | bytes) -> int: ... def recv(self, buflen: int = ..., flags: int = ...) -> bytes: ... diff --git a/mypy/typeshed/stdlib/stat.pyi b/mypy/typeshed/stdlib/stat.pyi index d6450fe77817..4518acb5a162 100644 --- a/mypy/typeshed/stdlib/stat.pyi +++ b/mypy/typeshed/stdlib/stat.pyi @@ -1,97 +1 @@ -import sys - -def S_ISDIR(mode: int) -> bool: ... -def S_ISCHR(mode: int) -> bool: ... -def S_ISBLK(mode: int) -> bool: ... -def S_ISREG(mode: int) -> bool: ... -def S_ISFIFO(mode: int) -> bool: ... -def S_ISLNK(mode: int) -> bool: ... -def S_ISSOCK(mode: int) -> bool: ... -def S_IMODE(mode: int) -> int: ... -def S_IFMT(mode: int) -> int: ... -def S_ISDOOR(mode: int) -> int: ... -def S_ISPORT(mode: int) -> int: ... -def S_ISWHT(mode: int) -> int: ... -def filemode(mode: int) -> str: ... - -ST_MODE: int -ST_INO: int -ST_DEV: int -ST_NLINK: int -ST_UID: int -ST_GID: int -ST_SIZE: int -ST_ATIME: int -ST_MTIME: int -ST_CTIME: int - -S_IFSOCK: int -S_IFLNK: int -S_IFREG: int -S_IFBLK: int -S_IFDIR: int -S_IFCHR: int -S_IFIFO: int -S_IFDOOR: int -S_IFPORT: int -S_IFWHT: int -S_ISUID: int -S_ISGID: int -S_ISVTX: int - -S_IRWXU: int -S_IRUSR: int -S_IWUSR: int -S_IXUSR: int - -S_IRWXG: int -S_IRGRP: int -S_IWGRP: int -S_IXGRP: int - -S_IRWXO: int -S_IROTH: int -S_IWOTH: int -S_IXOTH: int - -S_ENFMT: int -S_IREAD: int -S_IWRITE: int -S_IEXEC: int - -UF_NODUMP: int -UF_IMMUTABLE: int -UF_APPEND: int -UF_OPAQUE: int -UF_NOUNLINK: int -if sys.platform == "darwin": - UF_COMPRESSED: int # OS X 10.6+ only - UF_HIDDEN: int # OX X 10.5+ only -SF_ARCHIVED: int -SF_IMMUTABLE: int -SF_APPEND: int -SF_NOUNLINK: int -SF_SNAPSHOT: int - -FILE_ATTRIBUTE_ARCHIVE: int -FILE_ATTRIBUTE_COMPRESSED: int -FILE_ATTRIBUTE_DEVICE: int -FILE_ATTRIBUTE_DIRECTORY: int -FILE_ATTRIBUTE_ENCRYPTED: int -FILE_ATTRIBUTE_HIDDEN: int -FILE_ATTRIBUTE_INTEGRITY_STREAM: int -FILE_ATTRIBUTE_NORMAL: int -FILE_ATTRIBUTE_NOT_CONTENT_INDEXED: int -FILE_ATTRIBUTE_NO_SCRUB_DATA: int -FILE_ATTRIBUTE_OFFLINE: int -FILE_ATTRIBUTE_READONLY: int -FILE_ATTRIBUTE_REPARSE_POINT: int -FILE_ATTRIBUTE_SPARSE_FILE: int -FILE_ATTRIBUTE_SYSTEM: int -FILE_ATTRIBUTE_TEMPORARY: int -FILE_ATTRIBUTE_VIRTUAL: int - -if sys.platform == "win32" and sys.version_info >= (3, 8): - IO_REPARSE_TAG_SYMLINK: int - IO_REPARSE_TAG_MOUNT_POINT: int - IO_REPARSE_TAG_APPEXECLINK: int +from _stat import * diff --git a/mypy/typeshed/stdlib/statistics.pyi b/mypy/typeshed/stdlib/statistics.pyi index ec3574ab12b1..908d6adaf45d 100644 --- a/mypy/typeshed/stdlib/statistics.pyi +++ b/mypy/typeshed/stdlib/statistics.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import SupportsLessThanT +from _typeshed import SupportsRichComparisonT from decimal import Decimal from fractions import Fraction from typing import Any, Hashable, Iterable, NamedTuple, Sequence, SupportsFloat, Type, TypeVar, Union @@ -27,8 +27,8 @@ else: def harmonic_mean(data: Iterable[_NumberT]) -> _NumberT: ... def median(data: Iterable[_NumberT]) -> _NumberT: ... -def median_low(data: Iterable[SupportsLessThanT]) -> SupportsLessThanT: ... -def median_high(data: Iterable[SupportsLessThanT]) -> SupportsLessThanT: ... +def median_low(data: Iterable[SupportsRichComparisonT]) -> SupportsRichComparisonT: ... +def median_high(data: Iterable[SupportsRichComparisonT]) -> SupportsRichComparisonT: ... def median_grouped(data: Iterable[_NumberT], interval: _NumberT = ...) -> _NumberT: ... def mode(data: Iterable[_HashableT]) -> _HashableT: ... diff --git a/mypy/typeshed/stdlib/stringprep.pyi b/mypy/typeshed/stdlib/stringprep.pyi index cbc562d460f6..fc28c027ca9b 100644 --- a/mypy/typeshed/stdlib/stringprep.pyi +++ b/mypy/typeshed/stdlib/stringprep.pyi @@ -1,3 +1,11 @@ +b1_set: set[int] +b3_exceptions: dict[int, str] +c22_specials: set[int] +c6_set: set[int] +c7_set: set[int] +c8_set: set[int] +c9_set: set[int] + def in_table_a1(code: str) -> bool: ... def in_table_b1(code: str) -> bool: ... def map_table_b3(code: str) -> str: ... diff --git a/mypy/typeshed/stdlib/struct.pyi b/mypy/typeshed/stdlib/struct.pyi index d7c9cbef7dce..47af62973259 100644 --- a/mypy/typeshed/stdlib/struct.pyi +++ b/mypy/typeshed/stdlib/struct.pyi @@ -1,14 +1,14 @@ import sys from _typeshed import ReadableBuffer, WriteableBuffer -from typing import Any, Iterator, Tuple +from typing import Any, Iterator 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 = ...) -> Tuple[Any, ...]: ... -def iter_unpack(__format: str | bytes, __buffer: ReadableBuffer) -> Iterator[Tuple[Any, ...]]: ... +def unpack(__format: str | bytes, __buffer: ReadableBuffer) -> tuple[Any, ...]: ... +def unpack_from(__format: str | bytes, buffer: ReadableBuffer, offset: int = ...) -> tuple[Any, ...]: ... +def iter_unpack(__format: str | bytes, __buffer: ReadableBuffer) -> Iterator[tuple[Any, ...]]: ... def calcsize(__format: str | bytes) -> int: ... class Struct: @@ -20,6 +20,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_from(self, buffer: ReadableBuffer, offset: int = ...) -> Tuple[Any, ...]: ... - def iter_unpack(self, __buffer: ReadableBuffer) -> Iterator[Tuple[Any, ...]]: ... + def unpack(self, __buffer: ReadableBuffer) -> tuple[Any, ...]: ... + def unpack_from(self, buffer: ReadableBuffer, offset: int = ...) -> tuple[Any, ...]: ... + def iter_unpack(self, __buffer: ReadableBuffer) -> Iterator[tuple[Any, ...]]: ... diff --git a/mypy/typeshed/stdlib/symbol.pyi b/mypy/typeshed/stdlib/symbol.pyi index 2d3bd83087c7..234c814b55b5 100644 --- a/mypy/typeshed/stdlib/symbol.pyi +++ b/mypy/typeshed/stdlib/symbol.pyi @@ -1,3 +1,5 @@ +import sys + single_input: int file_input: int eval_input: int @@ -84,5 +86,13 @@ comp_if: int encoding_decl: int yield_expr: int yield_arg: int +if sys.version_info >= (3, 7): + 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 sym_name: dict[int, str] diff --git a/mypy/typeshed/stdlib/symtable.pyi b/mypy/typeshed/stdlib/symtable.pyi index 613ac90ef7a9..bc25a4c4639b 100644 --- a/mypy/typeshed/stdlib/symtable.pyi +++ b/mypy/typeshed/stdlib/symtable.pyi @@ -1,9 +1,9 @@ import sys -from typing import Any, Sequence, Tuple +from typing import Any, Sequence def symtable(code: str, filename: str, compile_type: str) -> SymbolTable: ... -class SymbolTable(object): +class SymbolTable: def __init__(self, raw_table: Any, filename: str) -> None: ... def get_type(self) -> str: ... def get_id(self) -> int: ... @@ -19,19 +19,22 @@ class SymbolTable(object): def get_children(self) -> list[SymbolTable]: ... class Function(SymbolTable): - def get_parameters(self) -> Tuple[str, ...]: ... - def get_locals(self) -> Tuple[str, ...]: ... - def get_globals(self) -> Tuple[str, ...]: ... - def get_frees(self) -> Tuple[str, ...]: ... + def get_parameters(self) -> tuple[str, ...]: ... + 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, ...]: ... class Class(SymbolTable): - def get_methods(self) -> Tuple[str, ...]: ... + def get_methods(self) -> tuple[str, ...]: ... -class Symbol(object): +class Symbol: if sys.version_info >= (3, 8): def __init__( self, name: str, flags: int, namespaces: Sequence[SymbolTable] | None = ..., *, module_scope: bool = ... ) -> None: ... + def is_nonlocal(self) -> bool: ... else: def __init__(self, name: str, flags: int, namespaces: Sequence[SymbolTable] | None = ...) -> None: ... def get_name(self) -> str: ... @@ -48,7 +51,7 @@ class Symbol(object): def get_namespaces(self) -> Sequence[SymbolTable]: ... def get_namespace(self) -> SymbolTable: ... -class SymbolTableFactory(object): +class SymbolTableFactory: def __init__(self) -> None: ... def new(self, table: Any, filename: str) -> SymbolTable: ... def __call__(self, table: Any, filename: str) -> SymbolTable: ... diff --git a/mypy/typeshed/stdlib/sys.pyi b/mypy/typeshed/stdlib/sys.pyi index 274e4b90fd6e..cb1545711d69 100644 --- a/mypy/typeshed/stdlib/sys.pyi +++ b/mypy/typeshed/stdlib/sys.pyi @@ -1,31 +1,18 @@ import sys +from _typeshed import structseq from builtins import object as _object from importlib.abc import PathEntryFinder from importlib.machinery import ModuleSpec from io import TextIOWrapper from types import FrameType, ModuleType, TracebackType -from typing import ( - Any, - AsyncGenerator, - Callable, - NoReturn, - Optional, - Protocol, - Sequence, - TextIO, - Tuple, - Type, - TypeVar, - Union, - overload, -) -from typing_extensions import Literal +from typing import Any, AsyncGenerator, Callable, NoReturn, Optional, Protocol, Sequence, TextIO, Type, TypeVar, Union, overload +from typing_extensions import Literal, final _T = TypeVar("_T") # The following type alias are stub-only and do not exist during runtime -_ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType] -_OptExcInfo = Union[_ExcInfo, Tuple[None, None, None]] +_ExcInfo = tuple[Type[BaseException], BaseException, TracebackType] +_OptExcInfo = Union[_ExcInfo, tuple[None, None, None]] # Intentionally omits one deprecated and one optional method of `importlib.abc.MetaPathFinder` class _MetaPathFinder(Protocol): @@ -146,12 +133,18 @@ class _int_info: bits_per_digit: int sizeof_digit: int -class _version_info(Tuple[int, int, int, str, int]): - major: int - minor: int - micro: int - releaselevel: str - serial: int +@final +class _version_info(structseq[Any | int], tuple[int, int, int, str, int]): + @property + def major(self) -> int: ... + @property + def minor(self) -> int: ... + @property + def micro(self) -> int: ... + @property + def releaselevel(self) -> str: ... + @property + def serial(self) -> int: ... version_info: _version_info @@ -161,7 +154,7 @@ def _current_frames() -> dict[int, FrameType]: ... def _getframe(__depth: int = ...) -> FrameType: ... def _debugmallocstats() -> None: ... def __displayhook__(value: object) -> None: ... -def __excepthook__(type_: Type[BaseException], value: BaseException, traceback: TracebackType) -> None: ... +def __excepthook__(type_: Type[BaseException], value: BaseException, traceback: TracebackType | None) -> None: ... def exc_info() -> _OptExcInfo: ... # sys.exit() accepts an optional argument of anything printable @@ -192,7 +185,7 @@ _TraceFunc = Callable[[FrameType, str, Any], Optional[Callable[[FrameType, str, def gettrace() -> _TraceFunc | None: ... def settrace(tracefunc: _TraceFunc | None) -> None: ... -class _WinVersion(Tuple[int, int, int, int, str, int, int, int, int, Tuple[int, int, int]]): +class _WinVersion(tuple[int, int, int, int, str, int, int, int, int, tuple[int, int, int]]): major: int minor: int build: int @@ -234,12 +227,12 @@ if sys.version_info >= (3, 8): err_msg: str | None object: _object | None unraisablehook: Callable[[UnraisableHookArgs], Any] - def addaudithook(hook: Callable[[str, Tuple[Any, ...]], Any]) -> None: ... + def addaudithook(hook: Callable[[str, tuple[Any, ...]], Any]) -> None: ... def audit(__event: str, *args: Any) -> None: ... _AsyncgenHook = Optional[Callable[[AsyncGenerator[Any, Any]], None]] -class _asyncgen_hooks(Tuple[_AsyncgenHook, _AsyncgenHook]): +class _asyncgen_hooks(tuple[_AsyncgenHook, _AsyncgenHook]): firstiter: _AsyncgenHook finalizer: _AsyncgenHook diff --git a/mypy/typeshed/stdlib/sysconfig.pyi b/mypy/typeshed/stdlib/sysconfig.pyi index ff828d519912..17077144f6e9 100644 --- a/mypy/typeshed/stdlib/sysconfig.pyi +++ b/mypy/typeshed/stdlib/sysconfig.pyi @@ -1,12 +1,12 @@ -from typing import IO, Any, Tuple, overload +from typing import IO, Any, overload def get_config_var(name: str) -> str | None: ... @overload def get_config_vars() -> dict[str, Any]: ... @overload def get_config_vars(arg: str, *args: str) -> list[Any]: ... -def get_scheme_names() -> Tuple[str, ...]: ... -def get_path_names() -> Tuple[str, ...]: ... +def get_scheme_names() -> tuple[str, ...]: ... +def get_path_names() -> tuple[str, ...]: ... def get_path(name: str, scheme: str = ..., vars: dict[str, Any] | None = ..., expand: bool = ...) -> str: ... def get_paths(scheme: str = ..., vars: dict[str, Any] | None = ..., expand: bool = ...) -> dict[str, str]: ... def get_python_version() -> str: ... diff --git a/mypy/typeshed/stdlib/syslog.pyi b/mypy/typeshed/stdlib/syslog.pyi index 49169f40db5c..cfa8df887c1b 100644 --- a/mypy/typeshed/stdlib/syslog.pyi +++ b/mypy/typeshed/stdlib/syslog.pyi @@ -1,43 +1,47 @@ +import sys from typing import overload +from typing_extensions import Literal -LOG_ALERT: int -LOG_AUTH: int -LOG_CONS: int -LOG_CRIT: int -LOG_CRON: int -LOG_DAEMON: int -LOG_DEBUG: int -LOG_EMERG: int -LOG_ERR: int -LOG_INFO: int -LOG_KERN: int -LOG_LOCAL0: int -LOG_LOCAL1: int -LOG_LOCAL2: int -LOG_LOCAL3: int -LOG_LOCAL4: int -LOG_LOCAL5: int -LOG_LOCAL6: int -LOG_LOCAL7: int -LOG_LPR: int -LOG_MAIL: int -LOG_NDELAY: int -LOG_NEWS: int -LOG_NOTICE: int -LOG_NOWAIT: int -LOG_PERROR: int -LOG_PID: int -LOG_SYSLOG: int -LOG_USER: int -LOG_UUCP: int -LOG_WARNING: int - -def LOG_MASK(a: int) -> int: ... -def LOG_UPTO(a: int) -> int: ... -def closelog() -> None: ... -def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... -def setlogmask(x: int) -> int: ... -@overload -def syslog(priority: int, message: str) -> None: ... -@overload -def syslog(message: str) -> None: ... +if sys.platform != "win32": + LOG_ALERT: Literal[1] + LOG_AUTH: Literal[32] + LOG_AUTHPRIV: Literal[80] + LOG_CONS: Literal[2] + LOG_CRIT: Literal[2] + LOG_CRON: Literal[72] + LOG_DAEMON: Literal[24] + LOG_DEBUG: Literal[7] + LOG_EMERG: Literal[0] + LOG_ERR: Literal[3] + LOG_INFO: Literal[6] + LOG_KERN: Literal[0] + LOG_LOCAL0: Literal[128] + LOG_LOCAL1: Literal[136] + LOG_LOCAL2: Literal[144] + LOG_LOCAL3: Literal[152] + LOG_LOCAL4: Literal[160] + LOG_LOCAL5: Literal[168] + LOG_LOCAL6: Literal[176] + LOG_LOCAL7: Literal[184] + LOG_LPR: Literal[48] + LOG_MAIL: Literal[16] + LOG_NDELAY: Literal[8] + LOG_NEWS: Literal[56] + LOG_NOTICE: Literal[5] + LOG_NOWAIT: Literal[16] + LOG_ODELAY: Literal[4] + LOG_PERROR: Literal[32] + LOG_PID: Literal[1] + LOG_SYSLOG: Literal[40] + LOG_USER: Literal[8] + LOG_UUCP: Literal[64] + LOG_WARNING: Literal[4] + def LOG_MASK(a: int) -> int: ... + def LOG_UPTO(a: int) -> int: ... + def closelog() -> None: ... + def openlog(ident: str = ..., logoption: int = ..., facility: int = ...) -> None: ... + def setlogmask(x: int) -> int: ... + @overload + def syslog(priority: int, message: str) -> None: ... + @overload + def syslog(message: str) -> None: ... diff --git a/mypy/typeshed/stdlib/tarfile.pyi b/mypy/typeshed/stdlib/tarfile.pyi index 0134316d8107..4931a6f0e679 100644 --- a/mypy/typeshed/stdlib/tarfile.pyi +++ b/mypy/typeshed/stdlib/tarfile.pyi @@ -5,7 +5,7 @@ from _typeshed import Self, StrOrBytesPath, StrPath 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, Protocol, Tuple, Type, TypeVar, overload +from typing import IO, Protocol, Type, TypeVar, overload from typing_extensions import Literal _TF = TypeVar("_TF", bound=TarFile) @@ -62,10 +62,10 @@ DEFAULT_FORMAT: int # tarfile constants -SUPPORTED_TYPES: Tuple[bytes, ...] -REGULAR_TYPES: Tuple[bytes, ...] -GNU_TYPES: Tuple[bytes, ...] -PAX_FIELDS: Tuple[str, ...] +SUPPORTED_TYPES: tuple[bytes, ...] +REGULAR_TYPES: tuple[bytes, ...] +GNU_TYPES: tuple[bytes, ...] +PAX_FIELDS: tuple[str, ...] PAX_NUMBER_FIELDS: dict[str, type] PAX_NAME_FIELDS: set[str] diff --git a/mypy/typeshed/stdlib/tempfile.pyi b/mypy/typeshed/stdlib/tempfile.pyi index 119c111bc4e1..4aec26175a48 100644 --- a/mypy/typeshed/stdlib/tempfile.pyi +++ b/mypy/typeshed/stdlib/tempfile.pyi @@ -2,7 +2,7 @@ import os import sys from _typeshed import Self from types import TracebackType -from typing import IO, Any, AnyStr, Generic, Iterable, Iterator, Tuple, Type, Union, overload +from typing import IO, Any, AnyStr, Generic, Iterable, Iterator, Type, Union, overload from typing_extensions import Literal if sys.version_info >= (3, 9): @@ -206,7 +206,7 @@ class SpooledTemporaryFile(IO[AnyStr]): @property def encoding(self) -> str: ... # undocumented @property - def newlines(self) -> str | Tuple[str, ...] | None: ... # undocumented + 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 diff --git a/mypy/typeshed/stdlib/termios.pyi b/mypy/typeshed/stdlib/termios.pyi index ed8522dccc51..7142df15715d 100644 --- a/mypy/typeshed/stdlib/termios.pyi +++ b/mypy/typeshed/stdlib/termios.pyi @@ -1,246 +1,246 @@ +import sys from _typeshed import FileDescriptorLike -from typing import Any, List, Union +from typing import Any, Union -_Attr = List[Union[int, List[Union[bytes, int]]]] +if sys.platform != "win32": + _Attr = list[Union[int, list[Union[bytes, int]]]] -# TODO constants not really documented -B0: int -B1000000: int -B110: int -B115200: int -B1152000: int -B1200: int -B134: int -B150: int -B1500000: int -B1800: int -B19200: int -B200: int -B2000000: int -B230400: int -B2400: int -B2500000: int -B300: int -B3000000: int -B3500000: int -B38400: int -B4000000: int -B460800: int -B4800: int -B50: int -B500000: int -B57600: int -B576000: int -B600: int -B75: int -B921600: int -B9600: int -BRKINT: int -BS0: int -BS1: int -BSDLY: int -CBAUD: int -CBAUDEX: int -CDSUSP: int -CEOF: int -CEOL: int -CEOT: int -CERASE: int -CFLUSH: int -CIBAUD: int -CINTR: int -CKILL: int -CLNEXT: int -CLOCAL: int -CQUIT: int -CR0: int -CR1: int -CR2: int -CR3: int -CRDLY: int -CREAD: int -CRPRNT: int -CRTSCTS: int -CS5: int -CS6: int -CS7: int -CS8: int -CSIZE: int -CSTART: int -CSTOP: int -CSTOPB: int -CSUSP: int -CWERASE: int -ECHO: int -ECHOCTL: int -ECHOE: int -ECHOK: int -ECHOKE: int -ECHONL: int -ECHOPRT: int -EXTA: int -EXTB: int -FF0: int -FF1: int -FFDLY: int -FIOASYNC: int -FIOCLEX: int -FIONBIO: int -FIONCLEX: int -FIONREAD: int -FLUSHO: int -HUPCL: int -ICANON: int -ICRNL: int -IEXTEN: int -IGNBRK: int -IGNCR: int -IGNPAR: int -IMAXBEL: int -INLCR: int -INPCK: int -IOCSIZE_MASK: int -IOCSIZE_SHIFT: int -ISIG: int -ISTRIP: int -IUCLC: int -IXANY: int -IXOFF: int -IXON: int -NCC: int -NCCS: int -NL0: int -NL1: int -NLDLY: int -NOFLSH: int -N_MOUSE: int -N_PPP: int -N_SLIP: int -N_STRIP: int -N_TTY: int -OCRNL: int -OFDEL: int -OFILL: int -OLCUC: int -ONLCR: int -ONLRET: int -ONOCR: int -OPOST: int -PARENB: int -PARMRK: int -PARODD: int -PENDIN: int -TAB0: int -TAB1: int -TAB2: int -TAB3: int -TABDLY: int -TCFLSH: int -TCGETA: int -TCGETS: int -TCIFLUSH: int -TCIOFF: int -TCIOFLUSH: int -TCION: int -TCOFLUSH: int -TCOOFF: int -TCOON: int -TCSADRAIN: int -TCSAFLUSH: int -TCSANOW: int -TCSBRK: int -TCSBRKP: int -TCSETA: int -TCSETAF: int -TCSETAW: int -TCSETS: int -TCSETSF: int -TCSETSW: int -TCXONC: int -TIOCCONS: int -TIOCEXCL: int -TIOCGETD: int -TIOCGICOUNT: int -TIOCGLCKTRMIOS: int -TIOCGPGRP: int -TIOCGSERIAL: int -TIOCGSOFTCAR: int -TIOCGWINSZ: int -TIOCINQ: int -TIOCLINUX: int -TIOCMBIC: int -TIOCMBIS: int -TIOCMGET: int -TIOCMIWAIT: int -TIOCMSET: int -TIOCM_CAR: int -TIOCM_CD: int -TIOCM_CTS: int -TIOCM_DSR: int -TIOCM_DTR: int -TIOCM_LE: int -TIOCM_RI: int -TIOCM_RNG: int -TIOCM_RTS: int -TIOCM_SR: int -TIOCM_ST: int -TIOCNOTTY: int -TIOCNXCL: int -TIOCOUTQ: int -TIOCPKT: int -TIOCPKT_DATA: int -TIOCPKT_DOSTOP: int -TIOCPKT_FLUSHREAD: int -TIOCPKT_FLUSHWRITE: int -TIOCPKT_NOSTOP: int -TIOCPKT_START: int -TIOCPKT_STOP: int -TIOCSCTTY: int -TIOCSERCONFIG: int -TIOCSERGETLSR: int -TIOCSERGETMULTI: int -TIOCSERGSTRUCT: int -TIOCSERGWILD: int -TIOCSERSETMULTI: int -TIOCSERSWILD: int -TIOCSER_TEMT: int -TIOCSETD: int -TIOCSLCKTRMIOS: int -TIOCSPGRP: int -TIOCSSERIAL: int -TIOCSSOFTCAR: int -TIOCSTI: int -TIOCSWINSZ: int -TOSTOP: int -VDISCARD: int -VEOF: int -VEOL: int -VEOL2: int -VERASE: int -VINTR: int -VKILL: int -VLNEXT: int -VMIN: int -VQUIT: int -VREPRINT: int -VSTART: int -VSTOP: int -VSUSP: int -VSWTC: int -VSWTCH: int -VT0: int -VT1: int -VTDLY: int -VTIME: int -VWERASE: int -XCASE: int -XTABS: int - -def tcgetattr(__fd: FileDescriptorLike) -> list[Any]: ... -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: ... - -class error(Exception): ... + # TODO constants not really documented + B0: int + B1000000: int + B110: int + B115200: int + B1152000: int + B1200: int + B134: int + B150: int + B1500000: int + B1800: int + B19200: int + B200: int + B2000000: int + B230400: int + B2400: int + B2500000: int + B300: int + B3000000: int + B3500000: int + B38400: int + B4000000: int + B460800: int + B4800: int + B50: int + B500000: int + B57600: int + B576000: int + B600: int + B75: int + B921600: int + B9600: int + BRKINT: int + BS0: int + BS1: int + BSDLY: int + CBAUD: int + CBAUDEX: int + CDSUSP: int + CEOF: int + CEOL: int + CEOT: int + CERASE: int + CFLUSH: int + CIBAUD: int + CINTR: int + CKILL: int + CLNEXT: int + CLOCAL: int + CQUIT: int + CR0: int + CR1: int + CR2: int + CR3: int + CRDLY: int + CREAD: int + CRPRNT: int + CRTSCTS: int + CS5: int + CS6: int + CS7: int + CS8: int + CSIZE: int + CSTART: int + CSTOP: int + CSTOPB: int + CSUSP: int + CWERASE: int + ECHO: int + ECHOCTL: int + ECHOE: int + ECHOK: int + ECHOKE: int + ECHONL: int + ECHOPRT: int + EXTA: int + EXTB: int + FF0: int + FF1: int + FFDLY: int + FIOASYNC: int + FIOCLEX: int + FIONBIO: int + FIONCLEX: int + FIONREAD: int + FLUSHO: int + HUPCL: int + ICANON: int + ICRNL: int + IEXTEN: int + IGNBRK: int + IGNCR: int + IGNPAR: int + IMAXBEL: int + INLCR: int + INPCK: int + IOCSIZE_MASK: int + IOCSIZE_SHIFT: int + ISIG: int + ISTRIP: int + IUCLC: int + IXANY: int + IXOFF: int + IXON: int + NCC: int + NCCS: int + NL0: int + NL1: int + NLDLY: int + NOFLSH: int + N_MOUSE: int + N_PPP: int + N_SLIP: int + N_STRIP: int + N_TTY: int + OCRNL: int + OFDEL: int + OFILL: int + OLCUC: int + ONLCR: int + ONLRET: int + ONOCR: int + OPOST: int + PARENB: int + PARMRK: int + PARODD: int + PENDIN: int + TAB0: int + TAB1: int + TAB2: int + TAB3: int + TABDLY: int + TCFLSH: int + TCGETA: int + TCGETS: int + TCIFLUSH: int + TCIOFF: int + TCIOFLUSH: int + TCION: int + TCOFLUSH: int + TCOOFF: int + TCOON: int + TCSADRAIN: int + TCSAFLUSH: int + TCSANOW: int + TCSBRK: int + TCSBRKP: int + TCSETA: int + TCSETAF: int + TCSETAW: int + TCSETS: int + TCSETSF: int + TCSETSW: int + TCXONC: int + TIOCCONS: int + TIOCEXCL: int + TIOCGETD: int + TIOCGICOUNT: int + TIOCGLCKTRMIOS: int + TIOCGPGRP: int + TIOCGSERIAL: int + TIOCGSOFTCAR: int + TIOCGWINSZ: int + TIOCINQ: int + TIOCLINUX: int + TIOCMBIC: int + TIOCMBIS: int + TIOCMGET: int + TIOCMIWAIT: int + TIOCMSET: int + TIOCM_CAR: int + TIOCM_CD: int + TIOCM_CTS: int + TIOCM_DSR: int + TIOCM_DTR: int + TIOCM_LE: int + TIOCM_RI: int + TIOCM_RNG: int + TIOCM_RTS: int + TIOCM_SR: int + TIOCM_ST: int + TIOCNOTTY: int + TIOCNXCL: int + TIOCOUTQ: int + TIOCPKT: int + TIOCPKT_DATA: int + TIOCPKT_DOSTOP: int + TIOCPKT_FLUSHREAD: int + TIOCPKT_FLUSHWRITE: int + TIOCPKT_NOSTOP: int + TIOCPKT_START: int + TIOCPKT_STOP: int + TIOCSCTTY: int + TIOCSERCONFIG: int + TIOCSERGETLSR: int + TIOCSERGETMULTI: int + TIOCSERGSTRUCT: int + TIOCSERGWILD: int + TIOCSERSETMULTI: int + TIOCSERSWILD: int + TIOCSER_TEMT: int + TIOCSETD: int + TIOCSLCKTRMIOS: int + TIOCSPGRP: int + TIOCSSERIAL: int + TIOCSSOFTCAR: int + TIOCSTI: int + TIOCSWINSZ: int + TOSTOP: int + VDISCARD: int + VEOF: int + VEOL: int + VEOL2: int + VERASE: int + VINTR: int + VKILL: int + VLNEXT: int + VMIN: int + VQUIT: int + VREPRINT: int + VSTART: int + VSTOP: int + VSUSP: int + VSWTC: int + VSWTCH: int + VT0: int + VT1: int + VTDLY: int + VTIME: int + VWERASE: int + XCASE: int + XTABS: int + def tcgetattr(__fd: FileDescriptorLike) -> list[Any]: ... + 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: ... + class error(Exception): ... diff --git a/mypy/typeshed/stdlib/threading.pyi b/mypy/typeshed/stdlib/threading.pyi index 64998d86bf9f..3e91221baed2 100644 --- a/mypy/typeshed/stdlib/threading.pyi +++ b/mypy/typeshed/stdlib/threading.pyi @@ -11,8 +11,9 @@ _T = TypeVar("_T") __all__: list[str] def active_count() -> int: ... +def activeCount() -> int: ... # deprecated alias for active_count() def current_thread() -> Thread: ... -def currentThread() -> Thread: ... +def currentThread() -> Thread: ... # deprecated alias for current_thread() def get_ident() -> int: ... def enumerate() -> list[Thread]: ... def main_thread() -> Thread: ... @@ -22,13 +23,18 @@ if sys.version_info >= (3, 8): def settrace(func: _TF) -> None: ... def setprofile(func: _PF | None) -> None: ... + +if sys.version_info >= (3, 10): + def gettrace() -> _TF | None: ... + def getprofile() -> _PF | None: ... + def stack_size(size: int = ...) -> int: ... TIMEOUT_MAX: float class ThreadError(Exception): ... -class local(object): +class local: def __getattribute__(self, name: str) -> Any: ... def __setattr__(self, name: str, value: Any) -> None: ... def __delattr__(self, name: str) -> None: ... @@ -50,18 +56,20 @@ class Thread: def start(self) -> None: ... def run(self) -> None: ... def join(self, timeout: float | 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 def is_alive(self) -> bool: ... if sys.version_info < (3, 9): def isAlive(self) -> bool: ... + # the following methods are all deprecated + def getName(self) -> str: ... + def setName(self, name: str) -> None: ... def isDaemon(self) -> bool: ... def setDaemon(self, daemonic: bool) -> None: ... -class _DummyThread(Thread): ... +class _DummyThread(Thread): + def __init__(self) -> None: ... class Lock: def __init__(self) -> None: ... @@ -75,12 +83,12 @@ class Lock: class _RLock: def __init__(self) -> None: ... - def __enter__(self) -> bool: ... + def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... + def release(self) -> None: ... + __enter__ = acquire def __exit__( self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> bool | None: ... - def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... - def release(self) -> None: ... RLock = _RLock @@ -96,7 +104,7 @@ class Condition: def wait_for(self, predicate: Callable[[], _T], timeout: float | None = ...) -> _T: ... def notify(self, n: int = ...) -> None: ... def notify_all(self) -> None: ... - def notifyAll(self) -> None: ... + def notifyAll(self) -> None: ... # deprecated alias for notify_all() class Semaphore: def __init__(self, value: int = ...) -> None: ... @@ -115,6 +123,7 @@ class BoundedSemaphore(Semaphore): ... class Event: def __init__(self) -> None: ... def is_set(self) -> bool: ... + def isSet(self) -> bool: ... # deprecated alias for is_set() def set(self) -> None: ... def clear(self) -> None: ... def wait(self, timeout: float | None = ...) -> bool: ... diff --git a/mypy/typeshed/stdlib/time.pyi b/mypy/typeshed/stdlib/time.pyi index bf370d68e83d..6e23b331d1c8 100644 --- a/mypy/typeshed/stdlib/time.pyi +++ b/mypy/typeshed/stdlib/time.pyi @@ -1,9 +1,10 @@ import sys +from _typeshed import structseq from types import SimpleNamespace -from typing import Any, NamedTuple, Tuple +from typing import Any, Union from typing_extensions import final -_TimeTuple = Tuple[int, int, int, int, int, int, int, int, int] +_TimeTuple = tuple[int, int, int, int, int, int, int, int, int] altzone: int daylight: int @@ -32,39 +33,31 @@ if sys.version_info >= (3, 8) and sys.platform == "darwin": if sys.version_info >= (3, 9) and sys.platform == "linux": CLOCK_TAI: int -class _struct_time(NamedTuple): - tm_year: int - tm_mon: int - tm_mday: int - tm_hour: int - tm_min: int - tm_sec: int - tm_wday: int - tm_yday: int - tm_isdst: int +# Constructor takes an iterable of any type, of length between 9 and 11 elements. +# However, it always *behaves* like a tuple of 9 elements, +# even if an iterable with length >9 is passed. +# https://github.com/python/typeshed/pull/6560#discussion_r767162532 +@final +class struct_time(structseq[Union[Any, int]], _TimeTuple): @property - def n_fields(self) -> int: ... + def tm_year(self) -> int: ... @property - def n_sequence_fields(self) -> int: ... + def tm_mon(self) -> int: ... @property - def n_unnamed_fields(self) -> int: ... - -@final -class struct_time(_struct_time): - def __init__( - self, - o: tuple[int, int, int, int, int, int, int, int, int] - | tuple[int, int, int, int, int, int, int, int, int, str] - | tuple[int, int, int, int, int, int, int, int, int, str, int], - _arg: Any = ..., - ) -> None: ... - def __new__( - cls, - o: tuple[int, int, int, int, int, int, int, int, int] - | tuple[int, int, int, int, int, int, int, int, int, str] - | tuple[int, int, int, int, int, int, int, int, int, str, int], - _arg: Any = ..., - ) -> struct_time: ... + def tm_mday(self) -> int: ... + @property + def tm_hour(self) -> int: ... + @property + def tm_min(self) -> int: ... + @property + def tm_sec(self) -> int: ... + @property + def tm_wday(self) -> int: ... + @property + def tm_yday(self) -> int: ... + @property + def tm_isdst(self) -> int: ... + # These final two properties only exist if a 10- or 11-item sequence was passed to the constructor. @property def tm_zone(self) -> str: ... @property diff --git a/mypy/typeshed/stdlib/tkinter/__init__.pyi b/mypy/typeshed/stdlib/tkinter/__init__.pyi index bda37b406fc3..50de97f48fdc 100644 --- a/mypy/typeshed/stdlib/tkinter/__init__.pyi +++ b/mypy/typeshed/stdlib/tkinter/__init__.pyi @@ -2,10 +2,10 @@ import _tkinter import sys from _typeshed import StrOrBytesPath from enum import Enum -from tkinter.constants import * # comment this out to find undefined identifier names with flake8 +from tkinter.constants import * from tkinter.font import _FontDescription from types import TracebackType -from typing import Any, Callable, Generic, List, Mapping, Optional, Protocol, Sequence, Tuple, Type, TypeVar, Union, overload +from typing import Any, Callable, Generic, Mapping, Optional, Protocol, Sequence, Type, TypeVar, Union, overload from typing_extensions import Literal, TypedDict # Using anything from tkinter.font in this file means that 'import tkinter' @@ -24,93 +24,46 @@ EXCEPTION = _tkinter.EXCEPTION # - Misc: any widget (don't use BaseWidget because Tk doesn't inherit from BaseWidget) # - Widget: anything that is meant to be put into another widget with e.g. pack or grid # -# Instructions for figuring out the correct type of each widget option: -# - See discussion on #4363. +# Don't trust tkinter's docstrings, because they have been created by copy/pasting from +# Tk's manual pages more than 10 years ago. Use the latest manual pages instead: # -# - Find the option from the manual page of the widget. Usually the manual -# page of a non-ttk widget has the same name as the tkinter class, in the -# 3tk section: +# $ sudo apt install tk-doc tcl-doc +# $ man 3tk label # tkinter.Label +# $ man 3tk ttk_label # tkinter.ttk.Label +# $ man 3tcl after # tkinter.Misc.after # -# $ sudo apt install tk-doc -# $ man 3tk label -# -# Ttk manual pages tend to have ttk_ prefixed names: -# -# $ man 3tk ttk_label -# -# Non-GUI things like the .after() method are often in the 3tcl section: -# -# $ sudo apt install tcl-doc -# $ man 3tcl after -# -# If you don't have man or apt, you can read these manual pages online: -# -# https://www.tcl.tk/doc/ -# -# Every option has '-' in front of its name in the manual page (and in Tcl). -# For example, there's an option named '-text' in the label manual page. -# -# - Tkinter has some options documented in docstrings, but don't rely on them. -# They aren't updated when a new version of Tk comes out, so the latest Tk -# manual pages (see above) are much more likely to actually contain all -# possible options. -# -# Also, reading tkinter's source code typically won't help much because it -# uses a lot of **kwargs and duck typing. Typically every argument goes into -# self.tk.call, which is _tkinter.TkappType.call, and the return value is -# whatever that returns. The type of that depends on how the Tcl interpreter -# represents the return value of the executed Tcl code. -# -# - If you think that int is an appropriate type for something, then you may -# actually want _ScreenUnits instead. -# -# - If you think that Callable[something] is an appropriate type for -# something, then you may actually want Callable[something] | str, -# because it's often possible to specify a string of Tcl code. -# -# - If you think the correct type is Iterable[Foo] or Sequence[Foo], it is -# probably list[Foo] | tuple[Foo, ...], disallowing other sequences such -# as deques: -# -# >>> tkinter.Label(font=('Helvetica', 12, collections.deque(['bold']))) -# Traceback (most recent call last): -# ... -# _tkinter.TclError: unknown font style "deque(['bold'])" -# -# - Some options can be set only in __init__, but all options are available -# when getting their values with configure's return value or cget. -# -# - Asks other tkinter users if you haven't worked much with tkinter. +# You can also read the manual pages online: https://www.tcl.tk/doc/ # Some widgets have an option named -compound that accepts different values # than the _Compound defined here. Many other options have similar things. _Anchor = Literal["nw", "n", "ne", "w", "center", "e", "sw", "s", "se"] # manual page: Tk_GetAnchor _Bitmap = str # manual page: Tk_GetBitmap -_ButtonCommand = Union[str, Callable[[], Any]] # return value is returned from Button.invoke() +_ButtonCommand = Union[str, Callable[[], Any]] # accepts string of tcl code, return value is returned from Button.invoke() _CanvasItemId = int _Color = str # typically '#rrggbb', '#rgb' or color names. _Compound = Literal["top", "left", "center", "right", "bottom", "none"] # -compound in manual page named 'options' -_Cursor = Union[str, Tuple[str], Tuple[str, str], Tuple[str, str, str], Tuple[str, str, str, str]] # manual page: Tk_GetCursor +_Cursor = Union[str, tuple[str], tuple[str, str], tuple[str, str, str], tuple[str, str, str, str]] # manual page: Tk_GetCursor _EntryValidateCommand = Union[ - Callable[[], bool], str, List[str], Tuple[str, ...] + Callable[[], bool], str, list[str], tuple[str, ...] ] # example when it's sequence: entry['invalidcommand'] = [entry.register(print), '%P'] _GridIndex = Union[int, str, Literal["all"]] _ImageSpec = Union[_Image, str] # str can be from e.g. tkinter.image_names() _Padding = Union[ _ScreenUnits, - Tuple[_ScreenUnits], - Tuple[_ScreenUnits, _ScreenUnits], - Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits], - Tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits], + tuple[_ScreenUnits], + tuple[_ScreenUnits, _ScreenUnits], + tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits], + tuple[_ScreenUnits, _ScreenUnits, _ScreenUnits, _ScreenUnits], ] _Relief = Literal["raised", "sunken", "flat", "ridge", "solid", "groove"] # manual page: Tk_GetRelief -_ScreenUnits = Union[str, float] # manual page: Tk_GetPixels +_ScreenUnits = Union[str, float] # Often the right type instead of int. Manual page: Tk_GetPixels _XYScrollCommand = Union[str, Callable[[float, float], Any]] # -xscrollcommand and -yscrollcommand in 'options' manual page _TakeFocusValue = Union[int, Literal[""], Callable[[str], Optional[bool]]] # -takefocus in manual page named 'options' class EventType(str, Enum): Activate: str ButtonPress: str + Button = ButtonPress ButtonRelease: str Circulate: str CirculateRequest: str @@ -128,6 +81,7 @@ class EventType(str, Enum): GraphicsExpose: str Gravity: str KeyPress: str + Key = KeyPress KeyRelease: str Keymap: str Leave: str @@ -183,7 +137,7 @@ class Variable: def get(self) -> Any: ... def trace_add(self, mode: _TraceMode, callback: Callable[[str, str, str], Any]) -> str: ... def trace_remove(self, mode: _TraceMode, cbname: str) -> None: ... - def trace_info(self) -> list[tuple[Tuple[_TraceMode, ...], str]]: ... + def trace_info(self) -> list[tuple[tuple[_TraceMode, ...], str]]: ... def trace_variable(self, mode, callback): ... # deprecated def trace_vdelete(self, mode, cbname): ... # deprecated def trace_vinfo(self): ... # deprecated @@ -295,7 +249,7 @@ class Misc: def winfo_geometry(self) -> str: ... def winfo_height(self) -> int: ... def winfo_id(self) -> int: ... - def winfo_interps(self, displayof: Literal[0] | Misc | None = ...) -> Tuple[str, ...]: ... + def winfo_interps(self, displayof: Literal[0] | Misc | None = ...) -> tuple[str, ...]: ... def winfo_ismapped(self) -> bool: ... def winfo_manager(self) -> str: ... def winfo_name(self) -> str: ... @@ -466,9 +420,9 @@ class Misc: x: _ScreenUnits = ..., y: _ScreenUnits = ..., ) -> None: ... - def event_info(self, virtual: str | None = ...) -> Tuple[str, ...]: ... - def image_names(self) -> Tuple[str, ...]: ... - def image_types(self) -> Tuple[str, ...]: ... + def event_info(self, virtual: str | None = ...) -> tuple[str, ...]: ... + def image_names(self) -> tuple[str, ...]: ... + def image_types(self) -> tuple[str, ...]: ... # See #4363 and #4891 def __setitem__(self, key: str, value: Any) -> None: ... def __getitem__(self, key: str) -> Any: ... @@ -514,7 +468,7 @@ class Wm: ) -> tuple[int, int, int, int] | None: ... aspect = wm_aspect @overload - def wm_attributes(self) -> Tuple[Any, ...]: ... + def wm_attributes(self) -> tuple[Any, ...]: ... @overload def wm_attributes(self, __option: str) -> Any: ... @overload @@ -525,7 +479,7 @@ class Wm: @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: ... colormapwindows = wm_colormapwindows @@ -589,7 +543,7 @@ class Wm: @overload def wm_protocol(self, name: str, func: None = ...) -> str: ... @overload - def wm_protocol(self, name: None = ..., func: None = ...) -> Tuple[str, ...]: ... + def wm_protocol(self, name: None = ..., func: None = ...) -> tuple[str, ...]: ... protocol = wm_protocol @overload def wm_resizable(self, width: None = ..., height: None = ...) -> tuple[bool, bool]: ... @@ -688,7 +642,8 @@ class Tk(Misc, Wm): quit: Any record: Any setvar: Any - split: Any + if sys.version_info < (3, 11): + split: Any splitlist: Any unsetvar: Any wantobjects: Any @@ -739,14 +694,6 @@ class Pack: pack = pack_configure forget = pack_forget propagate = Misc.pack_propagate - # commented out to avoid mypy getting confused with multiple - # inheritance and how things get overridden with different things - # info = pack_info - # pack_propagate = Misc.pack_propagate - # configure = pack_configure - # config = pack_configure - # slaves = Misc.pack_slaves - # pack_slaves = Misc.pack_slaves class _PlaceInfo(_InMiscNonTotal): # empty dict if widget hasn't been placed anchor: _Anchor @@ -783,13 +730,6 @@ class Place: def place_info(self) -> _PlaceInfo: ... place = place_configure info = place_info - # commented out to avoid mypy getting confused with multiple - # inheritance and how things get overridden with different things - # config = place_configure - # configure = place_configure - # forget = place_forget - # slaves = Misc.place_slaves - # place_slaves = Misc.place_slaves class _GridInfo(_InMiscNonTotal): # empty dict if widget hasn't been gridded column: int @@ -825,24 +765,6 @@ class Grid: grid = grid_configure location = Misc.grid_location size = Misc.grid_size - # commented out to avoid mypy getting confused with multiple - # inheritance and how things get overridden with different things - # bbox = Misc.grid_bbox - # grid_bbox = Misc.grid_bbox - # forget = grid_forget - # info = grid_info - # grid_location = Misc.grid_location - # grid_propagate = Misc.grid_propagate - # grid_size = Misc.grid_size - # rowconfigure = Misc.grid_rowconfigure - # grid_rowconfigure = Misc.grid_rowconfigure - # grid_columnconfigure = Misc.grid_columnconfigure - # columnconfigure = Misc.grid_columnconfigure - # config = grid_configure - # configure = grid_configure - # propagate = Misc.grid_propagate - # slaves = Misc.grid_slaves - # grid_slaves = Misc.grid_slaves class BaseWidget(Misc): master: Misc @@ -1121,21 +1043,19 @@ class Canvas(Widget, XView, YView): def addtag_overlapping(self, newtag: str, x1: _ScreenUnits, y1: _ScreenUnits, x2: _ScreenUnits, y2: _ScreenUnits) -> None: ... def addtag_withtag(self, newtag: str, tagOrId: str | _CanvasItemId) -> None: ... def find(self, *args): ... # internal method - def find_above(self, tagOrId: str | _CanvasItemId) -> Tuple[_CanvasItemId, ...]: ... - def find_all(self) -> Tuple[_CanvasItemId, ...]: ... - def find_below(self, tagOrId: str | _CanvasItemId) -> Tuple[_CanvasItemId, ...]: ... + def find_above(self, tagOrId: str | _CanvasItemId) -> tuple[_CanvasItemId, ...]: ... + def find_all(self) -> tuple[_CanvasItemId, ...]: ... + def find_below(self, tagOrId: str | _CanvasItemId) -> tuple[_CanvasItemId, ...]: ... def find_closest( self, x: _ScreenUnits, y: _ScreenUnits, halo: _ScreenUnits | None = ..., start: str | _CanvasItemId | None = ... - ) -> Tuple[_CanvasItemId, ...]: ... + ) -> tuple[_CanvasItemId, ...]: ... def find_enclosed( self, x1: _ScreenUnits, y1: _ScreenUnits, x2: _ScreenUnits, y2: _ScreenUnits - ) -> Tuple[_CanvasItemId, ...]: ... - def find_overlapping(self, x1: _ScreenUnits, y1: _ScreenUnits, x2: _ScreenUnits, y2: float) -> Tuple[_CanvasItemId, ...]: ... - def find_withtag(self, tagOrId: str | _CanvasItemId) -> Tuple[_CanvasItemId, ...]: ... - # Canvas.bbox() args are `str | _CanvasItemId`, but mypy rejects that - # description because it's incompatible with Misc.bbox(), an alias for - # Misc.grid_bbox(). Yes it is, but there's not much we can do about it. - def bbox(self, *args: str | _CanvasItemId) -> tuple[int, int, int, int]: ... # type: ignore + ) -> tuple[_CanvasItemId, ...]: ... + def find_overlapping(self, x1: _ScreenUnits, y1: _ScreenUnits, x2: _ScreenUnits, y2: float) -> tuple[_CanvasItemId, ...]: ... + def find_withtag(self, tagOrId: str | _CanvasItemId) -> tuple[_CanvasItemId, ...]: ... + # Incompatible with Misc.bbox(), tkinter violates LSP + def bbox(self, *args: str | _CanvasItemId) -> tuple[int, int, int, int]: ... # type: ignore[override] @overload def tag_bind( self, @@ -1156,7 +1076,7 @@ class Canvas(Widget, XView, YView): @overload def coords(self) -> list[float]: ... @overload - def coords(self, __args: list[int] | list[float] | Tuple[float, ...]) -> None: ... + def coords(self, __args: list[int] | list[float] | tuple[float, ...]) -> None: ... @overload def coords(self, __x1: float, __y1: float, *args: float) -> None: ... # create_foo() methods accept coords as a list, a tuple, or as separate arguments. @@ -1172,16 +1092,16 @@ class Canvas(Widget, XView, YView): __x1: float, __y1: float, *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., arrow: Literal["first", "last", "both"] = ..., arrowshape: tuple[float, float, float] = ..., capstyle: Literal["round", "projecting", "butt"] = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledstipple: _Bitmap = ..., disabledwidth: _ScreenUnits = ..., @@ -1192,7 +1112,7 @@ class Canvas(Widget, XView, YView): splinesteps: float = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1200,16 +1120,16 @@ class Canvas(Widget, XView, YView): self, __coords: tuple[float, float, float, float] | list[int] | list[float], *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., arrow: Literal["first", "last", "both"] = ..., arrowshape: tuple[float, float, float] = ..., capstyle: Literal["round", "projecting", "butt"] = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledstipple: _Bitmap = ..., disabledwidth: _ScreenUnits = ..., @@ -1220,7 +1140,7 @@ class Canvas(Widget, XView, YView): splinesteps: float = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1231,15 +1151,15 @@ class Canvas(Widget, XView, YView): __x1: float, __y1: float, *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1252,7 +1172,7 @@ class Canvas(Widget, XView, YView): outlinestipple: _Bitmap = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1260,15 +1180,15 @@ class Canvas(Widget, XView, YView): self, __coords: tuple[float, float, float, float] | list[int] | list[float], *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1281,7 +1201,7 @@ class Canvas(Widget, XView, YView): outlinestipple: _Bitmap = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1292,15 +1212,15 @@ class Canvas(Widget, XView, YView): __x1: float, __y1: float, *xy_pairs: float, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1316,23 +1236,23 @@ class Canvas(Widget, XView, YView): splinesteps: float = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload def create_polygon( self, - __coords: Tuple[float, ...] | list[int] | list[float], + __coords: tuple[float, ...] | list[int] | list[float], *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1348,7 +1268,7 @@ class Canvas(Widget, XView, YView): splinesteps: float = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1359,15 +1279,15 @@ class Canvas(Widget, XView, YView): __x1: float, __y1: float, *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1380,7 +1300,7 @@ class Canvas(Widget, XView, YView): outlinestipple: _Bitmap = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1388,15 +1308,15 @@ class Canvas(Widget, XView, YView): self, __coords: tuple[float, float, float, float] | list[int] | list[float], *, - activedash: str | list[int] | Tuple[int, ...] = ..., + activedash: str | list[int] | tuple[int, ...] = ..., activefill: _Color = ..., activeoutline: _Color = ..., activeoutlinestipple: _Color = ..., activestipple: str = ..., activewidth: _ScreenUnits = ..., - dash: str | list[int] | Tuple[int, ...] = ..., + dash: str | list[int] | tuple[int, ...] = ..., dashoffset: _ScreenUnits = ..., - disableddash: str | list[int] | Tuple[int, ...] = ..., + disableddash: str | list[int] | tuple[int, ...] = ..., disabledfill: _Color = ..., disabledoutline: _Color = ..., disabledoutlinestipple: _Color = ..., @@ -1409,7 +1329,7 @@ class Canvas(Widget, XView, YView): outlinestipple: _Bitmap = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @overload @@ -1429,7 +1349,7 @@ class Canvas(Widget, XView, YView): offset: _ScreenUnits = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., text: float | str = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @@ -1449,7 +1369,7 @@ class Canvas(Widget, XView, YView): offset: _ScreenUnits = ..., state: Literal["normal", "active", "disabled"] = ..., stipple: _Bitmap = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., text: float | str = ..., width: _ScreenUnits = ..., ) -> _CanvasItemId: ... @@ -1462,7 +1382,7 @@ class Canvas(Widget, XView, YView): anchor: _Anchor = ..., height: _ScreenUnits = ..., state: Literal["normal", "active", "disabled"] = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., window: Widget = ..., ) -> _CanvasItemId: ... @@ -1474,7 +1394,7 @@ class Canvas(Widget, XView, YView): anchor: _Anchor = ..., height: _ScreenUnits = ..., state: Literal["normal", "active", "disabled"] = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., width: _ScreenUnits = ..., window: Widget = ..., ) -> _CanvasItemId: ... @@ -1485,7 +1405,7 @@ class Canvas(Widget, XView, YView): @overload def dtag(self, __id: _CanvasItemId, __tag_to_delete: str) -> None: ... def focus(self, *args): ... - def gettags(self, __tagOrId: str | _CanvasItemId) -> Tuple[str, ...]: ... + def gettags(self, __tagOrId: str | _CanvasItemId) -> tuple[str, ...]: ... def icursor(self, *args): ... def index(self, *args): ... def insert(self, *args): ... @@ -1505,10 +1425,10 @@ class Canvas(Widget, XView, YView): # # But mypy doesn't like aliasing here (maybe because Misc defines the same names) def tag_lower(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... - def lower(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore + def lower(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore[override] def tag_raise(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... - def tkraise(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore - def lift(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore + def tkraise(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore[override] + def lift(self, __first: str | _CanvasItemId, __second: str | _CanvasItemId | None = ...) -> None: ... # type: ignore[override] def scale(self, *args): ... def scan_mark(self, x, y): ... def scan_dragto(self, x, y, gain: int = ...): ... @@ -1737,7 +1657,7 @@ class Entry(Widget, XView): def scan_mark(self, x): ... def scan_dragto(self, x): ... def selection_adjust(self, index: _EntryIndex) -> None: ... - def selection_clear(self) -> None: ... # type: ignore + def selection_clear(self) -> None: ... # type: ignore[override] def selection_from(self, index: _EntryIndex) -> None: ... def selection_present(self) -> bool: ... def selection_range(self, start: _EntryIndex, end: _EntryIndex) -> None: ... @@ -1760,9 +1680,9 @@ class Frame(Widget): bg: _Color = ..., border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - class_: str = ..., - colormap: Literal["new", ""] | Misc = ..., - container: bool = ..., + 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 = ..., highlightbackground: _Color = ..., @@ -1773,7 +1693,7 @@ class Frame(Widget): pady: _ScreenUnits = ..., relief: _Relief = ..., takefocus: _TakeFocusValue = ..., - visual: str | tuple[str, int] = ..., + visual: str | tuple[str, int] = ..., # can't be changed with configure() width: _ScreenUnits = ..., ) -> None: ... @overload @@ -1983,7 +1903,7 @@ class Listbox(Widget, XView, YView): def see(self, index): ... def selection_anchor(self, index): ... select_anchor: Any - def selection_clear(self, first, last: Any | None = ...): ... # type: ignore + def selection_clear(self, first, last: Any | None = ...): ... # type: ignore[override] select_clear: Any def selection_includes(self, index): ... select_includes: Any @@ -2730,7 +2650,7 @@ class Text(Widget, XView, YView): startline: int | Literal[""] = ..., state: Literal["normal", "disabled"] = ..., # Literal inside Tuple doesn't actually work - tabs: _ScreenUnits | str | Tuple[_ScreenUnits | str, ...] = ..., + tabs: _ScreenUnits | str | tuple[_ScreenUnits | str, ...] = ..., tabstyle: Literal["tabular", "wordprocessor"] = ..., takefocus: _TakeFocusValue = ..., undo: bool = ..., @@ -2781,7 +2701,7 @@ class Text(Widget, XView, YView): spacing3: _ScreenUnits = ..., startline: int | Literal[""] = ..., state: Literal["normal", "disabled"] = ..., - tabs: _ScreenUnits | str | Tuple[_ScreenUnits | str, ...] = ..., + tabs: _ScreenUnits | str | tuple[_ScreenUnits | str, ...] = ..., tabstyle: Literal["tabular", "wordprocessor"] = ..., takefocus: _TakeFocusValue = ..., undo: bool = ..., @@ -2793,7 +2713,7 @@ class Text(Widget, XView, YView): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... config = configure - def bbox(self, index: _TextIndex) -> tuple[int, int, int, int] | None: ... # type: ignore + def bbox(self, index: _TextIndex) -> tuple[int, int, int, int] | None: ... # type: ignore[override] def compare(self, index1: _TextIndex, op: Literal["<", "<=", "==", ">=", ">", "!="], index2: _TextIndex) -> bool: ... def count(self, index1, index2, *args): ... # TODO @overload @@ -2860,20 +2780,20 @@ class Text(Widget, XView, YView): def image_create(self, index, cnf=..., **kw): ... def image_names(self): ... def index(self, index: _TextIndex) -> str: ... - def insert(self, index: _TextIndex, chars: str, *args: str | list[str] | Tuple[str, ...]) -> None: ... + def insert(self, index: _TextIndex, chars: str, *args: str | list[str] | tuple[str, ...]) -> None: ... @overload def mark_gravity(self, markName: str, direction: None = ...) -> Literal["left", "right"]: ... @overload def mark_gravity(self, markName: str, direction: Literal["left", "right"]) -> None: ... # actually returns empty string - def mark_names(self) -> Tuple[str, ...]: ... + def mark_names(self) -> tuple[str, ...]: ... def mark_set(self, markName: str, index: _TextIndex) -> None: ... def mark_unset(self, *markNames: str) -> None: ... def mark_next(self, index: _TextIndex) -> str | None: ... def mark_previous(self, index: _TextIndex) -> str | None: ... # **kw of peer_create is same as the kwargs of Text.__init__ def peer_create(self, newPathName: str | Text, cnf: dict[str, Any] = ..., **kw: Any) -> None: ... - def peer_names(self) -> Tuple[_tkinter.Tcl_Obj, ...]: ... - def replace(self, index1: _TextIndex, index2: _TextIndex, chars: str, *args: str | list[str] | Tuple[str, ...]) -> None: ... + def peer_names(self) -> tuple[_tkinter.Tcl_Obj, ...]: ... + def replace(self, index1: _TextIndex, index2: _TextIndex, chars: str, *args: str | list[str] | tuple[str, ...]) -> None: ... def scan_mark(self, x: int, y: int) -> None: ... def scan_dragto(self, x: int, y: int) -> None: ... def search( @@ -2945,11 +2865,11 @@ class Text(Widget, XView, YView): tag_config = tag_configure 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: ... - def tag_names(self, index: _TextIndex | None = ...) -> Tuple[str, ...]: ... + def tag_names(self, index: _TextIndex | None = ...) -> tuple[str, ...]: ... def tag_nextrange(self, tagName: str, index1: _TextIndex, index2: _TextIndex | None = ...) -> tuple[str, str] | tuple[()]: ... def tag_prevrange(self, tagName: str, index1: _TextIndex, index2: _TextIndex | None = ...) -> tuple[str, str] | tuple[()]: ... def tag_raise(self, tagName: str, aboveThis: str | None = ...) -> None: ... - def tag_ranges(self, tagName: str) -> Tuple[_tkinter.Tcl_Obj, ...]: ... + def tag_ranges(self, tagName: str) -> tuple[_tkinter.Tcl_Obj, ...]: ... # tag_remove and tag_delete are different def tag_remove(self, tagName: str, index1: _TextIndex, index2: _TextIndex | None = ...) -> None: ... # TODO: window_* methods @@ -3039,10 +2959,10 @@ class PhotoImage(Image): str | list[str] | list[list[_Color]] - | list[Tuple[_Color, ...]] - | Tuple[str, ...] - | Tuple[list[_Color], ...] - | Tuple[Tuple[_Color, ...], ...] + | list[tuple[_Color, ...]] + | tuple[str, ...] + | tuple[list[_Color], ...] + | tuple[tuple[_Color, ...], ...] ), to: tuple[int, int] | None = ..., ) -> None: ... @@ -3066,8 +2986,8 @@ class BitmapImage(Image): maskfile: StrOrBytesPath = ..., ) -> None: ... -def image_names() -> Tuple[str, ...]: ... -def image_types() -> Tuple[str, ...]: ... +def image_names() -> tuple[str, ...]: ... +def image_types() -> tuple[str, ...]: ... class Spinbox(Widget, XView): def __init__( @@ -3086,7 +3006,7 @@ class Spinbox(Widget, XView): buttondownrelief: _Relief = ..., buttonuprelief: _Relief = ..., # percent substitutions don't seem to be supported, it's similar to Entry's validation stuff - command: Callable[[], Any] | str | list[str] | Tuple[str, ...] = ..., + command: Callable[[], Any] | str | list[str] | tuple[str, ...] = ..., cursor: _Cursor = ..., disabledbackground: _Color = ..., disabledforeground: _Color = ..., @@ -3123,7 +3043,7 @@ class Spinbox(Widget, XView): validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: _EntryValidateCommand = ..., vcmd: _EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., wrap: bool = ..., xscrollcommand: _XYScrollCommand = ..., @@ -3143,7 +3063,7 @@ class Spinbox(Widget, XView): buttoncursor: _Cursor = ..., buttondownrelief: _Relief = ..., buttonuprelief: _Relief = ..., - command: Callable[[], Any] | str | list[str] | Tuple[str, ...] = ..., + command: Callable[[], Any] | str | list[str] | tuple[str, ...] = ..., cursor: _Cursor = ..., disabledbackground: _Color = ..., disabledforeground: _Color = ..., @@ -3179,7 +3099,7 @@ class Spinbox(Widget, XView): validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: _EntryValidateCommand = ..., vcmd: _EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., wrap: bool = ..., xscrollcommand: _XYScrollCommand = ..., @@ -3199,7 +3119,7 @@ class Spinbox(Widget, XView): def scan(self, *args): ... def scan_mark(self, x): ... def scan_dragto(self, x): ... - def selection(self, *args: Any) -> Tuple[int, ...]: ... + def selection(self, *args: Any) -> tuple[int, ...]: ... def selection_adjust(self, index): ... def selection_clear(self): ... def selection_element(self, element: Any | None = ...): ... @@ -3220,9 +3140,9 @@ class LabelFrame(Widget): bg: _Color = ..., border: _ScreenUnits = ..., borderwidth: _ScreenUnits = ..., - class_: str = ..., - colormap: Literal["new", ""] | Misc = ..., - container: bool = ..., # undocumented + 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 = ..., fg: _Color = ..., font: _FontDescription = ..., @@ -3240,7 +3160,7 @@ class LabelFrame(Widget): relief: _Relief = ..., takefocus: _TakeFocusValue = ..., text: float | str = ..., - visual: str | tuple[str, int] = ..., + visual: str | tuple[str, int] = ..., # can't be changed with configure() width: _ScreenUnits = ..., ) -> None: ... @overload diff --git a/mypy/typeshed/stdlib/tkinter/filedialog.pyi b/mypy/typeshed/stdlib/tkinter/filedialog.pyi index 0fc7d6e8a3bc..b818d5e8253e 100644 --- a/mypy/typeshed/stdlib/tkinter/filedialog.pyi +++ b/mypy/typeshed/stdlib/tkinter/filedialog.pyi @@ -1,6 +1,6 @@ from _typeshed import StrOrBytesPath from tkinter import Button, Entry, Frame, Listbox, Misc, Scrollbar, StringVar, Toplevel, commondialog -from typing import IO, Any, ClassVar, Iterable, Tuple +from typing import IO, Any, ClassVar, Iterable from typing_extensions import Literal dialogstates: dict[Any, tuple[Any, Any]] @@ -64,7 +64,7 @@ def asksaveasfilename( *, confirmoverwrite: bool | None = ..., defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., @@ -74,7 +74,7 @@ def asksaveasfilename( def askopenfilename( *, defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., @@ -84,13 +84,13 @@ def askopenfilename( def askopenfilenames( *, defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., title: str | None = ..., typevariable: StringVar | str | None = ..., -) -> Literal[""] | Tuple[str, ...]: ... +) -> Literal[""] | tuple[str, ...]: ... def askdirectory( *, initialdir: StrOrBytesPath | None = ..., mustexist: bool | None = ..., parent: Misc | None = ..., title: str | None = ... ) -> str: ... # can be empty string @@ -101,7 +101,7 @@ def asksaveasfile( *, confirmoverwrite: bool | None = ..., defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., @@ -112,7 +112,7 @@ def askopenfile( mode: str = ..., *, defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., @@ -123,11 +123,11 @@ def askopenfiles( mode: str = ..., *, defaultextension: str | None = ..., - filetypes: Iterable[tuple[str, str | list[str] | Tuple[str, ...]]] | None = ..., + filetypes: Iterable[tuple[str, str | list[str] | tuple[str, ...]]] | None = ..., initialdir: StrOrBytesPath | None = ..., initialfile: StrOrBytesPath | None = ..., parent: Misc | None = ..., title: str | None = ..., typevariable: StringVar | str | None = ..., -) -> Tuple[IO[Any], ...]: ... # can be empty tuple +) -> tuple[IO[Any], ...]: ... # can be empty tuple def test() -> None: ... diff --git a/mypy/typeshed/stdlib/tkinter/font.pyi b/mypy/typeshed/stdlib/tkinter/font.pyi index fccc0fbf1f0a..211e8ec9a0be 100644 --- a/mypy/typeshed/stdlib/tkinter/font.pyi +++ b/mypy/typeshed/stdlib/tkinter/font.pyi @@ -1,7 +1,7 @@ import _tkinter import sys import tkinter -from typing import Any, List, Tuple, Union, overload +from typing import Any, Union, overload from typing_extensions import Literal, TypedDict NORMAL: Literal["normal"] @@ -15,8 +15,8 @@ _FontDescription = Union[ # A font object constructed in Python Font, # ("Helvetica", 12, BOLD) - List[Any], - Tuple[Any, ...], + list[Any], + tuple[Any, ...], # A font object constructed in Tcl _tkinter.Tcl_Obj, ] @@ -102,8 +102,8 @@ class Font: def metrics(self, *, displayof: tkinter.Misc | None = ...) -> _MetricsDict: ... def measure(self, text: str, displayof: tkinter.Misc | None = ...) -> int: ... -def families(root: tkinter.Misc | None = ..., displayof: tkinter.Misc | None = ...) -> Tuple[str, ...]: ... -def names(root: tkinter.Misc | None = ...) -> Tuple[str, ...]: ... +def families(root: tkinter.Misc | None = ..., displayof: tkinter.Misc | None = ...) -> tuple[str, ...]: ... +def names(root: tkinter.Misc | None = ...) -> tuple[str, ...]: ... if sys.version_info >= (3, 10): def nametofont(name: str, root: tkinter.Misc | None = ...) -> Font: ... diff --git a/mypy/typeshed/stdlib/tkinter/tix.pyi b/mypy/typeshed/stdlib/tkinter/tix.pyi index 3037212c0ad1..6842ab7b1108 100644 --- a/mypy/typeshed/stdlib/tkinter/tix.pyi +++ b/mypy/typeshed/stdlib/tkinter/tix.pyi @@ -1,5 +1,5 @@ import tkinter -from typing import Any, Tuple +from typing import Any from typing_extensions import Literal WINDOW: Literal["window"] @@ -194,7 +194,7 @@ class HList(TixWidget, tkinter.XView, tkinter.YView): def indicator_size(self, entry: str) -> int: ... def info_anchor(self) -> str: ... def info_bbox(self, entry: str) -> tuple[int, int, int, int]: ... - def info_children(self, entry: str | None = ...) -> Tuple[str, ...]: ... + def info_children(self, entry: str | None = ...) -> tuple[str, ...]: ... def info_data(self, entry: str) -> Any: ... def info_dragsite(self) -> str: ... def info_dropsite(self) -> str: ... @@ -203,7 +203,7 @@ class HList(TixWidget, tkinter.XView, tkinter.YView): def info_next(self, entry: str) -> str: ... def info_parent(self, entry: str) -> str: ... def info_prev(self, entry: str) -> str: ... - def info_selection(self) -> Tuple[str, ...]: ... + def info_selection(self) -> tuple[str, ...]: ... def item_cget(self, entry: str, col: int, opt: Any) -> Any: ... def item_configure(self, entry: str, col: int, cnf: dict[str, Any] = ..., **kw: Any) -> Any | None: ... def item_create(self, entry: str, col: int, cnf: dict[str, Any] = ..., **kw: Any) -> None: ... @@ -224,7 +224,7 @@ class CheckList(TixWidget): def close(self, entrypath: str) -> None: ... def getmode(self, entrypath: str) -> str: ... def open(self, entrypath: str) -> None: ... - def getselection(self, mode: str = ...) -> Tuple[str, ...]: ... + def getselection(self, mode: str = ...) -> tuple[str, ...]: ... def getstatus(self, entrypath: str) -> str: ... def setstatus(self, entrypath: str, mode: str = ...) -> None: ... @@ -253,7 +253,7 @@ class TList(TixWidget, tkinter.XView, tkinter.YView): def info_down(self, index: int) -> int: ... def info_left(self, index: int) -> int: ... def info_right(self, index: int) -> int: ... - def info_selection(self) -> Tuple[int, ...]: ... + def info_selection(self) -> tuple[int, ...]: ... def info_size(self) -> int: ... def info_up(self, index: int) -> int: ... def nearest(self, x: int, y: int) -> int: ... @@ -266,7 +266,7 @@ class PanedWindow(TixWidget): def __init__(self, master: tkinter.Widget | None, cnf: dict[str, Any] = ..., **kw: Any) -> None: ... def add(self, name: str, cnf: dict[str, Any] = ..., **kw: Any) -> None: ... def delete(self, name: str) -> None: ... - def forget(self, name: str) -> None: ... # type: ignore + def forget(self, name: str) -> None: ... # type: ignore[override] def panecget(self, entry: str, opt: Any) -> Any: ... def paneconfigure(self, entry: str, cnf: dict[str, Any] = ..., **kw: Any) -> Any | None: ... def panes(self) -> list[tkinter.Widget]: ... diff --git a/mypy/typeshed/stdlib/tkinter/ttk.pyi b/mypy/typeshed/stdlib/tkinter/ttk.pyi index be0713ec2e4b..f7319291da6d 100644 --- a/mypy/typeshed/stdlib/tkinter/ttk.pyi +++ b/mypy/typeshed/stdlib/tkinter/ttk.pyi @@ -2,7 +2,7 @@ import _tkinter import sys import tkinter from tkinter.font import _FontDescription -from typing import Any, Callable, Tuple, Union, overload +from typing import Any, Callable, Union, overload from typing_extensions import Literal, TypedDict def tclobjs_to_py(adict): ... @@ -24,7 +24,7 @@ class Style: def element_options(self, elementname): ... def theme_create(self, themename, parent: Any | None = ..., settings: Any | None = ...): ... def theme_settings(self, themename, settings): ... - def theme_names(self) -> Tuple[str, ...]: ... + def theme_names(self) -> tuple[str, ...]: ... @overload def theme_use(self, themename: str) -> None: ... @overload @@ -158,7 +158,7 @@ class Entry(Widget, tkinter.Entry): width: int = ..., xscrollcommand: tkinter._XYScrollCommand = ..., ) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., @@ -183,7 +183,7 @@ class Entry(Widget, tkinter.Entry): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... # config must be copy/pasted, otherwise ttk.Entry().config is mypy error (don't know why) - @overload # type: ignore + @overload # type: ignore[override] def config( self, cnf: dict[str, Any] | None = ..., @@ -234,11 +234,11 @@ class Combobox(Entry): textvariable: tkinter.Variable = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., # undocumented validatecommand: tkinter._EntryValidateCommand = ..., # undocumented - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., xscrollcommand: tkinter._XYScrollCommand = ..., # undocumented ) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., @@ -259,14 +259,14 @@ class Combobox(Entry): textvariable: tkinter.Variable = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: tkinter._EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., xscrollcommand: tkinter._XYScrollCommand = ..., ) -> dict[str, tuple[str, str, str, Any, Any]] | None: ... @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... # config must be copy/pasted, otherwise ttk.Combobox().config is mypy error (don't know why) - @overload # type: ignore + @overload # type: ignore[override] def config( self, cnf: dict[str, Any] | None = ..., @@ -287,7 +287,7 @@ class Combobox(Entry): textvariable: tkinter.Variable = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: tkinter._EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., xscrollcommand: tkinter._XYScrollCommand = ..., ) -> dict[str, tuple[str, str, str, Any, Any]] | None: ... @@ -541,13 +541,13 @@ class Panedwindow(Widget, tkinter.PanedWindow): # width and height for tkinter.ttk.Panedwindow are int but for tkinter.PanedWindow they are screen units height: int = ..., name: str = ..., - orient: Literal["vertical", "horizontal"] = ..., + orient: Literal["vertical", "horizontal"] = ..., # can't be changed with configure() style: str = ..., takefocus: tkinter._TakeFocusValue = ..., width: int = ..., ) -> None: ... def add(self, child: tkinter.Widget, *, weight: int = ..., **kw) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., @@ -561,7 +561,7 @@ class Panedwindow(Widget, tkinter.PanedWindow): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... # config must be copy/pasted, otherwise ttk.Panedwindow().config is mypy error (don't know why) - @overload # type: ignore + @overload # type: ignore[override] def config( self, cnf: dict[str, Any] | None = ..., @@ -688,7 +688,7 @@ class Scale(Widget, tkinter.Scale): value: float = ..., variable: tkinter.IntVar | tkinter.DoubleVar = ..., ) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., @@ -708,7 +708,7 @@ class Scale(Widget, tkinter.Scale): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... # config must be copy/pasted, otherwise ttk.Scale().config is mypy error (don't know why) - @overload # type: ignore + @overload # type: ignore[override] def config( self, cnf: dict[str, Any] | None = ..., @@ -742,7 +742,7 @@ class Scrollbar(Widget, tkinter.Scrollbar): style: str = ..., takefocus: tkinter._TakeFocusValue = ..., ) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., @@ -756,7 +756,7 @@ class Scrollbar(Widget, tkinter.Scrollbar): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... # config must be copy/pasted, otherwise ttk.Scrollbar().config is mypy error (don't know why) - @overload # type: ignore + @overload # type: ignore[override] def config( self, cnf: dict[str, Any] | None = ..., @@ -828,7 +828,7 @@ if sys.version_info >= (3, 7): *, background: tkinter._Color = ..., # undocumented class_: str = ..., - command: Callable[[], Any] | str | list[str] | Tuple[str, ...] = ..., + command: Callable[[], Any] | str | list[str] | tuple[str, ...] = ..., cursor: tkinter._Cursor = ..., exportselection: bool = ..., # undocumented font: _FontDescription = ..., # undocumented @@ -847,18 +847,18 @@ if sys.version_info >= (3, 7): to: float = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: tkinter._EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., # undocumented wrap: bool = ..., xscrollcommand: tkinter._XYScrollCommand = ..., ) -> None: ... - @overload # type: ignore + @overload # type: ignore[override] def configure( self, cnf: dict[str, Any] | None = ..., *, background: tkinter._Color = ..., - command: Callable[[], Any] | str | list[str] | Tuple[str, ...] = ..., + command: Callable[[], Any] | str | list[str] | tuple[str, ...] = ..., cursor: tkinter._Cursor = ..., exportselection: bool = ..., font: _FontDescription = ..., @@ -876,14 +876,14 @@ if sys.version_info >= (3, 7): to: float = ..., validate: Literal["none", "focus", "focusin", "focusout", "key", "all"] = ..., validatecommand: tkinter._EntryValidateCommand = ..., - values: list[str] | Tuple[str, ...] = ..., + values: list[str] | tuple[str, ...] = ..., width: int = ..., wrap: bool = ..., xscrollcommand: tkinter._XYScrollCommand = ..., ) -> dict[str, tuple[str, str, str, Any, Any]] | None: ... @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... - config = configure # type: ignore + config = configure # type: ignore[assignment] def set(self, value: Any) -> None: ... class _TreeviewItemDict(TypedDict): @@ -922,9 +922,9 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): master: tkinter.Misc | None = ..., *, class_: str = ..., - columns: str | list[str] | Tuple[str, ...] = ..., + columns: str | list[str] | tuple[str, ...] = ..., cursor: tkinter._Cursor = ..., - displaycolumns: str | list[str] | Tuple[str, ...] | list[int] | Tuple[int, ...] | Literal["#all"] = ..., + displaycolumns: str | list[str] | tuple[str, ...] | list[int] | tuple[int, ...] | Literal["#all"] = ..., height: int = ..., name: str = ..., padding: tkinter._Padding = ..., @@ -933,7 +933,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): # # '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, ...] = ..., + show: Literal["tree", "headings", "tree headings", ""] | list[str] | tuple[str, ...] = ..., style: str = ..., takefocus: tkinter._TakeFocusValue = ..., xscrollcommand: tkinter._XYScrollCommand = ..., @@ -944,13 +944,13 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): self, cnf: dict[str, Any] | None = ..., *, - columns: str | list[str] | Tuple[str, ...] = ..., + columns: str | list[str] | tuple[str, ...] = ..., cursor: tkinter._Cursor = ..., - displaycolumns: str | list[str] | Tuple[str, ...] | list[int] | Tuple[int, ...] | Literal["#all"] = ..., + displaycolumns: str | list[str] | tuple[str, ...] | list[int] | tuple[int, ...] | Literal["#all"] = ..., height: int = ..., padding: tkinter._Padding = ..., selectmode: Literal["extended", "browse", "none"] = ..., - show: Literal["tree", "headings", "tree headings", ""] | list[str] | Tuple[str, ...] = ..., + show: Literal["tree", "headings", "tree headings", ""] | list[str] | tuple[str, ...] = ..., style: str = ..., takefocus: tkinter._TakeFocusValue = ..., xscrollcommand: tkinter._XYScrollCommand = ..., @@ -959,8 +959,8 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): @overload def configure(self, cnf: str) -> tuple[str, str, str, Any, Any]: ... config = configure - def bbox(self, item, column: _TreeviewColumnId | None = ...) -> tuple[int, int, int, int] | Literal[""]: ... # type: ignore - def get_children(self, item: str | None = ...) -> Tuple[str, ...]: ... + def bbox(self, item, column: _TreeviewColumnId | None = ...) -> tuple[int, int, int, int] | Literal[""]: ... # type: ignore[override] + def get_children(self, item: str | None = ...) -> tuple[str, ...]: ... def set_children(self, item: str, *newchildren: str) -> None: ... @overload def column(self, column: _TreeviewColumnId, option: Literal["width", "minwidth"]) -> int: ... @@ -987,7 +987,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): def delete(self, *items: str) -> None: ... def detach(self, *items: str) -> None: ... def exists(self, item: str) -> bool: ... - @overload # type: ignore + @overload # type: ignore[override] def focus(self, item: None = ...) -> str: ... # can return empty string @overload def focus(self, item: str) -> Literal[""]: ... @@ -1027,20 +1027,20 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): id: str = ..., # same as iid text: str = ..., image: tkinter._ImageSpec = ..., - values: list[Any] | Tuple[Any, ...] = ..., + values: list[Any] | tuple[Any, ...] = ..., open: bool = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., ) -> str: ... @overload def item(self, item: str, option: Literal["text"]) -> str: ... @overload def item(self, item: str, option: Literal["image"]) -> tuple[str] | Literal[""]: ... @overload - def item(self, item: str, option: Literal["values"]) -> Tuple[Any, ...] | Literal[""]: ... + def item(self, item: str, option: Literal["values"]) -> tuple[Any, ...] | Literal[""]: ... @overload def item(self, item: str, option: Literal["open"]) -> bool: ... # actually 0 or 1 @overload - def item(self, item: str, option: Literal["tags"]) -> Tuple[str, ...] | Literal[""]: ... + def item(self, item: str, option: Literal["tags"]) -> tuple[str, ...] | Literal[""]: ... @overload def item(self, item: str, option: str) -> Any: ... @overload @@ -1051,9 +1051,9 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): *, text: str = ..., image: tkinter._ImageSpec = ..., - values: list[Any] | Tuple[Any, ...] | Literal[""] = ..., + values: list[Any] | tuple[Any, ...] | Literal[""] = ..., open: bool = ..., - tags: str | list[str] | Tuple[str, ...] = ..., + tags: str | list[str] | tuple[str, ...] = ..., ) -> _TreeviewItemDict | None: ... def move(self, item: str, parent: str, index: int) -> None: ... reattach = move @@ -1062,13 +1062,13 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): def prev(self, item: str) -> str: ... # returning empty string means first item def see(self, item: str) -> None: ... if sys.version_info >= (3, 8): - def selection(self) -> Tuple[str, ...]: ... + def selection(self) -> tuple[str, ...]: ... else: - def selection(self, selop: Any | None = ..., items: Any | None = ...) -> Tuple[str, ...]: ... - def selection_set(self, items: str | list[str] | Tuple[str, ...]) -> None: ... - def selection_add(self, items: str | list[str] | Tuple[str, ...]) -> None: ... - def selection_remove(self, items: str | list[str] | Tuple[str, ...]) -> None: ... - def selection_toggle(self, items: str | list[str] | Tuple[str, ...]) -> None: ... + def selection(self, selop: Any | None = ..., items: Any | None = ...) -> tuple[str, ...]: ... + def selection_set(self, items: str | list[str] | tuple[str, ...]) -> None: ... + def selection_add(self, items: str | list[str] | tuple[str, ...]) -> None: ... + def selection_remove(self, items: str | list[str] | tuple[str, ...]) -> None: ... + def selection_toggle(self, items: str | list[str] | tuple[str, ...]) -> None: ... @overload def set(self, item: str, column: None = ..., value: None = ...) -> dict[str, Any]: ... @overload @@ -1104,7 +1104,7 @@ class Treeview(Widget, tkinter.XView, tkinter.YView): image: tkinter._ImageSpec = ..., ) -> _TreeviewTagDict | Any: ... # can be None but annoying to check @overload - def tag_has(self, tagname: str, item: None = ...) -> Tuple[str, ...]: ... + def tag_has(self, tagname: str, item: None = ...) -> tuple[str, ...]: ... @overload def tag_has(self, tagname: str, item: str) -> bool: ... diff --git a/mypy/typeshed/stdlib/token.pyi b/mypy/typeshed/stdlib/token.pyi index 90381833511b..9451015e9df5 100644 --- a/mypy/typeshed/stdlib/token.pyi +++ b/mypy/typeshed/stdlib/token.pyi @@ -71,6 +71,8 @@ if sys.version_info >= (3, 8): TYPE_IGNORE: int COLONEQUAL: int EXACT_TOKEN_TYPES: dict[str, int] +if sys.version_info >= (3, 10): + SOFT_KEYWORD: int def ISTERMINAL(x: int) -> bool: ... def ISNONTERMINAL(x: int) -> bool: ... diff --git a/mypy/typeshed/stdlib/tokenize.pyi b/mypy/typeshed/stdlib/tokenize.pyi index a8294adb653f..7614ebfe403e 100644 --- a/mypy/typeshed/stdlib/tokenize.pyi +++ b/mypy/typeshed/stdlib/tokenize.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import StrOrBytesPath from builtins import open as _builtin_open from token import * # noqa: F403 -from typing import Any, Callable, Generator, Iterable, NamedTuple, Pattern, Sequence, TextIO, Tuple, Union +from typing import Any, Callable, Generator, Iterable, NamedTuple, Pattern, Sequence, TextIO, Union if sys.version_info < (3, 7): COMMENT: int @@ -12,7 +12,7 @@ if sys.version_info < (3, 7): cookie_re: Pattern[str] blank_re: Pattern[bytes] -_Position = Tuple[int, int] +_Position = tuple[int, int] class _TokenInfo(NamedTuple): type: int diff --git a/mypy/typeshed/stdlib/trace.pyi b/mypy/typeshed/stdlib/trace.pyi index bab75c9ada8d..ee8dffa67820 100644 --- a/mypy/typeshed/stdlib/trace.pyi +++ b/mypy/typeshed/stdlib/trace.pyi @@ -1,13 +1,13 @@ import sys import types from _typeshed import StrPath -from typing import Any, Callable, Mapping, Optional, Sequence, Tuple, TypeVar +from typing import Any, Callable, Mapping, Optional, Sequence, TypeVar from typing_extensions import ParamSpec _T = TypeVar("_T") _P = ParamSpec("_P") _localtrace = Callable[[types.FrameType, str, Any], Callable[..., Any]] -_fileModuleFunction = Tuple[str, Optional[str], str] +_fileModuleFunction = tuple[str, Optional[str], str] class CoverageResults: def __init__( @@ -43,9 +43,9 @@ class Trace: self, cmd: str | types.CodeType, globals: Mapping[str, Any] | None = ..., locals: Mapping[str, Any] | None = ... ) -> None: ... if sys.version_info >= (3, 9): - def runfunc(self, __func: Callable[_P, _T], *args: _P.args, **kw: _P.kwargs) -> _T: ... # type: ignore + 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: ... # type: ignore + def runfunc(self, func: Callable[_P, _T], *args: _P.args, **kw: _P.kwargs) -> _T: ... def file_module_function_of(self, frame: types.FrameType) -> _fileModuleFunction: ... def globaltrace_trackcallers(self, frame: types.FrameType, why: str, arg: Any) -> None: ... def globaltrace_countfuncs(self, frame: types.FrameType, why: str, arg: Any) -> None: ... diff --git a/mypy/typeshed/stdlib/traceback.pyi b/mypy/typeshed/stdlib/traceback.pyi index e685b09a6ae4..4e36490c24e4 100644 --- a/mypy/typeshed/stdlib/traceback.pyi +++ b/mypy/typeshed/stdlib/traceback.pyi @@ -1,13 +1,14 @@ import sys from _typeshed import SupportsWrite from types import FrameType, TracebackType -from typing import IO, Any, Generator, Iterable, Iterator, List, Mapping, Optional, Tuple, Type +from typing import IO, Any, Generator, Iterable, Iterator, Mapping, Optional, Type, overload -_PT = Tuple[str, int, str, Optional[str]] +_PT = tuple[str, int, str, Optional[str]] def print_tb(tb: TracebackType | None, limit: int | None = ..., file: IO[str] | None = ...) -> None: ... if sys.version_info >= (3, 10): + @overload def print_exception( __exc: Type[BaseException] | None, value: BaseException | None = ..., @@ -16,6 +17,20 @@ if sys.version_info >= (3, 10): file: IO[str] | None = ..., chain: bool = ..., ) -> None: ... + @overload + def print_exception( + __exc: BaseException, *, limit: int | None = ..., file: IO[str] | None = ..., chain: bool = ... + ) -> None: ... + @overload + def format_exception( + __exc: Type[BaseException] | None, + value: BaseException | None = ..., + tb: TracebackType | None = ..., + limit: int | None = ..., + chain: bool = ..., + ) -> list[str]: ... + @overload + def format_exception(__exc: BaseException, *, limit: int | None = ..., chain: bool = ...) -> list[str]: ... else: def print_exception( @@ -26,6 +41,13 @@ else: file: IO[str] | None = ..., chain: bool = ..., ) -> None: ... + def format_exception( + etype: Type[BaseException] | None, + value: BaseException | None, + tb: TracebackType | None, + limit: int | None = ..., + chain: bool = ..., + ) -> list[str]: ... def print_exc(limit: int | None = ..., file: IO[str] | None = ..., chain: bool = ...) -> None: ... def print_last(limit: int | None = ..., file: IO[str] | None = ..., chain: bool = ...) -> None: ... @@ -43,24 +65,6 @@ if sys.version_info >= (3, 10): else: def format_exception_only(etype: Type[BaseException] | None, value: BaseException | None) -> list[str]: ... -if sys.version_info >= (3, 10): - def format_exception( - __exc: Type[BaseException] | None, - value: BaseException | None = ..., - tb: TracebackType | None = ..., - limit: int | None = ..., - chain: bool = ..., - ) -> list[str]: ... - -else: - def format_exception( - etype: Type[BaseException] | None, - value: BaseException | None, - tb: TracebackType | None, - limit: int | None = ..., - chain: bool = ..., - ) -> list[str]: ... - def format_exc(limit: int | None = ..., chain: bool = ...) -> str: ... def format_tb(tb: TracebackType | None, limit: int | None = ...) -> list[str]: ... def format_stack(f: FrameType | None = ..., limit: int | None = ...) -> list[str]: ... @@ -84,7 +88,7 @@ class TracebackException: self, exc_type: Type[BaseException], exc_value: BaseException, - exc_traceback: TracebackType, + exc_traceback: TracebackType | None, *, limit: int | None = ..., lookup_lines: bool = ..., @@ -107,7 +111,7 @@ class TracebackException: self, exc_type: Type[BaseException], exc_value: BaseException, - exc_traceback: TracebackType, + exc_traceback: TracebackType | None, *, limit: int | None = ..., lookup_lines: bool = ..., @@ -142,7 +146,7 @@ class FrameSummary(Iterable[Any]): def __getitem__(self, i: int) -> Any: ... def __iter__(self) -> Iterator[Any]: ... -class StackSummary(List[FrameSummary]): +class StackSummary(list[FrameSummary]): @classmethod def extract( cls, diff --git a/mypy/typeshed/stdlib/tracemalloc.pyi b/mypy/typeshed/stdlib/tracemalloc.pyi index ca4d5901b870..4d7bbb7994a6 100644 --- a/mypy/typeshed/stdlib/tracemalloc.pyi +++ b/mypy/typeshed/stdlib/tracemalloc.pyi @@ -1,6 +1,7 @@ import sys from _tracemalloc import * -from typing import Optional, Sequence, Tuple, Union, overload +from typing import Optional, Sequence, Union, overload +from typing_extensions import SupportsIndex def get_object_traceback(obj: object) -> Traceback | None: ... def take_snapshot() -> Snapshot: ... @@ -34,7 +35,7 @@ class StatisticDiff: traceback: Traceback def __init__(self, traceback: Traceback, size: int, size_diff: int, count: int, count_diff: int) -> None: ... -_FrameTupleT = Tuple[str, int] +_FrameTupleT = tuple[str, int] class Frame: filename: str @@ -42,9 +43,9 @@ class Frame: def __init__(self, frame: _FrameTupleT) -> None: ... if sys.version_info >= (3, 9): - _TraceTupleT = Union[Tuple[int, int, Sequence[_FrameTupleT], Optional[int]], Tuple[int, int, Sequence[_FrameTupleT]]] + _TraceTupleT = Union[tuple[int, int, Sequence[_FrameTupleT], Optional[int]], tuple[int, int, Sequence[_FrameTupleT]]] else: - _TraceTupleT = Tuple[int, int, Sequence[_FrameTupleT]] + _TraceTupleT = tuple[int, int, Sequence[_FrameTupleT]] class Trace: domain: int @@ -63,7 +64,7 @@ class Traceback(Sequence[Frame]): else: def format(self, limit: int | None = ...) -> list[str]: ... @overload - def __getitem__(self, i: int) -> Frame: ... + def __getitem__(self, i: SupportsIndex) -> Frame: ... @overload def __getitem__(self, s: slice) -> Sequence[Frame]: ... def __len__(self) -> int: ... diff --git a/mypy/typeshed/stdlib/tty.pyi b/mypy/typeshed/stdlib/tty.pyi index c0dc418e9933..015669a68084 100644 --- a/mypy/typeshed/stdlib/tty.pyi +++ b/mypy/typeshed/stdlib/tty.pyi @@ -1,15 +1,16 @@ +import sys from typing import IO, Union -_FD = Union[int, IO[str]] +if sys.platform != "win32": + _FD = Union[int, IO[str]] -# XXX: Undocumented integer constants -IFLAG: int -OFLAG: int -CFLAG: int -LFLAG: int -ISPEED: int -OSPEED: int -CC: int - -def setraw(fd: _FD, when: int = ...) -> None: ... -def setcbreak(fd: _FD, when: int = ...) -> None: ... + # XXX: Undocumented integer constants + IFLAG: int + OFLAG: int + CFLAG: int + LFLAG: int + ISPEED: int + OSPEED: int + CC: int + def setraw(fd: _FD, when: int = ...) -> None: ... + def setcbreak(fd: _FD, when: int = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/turtle.pyi b/mypy/typeshed/stdlib/turtle.pyi index 9371f2a7a547..e5efcb4f6ed9 100644 --- a/mypy/typeshed/stdlib/turtle.pyi +++ b/mypy/typeshed/stdlib/turtle.pyi @@ -1,24 +1,26 @@ -from tkinter import Canvas, PhotoImage -from typing import Any, Callable, Dict, Sequence, Tuple, TypeVar, Union, overload +from tkinter import Canvas, Frame, PhotoImage +from typing import Any, Callable, ClassVar, Sequence, TypeVar, Union, overload # Note: '_Color' is the alias we use for arguments and _AnyColor is the # alias we use for return types. Really, these two aliases should be the # same, but as per the "no union returns" typeshed policy, we'll return # Any instead. -_Color = Union[str, Tuple[float, float, float]] +_Color = Union[str, tuple[float, float, float]] _AnyColor = Any # TODO: Replace this with a TypedDict once it becomes standardized. -_PenState = Dict[str, Any] +_PenState = dict[str, Any] _Speed = Union[str, float] -_PolygonCoords = Sequence[Tuple[float, float]] +_PolygonCoords = Sequence[tuple[float, float]] # TODO: Type this more accurately # Vec2D is actually a custom subclass of 'tuple'. -Vec2D = Tuple[float, float] +Vec2D = tuple[float, float] -class TurtleScreenBase(object): +class ScrolledCanvas(Frame): ... + +class TurtleScreenBase: cv: Canvas canvwidth: int canvheight: int @@ -34,7 +36,7 @@ class TurtleScreenBase(object): class Terminator(Exception): ... class TurtleGraphicsError(Exception): ... -class Shape(object): +class Shape: def __init__(self, type_: str, data: _PolygonCoords | PhotoImage | None = ...) -> None: ... def addcomponent(self, poly: _PolygonCoords, fill: _Color, outline: _Color | None = ...) -> None: ... @@ -92,7 +94,7 @@ class TurtleScreen(TurtleScreenBase): def onkeypress(self, fun: Callable[[], Any], key: str | None = ...) -> None: ... onkeyrelease = onkey -class TNavigator(object): +class TNavigator: START_ORIENTATION: dict[str, Vec2D] DEFAULT_MODE: str DEFAULT_ANGLEOFFSET: int @@ -136,7 +138,7 @@ class TNavigator(object): setposition = goto seth = setheading -class TPen(object): +class TPen: def __init__(self, resizemode: str = ...) -> None: ... @overload def resizemode(self, rmode: None = ...) -> str: ... @@ -178,7 +180,7 @@ class TPen(object): def isvisible(self) -> bool: ... # Note: signatures 1 and 2 overlap unsafely when no arguments are provided @overload - def pen(self) -> _PenState: ... # type: ignore + def pen(self) -> _PenState: ... # type: ignore[misc] @overload def pen( self, @@ -206,6 +208,8 @@ class TPen(object): _T = TypeVar("_T") class RawTurtle(TPen, TNavigator): + screen: TurtleScreen + screens: ClassVar[list[TurtleScreen]] def __init__( self, canvas: Canvas | TurtleScreen | None = ..., shape: str = ..., undobuffersize: int = ..., visible: bool = ... ) -> None: ... @@ -220,7 +224,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 + def shapesize(self) -> tuple[float, float, float]: ... # type: ignore[misc] @overload def shapesize( self, stretch_wid: float | None = ..., stretch_len: float | None = ..., outline: float | None = ... @@ -231,7 +235,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 + def shapetransform(self) -> tuple[float, float, float, float]: ... # type: ignore[misc] @overload def shapetransform( self, t11: float | None = ..., t12: float | None = ..., t21: float | None = ..., t22: float | None = ... @@ -247,7 +251,7 @@ class RawTurtle(TPen, TNavigator): # a compound stamp or not. So, as per the "no Union return" policy, # we return Any. def stamp(self) -> Any: ... - def clearstamp(self, stampid: int | Tuple[int, ...]) -> None: ... + def clearstamp(self, stampid: int | tuple[int, ...]) -> None: ... def clearstamps(self, n: int | None = ...) -> None: ... def filling(self) -> bool: ... def begin_fill(self) -> None: ... @@ -449,7 +453,7 @@ def isvisible() -> bool: ... # Note: signatures 1 and 2 overlap unsafely when no arguments are provided @overload -def pen() -> _PenState: ... # type: ignore +def pen() -> _PenState: ... # type: ignore[misc] @overload def pen( pen: _PenState | None = ..., @@ -485,7 +489,7 @@ def shape(name: str) -> None: ... # Unsafely overlaps when no arguments are provided @overload -def shapesize() -> tuple[float, float, float]: ... # type: ignore +def shapesize() -> tuple[float, float, float]: ... # type: ignore[misc] @overload def shapesize(stretch_wid: float | None = ..., stretch_len: float | None = ..., outline: float | None = ...) -> None: ... @overload @@ -495,7 +499,7 @@ def shearfactor(shear: float) -> None: ... # Unsafely overlaps when no arguments are provided @overload -def shapetransform() -> tuple[float, float, float, float]: ... # type: ignore +def shapetransform() -> tuple[float, float, float, float]: ... # type: ignore[misc] @overload def shapetransform( t11: float | None = ..., t12: float | None = ..., t21: float | None = ..., t22: float | None = ... @@ -512,7 +516,7 @@ def tilt(angle: float) -> None: ... # a compound stamp or not. So, as per the "no Union return" policy, # we return Any. def stamp() -> Any: ... -def clearstamp(stampid: int | Tuple[int, ...]) -> None: ... +def clearstamp(stampid: int | tuple[int, ...]) -> None: ... def clearstamps(n: int | None = ...) -> None: ... def filling() -> bool: ... def begin_fill() -> None: ... diff --git a/mypy/typeshed/stdlib/types.pyi b/mypy/typeshed/stdlib/types.pyi index 899024f2dd4d..caf745b99554 100644 --- a/mypy/typeshed/stdlib/types.pyi +++ b/mypy/typeshed/stdlib/types.pyi @@ -1,4 +1,5 @@ import sys +from _typeshed import SupportsKeysAndGetItem from importlib.abc import _LoaderProtocol from importlib.machinery import ModuleSpec from typing import ( @@ -15,7 +16,6 @@ from typing import ( KeysView, Mapping, MutableSequence, - Tuple, Type, TypeVar, ValuesView, @@ -36,14 +36,15 @@ _V_co = TypeVar("_V_co", covariant=True) @final class _Cell: - __hash__: None # type: ignore + __hash__: None # type: ignore[assignment] cell_contents: Any +# Make sure this class definition stays roughly in line with `builtins.function` @final class FunctionType: - __closure__: Tuple[_Cell, ...] | None + __closure__: tuple[_Cell, ...] | None __code__: CodeType - __defaults__: Tuple[Any, ...] | None + __defaults__: tuple[Any, ...] | None __dict__: dict[str, Any] __globals__: dict[str, Any] __name__: str @@ -55,11 +56,11 @@ class FunctionType: code: CodeType, globals: dict[str, Any], name: str | None = ..., - argdefs: Tuple[object, ...] | None = ..., - closure: Tuple[_Cell, ...] | None = ..., + argdefs: tuple[object, ...] | None = ..., + closure: tuple[_Cell, ...] | None = ..., ) -> None: ... def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def __get__(self, obj: object | None, type: type | None) -> MethodType: ... + def __get__(self, obj: object | None, type: type | None = ...) -> MethodType: ... LambdaType = FunctionType @@ -75,15 +76,15 @@ class CodeType: co_stacksize: int co_flags: int co_code: bytes - co_consts: Tuple[Any, ...] - co_names: Tuple[str, ...] - co_varnames: Tuple[str, ...] + co_consts: tuple[Any, ...] + co_names: tuple[str, ...] + co_varnames: tuple[str, ...] co_filename: str co_name: str co_firstlineno: int co_lnotab: bytes - co_freevars: Tuple[str, ...] - co_cellvars: Tuple[str, ...] + co_freevars: tuple[str, ...] + co_cellvars: tuple[str, ...] if sys.version_info >= (3, 8): def __init__( self, @@ -94,15 +95,15 @@ class CodeType: stacksize: int, flags: int, codestring: bytes, - constants: Tuple[Any, ...], - names: Tuple[str, ...], - varnames: Tuple[str, ...], + constants: tuple[Any, ...], + names: tuple[str, ...], + varnames: tuple[str, ...], filename: str, name: str, firstlineno: int, lnotab: bytes, - freevars: Tuple[str, ...] = ..., - cellvars: Tuple[str, ...] = ..., + freevars: tuple[str, ...] = ..., + cellvars: tuple[str, ...] = ..., ) -> None: ... else: def __init__( @@ -113,17 +114,40 @@ class CodeType: stacksize: int, flags: int, codestring: bytes, - constants: Tuple[Any, ...], - names: Tuple[str, ...], - varnames: Tuple[str, ...], + constants: tuple[Any, ...], + names: tuple[str, ...], + varnames: tuple[str, ...], filename: str, name: str, firstlineno: int, lnotab: bytes, - freevars: Tuple[str, ...] = ..., - cellvars: Tuple[str, ...] = ..., + freevars: tuple[str, ...] = ..., + cellvars: tuple[str, ...] = ..., ) -> None: ... - if sys.version_info >= (3, 8): + if sys.version_info >= (3, 10): + def replace( + self, + *, + co_argcount: int = ..., + co_posonlyargcount: int = ..., + co_kwonlyargcount: int = ..., + co_nlocals: int = ..., + co_stacksize: int = ..., + co_flags: int = ..., + co_firstlineno: int = ..., + co_code: bytes = ..., + co_consts: tuple[Any, ...] = ..., + co_names: tuple[str, ...] = ..., + co_varnames: tuple[str, ...] = ..., + co_freevars: tuple[str, ...] = ..., + co_cellvars: tuple[str, ...] = ..., + co_filename: str = ..., + co_name: str = ..., + co_linetable: object = ..., + ) -> CodeType: ... + def co_lines(self) -> Iterator[tuple[int, int, int | None]]: ... + co_linetable: object + elif sys.version_info >= (3, 8): def replace( self, *, @@ -135,11 +159,11 @@ class CodeType: co_flags: int = ..., co_firstlineno: int = ..., co_code: bytes = ..., - co_consts: Tuple[Any, ...] = ..., - co_names: Tuple[str, ...] = ..., - co_varnames: Tuple[str, ...] = ..., - co_freevars: Tuple[str, ...] = ..., - co_cellvars: Tuple[str, ...] = ..., + co_consts: tuple[Any, ...] = ..., + co_names: tuple[str, ...] = ..., + co_varnames: tuple[str, ...] = ..., + co_freevars: tuple[str, ...] = ..., + co_cellvars: tuple[str, ...] = ..., co_filename: str = ..., co_name: str = ..., co_lnotab: bytes = ..., @@ -149,8 +173,8 @@ class CodeType: @final class MappingProxyType(Mapping[_KT, _VT_co], Generic[_KT, _VT_co]): - __hash__: None # type: ignore - def __init__(self, mapping: Mapping[_KT, _VT_co]) -> None: ... + __hash__: None # type: ignore[assignment] + def __init__(self, mapping: SupportsKeysAndGetItem[_KT, _VT_co]) -> None: ... def __getitem__(self, k: _KT) -> _VT_co: ... def __iter__(self) -> Iterator[_KT]: ... def __len__(self) -> int: ... @@ -165,7 +189,7 @@ class MappingProxyType(Mapping[_KT, _VT_co], Generic[_KT, _VT_co]): def __ror__(self, __value: Mapping[_T1, _T2]) -> dict[_KT | _T1, _VT_co | _T2]: ... class SimpleNamespace: - __hash__: None # type: ignore + __hash__: None # type: ignore[assignment] def __init__(self, **kwargs: Any) -> None: ... def __getattribute__(self, name: str) -> Any: ... def __setattr__(self, name: str, value: Any) -> None: ... @@ -218,6 +242,8 @@ class AsyncGeneratorType(AsyncGenerator[_T_co, _T_contra]): @overload def athrow(self, __typ: BaseException, __val: None = ..., __tb: TracebackType | None = ...) -> Awaitable[_T_co]: ... def aclose(self) -> Awaitable[None]: ... + if sys.version_info >= (3, 9): + def __class_getitem__(cls, __item: Any) -> GenericAlias: ... @final class CoroutineType(Coroutine[_T_co, _T_contra, _V_co]): @@ -255,8 +281,8 @@ class _StaticFunctionType: @final class MethodType: - __closure__: Tuple[_Cell, ...] | None # inherited from the added function - __defaults__: Tuple[Any, ...] | None # inherited from the added function + __closure__: tuple[_Cell, ...] | None # inherited from the added function + __defaults__: tuple[Any, ...] | None # inherited from the added function __func__: _StaticFunctionType __self__: object __name__: str # inherited from the added function @@ -328,7 +354,10 @@ class FrameType: f_code: CodeType f_globals: dict[str, Any] f_lasti: int - f_lineno: int + # see discussion in #6769: f_lineno *can* sometimes be None, + # but you should probably file a bug report with CPython if you encounter it being None in the wild. + # An `int | None` annotation here causes too many false-positive errors. + f_lineno: int | Any f_locals: dict[str, Any] f_trace: Callable[[FrameType, str, Any], Any] | None if sys.version_info >= (3, 7): @@ -359,18 +388,18 @@ if sys.version_info >= (3, 7): kwds: dict[str, Any] | None = ..., exec_body: Callable[[dict[str, Any]], None] | None = ..., ) -> type: ... - def resolve_bases(bases: Iterable[object]) -> Tuple[Any, ...]: ... + def resolve_bases(bases: Iterable[object]) -> tuple[Any, ...]: ... else: def new_class( name: str, - bases: Tuple[type, ...] = ..., + bases: tuple[type, ...] = ..., kwds: dict[str, Any] | None = ..., exec_body: Callable[[dict[str, Any]], None] | None = ..., ) -> type: ... def prepare_class( - name: str, bases: Tuple[type, ...] = ..., kwds: dict[str, Any] | None = ... + name: str, bases: tuple[type, ...] = ..., kwds: dict[str, Any] | None = ... ) -> tuple[type, dict[str, Any], dict[str, Any]]: ... # Actually a different type, but `property` is special and we want that too. @@ -381,10 +410,11 @@ _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[_R, Any, Any]]) -> Callable[_P, Awaitable[_R]]: ... # type: ignore +def coroutine(func: Callable[_P, Generator[_R, Any, Any]]) -> Callable[_P, Awaitable[_R]]: ... # type: ignore[misc] @overload -def coroutine(func: _Fn) -> _Fn: ... # type: ignore +def coroutine(func: _Fn) -> _Fn: ... if sys.version_info >= (3, 8): CellType = _Cell @@ -392,8 +422,8 @@ if sys.version_info >= (3, 8): if sys.version_info >= (3, 9): class GenericAlias: __origin__: type - __args__: Tuple[Any, ...] - __parameters__: Tuple[Any, ...] + __args__: tuple[Any, ...] + __parameters__: tuple[Any, ...] def __init__(self, origin: type, args: Any) -> None: ... def __getattr__(self, name: str) -> Any: ... # incomplete @@ -407,6 +437,6 @@ if sys.version_info >= (3, 10): NotImplementedType = _NotImplementedType # noqa F811 from builtins @final class UnionType: - __args__: Tuple[Any, ...] + __args__: tuple[Any, ...] def __or__(self, obj: Any) -> UnionType: ... def __ror__(self, obj: Any) -> UnionType: ... diff --git a/mypy/typeshed/stdlib/typing.pyi b/mypy/typeshed/stdlib/typing.pyi index 4656add7ec21..6e461b8aa260 100644 --- a/mypy/typeshed/stdlib/typing.pyi +++ b/mypy/typeshed/stdlib/typing.pyi @@ -1,5 +1,6 @@ import collections # Needed by aliases like DefaultDict, see mypy issue 2986 import sys +from _typeshed import SupportsKeysAndGetItem from abc import ABCMeta, abstractmethod from types import BuiltinFunctionType, CodeType, FrameType, FunctionType, MethodType, ModuleType, TracebackType from typing_extensions import Literal as _Literal, ParamSpec as _ParamSpec, final as _final @@ -10,9 +11,6 @@ if sys.version_info >= (3, 7): if sys.version_info >= (3, 9): from types import GenericAlias -# Definitions of special type checking related constructs. Their definitions -# are not used, so their value does not matter. - Any = object() class TypeVar: @@ -29,11 +27,18 @@ class TypeVar: covariant: bool = ..., contravariant: bool = ..., ) -> None: ... + if sys.version_info >= (3, 10): + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... +# Used for an undocumented mypy feature. Does not exist at runtime. _promote = object() class _SpecialForm: def __getitem__(self, typeargs: Any) -> object: ... + if sys.version_info >= (3, 10): + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... _F = TypeVar("_F", bound=Callable[..., Any]) _P = _ParamSpec("_P") @@ -80,9 +85,20 @@ if sys.version_info >= (3, 10): def args(self) -> ParamSpecArgs: ... @property def kwargs(self) -> ParamSpecKwargs: ... + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... Concatenate: _SpecialForm = ... TypeAlias: _SpecialForm = ... TypeGuard: _SpecialForm = ... + class NewType: + def __init__(self, name: str, tp: type) -> None: ... + def __call__(self, x: _T) -> _T: ... + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... + __supertype__: type + +else: + def NewType(name: str, tp: Type[_T]) -> Type[_T]: ... # These type variables are used by the container types. _S = TypeVar("_S") @@ -96,7 +112,7 @@ _T_contra = TypeVar("_T_contra", contravariant=True) # Ditto contravariant. _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]: ... # type: ignore +def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... # type: ignore[misc] # Type aliases and type constructors @@ -122,6 +138,14 @@ if sys.version_info >= (3, 9): # Predefined type variables. AnyStr = TypeVar("AnyStr", str, bytes) +if sys.version_info >= (3, 8): + # This class did actually exist in 3.7, but had a different base. + # We'll just pretend it didn't exist though: the main external use case for _ProtocolMeta is + # to inherit from for your own custom protocol metaclasses. If you're using 3.7, at runtime + # you'd use typing_extensions.Protocol, which would be unrelated to typing._ProtocolMeta and + # so you'd run into metaclass conflicts at runtime if you used typing._ProtocolMeta. + class _ProtocolMeta(ABCMeta): ... + # Abstract base classes. def runtime_checkable(cls: _TC) -> _TC: ... @@ -246,7 +270,7 @@ class Coroutine(Awaitable[_V_co], Generic[_T_co, _T_contra, _V_co]): @abstractmethod def close(self) -> None: ... -# NOTE: This type does not exist in typing.py or PEP 484. +# NOTE: This type does not exist in typing.py or PEP 484 but mypy needs it to exist. # The parameters correspond to Generator, but the 4th is the original type. class AwaitableGenerator( Awaitable[_V_co], Generator[_T_co, _T_contra, _V_co], Generic[_T_co, _T_contra, _V_co, _S], metaclass=ABCMeta @@ -465,7 +489,7 @@ class MutableMapping(Mapping[_KT, _VT], Generic[_KT, _VT]): # known to be a Mapping with unknown type parameters, which is closer # to the behavior we want. See mypy issue #1430. @overload - def update(self, __m: Mapping[_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: ... @overload @@ -550,7 +574,7 @@ class Match(Generic[AnyStr]): pos: int endpos: int lastindex: int | None - lastgroup: AnyStr | None + lastgroup: str | None string: AnyStr # The regular expression object whose match() or search() method produced @@ -598,7 +622,7 @@ class Pattern(Generic[AnyStr]): def search(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Match[AnyStr] | None: ... def match(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Match[AnyStr] | None: ... def fullmatch(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Match[AnyStr] | None: ... - def split(self, string: AnyStr, maxsplit: int = ...) -> list[AnyStr]: ... + def split(self, string: AnyStr, maxsplit: int = ...) -> list[AnyStr | Any]: ... def findall(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> list[Any]: ... def finditer(self, string: AnyStr, pos: int = ..., endpos: int = ...) -> Iterator[Match[AnyStr]]: ... @overload @@ -657,9 +681,11 @@ def cast(typ: object, val: Any) -> Any: ... # Type constructors -# NamedTuple is special-cased in the type checker class NamedTuple(Tuple[Any, ...]): - _field_types: collections.OrderedDict[str, Type[Any]] + if sys.version_info < (3, 8): + _field_types: collections.OrderedDict[str, type] + elif sys.version_info < (3, 9): + _field_types: dict[str, type] _field_defaults: dict[str, Any] _fields: Tuple[str, ...] _source: str @@ -691,8 +717,6 @@ class _TypedDict(Mapping[str, object], metaclass=ABCMeta): def __or__(self: _T, __value: _T) -> _T: ... def __ior__(self: _T, __value: _T) -> _T: ... -def NewType(name: str, tp: Type[_T]) -> Type[_T]: ... - # This itself is only available during type checking def type_check_only(func_or_cls: _F) -> _F: ... @@ -704,14 +728,17 @@ if sys.version_info >= (3, 7): __forward_value__: Any | None __forward_is_argument__: bool if sys.version_info >= (3, 9): - # The module argument was added in Python 3.9.7. - def __init__(self, arg: str, is_argument: bool = ..., module: Any | None = ...) -> None: ... + # The module and is_class arguments were added in later Python 3.9 versions. + def __init__(self, arg: str, is_argument: bool = ..., module: Any | None = ..., *, is_class: bool = ...) -> None: ... else: def __init__(self, arg: str, is_argument: bool = ...) -> None: ... def _evaluate(self, globalns: dict[str, Any] | None, localns: dict[str, Any] | None) -> Any | None: ... def __eq__(self, other: Any) -> bool: ... def __hash__(self) -> int: ... def __repr__(self) -> str: ... + if sys.version_info >= (3, 11): + def __or__(self, other: Any) -> _SpecialForm: ... + def __ror__(self, other: Any) -> _SpecialForm: ... if sys.version_info >= (3, 10): - def is_typeddict(tp: Any) -> bool: ... + def is_typeddict(tp: object) -> bool: ... diff --git a/mypy/typeshed/stdlib/typing_extensions.pyi b/mypy/typeshed/stdlib/typing_extensions.pyi index ce407f996022..e7f288377b83 100644 --- a/mypy/typeshed/stdlib/typing_extensions.pyi +++ b/mypy/typeshed/stdlib/typing_extensions.pyi @@ -22,7 +22,6 @@ from typing import ( NewType as NewType, NoReturn as NoReturn, Text as Text, - Tuple, Type as Type, TypeVar, ValuesView, @@ -53,6 +52,11 @@ Literal: _SpecialForm = ... def IntVar(name: str) -> Any: ... # returns a new TypeVar +if sys.version_info < (3, 8): + # Technically in 3.6 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(abc.ABCMeta): ... + # Internal mypy fallback type for all typed dicts (does not exist at runtime) class _TypedDict(Mapping[str, object], metaclass=abc.ABCMeta): __required_keys__: frozenset[str] @@ -82,7 +86,7 @@ if sys.version_info >= (3, 7): localns: dict[str, Any] | None = ..., include_extras: bool = ..., ) -> dict[str, Any]: ... - def get_args(tp: Any) -> Tuple[Any, ...]: ... + def get_args(tp: Any) -> tuple[Any, ...]: ... def get_origin(tp: Any) -> Any | None: ... Annotated: _SpecialForm = ... diff --git a/mypy/typeshed/stdlib/unicodedata.pyi b/mypy/typeshed/stdlib/unicodedata.pyi index 66c93f7439f7..ead25ba4062c 100644 --- a/mypy/typeshed/stdlib/unicodedata.pyi +++ b/mypy/typeshed/stdlib/unicodedata.pyi @@ -24,7 +24,7 @@ def name(__chr: str, __default: _T = ...) -> str | _T: ... def normalize(__form: str, __unistr: str) -> str: ... def numeric(__chr: str, __default: _T = ...) -> float | _T: ... -class UCD(object): +class UCD: # The methods below are constructed from the same array in C # (unicodedata_functions) and hence identical to the methods above. unidata_version: str diff --git a/mypy/typeshed/stdlib/unittest/__init__.pyi b/mypy/typeshed/stdlib/unittest/__init__.pyi index 8f0ef896fa0c..d3b0efaa83ff 100644 --- a/mypy/typeshed/stdlib/unittest/__init__.pyi +++ b/mypy/typeshed/stdlib/unittest/__init__.pyi @@ -10,15 +10,25 @@ from .case import ( skipIf as skipIf, skipUnless as skipUnless, ) +from .loader import ( + TestLoader as TestLoader, + defaultTestLoader as defaultTestLoader, + findTestCases as findTestCases, + getTestCaseNames as getTestCaseNames, + makeSuite as makeSuite, +) +from .main import TestProgram as TestProgram, main as main +from .result import TestResult as TestResult +from .runner import TextTestResult as TextTestResult, TextTestRunner as TextTestRunner +from .signals import ( + installHandler as installHandler, + registerResult as registerResult, + removeHandler as removeHandler, + removeResult as removeResult, +) +from .suite import BaseTestSuite as BaseTestSuite, TestSuite as TestSuite if sys.version_info >= (3, 8): from .case import addModuleCleanup as addModuleCleanup -from unittest.loader import * -from unittest.main import * -from unittest.result import TestResult as TestResult -from unittest.runner import * -from unittest.signals import * -from unittest.suite import * - def load_tests(loader: TestLoader, tests: TestSuite, pattern: str | None) -> TestSuite: ... diff --git a/mypy/typeshed/stdlib/unittest/_log.pyi b/mypy/typeshed/stdlib/unittest/_log.pyi new file mode 100644 index 000000000000..f9e406199cd4 --- /dev/null +++ b/mypy/typeshed/stdlib/unittest/_log.pyi @@ -0,0 +1,27 @@ +import logging +import sys +from types import TracebackType +from typing import ClassVar, Generic, NamedTuple, Type, TypeVar +from unittest.case import TestCase + +_L = TypeVar("_L", None, _LoggingWatcher) + +class _LoggingWatcher(NamedTuple): + records: list[logging.LogRecord] + output: list[str] + +class _AssertLogsContext(Generic[_L]): + LOGGING_FORMAT: ClassVar[str] + test_case: TestCase + logger_name: str + level: int + msg: None + if sys.version_info >= (3, 10): + def __init__(self, test_case: TestCase, logger_name: str, level: int, no_logs: bool) -> None: ... + no_logs: bool + else: + def __init__(self, test_case: TestCase, logger_name: str, level: int) -> None: ... + def __enter__(self) -> _L: ... + def __exit__( + self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> bool | None: ... diff --git a/mypy/typeshed/stdlib/unittest/case.pyi b/mypy/typeshed/stdlib/unittest/case.pyi index 2ae07144373c..858bf38e700d 100644 --- a/mypy/typeshed/stdlib/unittest/case.pyi +++ b/mypy/typeshed/stdlib/unittest/case.pyi @@ -3,13 +3,14 @@ import logging import sys import unittest.result from _typeshed import Self -from collections.abc import Set # equivalent to typing.AbstractSet, not builtins.set +from collections.abc import Set as AbstractSet from contextlib import AbstractContextManager from types import TracebackType from typing import ( Any, AnyStr, Callable, + ClassVar, Container, Generic, Iterable, @@ -18,7 +19,6 @@ from typing import ( NoReturn, Pattern, Sequence, - Tuple, Type, TypeVar, overload, @@ -31,6 +31,33 @@ if sys.version_info >= (3, 9): _E = TypeVar("_E", bound=BaseException) _FT = TypeVar("_FT", bound=Callable[..., Any]) +DIFF_OMITTED: str + +class _BaseTestCaseContext: + def __init__(self, test_case: TestCase) -> None: ... + +if sys.version_info >= (3, 9): + from unittest._log import _AssertLogsContext, _LoggingWatcher +else: + # Unused dummy for _AssertLogsContext. Starting with Python 3.10, + # this is generic over the logging watcher, but in lower versions + # the watcher is hard-coded. + _L = TypeVar("_L") + class _LoggingWatcher(NamedTuple): + records: list[logging.LogRecord] + output: list[str] + class _AssertLogsContext(_BaseTestCaseContext, Generic[_L]): + LOGGING_FORMAT: ClassVar[str] + test_case: TestCase + logger_name: str + level: int + msg: None + def __init__(self, test_case: TestCase, logger_name: str, level: int) -> None: ... + def __enter__(self) -> _LoggingWatcher: ... + def __exit__( + self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> bool | None: ... + if sys.version_info >= (3, 8): def addModuleCleanup(__function: Callable[..., Any], *args: Any, **kwargs: Any) -> None: ... def doModuleCleanups() -> None: ... @@ -74,26 +101,26 @@ class TestCase: def assertIsNotNone(self, obj: Any, msg: Any = ...) -> None: ... def assertIn(self, member: Any, container: Iterable[Any] | Container[Any], msg: Any = ...) -> None: ... def assertNotIn(self, member: Any, container: Iterable[Any] | Container[Any], msg: Any = ...) -> None: ... - def assertIsInstance(self, obj: Any, cls: type | Tuple[type, ...], msg: Any = ...) -> None: ... - def assertNotIsInstance(self, obj: Any, cls: type | Tuple[type, ...], msg: Any = ...) -> None: ... + def assertIsInstance(self, obj: Any, cls: type | tuple[type, ...], msg: Any = ...) -> None: ... + def assertNotIsInstance(self, obj: Any, cls: type | tuple[type, ...], msg: Any = ...) -> None: ... def assertGreater(self, a: Any, b: Any, msg: Any = ...) -> None: ... def assertGreaterEqual(self, a: Any, b: Any, msg: Any = ...) -> None: ... def assertLess(self, a: Any, b: Any, msg: Any = ...) -> None: ... def assertLessEqual(self, a: Any, b: Any, msg: Any = ...) -> None: ... @overload - def assertRaises( # type: ignore + def assertRaises( # type: ignore[misc] self, - expected_exception: Type[BaseException] | Tuple[Type[BaseException], ...], + expected_exception: Type[BaseException] | tuple[Type[BaseException], ...], callable: Callable[..., Any], *args: Any, **kwargs: Any, ) -> None: ... @overload - def assertRaises(self, expected_exception: Type[_E] | Tuple[Type[_E], ...], msg: Any = ...) -> _AssertRaisesContext[_E]: ... + def assertRaises(self, expected_exception: Type[_E] | tuple[Type[_E], ...], msg: Any = ...) -> _AssertRaisesContext[_E]: ... @overload - def assertRaisesRegex( # type: ignore + def assertRaisesRegex( # type: ignore[misc] self, - expected_exception: Type[BaseException] | Tuple[Type[BaseException], ...], + expected_exception: Type[BaseException] | tuple[Type[BaseException], ...], expected_regex: str | bytes | Pattern[str] | Pattern[bytes], callable: Callable[..., Any], *args: Any, @@ -102,20 +129,20 @@ class TestCase: @overload def assertRaisesRegex( self, - expected_exception: Type[_E] | Tuple[Type[_E], ...], + expected_exception: Type[_E] | tuple[Type[_E], ...], expected_regex: str | bytes | Pattern[str] | Pattern[bytes], msg: Any = ..., ) -> _AssertRaisesContext[_E]: ... @overload - def assertWarns( # type: ignore - self, expected_warning: Type[Warning] | Tuple[Type[Warning], ...], callable: Callable[..., Any], *args: Any, **kwargs: Any + def assertWarns( # type: ignore[misc] + self, expected_warning: Type[Warning] | tuple[Type[Warning], ...], callable: Callable[..., Any], *args: Any, **kwargs: Any ) -> None: ... @overload - def assertWarns(self, expected_warning: Type[Warning] | Tuple[Type[Warning], ...], msg: Any = ...) -> _AssertWarnsContext: ... + def assertWarns(self, expected_warning: Type[Warning] | tuple[Type[Warning], ...], msg: Any = ...) -> _AssertWarnsContext: ... @overload - def assertWarnsRegex( # type: ignore + def assertWarnsRegex( # type: ignore[misc] self, - expected_warning: Type[Warning] | Tuple[Type[Warning], ...], + expected_warning: Type[Warning] | tuple[Type[Warning], ...], expected_regex: str | bytes | Pattern[str] | Pattern[bytes], callable: Callable[..., Any], *args: Any, @@ -124,11 +151,17 @@ class TestCase: @overload def assertWarnsRegex( self, - expected_warning: Type[Warning] | Tuple[Type[Warning], ...], + expected_warning: Type[Warning] | tuple[Type[Warning], ...], expected_regex: str | bytes | Pattern[str] | Pattern[bytes], msg: Any = ..., ) -> _AssertWarnsContext: ... - def assertLogs(self, logger: str | logging.Logger | None = ..., level: int | str | None = ...) -> _AssertLogsContext: ... + def assertLogs( + self, logger: str | logging.Logger | None = ..., level: int | str | None = ... + ) -> _AssertLogsContext[_LoggingWatcher]: ... + if sys.version_info >= (3, 10): + def assertNoLogs( + self, logger: str | logging.Logger | None = ..., level: int | str | None = ... + ) -> _AssertLogsContext[None]: ... @overload def assertAlmostEqual( self, first: float, second: float, places: int | None = ..., msg: Any = ..., delta: float | None = ... @@ -166,8 +199,8 @@ class TestCase: self, seq1: Sequence[Any], seq2: Sequence[Any], msg: Any = ..., seq_type: Type[Sequence[Any]] | None = ... ) -> None: ... def assertListEqual(self, list1: list[Any], list2: list[Any], msg: Any = ...) -> None: ... - def assertTupleEqual(self, tuple1: Tuple[Any, ...], tuple2: Tuple[Any, ...], msg: Any = ...) -> None: ... - def assertSetEqual(self, set1: Set[object], set2: Set[object], msg: Any = ...) -> None: ... + def assertTupleEqual(self, tuple1: tuple[Any, ...], tuple2: tuple[Any, ...], msg: Any = ...) -> None: ... + def assertSetEqual(self, set1: AbstractSet[object], set2: AbstractSet[object], msg: Any = ...) -> None: ... def assertDictEqual(self, d1: Mapping[Any, object], d2: Mapping[Any, object], msg: Any = ...) -> None: ... def fail(self, msg: Any = ...) -> NoReturn: ... def countTestCases(self) -> int: ... @@ -186,49 +219,53 @@ class TestCase: def doClassCleanups(cls) -> None: ... def _formatMessage(self, msg: str | None, standardMsg: str) -> str: ... # undocumented def _getAssertEqualityFunc(self, first: Any, second: Any) -> Callable[..., None]: ... # undocumented - # below is deprecated - def failUnlessEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ... - def assertEquals(self, first: Any, second: Any, msg: Any = ...) -> None: ... - def failIfEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ... - def assertNotEquals(self, first: Any, second: Any, msg: Any = ...) -> None: ... - def failUnless(self, expr: bool, msg: Any = ...) -> None: ... - def assert_(self, expr: bool, msg: Any = ...) -> None: ... - def failIf(self, expr: bool, msg: Any = ...) -> None: ... - @overload - def failUnlessRaises( # type: ignore - self, - exception: Type[BaseException] | Tuple[Type[BaseException], ...], - callable: Callable[..., Any] = ..., - *args: Any, - **kwargs: Any, - ) -> None: ... - @overload - def failUnlessRaises(self, exception: Type[_E] | Tuple[Type[_E], ...], msg: Any = ...) -> _AssertRaisesContext[_E]: ... - def failUnlessAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... - def assertAlmostEquals(self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ...) -> None: ... - def failIfAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... - def assertNotAlmostEquals( - self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ... - ) -> None: ... - def assertRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... - def assertNotRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... - @overload - def assertRaisesRegexp( # type: ignore - self, - exception: Type[BaseException] | Tuple[Type[BaseException], ...], - expected_regex: str | bytes | Pattern[str] | Pattern[bytes], - callable: Callable[..., Any], - *args: Any, - **kwargs: Any, - ) -> None: ... - @overload - def assertRaisesRegexp( - self, - exception: Type[_E] | Tuple[Type[_E], ...], - expected_regex: str | bytes | Pattern[str] | Pattern[bytes], - msg: Any = ..., - ) -> _AssertRaisesContext[_E]: ... - def assertDictContainsSubset(self, subset: Mapping[Any, Any], dictionary: Mapping[Any, Any], msg: object = ...) -> None: ... + if sys.version_info < (3, 11): + def failUnlessEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ... + def assertEquals(self, first: Any, second: Any, msg: Any = ...) -> None: ... + def failIfEqual(self, first: Any, second: Any, msg: Any = ...) -> None: ... + def assertNotEquals(self, first: Any, second: Any, msg: Any = ...) -> None: ... + def failUnless(self, expr: bool, msg: Any = ...) -> None: ... + def assert_(self, expr: bool, msg: Any = ...) -> None: ... + def failIf(self, expr: bool, msg: Any = ...) -> None: ... + @overload + def failUnlessRaises( # type: ignore[misc] + self, + exception: Type[BaseException] | tuple[Type[BaseException], ...], + callable: Callable[..., Any] = ..., + *args: Any, + **kwargs: Any, + ) -> None: ... + @overload + def failUnlessRaises(self, exception: Type[_E] | tuple[Type[_E], ...], msg: Any = ...) -> _AssertRaisesContext[_E]: ... + def failUnlessAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... + def assertAlmostEquals( + self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ... + ) -> None: ... + def failIfAlmostEqual(self, first: float, second: float, places: int = ..., msg: Any = ...) -> None: ... + def assertNotAlmostEquals( + self, first: float, second: float, places: int = ..., msg: Any = ..., delta: float = ... + ) -> None: ... + def assertRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... + def assertNotRegexpMatches(self, text: AnyStr, regex: AnyStr | Pattern[AnyStr], msg: Any = ...) -> None: ... + @overload + def assertRaisesRegexp( # type: ignore[misc] + self, + exception: Type[BaseException] | tuple[Type[BaseException], ...], + expected_regex: str | bytes | Pattern[str] | Pattern[bytes], + callable: Callable[..., Any], + *args: Any, + **kwargs: Any, + ) -> None: ... + @overload + def assertRaisesRegexp( + self, + exception: Type[_E] | tuple[Type[_E], ...], + expected_regex: str | bytes | Pattern[str] | Pattern[bytes], + msg: Any = ..., + ) -> _AssertRaisesContext[_E]: ... + def assertDictContainsSubset( + self, subset: Mapping[Any, Any], dictionary: Mapping[Any, Any], msg: object = ... + ) -> None: ... class FunctionTestCase(TestCase): def __init__( @@ -240,10 +277,6 @@ class FunctionTestCase(TestCase): ) -> None: ... def runTest(self) -> None: ... -class _LoggingWatcher(NamedTuple): - records: list[logging.LogRecord] - output: list[str] - class _AssertRaisesContext(Generic[_E]): exception: _E def __enter__(self: Self) -> Self: ... @@ -262,16 +295,3 @@ class _AssertWarnsContext: def __exit__( self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> None: ... - -class _AssertLogsContext: - LOGGING_FORMAT: str - records: list[logging.LogRecord] - output: list[str] - def __init__(self, test_case: TestCase, logger_name: str, level: int) -> None: ... - if sys.version_info >= (3, 10): - def __enter__(self) -> _LoggingWatcher | None: ... - else: - def __enter__(self) -> _LoggingWatcher: ... - def __exit__( - self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> bool | None: ... diff --git a/mypy/typeshed/stdlib/unittest/loader.pyi b/mypy/typeshed/stdlib/unittest/loader.pyi index d3cb4cef733b..aca7e4f9554f 100644 --- a/mypy/typeshed/stdlib/unittest/loader.pyi +++ b/mypy/typeshed/stdlib/unittest/loader.pyi @@ -3,10 +3,12 @@ import unittest.case import unittest.result import unittest.suite from types import ModuleType -from typing import Any, Callable, List, Sequence, Type +from typing import Any, Callable, Pattern, Sequence, Type _SortComparisonMethod = Callable[[str, str], int] -_SuiteClass = Callable[[List[unittest.case.TestCase]], unittest.suite.TestSuite] +_SuiteClass = Callable[[list[unittest.case.TestCase]], unittest.suite.TestSuite] + +VALID_MODULE_NAME: Pattern[str] class TestLoader: errors: list[Type[BaseException]] diff --git a/mypy/typeshed/stdlib/unittest/main.pyi b/mypy/typeshed/stdlib/unittest/main.pyi index cd887cec27d0..6d1117ecaf79 100644 --- a/mypy/typeshed/stdlib/unittest/main.pyi +++ b/mypy/typeshed/stdlib/unittest/main.pyi @@ -6,6 +6,9 @@ import unittest.suite from types import ModuleType from typing import Any, Iterable, Protocol, Type +MAIN_EXAMPLES: str +MODULE_EXAMPLES: str + class _TestRunner(Protocol): def run(self, test: unittest.suite.TestSuite | unittest.case.TestCase) -> unittest.result.TestResult: ... diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index 567ce346f464..72d0bab95c2e 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -1,27 +1,61 @@ import sys -from typing import Any, Callable, Generic, Iterable, List, Mapping, Sequence, Tuple, Type, TypeVar, overload +from typing import Any, Awaitable, Callable, Generic, Iterable, Mapping, Sequence, Type, TypeVar, overload _T = TypeVar("_T") _TT = TypeVar("_TT", bound=Type[Any]) _R = TypeVar("_R") -__all__ = [ - "Mock", - "MagicMock", - "patch", - "sentinel", - "DEFAULT", - "ANY", - "call", - "create_autospec", - "AsyncMock", - "FILTER_DIR", - "NonCallableMock", - "NonCallableMagicMock", - "mock_open", - "PropertyMock", - "seal", -] +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", + ) +elif sys.version_info >= (3, 7): + __all__ = ( + "Mock", + "MagicMock", + "patch", + "sentinel", + "DEFAULT", + "ANY", + "call", + "create_autospec", + "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", + ) __version__: str FILTER_DIR: Any @@ -39,7 +73,7 @@ class _Sentinel: sentinel: Any DEFAULT: Any -class _Call(Tuple[Any, ...]): +class _Call(tuple[Any, ...]): def __new__( cls, value: Any = ..., name: Any | None = ..., parent: Any | None = ..., two: bool = ..., from_kall: bool = ... ) -> Any: ... @@ -53,25 +87,22 @@ class _Call(Tuple[Any, ...]): __ne__: Any def __call__(self, *args: Any, **kwargs: Any) -> _Call: ... def __getattr__(self, attr: Any) -> Any: ... - def count(self, *args: Any, **kwargs: Any) -> Any: ... - def index(self, *args: Any, **kwargs: Any) -> Any: ... + if sys.version_info >= (3, 8): + @property + def args(self): ... + @property + def kwargs(self): ... def call_list(self) -> Any: ... call: _Call -class _CallList(List[_Call]): +class _CallList(list[_Call]): def __contains__(self, value: Any) -> bool: ... -class _MockIter: - obj: Any - def __init__(self, obj: Any) -> None: ... - def __iter__(self) -> Any: ... - def __next__(self) -> Any: ... - class Base: def __init__(self, *args: Any, **kwargs: Any) -> None: ... -class NonCallableMock(Base, Any): # type: ignore +class NonCallableMock(Base, Any): def __new__(__cls, *args: Any, **kw: Any) -> NonCallableMock: ... def __init__( self, @@ -124,7 +155,7 @@ class NonCallableMock(Base, Any): # type: ignore call_args_list: _CallList mock_calls: _CallList def _format_mock_call_signature(self, args: Any, kwargs: Any) -> str: ... - def _call_matcher(self, _call: Tuple[_Call, ...]) -> _Call: ... + def _call_matcher(self, _call: tuple[_Call, ...]) -> _Call: ... def _get_child_mock(self, **kw: Any) -> NonCallableMock: ... class CallableMixin(Base): @@ -143,7 +174,10 @@ class CallableMixin(Base): _new_parent: Any | None = ..., **kwargs: Any, ) -> None: ... - def __call__(_mock_self, *args: Any, **kwargs: Any) -> Any: ... + if sys.version_info >= (3, 8): + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + else: + def __call__(_mock_self, *args: Any, **kwargs: Any) -> Any: ... class Mock(CallableMixin, NonCallableMock): ... @@ -162,25 +196,45 @@ class _patch(Generic[_T]): additional_patchers: Any # If new==DEFAULT, self is _patch[Any]. Ideally we'd be able to add an overload for it so that self is _patch[MagicMock], # but that's impossible with the current type system. - def __init__( - self: _patch[_T], - getter: Callable[[], Any], - attribute: str, - new: _T, - spec: Any | None, - create: bool, - spec_set: Any | None, - autospec: Any | None, - new_callable: Any | None, - kwargs: Mapping[str, Any], - ) -> None: ... + if sys.version_info >= (3, 10): + def __init__( + self: _patch[_T], + getter: Callable[[], Any], + attribute: str, + new: _T, + spec: Any | None, + create: bool, + spec_set: Any | None, + autospec: Any | None, + new_callable: Any | None, + kwargs: Mapping[str, Any], + *, + unsafe: bool = ..., + ) -> None: ... + else: + def __init__( + self: _patch[_T], + getter: Callable[[], Any], + attribute: str, + new: _T, + spec: Any | None, + create: bool, + spec_set: Any | None, + autospec: Any | None, + new_callable: Any | None, + kwargs: Mapping[str, Any], + ) -> None: ... def copy(self) -> _patch[_T]: ... @overload def __call__(self, func: _TT) -> _TT: ... @overload def __call__(self, func: Callable[..., _R]) -> Callable[..., _R]: ... + if sys.version_info >= (3, 8): + def decoration_helper(self, patched, args, keywargs): ... 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 get_original(self) -> tuple[Any, bool]: ... target: Any temp_original: Any @@ -210,7 +264,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 + def __call__( # type: ignore[misc] self, target: Any, new: _T, @@ -222,7 +276,7 @@ class _patcher: **kwargs: Any, ) -> _patch[_T]: ... @overload - def __call__( # type: ignore + def __call__( self, target: Any, *, @@ -235,7 +289,7 @@ class _patcher: ) -> _patch[MagicMock | AsyncMock]: ... else: @overload - def __call__( # type: ignore + def __call__( # type: ignore[misc] self, target: Any, new: _T, @@ -247,7 +301,7 @@ class _patcher: **kwargs: Any, ) -> _patch[_T]: ... @overload - def __call__( # type: ignore + def __call__( self, target: Any, *, @@ -260,7 +314,7 @@ class _patcher: ) -> _patch[MagicMock]: ... if sys.version_info >= (3, 8): @overload - def object( # type: ignore + def object( # type: ignore[misc] self, target: Any, attribute: str, @@ -273,7 +327,7 @@ class _patcher: **kwargs: Any, ) -> _patch[_T]: ... @overload - def object( # type: ignore + def object( self, target: Any, attribute: str, @@ -287,7 +341,7 @@ class _patcher: ) -> _patch[MagicMock | AsyncMock]: ... else: @overload - def object( # type: ignore + def object( # type: ignore[misc] self, target: Any, attribute: str, @@ -300,7 +354,7 @@ class _patcher: **kwargs: Any, ) -> _patch[_T]: ... @overload - def object( # type: ignore + def object( self, target: Any, attribute: str, @@ -357,10 +411,11 @@ if sys.version_info >= (3, 8): class MagicProxy: name: Any parent: Any - def __init__(self, name: Any, parent: Any) -> None: ... - def __call__(self, *args: Any, **kwargs: Any) -> Any: ... - def create_mock(self) -> Any: ... - def __get__(self, obj: Any, _type: Any | None = ...) -> Any: ... + def __init__(self, name, parent) -> None: ... + if sys.version_info < (3, 8): + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... + def create_mock(self): ... + def __get__(self, obj, _type: Any | None = ...): ... class _ANY: def __eq__(self, other: Any) -> bool: ... diff --git a/mypy/typeshed/stdlib/unittest/result.pyi b/mypy/typeshed/stdlib/unittest/result.pyi index 20c43cf38aa4..9a19aef77d21 100644 --- a/mypy/typeshed/stdlib/unittest/result.pyi +++ b/mypy/typeshed/stdlib/unittest/result.pyi @@ -1,11 +1,14 @@ import unittest.case from types import TracebackType -from typing import Any, Callable, TextIO, Tuple, Type, TypeVar, Union +from typing import Any, Callable, TextIO, Type, TypeVar, Union -_SysExcInfoType = Union[Tuple[Type[BaseException], BaseException, TracebackType], Tuple[None, None, None]] +_SysExcInfoType = Union[tuple[Type[BaseException], BaseException, TracebackType], tuple[None, None, None]] _F = TypeVar("_F", bound=Callable[..., Any]) +STDOUT_LINE: str +STDERR_LINE: str + # undocumented def failfast(method: _F) -> _F: ... diff --git a/mypy/typeshed/stdlib/unittest/runner.pyi b/mypy/typeshed/stdlib/unittest/runner.pyi index bf8f3c05c1cd..85481880ab17 100644 --- a/mypy/typeshed/stdlib/unittest/runner.pyi +++ b/mypy/typeshed/stdlib/unittest/runner.pyi @@ -17,7 +17,7 @@ class TextTestResult(unittest.result.TestResult): def printErrors(self) -> None: ... def printErrorList(self, flavour: str, errors: tuple[unittest.case.TestCase, str]) -> None: ... -class TextTestRunner(object): +class TextTestRunner: resultclass: _ResultClassType def __init__( self, diff --git a/mypy/typeshed/stdlib/unittest/signals.pyi b/mypy/typeshed/stdlib/unittest/signals.pyi index 375b7d736a35..e6f5f95e1eb1 100644 --- a/mypy/typeshed/stdlib/unittest/signals.pyi +++ b/mypy/typeshed/stdlib/unittest/signals.pyi @@ -11,4 +11,4 @@ def removeResult(result: unittest.result.TestResult) -> bool: ... @overload def removeHandler(method: None = ...) -> None: ... @overload -def removeHandler(method: Callable[_P, _T]) -> Callable[_P, _T]: ... # type: ignore +def removeHandler(method: Callable[_P, _T]) -> Callable[_P, _T]: ... diff --git a/mypy/typeshed/stdlib/unittest/util.pyi b/mypy/typeshed/stdlib/unittest/util.pyi index ab6ed053a6ff..680ca24b7c33 100644 --- a/mypy/typeshed/stdlib/unittest/util.pyi +++ b/mypy/typeshed/stdlib/unittest/util.pyi @@ -1,7 +1,7 @@ -from typing import Any, Sequence, Tuple, TypeVar +from typing import Any, Sequence, TypeVar _T = TypeVar("_T") -_Mismatch = Tuple[_T, _T, int] +_Mismatch = tuple[_T, _T, int] _MAX_LENGTH: int _PLACEHOLDER_LEN: int diff --git a/mypy/typeshed/stdlib/urllib/parse.pyi b/mypy/typeshed/stdlib/urllib/parse.pyi index a2467e96c43c..7404b5382014 100644 --- a/mypy/typeshed/stdlib/urllib/parse.pyi +++ b/mypy/typeshed/stdlib/urllib/parse.pyi @@ -1,5 +1,5 @@ import sys -from typing import Any, AnyStr, Callable, Generic, Mapping, NamedTuple, Sequence, Tuple, Union, overload +from typing import Any, AnyStr, Callable, Generic, Mapping, NamedTuple, Sequence, Union, overload if sys.version_info >= (3, 9): from types import GenericAlias @@ -35,7 +35,7 @@ class _NetlocResultMixinBase(Generic[AnyStr]): class _NetlocResultMixinStr(_NetlocResultMixinBase[str], _ResultMixinStr): ... class _NetlocResultMixinBytes(_NetlocResultMixinBase[bytes], _ResultMixinBytes): ... -class _DefragResultBase(Tuple[Any, ...], Generic[AnyStr]): +class _DefragResultBase(tuple[Any, ...], Generic[AnyStr]): url: AnyStr fragment: AnyStr @@ -116,10 +116,10 @@ def urldefrag(url: bytes | None) -> DefragResultBytes: ... def urlencode( query: Mapping[Any, Any] | Mapping[Any, Sequence[Any]] | Sequence[tuple[Any, Any]] | Sequence[tuple[Any, Sequence[Any]]], doseq: bool = ..., - safe: AnyStr = ..., + safe: _Str = ..., encoding: str = ..., errors: str = ..., - quote_via: Callable[[str, AnyStr, str, str], str] = ..., + quote_via: Callable[[AnyStr, _Str, str, str], str] = ..., ) -> str: ... def urljoin(base: AnyStr, url: AnyStr | None, allow_fragments: bool = ...) -> AnyStr: ... @overload diff --git a/mypy/typeshed/stdlib/urllib/request.pyi b/mypy/typeshed/stdlib/urllib/request.pyi index 3c8a6facde6f..3749d7a390ea 100644 --- a/mypy/typeshed/stdlib/urllib/request.pyi +++ b/mypy/typeshed/stdlib/urllib/request.pyi @@ -4,7 +4,7 @@ from _typeshed import StrOrBytesPath from email.message import Message from http.client import HTTPMessage, HTTPResponse, _HTTPConnectionProtocol from http.cookiejar import CookieJar -from typing import IO, Any, Callable, ClassVar, Mapping, NoReturn, Pattern, Sequence, Tuple, TypeVar, overload +from typing import IO, Any, Callable, ClassVar, Mapping, NoReturn, Pattern, Sequence, TypeVar, overload from urllib.error import HTTPError from urllib.response import addclosehook, addinfourl @@ -196,9 +196,9 @@ class HTTPSHandler(AbstractHTTPHandler): def https_request(self, request: Request) -> Request: ... # undocumented class FileHandler(BaseHandler): - names: ClassVar[Tuple[str, ...] | None] # undocumented + names: ClassVar[tuple[str, ...] | None] # undocumented def file_open(self, req: Request) -> addinfourl: ... - def get_names(self) -> Tuple[str, ...]: ... # undocumented + def get_names(self) -> tuple[str, ...]: ... # undocumented def open_local_file(self, req: Request) -> addinfourl: ... # undocumented class DataHandler(BaseHandler): diff --git a/mypy/typeshed/stdlib/urllib/response.pyi b/mypy/typeshed/stdlib/urllib/response.pyi index 647ebf874432..18b498b40744 100644 --- a/mypy/typeshed/stdlib/urllib/response.pyi +++ b/mypy/typeshed/stdlib/urllib/response.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import Self from email.message import Message from types import TracebackType -from typing import IO, Any, BinaryIO, Callable, Iterable, Tuple, Type, TypeVar +from typing import IO, Any, BinaryIO, Callable, Iterable, Type, TypeVar _AIUT = TypeVar("_AIUT", bound=addbase) @@ -37,7 +37,7 @@ class addbase(BinaryIO): class addclosehook(addbase): closehook: Callable[..., object] - hookargs: Tuple[Any, ...] + hookargs: tuple[Any, ...] def __init__(self, fp: IO[bytes], closehook: Callable[..., object], *hookargs: Any) -> None: ... class addinfo(addbase): diff --git a/mypy/typeshed/stdlib/uuid.pyi b/mypy/typeshed/stdlib/uuid.pyi index da13d819fbdf..782c0491ffb2 100644 --- a/mypy/typeshed/stdlib/uuid.pyi +++ b/mypy/typeshed/stdlib/uuid.pyi @@ -1,10 +1,10 @@ import sys -from typing import Any, Tuple +from typing import Any # Because UUID has properties called int and bytes we need to rename these temporarily. _Int = int _Bytes = bytes -_FieldsType = Tuple[int, int, int, int, int, int] +_FieldsType = tuple[int, int, int, int, int, int] if sys.version_info >= (3, 7): from enum import Enum diff --git a/mypy/typeshed/stdlib/venv/__init__.pyi b/mypy/typeshed/stdlib/venv/__init__.pyi index 25cf615a3243..7650e87d98b4 100644 --- a/mypy/typeshed/stdlib/venv/__init__.pyi +++ b/mypy/typeshed/stdlib/venv/__init__.pyi @@ -3,6 +3,9 @@ from _typeshed import StrOrBytesPath from types import SimpleNamespace from typing import Sequence +if sys.version_info >= (3, 9): + CORE_VENV_DEPS: tuple[str, ...] + class EnvBuilder: system_site_packages: bool clear: bool diff --git a/mypy/typeshed/stdlib/weakref.pyi b/mypy/typeshed/stdlib/weakref.pyi index dbb6b49f2f2e..fd1cad7fe840 100644 --- a/mypy/typeshed/stdlib/weakref.pyi +++ b/mypy/typeshed/stdlib/weakref.pyi @@ -1,5 +1,5 @@ from _weakrefset import WeakSet as WeakSet -from typing import Any, Callable, Generic, Iterable, Iterator, Mapping, MutableMapping, Tuple, Type, TypeVar, overload +from typing import Any, Callable, Generic, Iterable, Iterator, Mapping, MutableMapping, Type, TypeVar, overload from _weakref import ( CallableProxyType as CallableProxyType, @@ -17,7 +17,7 @@ _KT = TypeVar("_KT") _VT = TypeVar("_VT") _CallableT = TypeVar("_CallableT", bound=Callable[..., Any]) -ProxyTypes: Tuple[Type[Any], ...] +ProxyTypes: tuple[Type[Any], ...] class WeakMethod(ref[_CallableT], Generic[_CallableT]): def __new__(cls, meth: _CallableT, callback: Callable[[_CallableT], object] | None = ...) -> WeakMethod[_CallableT]: ... @@ -37,9 +37,9 @@ class WeakValueDictionary(MutableMapping[_KT, _VT]): def __str__(self) -> str: ... def copy(self) -> WeakValueDictionary[_KT, _VT]: ... # These are incompatible with Mapping - def keys(self) -> Iterator[_KT]: ... # type: ignore - def values(self) -> Iterator[_VT]: ... # type: ignore - def items(self) -> Iterator[tuple[_KT, _VT]]: ... # type: ignore + def keys(self) -> Iterator[_KT]: ... # type: ignore[override] + def values(self) -> Iterator[_VT]: ... # type: ignore[override] + 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: ... @@ -68,9 +68,9 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]): def __str__(self) -> str: ... def copy(self) -> WeakKeyDictionary[_KT, _VT]: ... # These are incompatible with Mapping - def keys(self) -> Iterator[_KT]: ... # type: ignore - def values(self) -> Iterator[_VT]: ... # type: ignore - def items(self) -> Iterator[tuple[_KT, _VT]]: ... # type: ignore + def keys(self) -> Iterator[_KT]: ... # type: ignore[override] + def values(self) -> Iterator[_VT]: ... # type: ignore[override] + def items(self) -> Iterator[tuple[_KT, _VT]]: ... # type: ignore[override] def keyrefs(self) -> list[ref[_KT]]: ... def setdefault(self, key: _KT, default: _VT = ...) -> _VT: ... @overload @@ -81,7 +81,7 @@ class WeakKeyDictionary(MutableMapping[_KT, _VT]): class finalize: def __init__(self, __obj: object, __func: Callable[..., Any], *args: Any, **kwargs: Any) -> None: ... def __call__(self, _: Any = ...) -> 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: ... + def detach(self) -> tuple[Any, Any, tuple[Any, ...], dict[str, Any]] | None: ... + def peek(self) -> tuple[Any, Any, tuple[Any, ...], dict[str, Any]] | None: ... alive: bool atexit: bool diff --git a/mypy/typeshed/stdlib/webbrowser.pyi b/mypy/typeshed/stdlib/webbrowser.pyi index c85288cc562f..459d886ac930 100644 --- a/mypy/typeshed/stdlib/webbrowser.pyi +++ b/mypy/typeshed/stdlib/webbrowser.pyi @@ -28,14 +28,9 @@ class BaseBrowser: def open_new_tab(self, url: str) -> bool: ... class GenericBrowser(BaseBrowser): - args: list[str] - name: str - basename: str def __init__(self, name: str | Sequence[str]) -> None: ... - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... -class BackgroundBrowser(GenericBrowser): - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... +class BackgroundBrowser(GenericBrowser): ... class UnixBrowser(BaseBrowser): raise_opts: list[str] | None @@ -45,59 +40,21 @@ class UnixBrowser(BaseBrowser): remote_action: str remote_action_newwin: str remote_action_newtab: str - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... -class Mozilla(UnixBrowser): - remote_args: list[str] - remote_action: str - remote_action_newwin: str - remote_action_newtab: str - background: bool +class Mozilla(UnixBrowser): ... class Galeon(UnixBrowser): raise_opts: list[str] - remote_args: list[str] - remote_action: str - remote_action_newwin: str - background: bool -class Chrome(UnixBrowser): - remote_args: list[str] - remote_action: str - remote_action_newwin: str - remote_action_newtab: str - background: bool - -class Opera(UnixBrowser): - remote_args: list[str] - remote_action: str - remote_action_newwin: str - remote_action_newtab: str - background: bool - -class Elinks(UnixBrowser): - remote_args: list[str] - remote_action: str - remote_action_newwin: str - remote_action_newtab: str - background: bool - redirect_stdout: bool - -class Konqueror(BaseBrowser): - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... - -class Grail(BaseBrowser): - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... +class Chrome(UnixBrowser): ... +class Opera(UnixBrowser): ... +class Elinks(UnixBrowser): ... +class Konqueror(BaseBrowser): ... +class Grail(BaseBrowser): ... if sys.platform == "win32": - class WindowsDefault(BaseBrowser): - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... + class WindowsDefault(BaseBrowser): ... if sys.platform == "darwin": - class MacOSX(BaseBrowser): - name: str - def __init__(self, name: str) -> None: ... - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... - class MacOSXOSAScript(BaseBrowser): - def __init__(self, name: str) -> None: ... - def open(self, url: str, new: int = ..., autoraise: bool = ...) -> bool: ... + class MacOSX(BaseBrowser): ... + class MacOSXOSAScript(BaseBrowser): ... # In runtime this class does not have `name` and `basename` diff --git a/mypy/typeshed/stdlib/winreg.pyi b/mypy/typeshed/stdlib/winreg.pyi index 5fff1104e246..57f0c4b3ddba 100644 --- a/mypy/typeshed/stdlib/winreg.pyi +++ b/mypy/typeshed/stdlib/winreg.pyi @@ -1,101 +1,101 @@ +import sys from _typeshed import Self from types import TracebackType from typing import Any, Type, Union -from typing_extensions import final +from typing_extensions import Literal, final -_KeyType = Union[HKEYType, int] +if sys.platform == "win32": + _KeyType = Union[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 CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = ..., access: int = ...) -> HKEYType: ... + def DeleteKey(__key: _KeyType, __sub_key: str) -> None: ... + def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = ..., reserved: int = ...) -> 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(__str: 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 = ..., access: int = ...) -> HKEYType: ... + def OpenKeyEx(key: _KeyType, sub_key: str, reserved: int = ..., access: int = ...) -> 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 SetValueEx( + __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: ... + HKEY_CLASSES_ROOT: int + HKEY_CURRENT_USER: int + HKEY_LOCAL_MACHINE: int + HKEY_USERS: int + HKEY_PERFORMANCE_DATA: int + HKEY_CURRENT_CONFIG: int + HKEY_DYN_DATA: 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 CreateKeyEx(key: _KeyType, sub_key: str | None, reserved: int = ..., access: int = ...) -> HKEYType: ... -def DeleteKey(__key: _KeyType, __sub_key: str) -> None: ... -def DeleteKeyEx(key: _KeyType, sub_key: str, access: int = ..., reserved: int = ...) -> 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(__str: 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 = ..., access: int = ...) -> HKEYType: ... -def OpenKeyEx(key: _KeyType, sub_key: str, reserved: int = ..., access: int = ...) -> 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 SetValueEx( - __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: ... + 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] -HKEY_CLASSES_ROOT: int -HKEY_CURRENT_USER: int -HKEY_LOCAL_MACHINE: int -HKEY_USERS: int -HKEY_PERFORMANCE_DATA: int -HKEY_CURRENT_CONFIG: int -HKEY_DYN_DATA: int + KEY_WOW64_64KEY: Literal[256] + KEY_WOW64_32KEY: Literal[512] -KEY_ALL_ACCESS: int -KEY_WRITE: int -KEY_READ: int -KEY_EXECUTE: int -KEY_QUERY_VALUE: int -KEY_SET_VALUE: int -KEY_CREATE_SUB_KEY: int -KEY_ENUMERATE_SUB_KEYS: int -KEY_NOTIFY: int -KEY_CREATE_LINK: int + 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] -KEY_WOW64_64KEY: int -KEY_WOW64_32KEY: int + 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_BINARY: int -REG_DWORD: int -REG_DWORD_LITTLE_ENDIAN: int -REG_DWORD_BIG_ENDIAN: int -REG_EXPAND_SZ: int -REG_LINK: int -REG_MULTI_SZ: int -REG_NONE: int -REG_QWORD: int -REG_QWORD_LITTLE_ENDIAN: int -REG_RESOURCE_LIST: int -REG_FULL_RESOURCE_DESCRIPTOR: int -REG_RESOURCE_REQUIREMENTS_LIST: int -REG_SZ: int + error = OSError -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 - -error = OSError - -# Though this class has a __name__ of PyHKEY, it's exposed as HKEYType for some reason -@final -class HKEYType: - def __bool__(self) -> bool: ... - def __int__(self) -> int: ... - def __enter__(self: Self) -> Self: ... - def __exit__( - self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> bool | None: ... - def Close(self) -> None: ... - def Detach(self) -> int: ... + # Though this class has a __name__ of PyHKEY, it's exposed as HKEYType for some reason + @final + class HKEYType: + def __bool__(self) -> bool: ... + def __int__(self) -> int: ... + def __enter__(self: Self) -> Self: ... + def __exit__( + self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None + ) -> bool | None: ... + def Close(self) -> None: ... + def Detach(self) -> int: ... diff --git a/mypy/typeshed/stdlib/wsgiref/handlers.pyi b/mypy/typeshed/stdlib/wsgiref/handlers.pyi index ac1e56b7664e..eccc0d164767 100644 --- a/mypy/typeshed/stdlib/wsgiref/handlers.pyi +++ b/mypy/typeshed/stdlib/wsgiref/handlers.pyi @@ -1,12 +1,12 @@ from abc import abstractmethod from types import TracebackType -from typing import IO, Callable, MutableMapping, Optional, Tuple, Type +from typing import IO, Callable, MutableMapping, Optional, Type from .headers import Headers from .types import ErrorStream, InputStream, StartResponse, WSGIApplication, WSGIEnvironment from .util import FileWrapper -_exc_info = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] +_exc_info = tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] def format_date_time(timestamp: float | None) -> str: ... # undocumented def read_environ() -> dict[str, str]: ... diff --git a/mypy/typeshed/stdlib/wsgiref/headers.pyi b/mypy/typeshed/stdlib/wsgiref/headers.pyi index 531a521d3824..b62124a2a936 100644 --- a/mypy/typeshed/stdlib/wsgiref/headers.pyi +++ b/mypy/typeshed/stdlib/wsgiref/headers.pyi @@ -1,6 +1,6 @@ -from typing import List, Pattern, Tuple, overload +from typing import Pattern, overload -_HeaderList = List[Tuple[str, str]] +_HeaderList = list[tuple[str, str]] tspecials: Pattern[str] # undocumented diff --git a/mypy/typeshed/stdlib/wsgiref/util.pyi b/mypy/typeshed/stdlib/wsgiref/util.pyi index a7f710e8012c..c769c77d36e9 100644 --- a/mypy/typeshed/stdlib/wsgiref/util.pyi +++ b/mypy/typeshed/stdlib/wsgiref/util.pyi @@ -1,3 +1,4 @@ +import sys from typing import IO, Any, Callable from .types import WSGIEnvironment @@ -7,7 +8,8 @@ class FileWrapper: blksize: int close: Callable[[], None] # only exists if filelike.close exists def __init__(self, filelike: IO[bytes], blksize: int = ...) -> None: ... - def __getitem__(self, key: Any) -> bytes: ... + if sys.version_info < (3, 11): + def __getitem__(self, key: Any) -> bytes: ... def __iter__(self) -> FileWrapper: ... def __next__(self) -> bytes: ... diff --git a/mypy/typeshed/stdlib/xml/dom/__init__.pyi b/mypy/typeshed/stdlib/xml/dom/__init__.pyi index c5766c326c3e..e5b91bf2a795 100644 --- a/mypy/typeshed/stdlib/xml/dom/__init__.pyi +++ b/mypy/typeshed/stdlib/xml/dom/__init__.pyi @@ -43,6 +43,7 @@ class IndexSizeErr(DOMException): ... class DomstringSizeErr(DOMException): ... class HierarchyRequestErr(DOMException): ... class WrongDocumentErr(DOMException): ... +class InvalidCharacterErr(DOMException): ... class NoDataAllowedErr(DOMException): ... class NoModificationAllowedErr(DOMException): ... class NotFoundErr(DOMException): ... diff --git a/mypy/typeshed/stdlib/xml/dom/expatbuilder.pyi b/mypy/typeshed/stdlib/xml/dom/expatbuilder.pyi index 964e6fa3f426..58914e8fabf1 100644 --- a/mypy/typeshed/stdlib/xml/dom/expatbuilder.pyi +++ b/mypy/typeshed/stdlib/xml/dom/expatbuilder.pyi @@ -1,3 +1,99 @@ -from typing import Any +from typing import Any, NoReturn +from xml.dom.minidom import Document, DOMImplementation, Node, TypeInfo +from xml.dom.xmlbuilder import DOMBuilderFilter, Options -def __getattr__(name: str) -> Any: ... # incomplete +TEXT_NODE = Node.TEXT_NODE +CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE +DOCUMENT_NODE = Node.DOCUMENT_NODE +FILTER_ACCEPT = DOMBuilderFilter.FILTER_ACCEPT +FILTER_REJECT = DOMBuilderFilter.FILTER_REJECT +FILTER_SKIP = DOMBuilderFilter.FILTER_SKIP +FILTER_INTERRUPT = DOMBuilderFilter.FILTER_INTERRUPT +theDOMImplementation: DOMImplementation | None + +class ElementInfo: + tagName: Any + def __init__(self, tagName, model: Any | None = ...) -> None: ... + def getAttributeType(self, aname) -> TypeInfo: ... + def getAttributeTypeNS(self, namespaceURI, localName) -> TypeInfo: ... + def isElementContent(self) -> bool: ... + def isEmpty(self) -> bool: ... + def isId(self, aname) -> bool: ... + def isIdNS(self, euri, ename, auri, aname) -> bool: ... + +class ExpatBuilder: + document: Document # Created in self.reset() + curNode: Any # Created in self.reset() + def __init__(self, options: Options | None = ...) -> None: ... + def createParser(self): ... + def getParser(self): ... + def reset(self) -> None: ... + def install(self, parser) -> None: ... + def parseFile(self, file) -> Document: ... + def parseString(self, string: str) -> Document: ... + def start_doctype_decl_handler(self, doctypeName, systemId, publicId, has_internal_subset) -> None: ... + def end_doctype_decl_handler(self) -> None: ... + def pi_handler(self, target, data) -> None: ... + def character_data_handler_cdata(self, data) -> None: ... + def character_data_handler(self, data) -> None: ... + def start_cdata_section_handler(self) -> None: ... + def end_cdata_section_handler(self) -> None: ... + def entity_decl_handler(self, entityName, is_parameter_entity, value, base, systemId, publicId, notationName) -> None: ... + def notation_decl_handler(self, notationName, base, systemId, publicId) -> None: ... + def comment_handler(self, data) -> None: ... + def external_entity_ref_handler(self, context, base, systemId, publicId) -> int: ... + def first_element_handler(self, name, attributes) -> None: ... + def start_element_handler(self, name, attributes) -> None: ... + def end_element_handler(self, name) -> None: ... + def element_decl_handler(self, name, model) -> None: ... + def attlist_decl_handler(self, elem, name, type, default, required) -> None: ... + def xml_decl_handler(self, version, encoding, standalone) -> None: ... + +class FilterVisibilityController: + filter: DOMBuilderFilter + def __init__(self, filter: DOMBuilderFilter) -> None: ... + def startContainer(self, node: Node) -> int: ... + def acceptNode(self, node: Node) -> int: ... + +class FilterCrutch: + def __init__(self, builder) -> None: ... + +class Rejecter(FilterCrutch): + def start_element_handler(self, *args: Any) -> None: ... + def end_element_handler(self, *args: Any) -> None: ... + +class Skipper(FilterCrutch): + def start_element_handler(self, *args: Any) -> None: ... + def end_element_handler(self, *args: Any) -> None: ... + +class FragmentBuilder(ExpatBuilder): + fragment: Any | None + originalDocument: Any + context: Any + def __init__(self, context, options: Options | None = ...) -> None: ... + +class Namespaces: + def createParser(self): ... + def install(self, parser) -> None: ... + def start_namespace_decl_handler(self, prefix, uri) -> None: ... + def start_element_handler(self, name, attributes) -> None: ... + def end_element_handler(self, name) -> None: ... + +class ExpatBuilderNS(Namespaces, ExpatBuilder): ... +class FragmentBuilderNS(Namespaces, FragmentBuilder): ... +class ParseEscape(Exception): ... + +class InternalSubsetExtractor(ExpatBuilder): + subset: Any | None + def getSubset(self) -> Any | None: ... + def parseFile(self, file) -> None: ... # type: ignore[override] + def parseString(self, string: str) -> None: ... # type: ignore[override] + def start_doctype_decl_handler(self, name, publicId, systemId, has_internal_subset) -> None: ... # type: ignore[override] + def end_doctype_decl_handler(self) -> NoReturn: ... + def start_element_handler(self, name, attrs) -> NoReturn: ... + +def parse(file, namespaces: bool = ...): ... +def parseString(string: str, namespaces: bool = ...): ... +def parseFragment(file, context, namespaces: bool = ...): ... +def parseFragmentString(string: str, context, namespaces: bool = ...): ... +def makeBuilder(options: Options) -> ExpatBuilderNS | ExpatBuilder: ... diff --git a/mypy/typeshed/stdlib/xml/dom/minicompat.pyi b/mypy/typeshed/stdlib/xml/dom/minicompat.pyi index 4bc60f7ab965..38e6d05e4743 100644 --- a/mypy/typeshed/stdlib/xml/dom/minicompat.pyi +++ b/mypy/typeshed/stdlib/xml/dom/minicompat.pyi @@ -1,17 +1,17 @@ -from typing import Any, Iterable, List, Tuple, Type, TypeVar +from typing import Any, Iterable, Type, TypeVar _T = TypeVar("_T") StringTypes: tuple[Type[str]] -class NodeList(List[_T]): +class NodeList(list[_T]): length: int def item(self, index: int) -> _T | None: ... -class EmptyNodeList(Tuple[Any, ...]): +class EmptyNodeList(tuple[Any, ...]): length: int def item(self, index: int) -> None: ... - def __add__(self, other: Iterable[_T]) -> NodeList[_T]: ... # type: ignore + def __add__(self, other: Iterable[_T]) -> NodeList[_T]: ... # type: ignore[override] def __radd__(self, other: Iterable[_T]) -> NodeList[_T]: ... def defproperty(klass: Type[Any], name: str, doc: str) -> None: ... diff --git a/mypy/typeshed/stdlib/xml/dom/minidom.pyi b/mypy/typeshed/stdlib/xml/dom/minidom.pyi index 4d1d7a9d0faf..e9a26e30d721 100644 --- a/mypy/typeshed/stdlib/xml/dom/minidom.pyi +++ b/mypy/typeshed/stdlib/xml/dom/minidom.pyi @@ -70,6 +70,10 @@ class Attr(Node): self, qName: str, namespaceURI: str | None = ..., localName: Any | None = ..., prefix: Any | None = ... ) -> None: ... def unlink(self) -> None: ... + @property + def isId(self) -> bool: ... + @property + def schemaType(self) -> Any: ... class NamedNodeMap: def __init__(self, attrs, attrsNS, ownerElement) -> None: ... @@ -96,6 +100,8 @@ class NamedNodeMap: def setNamedItem(self, node): ... def setNamedItemNS(self, node): ... def __delitem__(self, attname_or_tuple) -> None: ... + @property + def length(self) -> int: ... AttributeList = NamedNodeMap @@ -110,6 +116,7 @@ class Element(Node): schemaType: Any parentNode: Any tagName: str + nodeName: str prefix: Any namespaceURI: str | None childNodes: Any @@ -139,6 +146,8 @@ class Element(Node): def setIdAttribute(self, name) -> None: ... def setIdAttributeNS(self, namespaceURI: str, localName) -> None: ... def setIdAttributeNode(self, idAttr) -> None: ... + @property + def attributes(self) -> NamedNodeMap: ... class Childless: attributes: Any @@ -173,6 +182,8 @@ class CharacterData(Childless, Node): def insertData(self, offset: int, arg: str) -> None: ... def deleteData(self, offset: int, count: int) -> None: ... def replaceData(self, offset: int, count: int, arg: str) -> None: ... + @property + def length(self) -> int: ... class Text(CharacterData): nodeType: Any @@ -182,6 +193,10 @@ class Text(CharacterData): def splitText(self, offset): ... def writexml(self, writer, indent: str = ..., addindent: str = ..., newl: str = ...) -> None: ... def replaceWholeText(self, content): ... + @property + def isWhitespaceInElementContent(self) -> bool: ... + @property + def wholeText(self) -> str: ... class Comment(CharacterData): nodeType: Any @@ -205,15 +220,17 @@ class ReadOnlySequentialNamedNodeMap: def removeNamedItemNS(self, namespaceURI: str, localName) -> None: ... def setNamedItem(self, node) -> None: ... def setNamedItemNS(self, node) -> None: ... + @property + def length(self) -> int: ... -class Identified: ... +class Identified: + publicId: Any + systemId: Any class DocumentType(Identified, Childless, Node): nodeType: Any nodeValue: Any name: Any - publicId: Any - systemId: Any internalSubset: Any entities: Any notations: Any diff --git a/mypy/typeshed/stdlib/xml/dom/pulldom.pyi b/mypy/typeshed/stdlib/xml/dom/pulldom.pyi index ce8816b4a98a..c2b7aa0772fa 100644 --- a/mypy/typeshed/stdlib/xml/dom/pulldom.pyi +++ b/mypy/typeshed/stdlib/xml/dom/pulldom.pyi @@ -1,4 +1,5 @@ -from typing import IO, Any, Sequence, Tuple, Union +import sys +from typing import IO, Any, Sequence, Union from typing_extensions import Literal from xml.dom.minidom import Document, DOMImplementation, Element, Text from xml.sax.handler import ContentHandler @@ -16,7 +17,7 @@ CHARACTERS: Literal["CHARACTERS"] _DocumentFactory = Union[DOMImplementation, None] _Node = Union[Document, Element, Text] -_Event = Tuple[ +_Event = tuple[ Literal[ Literal["START_ELEMENT"], Literal["END_ELEMENT"], @@ -66,7 +67,8 @@ class DOMEventStream: bufsize: int def __init__(self, stream: IO[bytes], parser: XMLReader, bufsize: int) -> None: ... pulldom: Any - def __getitem__(self, pos): ... + if sys.version_info < (3, 11): + def __getitem__(self, pos): ... def __next__(self): ... def __iter__(self): ... def getEvent(self) -> _Event: ... diff --git a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi index d8936bdc2ab4..2738d735e73f 100644 --- a/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi +++ b/mypy/typeshed/stdlib/xml/dom/xmlbuilder.pyi @@ -1,6 +1,107 @@ -from typing import Any +from typing import Any, NoReturn, Optional +from typing_extensions import Literal +from urllib.request import OpenerDirector +from xml.dom.expatbuilder import ExpatBuilder, ExpatBuilderNS +from xml.dom.minidom import Node -def __getattr__(name: str) -> Any: ... # incomplete +# UNKNOWN TYPES: +# - `Options.errorHandler`. +# The same as `_DOMBuilderErrorHandlerType`? +# Maybe `xml.sax.handler.ErrorHandler`? +# - Return type of DOMBuilder.getFeature(). +# We could get rid of the `Any` if we knew more +# about `Options.errorHandler`. -class DocumentLS(Any): ... # type: ignore -class DOMImplementationLS(Any): ... # type: ignore +# ALIASES REPRESENTING MORE UNKNOWN TYPES: + +# probably the same as `Options.errorHandler`? +# Maybe `xml.sax.handler.ErrorHandler`? +_DOMBuilderErrorHandlerType = Optional[Any] +# probably some kind of IO... +_DOMInputSourceCharacterStreamType = Optional[Any] +# probably a string?? +_DOMInputSourceStringDataType = Optional[Any] +# probably a string?? +_DOMInputSourceEncodingType = Optional[Any] + +class Options: + namespaces: int + namespace_declarations: bool + validation: bool + external_parameter_entities: bool + external_general_entities: bool + external_dtd_subset: bool + validate_if_schema: bool + validate: bool + datatype_normalization: bool + create_entity_ref_nodes: bool + entities: bool + whitespace_in_element_content: bool + cdata_sections: bool + comments: bool + charset_overrides_xml_encoding: bool + infoset: bool + supported_mediatypes_only: bool + errorHandler: Any | None + filter: DOMBuilderFilter | None # a guess, but seems likely + +class DOMBuilder: + entityResolver: DOMEntityResolver | None # a guess, but seems likely + errorHandler: _DOMBuilderErrorHandlerType + filter: DOMBuilderFilter | None # a guess, but seems likely + ACTION_REPLACE: Literal[1] + ACTION_APPEND_AS_CHILDREN: Literal[2] + ACTION_INSERT_AFTER: Literal[3] + ACTION_INSERT_BEFORE: Literal[4] + def __init__(self) -> None: ... + def setFeature(self, name: str, state: int) -> None: ... + 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) -> Any: ... + def parseURI(self, uri: str) -> ExpatBuilder | ExpatBuilderNS: ... + def parse(self, input: DOMInputSource) -> ExpatBuilder | ExpatBuilderNS: ... + # `input` and `cnode` argtypes for `parseWithContext` are unknowable + # as the function does nothing with them, and always raises an exception. + # But `input` is *probably* `DOMInputSource`? + def parseWithContext(self, input: object, cnode: object, action: Literal[1, 2, 3, 4]) -> NoReturn: ... + +class DOMEntityResolver: + def resolveEntity(self, publicId: str | None, systemId: str) -> DOMInputSource: ... + +class DOMInputSource: + byteStream: OpenerDirector | None + characterStream: _DOMInputSourceCharacterStreamType + stringData: _DOMInputSourceStringDataType + encoding: _DOMInputSourceEncodingType + publicId: str | None + systemId: str | None + baseURI: str | None + +class DOMBuilderFilter: + FILTER_ACCEPT: Literal[1] + FILTER_REJECT: Literal[2] + FILTER_SKIP: Literal[3] + FILTER_INTERRUPT: Literal[4] + whatToShow: int + # The argtypes for acceptNode and startContainer appear to be irrelevant. + def acceptNode(self, element: object) -> Literal[1]: ... + def startContainer(self, element: object) -> Literal[1]: ... + +class DocumentLS: + async_: bool + def abort(self) -> NoReturn: ... + # `load()` and `loadXML()` always raise exceptions + # so the argtypes of `uri` and `source` are unknowable. + # `source` is *probably* `DOMInputSource`? + # `uri` is *probably* a str? (see DOMBuilder.parseURI()) + def load(self, uri: object) -> NoReturn: ... + def loadXML(self, source: object) -> NoReturn: ... + def saveXML(self, snode: Node | None) -> str: ... + +class DOMImplementationLS: + MODE_SYNCHRONOUS: Literal[1] + MODE_ASYNCHRONOUS: Literal[2] + def createDOMBuilder(self, mode: Literal[1], schemaType: None) -> DOMBuilder: ... + def createDOMWriter(self) -> NoReturn: ... + def createDOMInputSource(self) -> DOMInputSource: ... diff --git a/mypy/typeshed/stdlib/xml/etree/ElementInclude.pyi b/mypy/typeshed/stdlib/xml/etree/ElementInclude.pyi index 0ccccce4f3d0..b355bef1208c 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementInclude.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementInclude.pyi @@ -6,6 +6,9 @@ XINCLUDE: str XINCLUDE_INCLUDE: str XINCLUDE_FALLBACK: str +if sys.version_info >= (3, 9): + DEFAULT_MAX_INCLUSION_DEPTH: int + class FatalIncludeError(SyntaxError): ... def default_loader(href: str | bytes | int, parse: str, encoding: str | None = ...) -> str | Element: ... @@ -17,6 +20,7 @@ if sys.version_info >= (3, 9): def include( elem: Element, loader: Callable[..., str | Element] | None = ..., base_url: str | None = ..., max_depth: int | None = ... ) -> None: ... + class LimitedRecursiveIncludeError(FatalIncludeError): ... else: def include(elem: Element, loader: Callable[..., str | Element] | None = ...) -> None: ... diff --git a/mypy/typeshed/stdlib/xml/etree/ElementPath.pyi b/mypy/typeshed/stdlib/xml/etree/ElementPath.pyi index db4bd6a4e958..5a2dd69c1bee 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementPath.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementPath.pyi @@ -1,11 +1,11 @@ -from typing import Callable, Generator, List, Pattern, Tuple, TypeVar +from typing import Callable, Generator, Pattern, TypeVar from xml.etree.ElementTree import Element xpath_tokenizer_re: Pattern[str] -_token = Tuple[str, str] +_token = tuple[str, str] _next = Callable[[], _token] -_callback = Callable[[_SelectorContext, List[Element]], Generator[Element, None, None]] +_callback = Callable[[_SelectorContext, list[Element]], Generator[Element, None, None]] def xpath_tokenizer(pattern: str, namespaces: dict[str, str] | None = ...) -> Generator[_token, None, None]: ... def get_parent_map(context: _SelectorContext) -> dict[Element, Element]: ... diff --git a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi index 03a20dcad4cb..c4236cf292bb 100644 --- a/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi +++ b/mypy/typeshed/stdlib/xml/etree/ElementTree.pyi @@ -4,19 +4,19 @@ from typing import ( IO, Any, Callable, - Dict, Generator, ItemsView, Iterable, Iterator, KeysView, + Mapping, MutableSequence, Sequence, TypeVar, Union, overload, ) -from typing_extensions import Literal +from typing_extensions import Literal, SupportsIndex _T = TypeVar("_T") _File = Union[StrOrBytesPath, FileDescriptor, IO[Any]] @@ -87,14 +87,14 @@ class Element(MutableSequence[Element]): 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 __delitem__(self, i: int | slice) -> None: ... + def __delitem__(self, i: SupportsIndex | slice) -> None: ... @overload - def __getitem__(self, i: int) -> Element: ... + def __getitem__(self, i: SupportsIndex) -> Element: ... @overload def __getitem__(self, s: slice) -> MutableSequence[Element]: ... def __len__(self) -> int: ... @overload - def __setitem__(self, i: int, o: Element) -> None: ... + def __setitem__(self, i: SupportsIndex, o: Element) -> None: ... @overload def __setitem__(self, s: slice, o: Iterable[Element]) -> None: ... if sys.version_info < (3, 9): @@ -256,14 +256,32 @@ def fromstringlist(sequence: Sequence[str | bytes], parser: XMLParser | None = . # TreeBuilder is called by client code (they could pass strs, bytes or whatever); # but we don't want to use a too-broad type, or it would be too hard to write # elementfactories. -_ElementFactory = Callable[[Any, Dict[Any, Any]], Element] +_ElementFactory = Callable[[Any, dict[Any, Any]], Element] class TreeBuilder: - def __init__(self, element_factory: _ElementFactory | None = ...) -> None: ... + 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: ... def close(self) -> Element: ... def data(self, __data: str | bytes) -> None: ... def start(self, __tag: str | bytes, __attrs: dict[str | bytes, str | bytes]) -> Element: ... def end(self, __tag: str | bytes) -> 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 = ...) -> Element: ... if sys.version_info >= (3, 8): class C14NWriterTarget: @@ -279,6 +297,12 @@ if sys.version_info >= (3, 8): exclude_attrs: Iterable[str] | None = ..., exclude_tags: Iterable[str] | 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 diff --git a/mypy/typeshed/stdlib/xmlrpc/client.pyi b/mypy/typeshed/stdlib/xmlrpc/client.pyi index 061df849eff2..e9f9e03ae56d 100644 --- a/mypy/typeshed/stdlib/xmlrpc/client.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/client.pyi @@ -6,16 +6,16 @@ from _typeshed import Self, SupportsRead, SupportsWrite from datetime import datetime from io import BytesIO from types import TracebackType -from typing import Any, Callable, Dict, Iterable, List, Mapping, Protocol, Tuple, Type, Union, overload +from typing import Any, Callable, Iterable, Mapping, Protocol, Type, Union, overload from typing_extensions import Literal class _SupportsTimeTuple(Protocol): def timetuple(self) -> time.struct_time: ... _DateTimeComparable = Union[DateTime, datetime, str, _SupportsTimeTuple] -_Marshallable = Union[None, bool, int, float, str, bytes, Tuple[Any, ...], List[Any], Dict[Any, Any], datetime, DateTime, Binary] -_XMLDate = Union[int, datetime, Tuple[int, ...], time.struct_time] -_HostType = Union[Tuple[str, Dict[str, str]], str] +_Marshallable = Union[None, bool, int, float, str, bytes, tuple[Any, ...], list[Any], dict[Any, Any], datetime, DateTime, Binary] +_XMLDate = Union[int, datetime, tuple[int, ...], time.struct_time] +_HostType = Union[tuple[str, dict[str, str]], str] def escape(s: str) -> str: ... # undocumented @@ -63,12 +63,12 @@ def _strftime(value: _XMLDate) -> str: ... # undocumented class DateTime: value: str # undocumented - def __init__(self, value: int | str | datetime | time.struct_time | Tuple[int, ...] = ...) -> None: ... + def __init__(self, value: int | str | datetime | time.struct_time | tuple[int, ...] = ...) -> None: ... def __lt__(self, other: _DateTimeComparable) -> bool: ... def __le__(self, other: _DateTimeComparable) -> bool: ... def __gt__(self, other: _DateTimeComparable) -> bool: ... def __ge__(self, other: _DateTimeComparable) -> bool: ... - def __eq__(self, other: _DateTimeComparable) -> bool: ... # type: ignore + def __eq__(self, other: _DateTimeComparable) -> bool: ... # type: ignore[override] def make_comparable(self, other: _DateTimeComparable) -> tuple[str, str]: ... # undocumented def timetuple(self) -> time.struct_time: ... # undocumented def decode(self, data: Any) -> None: ... @@ -135,7 +135,7 @@ class Unmarshaller: _use_datetime: bool _use_builtin_types: bool def __init__(self, use_datetime: bool = ..., use_builtin_types: bool = ...) -> None: ... - def close(self) -> Tuple[_Marshallable, ...]: ... + def close(self) -> tuple[_Marshallable, ...]: ... def getmethodname(self) -> str | None: ... def xml(self, encoding: str, standalone: Any) -> None: ... # Standalone is ignored def start(self, tag: str, attrs: dict[str, str]) -> None: ... @@ -159,7 +159,7 @@ class Unmarshaller: class _MultiCallMethod: # undocumented - __call_list: list[tuple[str, Tuple[_Marshallable, ...]]] + __call_list: list[tuple[str, tuple[_Marshallable, ...]]] __name: str def __init__(self, call_list: list[tuple[str, _Marshallable]], name: str) -> None: ... def __getattr__(self, name: str) -> _MultiCallMethod: ... @@ -174,7 +174,7 @@ class MultiCallIterator: # undocumented class MultiCall: __server: ServerProxy - __call_list: list[tuple[str, Tuple[_Marshallable, ...]]] + __call_list: list[tuple[str, tuple[_Marshallable, ...]]] def __init__(self, server: ServerProxy) -> None: ... def __getattr__(self, item: str) -> _MultiCallMethod: ... def __call__(self) -> MultiCallIterator: ... @@ -186,13 +186,13 @@ FastUnmarshaller: Unmarshaller | None def getparser(use_datetime: bool = ..., use_builtin_types: bool = ...) -> tuple[ExpatParser, Unmarshaller]: ... def dumps( - params: Fault | Tuple[_Marshallable, ...], + params: Fault | tuple[_Marshallable, ...], methodname: str | None = ..., methodresponse: bool | None = ..., encoding: str | None = ..., allow_none: bool = ..., ) -> str: ... -def loads(data: str, use_datetime: bool = ..., use_builtin_types: bool = ...) -> tuple[Tuple[_Marshallable, ...], str | None]: ... +def loads(data: str, use_datetime: bool = ..., use_builtin_types: bool = ...) -> tuple[tuple[_Marshallable, ...], str | None]: ... def gzip_encode(data: bytes) -> bytes: ... # undocumented def gzip_decode(data: bytes, max_decode: int = ...) -> bytes: ... # undocumented @@ -204,9 +204,9 @@ class GzipDecodedResponse(gzip.GzipFile): # undocumented class _Method: # undocumented - __send: Callable[[str, Tuple[_Marshallable, ...]], _Marshallable] + __send: Callable[[str, tuple[_Marshallable, ...]], _Marshallable] __name: str - def __init__(self, send: Callable[[str, Tuple[_Marshallable, ...]], _Marshallable], name: str) -> None: ... + def __init__(self, send: Callable[[str, tuple[_Marshallable, ...]], _Marshallable], name: str) -> None: ... def __getattr__(self, name: str) -> _Method: ... def __call__(self, *args: _Marshallable) -> _Marshallable: ... @@ -228,10 +228,10 @@ class Transport: ) -> None: ... else: def __init__(self, use_datetime: bool = ..., use_builtin_types: bool = ...) -> None: ... - def request(self, host: _HostType, handler: str, request_body: bytes, verbose: bool = ...) -> Tuple[_Marshallable, ...]: ... + def request(self, host: _HostType, handler: str, request_body: bytes, verbose: bool = ...) -> tuple[_Marshallable, ...]: ... def single_request( self, host: _HostType, handler: str, request_body: bytes, verbose: bool = ... - ) -> Tuple[_Marshallable, ...]: ... + ) -> tuple[_Marshallable, ...]: ... def getparser(self) -> tuple[ExpatParser, Unmarshaller]: ... def get_host_info(self, host: _HostType) -> tuple[str, list[tuple[str, str]], dict[str, str]]: ... def make_connection(self, host: _HostType) -> http.client.HTTPConnection: ... @@ -239,7 +239,7 @@ class Transport: def send_request(self, host: _HostType, handler: str, request_body: bytes, debug: bool) -> http.client.HTTPConnection: ... def send_headers(self, connection: http.client.HTTPConnection, headers: list[tuple[str, str]]) -> None: ... def send_content(self, connection: http.client.HTTPConnection, request_body: bytes) -> None: ... - def parse_response(self, response: http.client.HTTPResponse) -> Tuple[_Marshallable, ...]: ... + def parse_response(self, response: http.client.HTTPResponse) -> tuple[_Marshallable, ...]: ... class SafeTransport(Transport): @@ -304,6 +304,6 @@ class ServerProxy: self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None ) -> None: ... def __close(self) -> None: ... # undocumented - def __request(self, methodname: str, params: Tuple[_Marshallable, ...]) -> Tuple[_Marshallable, ...]: ... # undocumented + def __request(self, methodname: str, params: tuple[_Marshallable, ...]) -> tuple[_Marshallable, ...]: ... # undocumented Server = ServerProxy diff --git a/mypy/typeshed/stdlib/xmlrpc/server.pyi b/mypy/typeshed/stdlib/xmlrpc/server.pyi index bf5611fbaa96..48105d1461f0 100644 --- a/mypy/typeshed/stdlib/xmlrpc/server.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/server.pyi @@ -3,11 +3,11 @@ import pydoc import socketserver import sys from datetime import datetime -from typing import Any, Callable, Dict, Iterable, List, Mapping, Pattern, Protocol, Tuple, Type, Union +from typing import Any, Callable, Iterable, Mapping, Pattern, Protocol, Type, Union from xmlrpc.client import Fault # TODO: Recursive type on tuple, list, dict -_Marshallable = Union[None, bool, int, float, str, bytes, Tuple[Any, ...], List[Any], Dict[Any, Any], datetime] +_Marshallable = Union[None, bool, int, float, str, bytes, tuple[Any, ...], list[Any], dict[Any, Any], datetime] # The dispatch accepts anywhere from 0 to N arguments, no easy way to allow this in mypy class _DispatchArity0(Protocol): @@ -53,7 +53,7 @@ class SimpleXMLRPCDispatcher: # undocumented def _marshaled_dispatch( self, data: str, - dispatch_method: Callable[[str | None, Tuple[_Marshallable, ...]], Fault | Tuple[_Marshallable, ...]] | None = ..., + dispatch_method: Callable[[str | None, tuple[_Marshallable, ...]], Fault | tuple[_Marshallable, ...]] | None = ..., path: Any | None = ..., ) -> str: ... # undocumented def system_listMethods(self) -> list[str]: ... # undocumented @@ -109,7 +109,7 @@ class MultiPathXMLRPCServer(SimpleXMLRPCServer): # undocumented def _marshaled_dispatch( self, data: str, - dispatch_method: Callable[[str | None, Tuple[_Marshallable, ...]], Fault | Tuple[_Marshallable, ...]] | None = ..., + dispatch_method: Callable[[str | None, tuple[_Marshallable, ...]], Fault | tuple[_Marshallable, ...]] | None = ..., path: Any | None = ..., ) -> str: ... @@ -120,7 +120,16 @@ class CGIXMLRPCRequestHandler(SimpleXMLRPCDispatcher): def handle_request(self, request_text: str | None = ...) -> None: ... class ServerHTMLDoc(pydoc.HTMLDoc): # undocumented - def docroutine(self, object: object, name: str, mod: str | None = ..., funcs: Mapping[str, str] = ..., classes: Mapping[str, str] = ..., methods: Mapping[str, str] = ..., cl: type | None = ...) -> str: ... # type: ignore + def docroutine( # type: ignore[override] + self, + object: object, + name: str, + mod: str | None = ..., + funcs: Mapping[str, str] = ..., + classes: Mapping[str, str] = ..., + methods: Mapping[str, str] = ..., + cl: type | None = ..., + ) -> str: ... def docserver(self, server_name: str, package_documentation: str, methods: dict[str, str]) -> str: ... class XMLRPCDocGenerator: # undocumented diff --git a/mypy/typeshed/stdlib/zipfile.pyi b/mypy/typeshed/stdlib/zipfile.pyi index 2335428549dc..c64690ba8ca9 100644 --- a/mypy/typeshed/stdlib/zipfile.pyi +++ b/mypy/typeshed/stdlib/zipfile.pyi @@ -3,10 +3,10 @@ import sys from _typeshed import Self, StrPath from os import PathLike from types import TracebackType -from typing import IO, Any, Callable, Iterable, Iterator, Protocol, Sequence, Tuple, Type, overload +from typing import IO, Any, Callable, Iterable, Iterator, Protocol, Sequence, Type, overload from typing_extensions import Literal -_DateTuple = Tuple[int, int, int, int, int, int] +_DateTuple = tuple[int, int, int, int, int, int] _ReadWriteMode = Literal["r", "w"] _ReadWriteBinaryMode = Literal["r", "w", "rb", "wb"] _ZipFileMode = Literal["r", "w", "x", "a"] @@ -97,10 +97,10 @@ class ZipExtFile(io.BufferedIOBase): close_fileobj: Literal[False] = ..., ) -> None: ... def read(self, n: int | None = ...) -> bytes: ... - def readline(self, limit: int = ...) -> bytes: ... # type: ignore + def readline(self, limit: int = ...) -> bytes: ... # type: ignore[override] def __repr__(self) -> str: ... def peek(self, n: int = ...) -> bytes: ... - def read1(self, n: int | None) -> bytes: ... # type: ignore + def read1(self, n: int | None) -> bytes: ... # type: ignore[override] if sys.version_info >= (3, 7): def seek(self, offset: int, whence: int = ...) -> int: ... diff --git a/mypy/typeshed/stdlib/zipimport.pyi b/mypy/typeshed/stdlib/zipimport.pyi index 155b9742aa57..3435092a4722 100644 --- a/mypy/typeshed/stdlib/zipimport.pyi +++ b/mypy/typeshed/stdlib/zipimport.pyi @@ -1,5 +1,6 @@ import os import sys +from importlib.machinery import ModuleSpec from types import CodeType, ModuleType from typing import Any @@ -8,7 +9,7 @@ if sys.version_info >= (3, 7): class ZipImportError(ImportError): ... -class zipimporter(object): +class zipimporter: archive: str prefix: str def __init__(self, path: str | bytes | os.PathLike[Any]) -> None: ... @@ -22,3 +23,6 @@ class zipimporter(object): def get_source(self, fullname: str) -> str | None: ... def is_package(self, fullname: str) -> bool: ... def load_module(self, fullname: str) -> ModuleType: ... + if sys.version_info >= (3, 10): + def find_spec(self, fullname: str, target: ModuleType | None = ...) -> ModuleSpec | None: ... + def invalidate_caches(self) -> None: ... diff --git a/mypy/typeshed/stdlib/zlib.pyi b/mypy/typeshed/stdlib/zlib.pyi index 5acc4190f1fe..646c96bd2bef 100644 --- a/mypy/typeshed/stdlib/zlib.pyi +++ b/mypy/typeshed/stdlib/zlib.pyi @@ -1,12 +1,16 @@ from array import array from typing import Any +from typing_extensions import Literal DEFLATED: int DEF_MEM_LEVEL: int MAX_WBITS: int ZLIB_VERSION: str +Z_NO_COMPRESSION: Literal[0] +Z_PARTIAL_FLUSH: Literal[1] Z_BEST_COMPRESSION: int Z_BEST_SPEED: int +Z_BLOCK: Literal[5] Z_DEFAULT_COMPRESSION: int Z_DEFAULT_STRATEGY: int Z_FILTERED: int @@ -17,6 +21,7 @@ Z_HUFFMAN_ONLY: int Z_NO_FLUSH: int Z_RLE: int Z_SYNC_FLUSH: int +Z_TREES: Literal[6] DEF_BUF_SIZE: int ZLIB_RUNTIME_VERSION: str diff --git a/mypy/typeshed/stubs/mypy-extensions/mypy_extensions.pyi b/mypy/typeshed/stubs/mypy-extensions/mypy_extensions.pyi index fc6de37d07d1..dd182c485177 100644 --- a/mypy/typeshed/stubs/mypy-extensions/mypy_extensions.pyi +++ b/mypy/typeshed/stubs/mypy-extensions/mypy_extensions.pyi @@ -1,6 +1,6 @@ import abc import sys -from typing import Any, Callable, Generic, ItemsView, KeysView, Mapping, Type, TypeVar, Union, ValuesView +from typing import Any, Callable, Generic, ItemsView, KeysView, Mapping, Type, TypeVar, ValuesView _T = TypeVar("_T") _U = TypeVar("_U") @@ -34,9 +34,8 @@ def VarArg(type: _T = ...) -> _T: ... def KwArg(type: _T = ...) -> _T: ... # Return type that indicates a function does not return. -# This type is equivalent to the None type, but the no-op Union is necessary to -# distinguish the None type from the None value. -NoReturn = Union[None] # Deprecated: Use typing.NoReturn instead. +# Deprecated: Use typing.NoReturn instead. +class NoReturn: ... # This is intended as a class decorator, but mypy rejects abstract classes # when a Type[_T] is expected, so we can't give it the type we want diff --git a/mypy/util.py b/mypy/util.py index cd1e15afb4cf..2d6888dd0a2e 100644 --- a/mypy/util.py +++ b/mypy/util.py @@ -517,6 +517,8 @@ def hash_digest(data: bytes) -> str: def parse_gray_color(cup: bytes) -> str: """Reproduce a gray color in ANSI escape sequence""" + if sys.platform == "win32": + assert False, "curses is not available on Windows" set_color = ''.join([cup[:-1].decode(), 'm']) gray = curses.tparm(set_color.encode('utf-8'), 1, 89).decode() return gray @@ -580,7 +582,7 @@ def initialize_win_colors(self) -> bool: def initialize_unix_colors(self) -> bool: """Return True if initialization was successful and we can use colors, False otherwise""" - if not CURSES_ENABLED: + if sys.platform == "win32" or not CURSES_ENABLED: return False try: # setupterm wants a fd to potentially write an "initialization sequence". diff --git a/mypy/version.py b/mypy/version.py index 8877d01e5bb8..daa805d65395 100644 --- a/mypy/version.py +++ b/mypy/version.py @@ -5,7 +5,7 @@ # - Release versions have the form "0.NNN". # - Dev versions have the form "0.NNN+dev" (PLUS sign to conform to PEP 440). # - For 1.0 we'll switch back to 1.2.3 form. -__version__ = '0.940+dev' +__version__ = '0.942' base_version = __version__ mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) diff --git a/mypyc/analysis/ircheck.py b/mypyc/analysis/ircheck.py index f15beceff8ce..6450766f404c 100644 --- a/mypyc/analysis/ircheck.py +++ b/mypyc/analysis/ircheck.py @@ -1,14 +1,20 @@ """Utilities for checking that internal ir is valid and consistent.""" -from typing import List, Union +from typing import List, Union, Set, Tuple from mypyc.ir.pprint import format_func from mypyc.ir.ops import ( OpVisitor, BasicBlock, Op, ControlOp, Goto, Branch, Return, Unreachable, Assign, AssignMulti, LoadErrorValue, LoadLiteral, GetAttr, SetAttr, LoadStatic, InitStatic, TupleGet, TupleSet, IncRef, DecRef, Call, MethodCall, Cast, Box, Unbox, RaiseStandardError, CallC, Truncate, LoadGlobal, IntOp, ComparisonOp, - LoadMem, SetMem, GetElementPtr, LoadAddress, KeepAlive + LoadMem, SetMem, GetElementPtr, LoadAddress, KeepAlive, Register, Integer, + BaseAssign ) -from mypyc.ir.func_ir import FuncIR +from mypyc.ir.rtypes import ( + RType, RPrimitive, RUnion, is_object_rprimitive, RInstance, RArray, + int_rprimitive, list_rprimitive, dict_rprimitive, set_rprimitive, + range_rprimitive, str_rprimitive, bytes_rprimitive, tuple_rprimitive +) +from mypyc.ir.func_ir import FuncIR, FUNC_STATICMETHOD class FnError(object): @@ -17,8 +23,11 @@ def __init__(self, source: Union[Op, BasicBlock], desc: str) -> None: self.desc = desc def __eq__(self, other: object) -> bool: - return isinstance(other, FnError) and self.source == other.source and \ - self.desc == other.desc + return ( + isinstance(other, FnError) + and self.source == other.source + and self.desc == other.desc + ) def __repr__(self) -> str: return f"FnError(source={self.source}, desc={self.desc})" @@ -28,19 +37,44 @@ def check_func_ir(fn: FuncIR) -> List[FnError]: """Applies validations to a given function ir and returns a list of errors found.""" errors = [] + op_set = set() + for block in fn.blocks: if not block.terminated: - errors.append(FnError( - source=block.ops[-1] if block.ops else block, - desc="Block not terminated", - )) + errors.append( + FnError( + source=block.ops[-1] if block.ops else block, + desc="Block not terminated", + ) + ) + for op in block.ops[:-1]: + if isinstance(op, ControlOp): + errors.append( + FnError( + source=op, + desc="Block has operations after control op", + ) + ) + + if op in op_set: + errors.append( + FnError( + source=op, + desc="Func has a duplicate op", + ) + ) + op_set.add(op) + + errors.extend(check_op_sources_valid(fn)) + if errors: + return errors op_checker = OpChecker(fn) for block in fn.blocks: for op in block.ops: op.accept(op_checker) - return errors + op_checker.errors + return op_checker.errors class IrCheckException(Exception): @@ -50,11 +84,90 @@ class IrCheckException(Exception): def assert_func_ir_valid(fn: FuncIR) -> None: errors = check_func_ir(fn) if errors: - raise IrCheckException("Internal error: Generated invalid IR: \n" + "\n".join( - format_func(fn, [(e.source, e.desc) for e in errors])), + raise IrCheckException( + "Internal error: Generated invalid IR: \n" + + "\n".join(format_func(fn, [(e.source, e.desc) for e in errors])), ) +def check_op_sources_valid(fn: FuncIR) -> List[FnError]: + errors = [] + valid_ops: Set[Op] = set() + valid_registers: Set[Register] = set() + + for block in fn.blocks: + valid_ops.update(block.ops) + + valid_registers.update( + [op.dest for op in block.ops if isinstance(op, BaseAssign)] + ) + + valid_registers.update(fn.arg_regs) + + for block in fn.blocks: + for op in block.ops: + for source in op.sources(): + if isinstance(source, Integer): + pass + elif isinstance(source, Op): + if source not in valid_ops: + errors.append( + FnError( + source=op, + desc=f"Invalid op reference to op of type {type(source).__name__}", + ) + ) + elif isinstance(source, Register): + if source not in valid_registers: + errors.append( + FnError( + source=op, + desc=f"Invalid op reference to register {source.name}", + ) + ) + + return errors + + +disjoint_types = set( + [ + int_rprimitive.name, + bytes_rprimitive.name, + str_rprimitive.name, + dict_rprimitive.name, + list_rprimitive.name, + set_rprimitive.name, + tuple_rprimitive.name, + range_rprimitive.name, + ] +) + + +def can_coerce_to(src: RType, dest: RType) -> bool: + """Check if src can be assigned to dest_rtype. + + Currently okay to have false positives. + """ + if isinstance(dest, RUnion): + return any(can_coerce_to(src, d) for d in dest.items) + + if isinstance(dest, RPrimitive): + if isinstance(src, RPrimitive): + # If either src or dest is a disjoint type, then they must both be. + if src.name in disjoint_types and dest.name in disjoint_types: + return src.name == dest.name + return src.size == dest.size + if isinstance(src, RInstance): + return is_object_rprimitive(dest) + if isinstance(src, RUnion): + # IR doesn't have the ability to narrow unions based on + # control flow, so cannot be a strict all() here. + return any(can_coerce_to(s, dest) for s in src.items) + return False + + return True + + class OpChecker(OpVisitor[None]): def __init__(self, parent_fn: FuncIR) -> None: self.parent_fn = parent_fn @@ -66,7 +179,16 @@ def fail(self, source: Op, desc: str) -> None: def check_control_op_targets(self, op: ControlOp) -> None: for target in op.targets(): if target not in self.parent_fn.blocks: - self.fail(source=op, desc=f"Invalid control operation target: {target.label}") + self.fail( + source=op, desc=f"Invalid control operation target: {target.label}" + ) + + def check_type_coercion(self, op: Op, src: RType, dest: RType) -> None: + if not can_coerce_to(src, dest): + self.fail( + source=op, + desc=f"Cannot coerce source type {src.name} to dest type {dest.name}", + ) def visit_goto(self, op: Goto) -> None: self.check_control_op_targets(op) @@ -75,29 +197,76 @@ def visit_branch(self, op: Branch) -> None: self.check_control_op_targets(op) def visit_return(self, op: Return) -> None: - pass + self.check_type_coercion(op, op.value.type, self.parent_fn.decl.sig.ret_type) def visit_unreachable(self, op: Unreachable) -> None: + # Unreachables are checked at a higher level since validation + # requires access to the entire basic block. pass def visit_assign(self, op: Assign) -> None: - pass + self.check_type_coercion(op, op.src.type, op.dest.type) def visit_assign_multi(self, op: AssignMulti) -> None: - pass + for src in op.src: + assert isinstance(op.dest.type, RArray) + self.check_type_coercion(op, src.type, op.dest.type.item_type) def visit_load_error_value(self, op: LoadErrorValue) -> None: + # Currently it is assumed that all types have an error value. + # Once this is fixed we can validate that the rtype here actually + # has an error value. pass + def check_tuple_items_valid_literals( + self, op: LoadLiteral, t: Tuple[object, ...] + ) -> None: + for x in t: + if x is not None and not isinstance( + x, (str, bytes, bool, int, float, complex, tuple) + ): + self.fail(op, f"Invalid type for item of tuple literal: {type(x)})") + if isinstance(x, tuple): + self.check_tuple_items_valid_literals(op, x) + def visit_load_literal(self, op: LoadLiteral) -> None: - pass + expected_type = None + if op.value is None: + expected_type = "builtins.object" + elif isinstance(op.value, int): + expected_type = "builtins.int" + elif isinstance(op.value, str): + expected_type = "builtins.str" + elif isinstance(op.value, bytes): + expected_type = "builtins.bytes" + elif isinstance(op.value, bool): + expected_type = "builtins.object" + elif isinstance(op.value, float): + expected_type = "builtins.float" + elif isinstance(op.value, complex): + expected_type = "builtins.object" + elif isinstance(op.value, tuple): + expected_type = "builtins.tuple" + self.check_tuple_items_valid_literals(op, op.value) + + assert expected_type is not None, "Missed a case for LoadLiteral check" + + if op.type.name not in [expected_type, "builtins.object"]: + self.fail( + op, + f"Invalid literal value for type: value has " + f"type {expected_type}, but op has type {op.type.name}", + ) def visit_get_attr(self, op: GetAttr) -> None: + # Nothing to do. pass def visit_set_attr(self, op: SetAttr) -> None: + # Nothing to do. pass + # Static operations cannot be checked at the function level. def visit_load_static(self, op: LoadStatic) -> None: pass @@ -105,22 +274,41 @@ def visit_init_static(self, op: InitStatic) -> None: pass def visit_tuple_get(self, op: TupleGet) -> None: + # Nothing to do. pass def visit_tuple_set(self, op: TupleSet) -> None: + # Nothing to do. pass def visit_inc_ref(self, op: IncRef) -> None: + # Nothing to do. pass def visit_dec_ref(self, op: DecRef) -> None: + # Nothing to do. pass def visit_call(self, op: Call) -> None: - pass + # Length is checked in constructor, and return type is set + # in a way that can't be incorrect + for arg_value, arg_runtime in zip(op.args, op.fn.sig.args): + self.check_type_coercion(op, arg_value.type, arg_runtime.type) def visit_method_call(self, op: MethodCall) -> None: - pass + # Similar to above, but we must look up method first. + method_decl = op.receiver_type.class_ir.method_decl(op.method) + if method_decl.kind == FUNC_STATICMETHOD: + decl_index = 0 + else: + decl_index = 1 + + if len(op.args) + decl_index != len(method_decl.sig.args): + self.fail(op, "Incorrect number of args for method call.") + + # Skip the receiver argument (self) + for arg_value, arg_runtime in zip(op.args, method_decl.sig.args[decl_index:]): + self.check_type_coercion(op, arg_value.type, arg_runtime.type) def visit_cast(self, op: Cast) -> None: pass diff --git a/mypyc/build.py b/mypyc/build.py index 571fb0dd2f5a..8528aa088ac0 100644 --- a/mypyc/build.py +++ b/mypyc/build.py @@ -308,8 +308,8 @@ def write_file(path: str, contents: str) -> None: old_contents = None if old_contents != encoded_contents: os.makedirs(os.path.dirname(path), exist_ok=True) - with open(path, 'wb') as f: - f.write(encoded_contents) + with open(path, 'wb') as g: + g.write(encoded_contents) # Fudge the mtime forward because otherwise when two builds happen close # together (like in a test) setuptools might not realize the source is newer diff --git a/mypyc/codegen/emitwrapper.py b/mypyc/codegen/emitwrapper.py index bbee8fea0d91..dd08bdb40bf3 100644 --- a/mypyc/codegen/emitwrapper.py +++ b/mypyc/codegen/emitwrapper.py @@ -286,21 +286,20 @@ def generate_bin_op_wrapper(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str: gen.emit_header() if fn.name not in reverse_op_methods and fn.name in reverse_op_method_names: # There's only a reverse operator method. - generate_bin_op_reverse_only_wrapper(cl, fn, emitter, gen) + generate_bin_op_reverse_only_wrapper(emitter, gen) else: rmethod = reverse_op_methods[fn.name] fn_rev = cl.get_method(rmethod) if fn_rev is None: # There's only a forward operator method. - generate_bin_op_forward_only_wrapper(cl, fn, emitter, gen) + generate_bin_op_forward_only_wrapper(fn, emitter, gen) else: # There's both a forward and a reverse operator method. generate_bin_op_both_wrappers(cl, fn, fn_rev, emitter, gen) return wrapper_name -def generate_bin_op_forward_only_wrapper(cl: ClassIR, - fn: FuncIR, +def generate_bin_op_forward_only_wrapper(fn: FuncIR, emitter: Emitter, gen: 'WrapperGenerator') -> None: gen.emit_arg_processing(error=GotoHandler('typefail'), raise_exception=False) @@ -331,9 +330,7 @@ def generate_bin_op_forward_only_wrapper(cl: ClassIR, gen.finish() -def generate_bin_op_reverse_only_wrapper(cl: ClassIR, - fn_rev: FuncIR, - emitter: Emitter, +def generate_bin_op_reverse_only_wrapper(emitter: Emitter, gen: 'WrapperGenerator') -> None: gen.arg_names = ['right', 'left'] gen.emit_arg_processing(error=GotoHandler('typefail'), raise_exception=False) @@ -650,47 +647,17 @@ def generate_wrapper_core(fn: FuncIR, It converts the PyObject *s to the necessary types, checking and unboxing if necessary, makes the call, then boxes the result if necessary and returns it. """ + gen = WrapperGenerator(None, emitter) + gen.set_target(fn) + gen.arg_names = arg_names or [arg.name for arg in fn.args] + gen.cleanups = cleanups or [] + gen.optional_args = optional_args or [] + gen.traceback_code = traceback_code or '' - optional_args = optional_args or [] - cleanups = cleanups or [] - use_goto = bool(cleanups or traceback_code) - error = ReturnHandler('NULL') if not use_goto else GotoHandler('fail') - - arg_names = arg_names or [arg.name for arg in fn.args] - for arg_name, arg in zip(arg_names, fn.args): - # Suppress the argument check for *args/**kwargs, since we know it must be right. - typ = arg.type if arg.kind not in (ARG_STAR, ARG_STAR2) else object_rprimitive - generate_arg_check(arg_name, - typ, - emitter, - error, - optional=arg in optional_args) - native_args = ', '.join('arg_{}'.format(arg) for arg in arg_names) - if fn.ret_type.is_unboxed or use_goto: - # TODO: The Py_RETURN macros return the correct PyObject * with reference count handling. - # Are they relevant? - emitter.emit_line('{}retval = {}{}({});'.format(emitter.ctype_spaced(fn.ret_type), - NATIVE_PREFIX, - fn.cname(emitter.names), - native_args)) - emitter.emit_lines(*cleanups) - if fn.ret_type.is_unboxed: - emitter.emit_error_check('retval', fn.ret_type, 'return NULL;') - emitter.emit_box('retval', 'retbox', fn.ret_type, declare_dest=True) - - emitter.emit_line('return {};'.format('retbox' if fn.ret_type.is_unboxed else 'retval')) - else: - emitter.emit_line('return {}{}({});'.format(NATIVE_PREFIX, - fn.cname(emitter.names), - native_args)) - # TODO: Tracebacks? - - if use_goto: - emitter.emit_label('fail') - emitter.emit_lines(*cleanups) - if traceback_code: - emitter.emit_lines(traceback_code) - emitter.emit_lines('return NULL;') + error = ReturnHandler('NULL') if not gen.use_goto() else GotoHandler('fail') + gen.emit_arg_processing(error=error) + gen.emit_call() + gen.emit_error_handling() def generate_arg_check(name: str, @@ -741,7 +708,7 @@ class WrapperGenerator: # TODO: Use this for more wrappers - def __init__(self, cl: ClassIR, emitter: Emitter) -> None: + def __init__(self, cl: Optional[ClassIR], emitter: Emitter) -> None: self.cl = cl self.emitter = emitter self.cleanups: List[str] = [] @@ -764,7 +731,7 @@ def wrapper_name(self) -> str: """Return the name of the wrapper function.""" return '{}{}{}'.format(DUNDER_PREFIX, self.target_name, - self.cl.name_prefix(self.emitter.names)) + self.cl.name_prefix(self.emitter.names) if self.cl else '') def use_goto(self) -> bool: """Do we use a goto for error handling (instead of straight return)?""" diff --git a/mypyc/doc/dev-intro.md b/mypyc/doc/dev-intro.md index bf0c1a836874..d11df7068e91 100644 --- a/mypyc/doc/dev-intro.md +++ b/mypyc/doc/dev-intro.md @@ -149,7 +149,7 @@ know for mypyc contributors: ([The C Programming Language](https://en.wikipedia.org/wiki/The_C_Programming_Language) is a classic book about C) * Basic familiarity with the Python C API (see - [Python C API documentation](https://docs.python.org/3/c-api/intro.html)) + [Python C API documentation](https://docs.python.org/3/c-api/intro.html)). [Extending and Embedding the Python Interpreter](https://docs.python.org/3/extending/index.html) is a good tutorial for beginners. * Basics of compilers (see the [mypy wiki](https://github.com/python/mypy/wiki/Learning-Resources) for some ideas) diff --git a/mypyc/ir/ops.py b/mypyc/ir/ops.py index 22dead2f7976..65480ebcc7c3 100644 --- a/mypyc/ir/ops.py +++ b/mypyc/ir/ops.py @@ -214,15 +214,21 @@ def accept(self, visitor: 'OpVisitor[T]') -> T: pass -class Assign(Op): +class BaseAssign(Op): + """Base class for ops that assign to a register.""" + def __init__(self, dest: Register, line: int = -1) -> None: + super().__init__(line) + self.dest = dest + + +class Assign(BaseAssign): """Assign a value to a Register (dest = src).""" error_kind = ERR_NEVER def __init__(self, dest: Register, src: Value, line: int = -1) -> None: - super().__init__(line) + super().__init__(dest, line) self.src = src - self.dest = dest def sources(self) -> List[Value]: return [self.src] @@ -234,7 +240,7 @@ def accept(self, visitor: 'OpVisitor[T]') -> T: return visitor.visit_assign(self) -class AssignMulti(Op): +class AssignMulti(BaseAssign): """Assign multiple values to a Register (dest = src1, src2, ...). This is used to initialize RArray values. It's provided to avoid @@ -248,12 +254,11 @@ class AssignMulti(Op): error_kind = ERR_NEVER def __init__(self, dest: Register, src: List[Value], line: int = -1) -> None: - super().__init__(line) + super().__init__(dest, line) assert src assert isinstance(dest.type, RArray) assert dest.type.length == len(src) self.src = src - self.dest = dest def sources(self) -> List[Value]: return self.src[:] @@ -490,6 +495,7 @@ def __init__(self, fn: 'FuncDecl', args: Sequence[Value], line: int) -> None: super().__init__(line) self.fn = fn self.args = list(args) + assert len(self.args) == len(fn.sig.args) self.type = fn.sig.ret_type def sources(self) -> List[Value]: diff --git a/mypyc/irbuild/classdef.py b/mypyc/irbuild/classdef.py index 6c2958c5b8de..80ec331cd550 100644 --- a/mypyc/irbuild/classdef.py +++ b/mypyc/irbuild/classdef.py @@ -8,7 +8,7 @@ ClassDef, FuncDef, OverloadedFuncDef, PassStmt, AssignmentStmt, CallExpr, NameExpr, StrExpr, ExpressionStmt, TempNode, Decorator, Lvalue, MemberExpr, RefExpr, TypeInfo, is_class_var ) -from mypy.types import Instance, get_proper_type +from mypy.types import Instance, get_proper_type, ENUM_REMOVED_PROPS from mypyc.ir.ops import ( Value, Register, Call, LoadErrorValue, LoadStatic, InitStatic, TupleSet, SetAttr, Return, BasicBlock, Branch, MethodCall, NAMESPACE_TYPE, LoadAddress @@ -517,8 +517,8 @@ def add_non_ext_class_attr(builder: IRBuilder, if ( cdef.info.bases and cdef.info.bases[0].type.fullname == 'enum.Enum' - # Skip "_order_" and "__order__", since Enum will remove it - and lvalue.name not in ('_order_', '__order__') + # Skip these since Enum will remove it + and lvalue.name not in ENUM_REMOVED_PROPS ): # Enum values are always boxed, so use object_rprimitive. attr_to_cache.append((lvalue, object_rprimitive)) diff --git a/mypyc/irbuild/prepare.py b/mypyc/irbuild/prepare.py index 3f028d900943..2cb3deac9700 100644 --- a/mypyc/irbuild/prepare.py +++ b/mypyc/irbuild/prepare.py @@ -142,7 +142,7 @@ def prepare_method_def(ir: ClassIR, module_name: str, cdef: ClassDef, mapper: Ma ir.method_decls[PROPSET_PREFIX + node.name] = decl if node.func.is_property: - assert node.func.type + assert node.func.type, f"Expected return type annotation for property '{node.name}'" decl.is_prop_getter = True ir.property_types[node.name] = decl.sig.ret_type diff --git a/mypyc/lib-rt/dict_ops.c b/mypyc/lib-rt/dict_ops.c index 21a9035021ea..b013a8a5f0b9 100644 --- a/mypyc/lib-rt/dict_ops.c +++ b/mypyc/lib-rt/dict_ops.c @@ -139,8 +139,8 @@ int CPyDict_UpdateInDisplay(PyObject *dict, PyObject *stuff) { if (ret < 0) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_TypeError, - "'%.200s' object is not a mapping", - stuff->ob_type->tp_name); + "'%.200s' object is not a mapping", + Py_TYPE(stuff)->tp_name); } } return ret; diff --git a/mypyc/lib-rt/exc_ops.c b/mypyc/lib-rt/exc_ops.c index b87d5471a411..7ef46479d2e8 100644 --- a/mypyc/lib-rt/exc_ops.c +++ b/mypyc/lib-rt/exc_ops.c @@ -140,7 +140,7 @@ static PyObject *CPy_GetTypeName(PyObject *type) { // Get the type of a value as a string, expanding tuples to include // all the element types. static PyObject *CPy_FormatTypeName(PyObject *value) { - if (value == Py_None) { + if (Py_IsNone(value)) { return PyUnicode_FromString("None"); } diff --git a/mypyc/lib-rt/generic_ops.c b/mypyc/lib-rt/generic_ops.c index 1dff949dcfcf..2f4a7941a6da 100644 --- a/mypyc/lib-rt/generic_ops.c +++ b/mypyc/lib-rt/generic_ops.c @@ -33,7 +33,7 @@ PyObject *CPyObject_GetAttr3(PyObject *v, PyObject *name, PyObject *defl) PyObject *CPyIter_Next(PyObject *iter) { - return (*iter->ob_type->tp_iternext)(iter); + return (*Py_TYPE(iter)->tp_iternext)(iter); } PyObject *CPyNumber_Power(PyObject *base, PyObject *index) diff --git a/mypyc/lib-rt/misc_ops.c b/mypyc/lib-rt/misc_ops.c index 6b5685ab1f1a..cebd1cf997f8 100644 --- a/mypyc/lib-rt/misc_ops.c +++ b/mypyc/lib-rt/misc_ops.c @@ -3,14 +3,13 @@ // These are registered in mypyc.primitives.misc_ops. #include -#include "pythoncapi_compat.h" #include "CPy.h" PyObject *CPy_GetCoro(PyObject *obj) { // If the type has an __await__ method, call it, // otherwise, fallback to calling __iter__. - PyAsyncMethods* async_struct = obj->ob_type->tp_as_async; + PyAsyncMethods* async_struct = Py_TYPE(obj)->tp_as_async; if (async_struct != NULL && async_struct->am_await != NULL) { return (async_struct->am_await)(obj); } else { @@ -25,7 +24,7 @@ PyObject *CPyIter_Send(PyObject *iter, PyObject *val) // Do a send, or a next if second arg is None. // (This behavior is to match the PEP 380 spec for yield from.) _Py_IDENTIFIER(send); - if (val == Py_None) { + if (Py_IsNone(val)) { return CPyIter_Next(iter); } else { return _PyObject_CallMethodIdOneArg(iter, &PyId_send, val); @@ -640,7 +639,7 @@ CPy_Super(PyObject *builtins, PyObject *self) { if (!super_type) return NULL; PyObject *result = PyObject_CallFunctionObjArgs( - super_type, (PyObject*)self->ob_type, self, NULL); + super_type, (PyObject*)Py_TYPE(self), self, NULL); Py_DECREF(super_type); return result; } diff --git a/mypyc/lib-rt/pythoncapi_compat.h b/mypyc/lib-rt/pythoncapi_compat.h index b4011d20a19a..c9191a1d7a57 100644 --- a/mypyc/lib-rt/pythoncapi_compat.h +++ b/mypyc/lib-rt/pythoncapi_compat.h @@ -1,7 +1,6 @@ -// Header file providing new functions of the Python C API to old Python -// versions. +// Header file providing new C API functions to old Python versions. // -// File distributed under the MIT license. +// File distributed under the Zero Clause BSD (0BSD) license. // Copyright Contributors to the pythoncapi_compat project. // // Homepage: @@ -10,7 +9,7 @@ // Latest version: // https://raw.githubusercontent.com/pythoncapi/pythoncapi_compat/master/pythoncapi_compat.h // -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: 0BSD #ifndef PYTHONCAPI_COMPAT #define PYTHONCAPI_COMPAT @@ -27,24 +26,34 @@ extern "C" { // the inline keyword in C (only in C++): use __inline instead. #if (defined(_MSC_VER) && _MSC_VER < 1900 \ && !defined(__cplusplus) && !defined(inline)) -# define inline __inline -# define PYTHONCAPI_COMPAT_MSC_INLINE - // These two macros are undefined at the end of this file +# define PYCAPI_COMPAT_INLINE(TYPE static __inline TYPE +#else +# define PYCAPI_COMPAT_STATIC_INLINE(TYPE) static inline TYPE #endif +// C++ compatibility +#ifdef __cplusplus +# define PYCAPI_COMPAT_CAST(TYPE, EXPR) reinterpret_cast(EXPR) +# define PYCAPI_COMPAT_NULL nullptr +#else +# define PYCAPI_COMPAT_CAST(TYPE, EXPR) (TYPE)(EXPR) +# define PYCAPI_COMPAT_NULL NULL +#endif + // Cast argument to PyObject* type. #ifndef _PyObject_CAST -# define _PyObject_CAST(op) ((PyObject*)(op)) +# define _PyObject_CAST(op) PYCAPI_COMPAT_CAST(PyObject*, op) #endif #ifndef _PyObject_CAST_CONST -# define _PyObject_CAST_CONST(op) ((const PyObject*)(op)) +# define _PyObject_CAST_CONST(op) PYCAPI_COMPAT_CAST(const PyObject*, op) #endif // bpo-42262 added Py_NewRef() to Python 3.10.0a3 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_NewRef) -static inline PyObject* _Py_NewRef(PyObject *obj) +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) +_Py_NewRef(PyObject *obj) { Py_INCREF(obj); return obj; @@ -55,7 +64,8 @@ static inline PyObject* _Py_NewRef(PyObject *obj) // bpo-42262 added Py_XNewRef() to Python 3.10.0a3 #if PY_VERSION_HEX < 0x030A00A3 && !defined(Py_XNewRef) -static inline PyObject* _Py_XNewRef(PyObject *obj) +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) +_Py_XNewRef(PyObject *obj) { Py_XINCREF(obj); return obj; @@ -66,7 +76,8 @@ static inline PyObject* _Py_XNewRef(PyObject *obj) // See https://bugs.python.org/issue42522 #if !defined(_Py_StealRef) -static inline PyObject* __Py_StealRef(PyObject *obj) +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) +__Py_StealRef(PyObject *obj) { Py_DECREF(obj); return obj; @@ -77,7 +88,8 @@ static inline PyObject* __Py_StealRef(PyObject *obj) // See https://bugs.python.org/issue42522 #if !defined(_Py_XStealRef) -static inline PyObject* __Py_XStealRef(PyObject *obj) +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) +__Py_XStealRef(PyObject *obj) { Py_XDECREF(obj); return obj; @@ -88,7 +100,8 @@ static inline PyObject* __Py_XStealRef(PyObject *obj) // bpo-39573 added Py_SET_REFCNT() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_REFCNT) -static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) +PYCAPI_COMPAT_STATIC_INLINE(void) +_Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { ob->ob_refcnt = refcnt; } @@ -133,7 +146,7 @@ static inline void _Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) // bpo-39573 added Py_SET_TYPE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE) -static inline void +PYCAPI_COMPAT_STATIC_INLINE(void) _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { ob->ob_type = type; @@ -144,7 +157,7 @@ _Py_SET_TYPE(PyObject *ob, PyTypeObject *type) // bpo-39573 added Py_SET_SIZE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE) -static inline void +PYCAPI_COMPAT_STATIC_INLINE(void) _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { ob->ob_size = size; @@ -155,47 +168,49 @@ _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 -static inline PyCodeObject* +PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*) PyFrame_GetCode(PyFrameObject *frame) { - assert(frame != NULL); - assert(frame->f_code != NULL); - return (PyCodeObject*)Py_NewRef(frame->f_code); + assert(frame != PYCAPI_COMPAT_NULL); + assert(frame->f_code != PYCAPI_COMPAT_NULL); + return PYCAPI_COMPAT_CAST(PyCodeObject*, Py_NewRef(frame->f_code)); } #endif -static inline PyCodeObject* +PYCAPI_COMPAT_STATIC_INLINE(PyCodeObject*) _PyFrame_GetCodeBorrow(PyFrameObject *frame) { - return (PyCodeObject *)_Py_StealRef(PyFrame_GetCode(frame)); + return PYCAPI_COMPAT_CAST(PyCodeObject *, + _Py_StealRef(PyFrame_GetCode(frame))); } // bpo-40421 added PyFrame_GetCode() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -static inline PyFrameObject* +PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) PyFrame_GetBack(PyFrameObject *frame) { - assert(frame != NULL); - return (PyFrameObject*)Py_XNewRef(frame->f_back); + assert(frame != PYCAPI_COMPAT_NULL); + return PYCAPI_COMPAT_CAST(PyFrameObject*, Py_XNewRef(frame->f_back)); } #endif #if !defined(PYPY_VERSION) -static inline PyFrameObject* +PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) _PyFrame_GetBackBorrow(PyFrameObject *frame) { - return (PyFrameObject *)_Py_XStealRef(PyFrame_GetBack(frame)); + return PYCAPI_COMPAT_CAST(PyFrameObject *, + _Py_XStealRef(PyFrame_GetBack(frame))); } #endif // bpo-39947 added PyThreadState_GetInterpreter() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 -static inline PyInterpreterState * +PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState *) PyThreadState_GetInterpreter(PyThreadState *tstate) { - assert(tstate != NULL); + assert(tstate != PYCAPI_COMPAT_NULL); return tstate->interp; } #endif @@ -203,37 +218,38 @@ PyThreadState_GetInterpreter(PyThreadState *tstate) // bpo-40429 added PyThreadState_GetFrame() to Python 3.9.0b1 #if PY_VERSION_HEX < 0x030900B1 && !defined(PYPY_VERSION) -static inline PyFrameObject* +PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) PyThreadState_GetFrame(PyThreadState *tstate) { - assert(tstate != NULL); - return (PyFrameObject *)Py_XNewRef(tstate->frame); + assert(tstate != PYCAPI_COMPAT_NULL); + return PYCAPI_COMPAT_CAST(PyFrameObject *, Py_XNewRef(tstate->frame)); } #endif #if !defined(PYPY_VERSION) -static inline PyFrameObject* +PYCAPI_COMPAT_STATIC_INLINE(PyFrameObject*) _PyThreadState_GetFrameBorrow(PyThreadState *tstate) { - return (PyFrameObject *)_Py_XStealRef(PyThreadState_GetFrame(tstate)); + return PYCAPI_COMPAT_CAST(PyFrameObject*, + _Py_XStealRef(PyThreadState_GetFrame(tstate))); } #endif // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 -static inline PyInterpreterState * +PYCAPI_COMPAT_STATIC_INLINE(PyInterpreterState*) PyInterpreterState_Get(void) { PyThreadState *tstate; PyInterpreterState *interp; tstate = PyThreadState_GET(); - if (tstate == NULL) { + if (tstate == PYCAPI_COMPAT_NULL) { Py_FatalError("GIL released (tstate is NULL)"); } interp = tstate->interp; - if (interp == NULL) { + if (interp == PYCAPI_COMPAT_NULL) { Py_FatalError("no current interpreter"); } return interp; @@ -243,17 +259,18 @@ PyInterpreterState_Get(void) // bpo-39947 added PyInterpreterState_Get() to Python 3.9.0a6 #if 0x030700A1 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -static inline uint64_t +PYCAPI_COMPAT_STATIC_INLINE(uint64_t) PyThreadState_GetID(PyThreadState *tstate) { - assert(tstate != NULL); + assert(tstate != PYCAPI_COMPAT_NULL); return tstate->id; } #endif // bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2 #if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -static inline void PyThreadState_EnterTracing(PyThreadState *tstate) +PYCAPI_COMPAT_STATIC_INLINE(void) +PyThreadState_EnterTracing(PyThreadState *tstate) { tstate->tracing++; #if PY_VERSION_HEX >= 0x030A00A1 @@ -266,11 +283,12 @@ static inline void PyThreadState_EnterTracing(PyThreadState *tstate) // bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2 #if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION) -static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) +PYCAPI_COMPAT_STATIC_INLINE(void) +PyThreadState_LeaveTracing(PyThreadState *tstate) { + int use_tracing = (tstate->c_tracefunc != PYCAPI_COMPAT_NULL + || tstate->c_profilefunc != PYCAPI_COMPAT_NULL); tstate->tracing--; - int use_tracing = (tstate->c_tracefunc != NULL - || tstate->c_profilefunc != NULL); #if PY_VERSION_HEX >= 0x030A00A1 tstate->cframe->use_tracing = use_tracing; #else @@ -282,7 +300,7 @@ static inline void PyThreadState_LeaveTracing(PyThreadState *tstate) // bpo-37194 added PyObject_CallNoArgs() to Python 3.9.0a1 #if PY_VERSION_HEX < 0x030900A1 -static inline PyObject* +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) PyObject_CallNoArgs(PyObject *func) { return PyObject_CallFunctionObjArgs(func, NULL); @@ -293,7 +311,7 @@ PyObject_CallNoArgs(PyObject *func) // bpo-39245 made PyObject_CallOneArg() public (previously called // _PyObject_CallOneArg) in Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 -static inline PyObject* +PYCAPI_COMPAT_STATIC_INLINE(PyObject*) PyObject_CallOneArg(PyObject *func, PyObject *arg) { return PyObject_CallFunctionObjArgs(func, arg, NULL); @@ -303,12 +321,12 @@ PyObject_CallOneArg(PyObject *func, PyObject *arg) // bpo-1635741 added PyModule_AddObjectRef() to Python 3.10.0a3 #if PY_VERSION_HEX < 0x030A00A3 -static inline int -PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) +PYCAPI_COMPAT_STATIC_INLINE(int) +PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value) { int res; Py_XINCREF(value); - res = PyModule_AddObject(module, name, value); + res = PyModule_AddObject(mod, name, value); if (res < 0) { Py_XDECREF(value); } @@ -319,8 +337,8 @@ PyModule_AddObjectRef(PyObject *module, const char *name, PyObject *value) // bpo-40024 added PyModule_AddType() to Python 3.9.0a5 #if PY_VERSION_HEX < 0x030900A5 -static inline int -PyModule_AddType(PyObject *module, PyTypeObject *type) +PYCAPI_COMPAT_STATIC_INLINE(int) +PyModule_AddType(PyObject *mod, PyTypeObject *type) { const char *name, *dot; @@ -330,13 +348,13 @@ PyModule_AddType(PyObject *module, PyTypeObject *type) // inline _PyType_Name() name = type->tp_name; - assert(name != NULL); + assert(name != PYCAPI_COMPAT_NULL); dot = strrchr(name, '.'); - if (dot != NULL) { + if (dot != PYCAPI_COMPAT_NULL) { name = dot + 1; } - return PyModule_AddObjectRef(module, name, (PyObject *)type); + return PyModule_AddObjectRef(mod, name, _PyObject_CAST(type)); } #endif @@ -344,7 +362,7 @@ PyModule_AddType(PyObject *module, PyTypeObject *type) // bpo-40241 added PyObject_GC_IsTracked() to Python 3.9.0a6. // bpo-4688 added _PyObject_GC_IS_TRACKED() to Python 2.7.0a2. #if PY_VERSION_HEX < 0x030900A6 && !defined(PYPY_VERSION) -static inline int +PYCAPI_COMPAT_STATIC_INLINE(int) PyObject_GC_IsTracked(PyObject* obj) { return (PyObject_IS_GC(obj) && _PyObject_GC_IS_TRACKED(obj)); @@ -354,17 +372,18 @@ PyObject_GC_IsTracked(PyObject* obj) // bpo-40241 added PyObject_GC_IsFinalized() to Python 3.9.0a6. // bpo-18112 added _PyGCHead_FINALIZED() to Python 3.4.0 final. #if PY_VERSION_HEX < 0x030900A6 && PY_VERSION_HEX >= 0x030400F0 && !defined(PYPY_VERSION) -static inline int +PYCAPI_COMPAT_STATIC_INLINE(int) PyObject_GC_IsFinalized(PyObject *obj) { - return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED((PyGC_Head *)(obj)-1)); + PyGC_Head *gc = PYCAPI_COMPAT_CAST(PyGC_Head *, obj) - 1; + return (PyObject_IS_GC(obj) && _PyGCHead_FINALIZED(gc)); } #endif // bpo-39573 added Py_IS_TYPE() to Python 3.9.0a4 #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_IS_TYPE) -static inline int +PYCAPI_COMPAT_STATIC_INLINE(int) _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { return ob->ob_type == type; } @@ -382,11 +401,6 @@ _Py_IS_TYPE(const PyObject *ob, const PyTypeObject *type) { #endif -#ifdef PYTHONCAPI_COMPAT_MSC_INLINE -# undef inline -# undef PYTHONCAPI_COMPAT_MSC_INLINE -#endif - #ifdef __cplusplus } #endif diff --git a/mypyc/test-data/irbuild-basic.test b/mypyc/test-data/irbuild-basic.test index 2032ea034e71..5aa5e25487c4 100644 --- a/mypyc/test-data/irbuild-basic.test +++ b/mypyc/test-data/irbuild-basic.test @@ -909,20 +909,19 @@ L0: [case testDownCastSpecialCases] from typing import cast, Optional, Tuple class A: pass -def f(o: Optional[A], n: int, t: Tuple[int, ...]) -> None: +def f(o: Optional[A], n: int, t: Tuple[int, ...], tt: Tuple[int, int]) -> None: a = cast(A, o) m = cast(bool, n) - tt: Tuple[int, int] t = tt [out] -def f(o, n, t): +def f(o, n, t, tt): o :: union[__main__.A, None] n :: int t :: tuple + tt :: tuple[int, int] r0, a :: __main__.A r1 :: object r2, m :: bool - tt :: tuple[int, int] r3 :: object L0: r0 = cast(__main__.A, o) diff --git a/mypyc/test-data/irbuild-dict.test b/mypyc/test-data/irbuild-dict.test index 69dd42f01dd3..089a9a02b0b0 100644 --- a/mypyc/test-data/irbuild-dict.test +++ b/mypyc/test-data/irbuild-dict.test @@ -458,4 +458,3 @@ L2: L3: r7 = box(None, 1) return r7 - diff --git a/mypyc/test-data/run-multimodule.test b/mypyc/test-data/run-multimodule.test index 1444254b7595..20c9002cdf1d 100644 --- a/mypyc/test-data/run-multimodule.test +++ b/mypyc/test-data/run-multimodule.test @@ -1,4 +1,14 @@ --- These test cases compile two modules at a time (native and other.py) +-- These test cases compile two or more modules at a time. +-- Any file prefixed with "other" is compiled. +-- +-- Note that these are run in three compilation modes: regular, +-- multi-file and separate. See the docstrings of +-- mypyc.test.test_run.TestRunMultiFile and +-- mypyc.test.test_run.TestRunSeparate for more information. +-- +-- Some of these files perform multiple incremental runs. See +-- test-data/unit/check-incremental.test for more information +-- about how this is specified (e.g. .2 file name suffixes). [case testMultiModulePackage] from p.other import g diff --git a/mypyc/test/test_ircheck.py b/mypyc/test/test_ircheck.py index 28d3c8e8c25d..3c56ddac3e85 100644 --- a/mypyc/test/test_ircheck.py +++ b/mypyc/test/test_ircheck.py @@ -1,9 +1,15 @@ import unittest -from typing import List - -from mypyc.analysis.ircheck import check_func_ir, FnError -from mypyc.ir.rtypes import none_rprimitive -from mypyc.ir.ops import BasicBlock, Op, Return, Integer, Goto +from typing import List, Optional + +from mypyc.analysis.ircheck import check_func_ir, FnError, can_coerce_to +from mypyc.ir.class_ir import ClassIR +from mypyc.ir.rtypes import ( + none_rprimitive, str_rprimitive, int32_rprimitive, int64_rprimitive, + RType, RUnion, bytes_rprimitive, RInstance, object_rprimitive +) +from mypyc.ir.ops import ( + BasicBlock, Op, Return, Integer, Goto, Register, LoadLiteral, Assign +) from mypyc.ir.func_ir import FuncIR, FuncDecl, FuncSignature from mypyc.ir.pprint import format_func @@ -30,19 +36,33 @@ def basic_block(self, ops: List[Op]) -> BasicBlock: block.ops = ops return block - def func_decl(self, name: str) -> FuncDecl: - return FuncDecl(name=name, class_name=None, module_name="module", sig=FuncSignature( - args=[], ret_type=none_rprimitive, - )) + def func_decl(self, name: str, ret_type: Optional[RType] = None) -> FuncDecl: + if ret_type is None: + ret_type = none_rprimitive + return FuncDecl( + name=name, + class_name=None, + module_name="module", + sig=FuncSignature( + args=[], + ret_type=ret_type, + ), + ) def test_valid_fn(self) -> None: - assert_no_errors(FuncIR( - decl=self.func_decl(name="func_1"), - arg_regs=[], - blocks=[self.basic_block(ops=[ - Return(value=NONE_VALUE), - ])], - )) + assert_no_errors( + FuncIR( + decl=self.func_decl(name="func_1"), + arg_regs=[], + blocks=[ + self.basic_block( + ops=[ + Return(value=NONE_VALUE), + ] + ) + ], + ) + ) def test_block_not_terminated_empty_block(self) -> None: block = self.basic_block([]) @@ -73,7 +93,108 @@ def test_invalid_goto(self) -> None: # block_1 omitted blocks=[block_2], ) - assert_has_error(fn, FnError(source=goto, desc="Invalid control operation target: 1")) + assert_has_error( + fn, FnError(source=goto, desc="Invalid control operation target: 1") + ) + + def test_invalid_register_source(self) -> None: + ret = Return( + value=Register( + type=none_rprimitive, + name="r1", + ) + ) + block = self.basic_block([ret]) + fn = FuncIR( + decl=self.func_decl(name="func_1"), + arg_regs=[], + blocks=[block], + ) + assert_has_error( + fn, FnError(source=ret, desc="Invalid op reference to register r1") + ) + + def test_invalid_op_source(self) -> None: + ret = Return( + value=LoadLiteral( + value="foo", + rtype=str_rprimitive, + ) + ) + block = self.basic_block([ret]) + fn = FuncIR( + decl=self.func_decl(name="func_1"), + arg_regs=[], + blocks=[block], + ) + assert_has_error( + fn, + FnError(source=ret, desc="Invalid op reference to op of type LoadLiteral"), + ) + + def test_invalid_return_type(self) -> None: + ret = Return(value=Integer(value=5, rtype=int32_rprimitive)) + fn = FuncIR( + decl=self.func_decl(name="func_1", ret_type=int64_rprimitive), + arg_regs=[], + blocks=[self.basic_block([ret])], + ) + assert_has_error( + fn, + FnError( + source=ret, desc="Cannot coerce source type int32 to dest type int64" + ), + ) + + def test_invalid_assign(self) -> None: + arg_reg = Register(type=int64_rprimitive, name="r1") + assign = Assign(dest=arg_reg, src=Integer(value=5, rtype=int32_rprimitive)) + ret = Return(value=NONE_VALUE) + fn = FuncIR( + decl=self.func_decl(name="func_1"), + arg_regs=[arg_reg], + blocks=[self.basic_block([assign, ret])], + ) + assert_has_error( + fn, + FnError( + source=assign, desc="Cannot coerce source type int32 to dest type int64" + ), + ) + + def test_can_coerce_to(self) -> None: + cls = ClassIR(name="Cls", module_name="cls") + valid_cases = [ + (int64_rprimitive, int64_rprimitive), + (str_rprimitive, str_rprimitive), + (str_rprimitive, object_rprimitive), + (object_rprimitive, str_rprimitive), + (RUnion([bytes_rprimitive, str_rprimitive]), str_rprimitive), + (str_rprimitive, RUnion([bytes_rprimitive, str_rprimitive])), + (RInstance(cls), object_rprimitive), + ] + + invalid_cases = [ + (int64_rprimitive, int32_rprimitive), + (RInstance(cls), str_rprimitive), + (str_rprimitive, bytes_rprimitive), + ] + + for src, dest in valid_cases: + assert can_coerce_to(src, dest) + for src, dest in invalid_cases: + assert not can_coerce_to(src, dest) + + def test_duplicate_op(self) -> None: + arg_reg = Register(type=int32_rprimitive, name="r1") + assign = Assign(dest=arg_reg, src=Integer(value=5, rtype=int32_rprimitive)) + block = self.basic_block([assign, assign, Return(value=NONE_VALUE)]) + fn = FuncIR( + decl=self.func_decl(name="func_1"), + arg_regs=[], + blocks=[block], + ) + assert_has_error(fn, FnError(source=assign, desc="Func has a duplicate op")) def test_pprint(self) -> None: block_1 = self.basic_block([Return(value=NONE_VALUE)]) diff --git a/mypyc/test/test_run.py b/mypyc/test/test_run.py index 306c151ef319..a5e356ea56a6 100644 --- a/mypyc/test/test_run.py +++ b/mypyc/test/test_run.py @@ -127,7 +127,7 @@ class TestRun(MypycDataSuite): base_path = test_temp_dir optional_out = True multi_file = False - separate = False + separate = False # If True, using separate (incremental) compilation def run_case(self, testcase: DataDrivenTestCase) -> None: # setup.py wants to be run from the root directory of the package, which we accommodate @@ -347,7 +347,11 @@ def get_separate(self, program_text: str, class TestRunMultiFile(TestRun): - """Run the main multi-module tests in multi-file compilation mode.""" + """Run the main multi-module tests in multi-file compilation mode. + + In multi-file mode each module gets compiled into a separate C file, + but all modules (C files) are compiled together. + """ multi_file = True test_name_suffix = '_multi' @@ -358,7 +362,20 @@ class TestRunMultiFile(TestRun): class TestRunSeparate(TestRun): - """Run the main multi-module tests in separate compilation mode.""" + """Run the main multi-module tests in separate compilation mode. + + In this mode there are multiple compilation groups, which are compiled + incrementally. Each group is compiled to a separate C file, and these C + files are compiled separately. + + Each compiled module is placed into a separate compilation group, unless + overridden by a special comment. Consider this example: + + # separate: [(["other.py", "other_b.py"], "stuff")] + + This puts other.py and other_b.py into a compilation group named "stuff". + Any files not mentioned in the comment will get single-file groups. + """ separate = True test_name_suffix = '_separate' diff --git a/test-data/unit/check-attr.test b/test-data/unit/check-attr.test index 083feb0152e5..7905f1add6ca 100644 --- a/test-data/unit/check-attr.test +++ b/test-data/unit/check-attr.test @@ -1465,3 +1465,93 @@ class C: self.b = 1 # E: Trying to assign name "b" that is not in "__slots__" of type "__main__.C" self.c = 2 # E: Trying to assign name "c" that is not in "__slots__" of type "__main__.C" [builtins fixtures/attr.pyi] + +[case testAttrsWithMatchArgs] +# flags: --python-version 3.10 +import attr + +@attr.s(match_args=True, auto_attribs=True) +class ToMatch: + x: int + y: int + # Not included: + z: int = attr.field(kw_only=True) + i: int = attr.field(init=False) + +reveal_type(ToMatch(x=1, y=2, z=3).__match_args__) # N: Revealed type is "Tuple[Literal['x']?, Literal['y']?]" +reveal_type(ToMatch(1, 2, z=3).__match_args__) # N: Revealed type is "Tuple[Literal['x']?, Literal['y']?]" +[builtins fixtures/attr.pyi] + +[case testAttrsWithMatchArgsDefaultCase] +# flags: --python-version 3.10 +import attr + +@attr.s(auto_attribs=True) +class ToMatch1: + x: int + y: int + +t1: ToMatch1 +reveal_type(t1.__match_args__) # N: Revealed type is "Tuple[Literal['x']?, Literal['y']?]" + +@attr.define +class ToMatch2: + x: int + y: int + +t2: ToMatch2 +reveal_type(t2.__match_args__) # N: Revealed type is "Tuple[Literal['x']?, Literal['y']?]" +[builtins fixtures/attr.pyi] + +[case testAttrsWithMatchArgsOverrideExisting] +# flags: --python-version 3.10 +import attr +from typing import Final + +@attr.s(match_args=True, auto_attribs=True) +class ToMatch: + __match_args__: Final = ('a', 'b') + x: int + y: int + +# It works the same way runtime does: +reveal_type(ToMatch(x=1, y=2).__match_args__) # N: Revealed type is "Tuple[Literal['a']?, Literal['b']?]" + +@attr.s(auto_attribs=True) +class WithoutMatch: + __match_args__: Final = ('a', 'b') + x: int + y: int + +reveal_type(WithoutMatch(x=1, y=2).__match_args__) # N: Revealed type is "Tuple[Literal['a']?, Literal['b']?]" +[builtins fixtures/attr.pyi] + +[case testAttrsWithMatchArgsOldVersion] +# flags: --python-version 3.9 +import attr + +@attr.s(match_args=True) +class NoMatchArgs: + ... + +n: NoMatchArgs + +reveal_type(n.__match_args__) # E: "NoMatchArgs" has no attribute "__match_args__" \ + # N: Revealed type is "Any" +[builtins fixtures/attr.pyi] + +[case testAttrsMultipleInheritance] +# flags: --python-version 3.10 +import attr + +@attr.s +class A: + x = attr.ib(type=int) + +@attr.s +class B: + y = attr.ib(type=int) + +class AB(A, B): + pass +[builtins fixtures/attr.pyi] diff --git a/test-data/unit/check-classes.test b/test-data/unit/check-classes.test index a2bcdade3287..65b0e8d69cb5 100644 --- a/test-data/unit/check-classes.test +++ b/test-data/unit/check-classes.test @@ -7134,3 +7134,153 @@ class B(A): # E: Final class __main__.B has abstract attributes "foo" [case testUndefinedBaseclassInNestedClass] class C: class C1(XX): pass # E: Name "XX" is not defined + +[case testClassScopeImports] +class Foo: + from mod import plain_function # E: Unsupported class scoped import + from mod import plain_var + +reveal_type(Foo.plain_function) # N: Revealed type is "Any" +reveal_type(Foo().plain_function) # N: Revealed type is "Any" + +reveal_type(Foo.plain_var) # N: Revealed type is "builtins.int" +reveal_type(Foo().plain_var) # N: Revealed type is "builtins.int" + +[file mod.py] +def plain_function(x: int, y: int) -> int: ... +plain_var: int + +[case testClassScopeImportModule] +class Foo: + import mod + +reveal_type(Foo.mod) # N: Revealed type is "builtins.object" +reveal_type(Foo.mod.foo) # N: Revealed type is "builtins.int" +[file mod.py] +foo: int + +[case testClassScopeImportAlias] +class Foo: + from mod import function # E: Unsupported class scoped import + foo = function + + from mod import var1 + bar = var1 + + from mod import var2 + baz = var2 + + from mod import var3 + qux = var3 + +reveal_type(Foo.foo) # N: Revealed type is "Any" +reveal_type(Foo.function) # N: Revealed type is "Any" + +reveal_type(Foo.bar) # N: Revealed type is "builtins.int" +reveal_type(Foo.var1) # N: Revealed type is "builtins.int" + +reveal_type(Foo.baz) # N: Revealed type is "mod.C" +reveal_type(Foo.var2) # N: Revealed type is "mod.C" + +reveal_type(Foo.qux) # N: Revealed type is "builtins.int" +reveal_type(Foo.var3) # N: Revealed type is "builtins.int" + +[file mod.py] +def function(x: int, y: int) -> int: ... +var1: int + +class C: ... +var2: C + +A = int +var3: A + + +[case testClassScopeImportModuleStar] +class Foo: + from mod import * # E: Unsupported class scoped import + +reveal_type(Foo.foo) # N: Revealed type is "builtins.int" +reveal_type(Foo.bar) # N: Revealed type is "Any" +reveal_type(Foo.baz) # E: "Type[Foo]" has no attribute "baz" \ + # N: Revealed type is "Any" + +[file mod.py] +foo: int +def bar(x: int) -> int: ... + +[case testClassScopeImportFunctionNested] +class Foo: + class Bar: + from mod import baz # E: Unsupported class scoped import + +reveal_type(Foo.Bar.baz) # N: Revealed type is "Any" +reveal_type(Foo.Bar().baz) # N: Revealed type is "Any" + +[file mod.py] +def baz(x: int) -> int: ... + +[case testClassScopeImportUndefined] +class Foo: + from unknown import foo # E: Cannot find implementation or library stub for module named "unknown" \ + # N: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports + +reveal_type(Foo.foo) # N: Revealed type is "Any" +reveal_type(Foo().foo) # N: Revealed type is "Any" + +[case testClassScopeImportWithFollowImports] +# flags: --follow-imports=skip +class Foo: + from mod import foo + +reveal_type(Foo().foo) # N: Revealed type is "Any" +[file mod.py] +def foo(x: int, y: int) -> int: ... + +[case testClassScopeImportVarious] +class Foo: + from mod1 import foo # E: Unsupported class scoped import + from mod2 import foo + + from mod1 import meth1 # E: Unsupported class scoped import + def meth1(self, a: str) -> str: ... # E: Name "meth1" already defined on line 5 + + def meth2(self, a: str) -> str: ... + from mod1 import meth2 # E: Unsupported class scoped import \ + # E: Name "meth2" already defined on line 8 + +class Bar: + from mod1 import foo # E: Unsupported class scoped import + +import mod1 +reveal_type(Foo.foo) # N: Revealed type is "Any" +reveal_type(Bar.foo) # N: Revealed type is "Any" +reveal_type(mod1.foo) # N: Revealed type is "def (x: builtins.int, y: builtins.int) -> builtins.int" + +[file mod1.py] +def foo(x: int, y: int) -> int: ... +def meth1(x: int) -> int: ... +def meth2(x: int) -> int: ... +[file mod2.py] +def foo(z: str) -> int: ... + + +[case testClassScopeImportWithError] +class Foo: + from mod import meth1 # E: Unsupported class scoped import + from mod import meth2 # E: Unsupported class scoped import + from mod import T + +reveal_type(Foo.T) # E: Type variable "Foo.T" cannot be used as an expression \ + # N: Revealed type is "Any" + +[file mod.pyi] +from typing import Any, TypeVar, overload + +@overload +def meth1(self: Any, y: int) -> int: ... +@overload +def meth1(self: Any, y: str) -> str: ... + +T = TypeVar("T") +def meth2(self: Any, y: T) -> T: ... diff --git a/test-data/unit/check-dataclasses.test b/test-data/unit/check-dataclasses.test index eed329bb59c7..1773ac0eac8d 100644 --- a/test-data/unit/check-dataclasses.test +++ b/test-data/unit/check-dataclasses.test @@ -1536,3 +1536,19 @@ A(a=1, b=2) A(1) A(a="foo") # E: Argument "a" to "A" has incompatible type "str"; expected "int" [builtins fixtures/dataclasses.pyi] + +[case testDataclassesMultipleInheritanceWithNonDataclass] +# flags: --python-version 3.10 +from dataclasses import dataclass + +@dataclass +class A: + prop_a: str + +@dataclass +class B: + prop_b: bool + +class Derived(A, B): + pass +[builtins fixtures/dataclasses.pyi] diff --git a/test-data/unit/check-enum.test b/test-data/unit/check-enum.test index 2af57da9cbdc..9e2b38bd9c8d 100644 --- a/test-data/unit/check-enum.test +++ b/test-data/unit/check-enum.test @@ -232,6 +232,20 @@ an_enum = SomeIntEnum.x an_enum = returns_some_int_enum() [out] +[case testStrEnumCreation] +# flags: --python-version 3.11 +from enum import StrEnum + +class MyStrEnum(StrEnum): + x = 'x' + y = 'y' + +reveal_type(MyStrEnum.x) # N: Revealed type is "Literal[__main__.MyStrEnum.x]?" +reveal_type(MyStrEnum.x.value) # N: Revealed type is "Literal['x']?" +reveal_type(MyStrEnum.y) # N: Revealed type is "Literal[__main__.MyStrEnum.y]?" +reveal_type(MyStrEnum.y.value) # N: Revealed type is "Literal['y']?" +[out] + [case testEnumMethods] from enum import Enum @@ -1391,9 +1405,9 @@ class E(Enum): e: E a: Literal[E.A, E.B, E.C] = e -b: Literal[E.A, E.B] = e # E: Incompatible types in assignment (expression has type "E", variable has type "Union[Literal[E.A], Literal[E.B]]") -c: Literal[E.A, E.C] = e # E: Incompatible types in assignment (expression has type "E", variable has type "Union[Literal[E.A], Literal[E.C]]") -b = a # E: Incompatible types in assignment (expression has type "Union[Literal[E.A], Literal[E.B], Literal[E.C]]", variable has type "Union[Literal[E.A], Literal[E.B]]") +b: Literal[E.A, E.B] = e # E: Incompatible types in assignment (expression has type "E", variable has type "Literal[E.A, E.B]") +c: Literal[E.A, E.C] = e # E: Incompatible types in assignment (expression has type "E", variable has type "Literal[E.A, E.C]") +b = a # E: Incompatible types in assignment (expression has type "Literal[E.A, E.B, E.C]", variable has type "Literal[E.A, E.B]") [builtins fixtures/bool.pyi] [case testIntEnumWithNewTypeValue] @@ -1868,3 +1882,201 @@ class WithOverload(enum.IntEnum): class SubWithOverload(WithOverload): # Should pass pass [builtins fixtures/tuple.pyi] + +[case testEnumBaseClassesOrder] +import enum + +# Base types: + +class First: + def __new__(cls, val): + pass + +class Second: + def __new__(cls, val): + pass + +class Third: + def __new__(cls, val): + pass + +class Mixin: + pass + +# Correct Enums: + +class Correct0(enum.Enum): + pass + +class Correct1(Mixin, First, enum.Enum): + pass + +class Correct2(First, enum.Enum): + pass + +class Correct3(Mixin, enum.Enum): + pass + +class RegularClass(Mixin, First, Second): + pass + +# Correct inheritance: + +class _InheritingDataAndMixin(Correct1): + pass + +class _CorrectWithData(First, Correct0): + pass + +class _CorrectWithDataAndMixin(Mixin, First, Correct0): + pass + +class _CorrectWithMixin(Mixin, Correct2): + pass + +# Wrong Enums: + +class TwoDataTypesViaInheritance(Second, Correct2): # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Correct2" + pass + +class TwoDataTypesViaInheritanceAndMixin(Second, Correct2, Mixin): # E: No base classes are allowed after "__main__.Correct2" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Correct2" + pass + +class MixinAfterEnum1(enum.Enum, Mixin): # E: No base classes are allowed after "enum.Enum" + pass + +class MixinAfterEnum2(First, enum.Enum, Mixin): # E: No base classes are allowed after "enum.Enum" + pass + +class TwoDataTypes(First, Second, enum.Enum): # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" + pass + +class TwoDataTypesAndIntEnumMixin(First, Second, enum.IntEnum, Mixin): # E: No base classes are allowed after "enum.IntEnum" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" + pass + +class ThreeDataTypes(First, Second, Third, enum.Enum): # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Third" + pass + +class ThreeDataTypesAndMixin(First, Second, Third, enum.Enum, Mixin): # E: No base classes are allowed after "enum.Enum" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Third" + pass + +class FromEnumAndOther1(Correct2, Second, enum.Enum): # E: No base classes are allowed after "__main__.Correct2" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" + pass + +class FromEnumAndOther2(Correct2, Second): # E: No base classes are allowed after "__main__.Correct2" \ + # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.Second" + pass +[builtins fixtures/tuple.pyi] + +[case testRegression12258] +from enum import Enum + +class MyEnum(Enum): ... + +class BytesEnum(bytes, MyEnum): ... # Should be ok +[builtins fixtures/tuple.pyi] + +[case testEnumWithNewHierarchy] +import enum + +class A: + def __new__(cls, val): ... +class B(A): + def __new__(cls, val): ... +class C: + def __new__(cls, val): ... + +class E1(A, enum.Enum): ... +class E2(B, enum.Enum): ... + +# Errors: + +class W1(C, E1): ... # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.E1" +class W2(C, E2): ... # E: Only a single data type mixin is allowed for Enum subtypes, found extra "__main__.E2" +[builtins fixtures/tuple.pyi] + +[case testEnumValueUnionSimplification] +from enum import IntEnum +from typing import Any + +class C(IntEnum): + X = 0 + Y = 1 + Z = 2 + +def f1(c: C) -> None: + x = {'x': c.value} + reveal_type(x) # N: Revealed type is "builtins.dict[builtins.str*, builtins.int]" + +def f2(c: C, a: Any) -> None: + x = {'x': c.value, 'y': a} + reveal_type(x) # N: Revealed type is "builtins.dict[builtins.str*, Any]" + y = {'y': a, 'x': c.value} + reveal_type(y) # N: Revealed type is "builtins.dict[builtins.str*, Any]" +[builtins fixtures/dict.pyi] + +[case testEnumIgnoreIsDeleted] +from enum import Enum + +class C(Enum): + _ignore_ = 'X' + +C._ignore_ # E: "Type[C]" has no attribute "_ignore_" +[typing fixtures/typing-medium.pyi] + +[case testCanOverrideDunderAttributes] +import typing +from enum import Enum, Flag + +class BaseEnum(Enum): + __dunder__ = 1 + __labels__: typing.Dict[int, str] + +class Override(BaseEnum): + __dunder__ = 2 + __labels__ = {1: "1"} + +Override.__dunder__ = 3 +BaseEnum.__dunder__ = 3 +Override.__labels__ = {2: "2"} + +class FlagBase(Flag): + __dunder__ = 1 + __labels__: typing.Dict[int, str] + +class FlagOverride(FlagBase): + __dunder__ = 2 + __labels = {1: "1"} + +FlagOverride.__dunder__ = 3 +FlagBase.__dunder__ = 3 +FlagOverride.__labels__ = {2: "2"} +[builtins fixtures/dict.pyi] + +[case testCanNotInitialize__members__] +import typing +from enum import Enum + +class WritingMembers(Enum): + __members__: typing.Dict[Enum, Enum] = {} # E: Assigned "__members__" will be overriden by "Enum" internally + +class OnlyAnnotatedMembers(Enum): + __members__: typing.Dict[Enum, Enum] +[builtins fixtures/dict.pyi] + +[case testCanOverrideDunderOnNonFirstBaseEnum] +import typing +from enum import Enum + +class Some: + __labels__: typing.Dict[int, str] + +class A(Some, Enum): + __labels__ = {1: "1"} +[builtins fixtures/dict.pyi] diff --git a/test-data/unit/check-errorcodes.test b/test-data/unit/check-errorcodes.test index 568d3a9522f9..a74771108ca2 100644 --- a/test-data/unit/check-errorcodes.test +++ b/test-data/unit/check-errorcodes.test @@ -75,41 +75,51 @@ for v in f(): # type: int, int # E: Syntax error in type annotation [syntax] [case testErrorCodeIgnore1] 'x'.foobar # type: ignore[attr-defined] -'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] +'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment 'x'.foobar # type: ignore [case testErrorCodeIgnore2] a = 'x'.foobar # type: int # type: ignore[attr-defined] -b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] +b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment c = 'x'.foobar # type: int # type: ignore [case testErrorCodeIgnore1_python2] 'x'.foobar # type: ignore[attr-defined] -'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] +'x'.foobar # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment 'x'.foobar # type: ignore [case testErrorCodeIgnore2_python2] a = 'x'.foobar # type: int # type: ignore[attr-defined] -b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] +b = 'x'.foobar # type: int # type: ignore[xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment c = 'x'.foobar # type: int # type: ignore [case testErrorCodeIgnoreMultiple1] a = 'x'.foobar(b) # type: ignore[name-defined, attr-defined] -a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] -a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] +a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment +a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment [case testErrorCodeIgnoreMultiple2] a = 'x'.foobar(b) # type: int # type: ignore[name-defined, attr-defined] -b = 'x'.foobar(b) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] +b = 'x'.foobar(b) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment [case testErrorCodeIgnoreMultiple1_python2] a = 'x'.foobar(b) # type: ignore[name-defined, attr-defined] -a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] -a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] +a = 'x'.foobar(b) # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment +a = 'x'.foobar(b) # type: ignore[xyz, w, attr-defined] # E: Name "b" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment [case testErrorCodeIgnoreMultiple2_python2] a = 'x'.foobar(b) # type: int # type: ignore[name-defined, attr-defined] -b = 'x'.foobar(b) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] +b = 'x'.foobar(b) # type: int # type: ignore[name-defined, xyz] # E: "str" has no attribute "foobar" [attr-defined] \ + # N: Error code "attr-defined" not covered by "type: ignore" comment [case testErrorCodeWarnUnusedIgnores1] # flags: --warn-unused-ignores @@ -135,21 +145,58 @@ x # type: ignore[name-defined, attr-defined] # E: Unused "type: ignore[attr-defi # flags: --warn-unused-ignores "x" # type: ignore[name-defined] # E: Unused "type: ignore" comment +[case testErrorCodeMissingWhenRequired] +# flags: --enable-error-code ignore-without-code +"x" # type: ignore # E: "type: ignore" comment without error code [ignore-without-code] +y # type: ignore # E: "type: ignore" comment without error code (consider "type: ignore[name-defined]" instead) [ignore-without-code] +z # type: ignore[name-defined] +"a" # type: ignore[ignore-without-code] + +[case testErrorCodeMissingDoesntTrampleUnusedIgnoresWarning] +# flags: --enable-error-code ignore-without-code --warn-unused-ignores +"x" # type: ignore # E: Unused "type: ignore" comment +"y" # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment +z # type: ignore[ignore-without-code] # E: Unused "type: ignore" comment # E: Name "z" is not defined [name-defined] # N: Error code "name-defined" not covered by "type: ignore" comment + +[case testErrorCodeMissingWholeFileIgnores] +# 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 + +[case testErrorCodeMissingMultiple] +# flags: --enable-error-code ignore-without-code --python-version 3.7 +from __future__ import annotations +class A: + attr: int + def func(self, var: int) -> A | None: ... + +a: A | None +# 'union-attr' should only be listed once (instead of twice) and list should be sorted +a.func("invalid string").attr # type: ignore # E: "type: ignore" comment without error code (consider "type: ignore[arg-type, union-attr]" instead) [ignore-without-code] +[builtins fixtures/tuple.pyi] + [case testErrorCodeIgnoreWithExtraSpace] x # type: ignore [name-defined] x2 # type: ignore [ name-defined ] x3 # type: ignore [ xyz , name-defined ] x4 # type: ignore[xyz,name-defined] -y # type: ignore [xyz] # E: Name "y" is not defined [name-defined] -y # type: ignore[ xyz ] # E: Name "y" is not defined [name-defined] -y # type: ignore[ xyz , foo ] # E: Name "y" is not defined [name-defined] +y # type: ignore [xyz] # E: Name "y" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment +y # type: ignore[ xyz ] # E: Name "y" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment +y # type: ignore[ xyz , foo ] # E: Name "y" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment a = z # type: int # type: ignore [name-defined] b = z2 # type: int # type: ignore [ name-defined ] c = z2 # type: int # type: ignore [ name-defined , xyz ] -d = zz # type: int # type: ignore [xyz] # E: Name "zz" is not defined [name-defined] -e = zz # type: int # type: ignore [ xyz ] # E: Name "zz" is not defined [name-defined] -f = zz # type: int # type: ignore [ xyz,foo ] # E: Name "zz" is not defined [name-defined] +d = zz # type: int # type: ignore [xyz] # E: Name "zz" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment +e = zz # type: int # type: ignore [ xyz ] # E: Name "zz" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment +f = zz # type: int # type: ignore [ xyz,foo ] # E: Name "zz" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment [case testErrorCodeIgnoreAfterArgComment] def f(x # type: xyz # type: ignore[name-defined] # Comment @@ -162,7 +209,8 @@ def g(x # type: xyz # type: ignore # Comment # type () -> None pass -def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] +def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment ): # type () -> None pass @@ -178,7 +226,8 @@ def g(x # type: xyz # type: ignore # Comment # type () -> None pass -def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] +def h(x # type: xyz # type: ignore[foo] # E: Name "xyz" is not defined [name-defined] \ + # N: Error code "name-defined" not covered by "type: ignore" comment ): # type () -> None pass @@ -944,3 +993,20 @@ class TensorType: ... t: TensorType["batch":..., float] # type: ignore reveal_type(t) # N: Revealed type is "__main__.TensorType" [builtins fixtures/tuple.pyi] + +[case testNoteAboutChangedTypedDictErrorCode] +from typing_extensions import TypedDict +class D(TypedDict): + x: int + +def f(d: D, s: str) -> None: + d[s] # type: ignore[xyz] \ + # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ + # N: Error code "literal-required" not covered by "type: ignore" comment + d[s] # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] + d[s] # type: ignore[misc] \ + # E: TypedDict key must be a string literal; expected one of ("x") [literal-required] \ + # N: Error code changed to literal-required; "type: ignore" comment may be out of date + d[s] # type: ignore[literal-required] +[builtins fixtures/dict.pyi] +[typing fixtures/typing-typeddict.pyi] diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index a275de94c9be..46f0cf02a125 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -202,6 +202,70 @@ class C: pass [builtins fixtures/tuple.pyi] +[case testDivPython2] +# flags: --python-version 2.7 +class A(object): + def __div__(self, other): + # type: (A, str) -> str + return 'a' + +a = A() +reveal_type(a / 'b') # N: Revealed type is "builtins.str" +a / 1 # E: Unsupported operand types for / ("A" and "int") +[builtins fixtures/bool.pyi] + +[case testDivPython2FutureImport] +# flags: --python-version 2.7 +from __future__ import division + +class A(object): + def __truediv__(self, other): + # type: (A, str) -> str + return 'a' + +a = A() +reveal_type(a / 'b') # N: Revealed type is "builtins.str" +a / 1 # E: Unsupported operand types for / ("A" and "int") +[builtins fixtures/bool.pyi] + +[case testDivPython2FutureImportNotLeaking] +# flags: --python-version 2.7 +import m1 + +[file m1.py] +import m2 + +class A(object): + def __div__(self, other): + # type: (A, str) -> str + return 'a' + +a = A() +reveal_type(a / 'b') # N: Revealed type is "builtins.str" +a / 1 # E: Unsupported operand types for / ("A" and "int") +[file m2.py] +from __future__ import division +[builtins fixtures/bool.pyi] + +[case testDivPython2FutureImportNotLeaking2] +# flags: --python-version 2.7 +import m1 + +[file m1.py] +import m2 + +class A(object): + def __div__(self, other): + # type: (A, str) -> str + return 'a' + +a = A() +reveal_type(a / 'b') # N: Revealed type is "builtins.str" +a / 1 # E: Unsupported operand types for / ("A" and "int") +[file m2.py] +# empty +[builtins fixtures/bool.pyi] + [case testIntDiv] a, b, c = None, None, None # type: (A, B, C) if int(): @@ -1688,6 +1752,22 @@ main:1: note: Revealed type is "Any" def reveal_type(x: int) -> None: pass reveal_type("foo") # E: Argument 1 to "reveal_type" has incompatible type "str"; expected "int" +[case testTypingRevealType] +from typing import reveal_type +from typing import reveal_type as show_me_the_type + +reveal_type(1) # N: Revealed type is "Literal[1]?" +show_me_the_type(1) # N: Revealed type is "Literal[1]?" + +[case testTypingExtensionsRevealType] +from typing_extensions import reveal_type +from typing_extensions import reveal_type as show_me_the_type + +reveal_type(1) # N: Revealed type is "Literal[1]?" +show_me_the_type(1) # N: Revealed type is "Literal[1]?" + +[builtins fixtures/tuple.pyi] + [case testRevealTypeVar] reveal_type = 1 1 + "foo" # E: Unsupported operand types for + ("int" and "str") @@ -2137,9 +2217,9 @@ def returns_1_or_2() -> Literal[1, 2]: ... THREE: Final = 3 -if returns_a_or_b() == 'c': # E: Non-overlapping equality check (left operand type: "Union[Literal['a'], Literal['b']]", right operand type: "Literal['c']") +if returns_a_or_b() == 'c': # E: Non-overlapping equality check (left operand type: "Literal['a', 'b']", right operand type: "Literal['c']") ... -if returns_1_or_2() is THREE: # E: Non-overlapping identity check (left operand type: "Union[Literal[1], Literal[2]]", right operand type: "Literal[3]") +if returns_1_or_2() is THREE: # E: Non-overlapping identity check (left operand type: "Literal[1, 2]", right operand type: "Literal[3]") ... [builtins fixtures/bool.pyi] diff --git a/test-data/unit/check-functions.test b/test-data/unit/check-functions.test index bdf75b2dc58c..30150ca436e8 100644 --- a/test-data/unit/check-functions.test +++ b/test-data/unit/check-functions.test @@ -2605,3 +2605,13 @@ def foo() -> None: pass reveal_type(foo()) # N: Revealed type is "None" + +[case testAnyArgument] +def a(b: any): pass # E: Function "builtins.any" is not valid as a type \ + # N: Perhaps you meant "typing.Any" instead of "any"? +[builtins fixtures/any.pyi] + +[case testCallableArgument] +def a(b: callable): pass # E: Function "builtins.callable" is not valid as a type \ + # N: Perhaps you meant "typing.Callable" instead of "callable"? +[builtins fixtures/callable.pyi] diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index f531947d1faf..64c1a2aad3cb 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -2390,8 +2390,8 @@ class B: def t3(self) -> None: if isinstance(self, (A1, A2)): reveal_type(self) # N: Revealed type is "Union[__main__.2, __main__.]" - x0: Literal[0] = self.f() # E: Incompatible types in assignment (expression has type "Union[Literal[1], Literal[2]]", variable has type "Literal[0]") - x1: Literal[1] = self.f() # E: Incompatible types in assignment (expression has type "Union[Literal[1], Literal[2]]", variable has type "Literal[1]") + x0: Literal[0] = self.f() # E: Incompatible types in assignment (expression has type "Literal[1, 2]", variable has type "Literal[0]") + x1: Literal[1] = self.f() # E: Incompatible types in assignment (expression has type "Literal[1, 2]", variable has type "Literal[1]") [builtins fixtures/isinstance.pyi] diff --git a/test-data/unit/check-kwargs.test b/test-data/unit/check-kwargs.test index 7f0b8af3ba0e..9f8de1265ee7 100644 --- a/test-data/unit/check-kwargs.test +++ b/test-data/unit/check-kwargs.test @@ -350,12 +350,15 @@ class A: pass [builtins fixtures/dict.pyi] [case testInvalidTypeForKeywordVarArg] -from typing import Dict +# flags: --strict-optional +from typing import Dict, Any, Optional def f(**kwargs: 'A') -> None: pass -d = None # type: Dict[A, A] +d = {} # type: Dict[A, A] f(**d) # E: Keywords must be strings f(**A()) # E: Argument after ** must be a mapping, not "A" class A: pass +kwargs: Optional[Any] +f(**kwargs) # E: Argument after ** must be a mapping, not "Optional[Any]" [builtins fixtures/dict.pyi] [case testPassingKeywordVarArgsToNonVarArgsFunction] diff --git a/test-data/unit/check-literal.test b/test-data/unit/check-literal.test index 37ae12419151..3886d3c39edd 100644 --- a/test-data/unit/check-literal.test +++ b/test-data/unit/check-literal.test @@ -846,7 +846,7 @@ def func(x: Literal['foo', 'bar', ' foo ']) -> None: ... func('foo') func('bar') func(' foo ') -func('baz') # E: Argument 1 to "func" has incompatible type "Literal['baz']"; expected "Union[Literal['foo'], Literal['bar'], Literal[' foo ']]" +func('baz') # E: Argument 1 to "func" has incompatible type "Literal['baz']"; expected "Literal['foo', 'bar', ' foo ']" a: Literal['foo'] b: Literal['bar'] @@ -860,7 +860,7 @@ func(b) func(c) func(d) func(e) -func(f) # E: Argument 1 to "func" has incompatible type "Union[Literal['foo'], Literal['bar'], Literal['baz']]"; expected "Union[Literal['foo'], Literal['bar'], Literal[' foo ']]" +func(f) # E: Argument 1 to "func" has incompatible type "Literal['foo', 'bar', 'baz']"; expected "Literal['foo', 'bar', ' foo ']" [builtins fixtures/tuple.pyi] [out] @@ -1129,8 +1129,8 @@ d: int foo(a) foo(b) -foo(c) # E: Argument 1 to "foo" has incompatible type "Union[Literal[4], Literal[5]]"; expected "Union[Literal[1], Literal[2], Literal[3]]" -foo(d) # E: Argument 1 to "foo" has incompatible type "int"; expected "Union[Literal[1], Literal[2], Literal[3]]" +foo(c) # E: Argument 1 to "foo" has incompatible type "Literal[4, 5]"; expected "Literal[1, 2, 3]" +foo(d) # E: Argument 1 to "foo" has incompatible type "int"; expected "Literal[1, 2, 3]" [builtins fixtures/tuple.pyi] [out] @@ -1144,7 +1144,7 @@ c: Literal[4, 'foo'] foo(a) foo(b) -foo(c) # E: Argument 1 to "foo" has incompatible type "Union[Literal[4], Literal['foo']]"; expected "int" +foo(c) # E: Argument 1 to "foo" has incompatible type "Literal[4, 'foo']"; expected "int" [builtins fixtures/tuple.pyi] [out] @@ -1248,19 +1248,19 @@ class Contravariant(Generic[T_contra]): pass a1: Invariant[Literal[1]] a2: Invariant[Literal[1, 2]] a3: Invariant[Literal[1, 2, 3]] -a2 = a1 # E: Incompatible types in assignment (expression has type "Invariant[Literal[1]]", variable has type "Invariant[Union[Literal[1], Literal[2]]]") -a2 = a3 # E: Incompatible types in assignment (expression has type "Invariant[Union[Literal[1], Literal[2], Literal[3]]]", variable has type "Invariant[Union[Literal[1], Literal[2]]]") +a2 = a1 # E: Incompatible types in assignment (expression has type "Invariant[Literal[1]]", variable has type "Invariant[Literal[1, 2]]") +a2 = a3 # E: Incompatible types in assignment (expression has type "Invariant[Literal[1, 2, 3]]", variable has type "Invariant[Literal[1, 2]]") b1: Covariant[Literal[1]] b2: Covariant[Literal[1, 2]] b3: Covariant[Literal[1, 2, 3]] b2 = b1 -b2 = b3 # E: Incompatible types in assignment (expression has type "Covariant[Union[Literal[1], Literal[2], Literal[3]]]", variable has type "Covariant[Union[Literal[1], Literal[2]]]") +b2 = b3 # E: Incompatible types in assignment (expression has type "Covariant[Literal[1, 2, 3]]", variable has type "Covariant[Literal[1, 2]]") c1: Contravariant[Literal[1]] c2: Contravariant[Literal[1, 2]] c3: Contravariant[Literal[1, 2, 3]] -c2 = c1 # E: Incompatible types in assignment (expression has type "Contravariant[Literal[1]]", variable has type "Contravariant[Union[Literal[1], Literal[2]]]") +c2 = c1 # E: Incompatible types in assignment (expression has type "Contravariant[Literal[1]]", variable has type "Contravariant[Literal[1, 2]]") c2 = c3 [builtins fixtures/tuple.pyi] [out] @@ -1275,12 +1275,12 @@ def bar(x: Sequence[Literal[1, 2]]) -> None: pass a: List[Literal[1]] b: List[Literal[1, 2, 3]] -foo(a) # E: Argument 1 to "foo" has incompatible type "List[Literal[1]]"; expected "List[Union[Literal[1], Literal[2]]]" \ +foo(a) # E: Argument 1 to "foo" has incompatible type "List[Literal[1]]"; expected "List[Literal[1, 2]]" \ # N: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance \ # N: Consider using "Sequence" instead, which is covariant -foo(b) # E: Argument 1 to "foo" has incompatible type "List[Union[Literal[1], Literal[2], Literal[3]]]"; expected "List[Union[Literal[1], Literal[2]]]" +foo(b) # E: Argument 1 to "foo" has incompatible type "List[Literal[1, 2, 3]]"; expected "List[Literal[1, 2]]" bar(a) -bar(b) # E: Argument 1 to "bar" has incompatible type "List[Union[Literal[1], Literal[2], Literal[3]]]"; expected "Sequence[Union[Literal[1], Literal[2]]]" +bar(b) # E: Argument 1 to "bar" has incompatible type "List[Literal[1, 2, 3]]"; expected "Sequence[Literal[1, 2]]" [builtins fixtures/list.pyi] [out] @@ -1363,9 +1363,9 @@ x = b # E: Incompatible types in assignment (expression has type "str", variabl y = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Literal[True]") z = d # This is ok: Literal[None] and None are equivalent. -combined = a # E: Incompatible types in assignment (expression has type "int", variable has type "Union[Literal[1], Literal['foo'], Literal[True], None]") -combined = b # E: Incompatible types in assignment (expression has type "str", variable has type "Union[Literal[1], Literal['foo'], Literal[True], None]") -combined = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Union[Literal[1], Literal['foo'], Literal[True], None]") +combined = a # E: Incompatible types in assignment (expression has type "int", variable has type "Optional[Literal[1, 'foo', True]]") +combined = b # E: Incompatible types in assignment (expression has type "str", variable has type "Optional[Literal[1, 'foo', True]]") +combined = c # E: Incompatible types in assignment (expression has type "bool", variable has type "Optional[Literal[1, 'foo', True]]") combined = d # Also ok, for similar reasons. e: Literal[1] = 1 @@ -1392,9 +1392,9 @@ a: Literal[1] = 2 # E: Incompatible types in assignment (expression ha b: Literal["foo"] = "bar" # E: Incompatible types in assignment (expression has type "Literal['bar']", variable has type "Literal['foo']") c: Literal[True] = False # E: Incompatible types in assignment (expression has type "Literal[False]", variable has type "Literal[True]") -d: Literal[1, 2] = 3 # E: Incompatible types in assignment (expression has type "Literal[3]", variable has type "Union[Literal[1], Literal[2]]") -e: Literal["foo", "bar"] = "baz" # E: Incompatible types in assignment (expression has type "Literal['baz']", variable has type "Union[Literal['foo'], Literal['bar']]") -f: Literal[True, 4] = False # E: Incompatible types in assignment (expression has type "Literal[False]", variable has type "Union[Literal[True], Literal[4]]") +d: Literal[1, 2] = 3 # E: Incompatible types in assignment (expression has type "Literal[3]", variable has type "Literal[1, 2]") +e: Literal["foo", "bar"] = "baz" # E: Incompatible types in assignment (expression has type "Literal['baz']", variable has type "Literal['foo', 'bar']") +f: Literal[True, 4] = False # E: Incompatible types in assignment (expression has type "Literal[False]", variable has type "Literal[True, 4]") [builtins fixtures/primitives.pyi] [out] @@ -1504,7 +1504,7 @@ reveal_type(arr3) # N: Revealed type is "builtins.list[builtins.int*]" reveal_type(arr4) # N: Revealed type is "builtins.list[builtins.object*]" reveal_type(arr5) # N: Revealed type is "builtins.list[builtins.object*]" -bad: List[Literal[1, 2]] = [1, 2, 3] # E: List item 2 has incompatible type "Literal[3]"; expected "Union[Literal[1], Literal[2]]" +bad: List[Literal[1, 2]] = [1, 2, 3] # E: List item 2 has incompatible type "Literal[3]"; expected "Literal[1, 2]" [builtins fixtures/list.pyi] [out] @@ -1619,19 +1619,19 @@ reveal_type(func(a)) # N: Revealed type is "Union[__main__.A, __main__.C]" reveal_type(func(b)) # N: Revealed type is "__main__.B" reveal_type(func(c)) # N: Revealed type is "Union[__main__.B, __main__.A]" reveal_type(func(d)) # N: Revealed type is "__main__.B" \ - # E: Argument 1 to "func" has incompatible type "Union[Literal[6], Literal[7]]"; expected "Union[Literal[3], Literal[4], Literal[5], Literal[6]]" + # E: Argument 1 to "func" has incompatible type "Literal[6, 7]"; expected "Literal[3, 4, 5, 6]" reveal_type(func(e)) # E: No overload variant of "func" matches argument type "int" \ # N: Possible overload variants: \ # N: def func(x: Literal[-40]) -> A \ - # N: def func(x: Union[Literal[3], Literal[4], Literal[5], Literal[6]]) -> B \ + # N: def func(x: Literal[3, 4, 5, 6]) -> B \ # N: def func(x: Literal['foo']) -> C \ # N: Revealed type is "Any" -reveal_type(func(f)) # E: No overload variant of "func" matches argument type "Union[Literal[7], Literal['bar']]" \ +reveal_type(func(f)) # E: No overload variant of "func" matches argument type "Literal[7, 'bar']" \ # N: Possible overload variants: \ # N: def func(x: Literal[-40]) -> A \ - # N: def func(x: Union[Literal[3], Literal[4], Literal[5], Literal[6]]) -> B \ + # N: def func(x: Literal[3, 4, 5, 6]) -> B \ # N: def func(x: Literal['foo']) -> C \ # N: Revealed type is "Any" [builtins fixtures/tuple.pyi] @@ -1657,7 +1657,7 @@ reveal_type(f(1)) # N: Revealed type is "builtins.int" reveal_type(f(2)) # N: Revealed type is "builtins.int" reveal_type(f(y)) # N: Revealed type is "builtins.object" reveal_type(f(z)) # N: Revealed type is "builtins.int" \ - # E: Argument 1 to "f" has incompatible type "Union[Literal[1], Literal[2], Literal['three']]"; expected "Union[Literal[1], Literal[2]]" + # E: Argument 1 to "f" has incompatible type "Literal[1, 2, 'three']"; expected "Literal[1, 2]" [builtins fixtures/tuple.pyi] [out] @@ -1726,8 +1726,8 @@ def f(x): x: Literal['a', 'b'] y: Literal['a', 'b'] -f(x, y) # E: Argument 1 to "f" has incompatible type "Union[Literal['a'], Literal['b']]"; expected "Literal['a']" \ - # E: Argument 2 to "f" has incompatible type "Union[Literal['a'], Literal['b']]"; expected "Literal['a']" \ +f(x, y) # E: Argument 1 to "f" has incompatible type "Literal['a', 'b']"; expected "Literal['a']" \ + # E: Argument 2 to "f" has incompatible type "Literal['a', 'b']"; expected "Literal['a']" \ [builtins fixtures/tuple.pyi] [out] diff --git a/test-data/unit/check-modules.test b/test-data/unit/check-modules.test index 4f0aa83912ea..6c32c088255d 100644 --- a/test-data/unit/check-modules.test +++ b/test-data/unit/check-modules.test @@ -131,9 +131,10 @@ def f() -> None: pass [case testImportWithinClassBody2] import typing class C: - from m import f + from m import f # E: Unsupported class scoped import f() - f(C) # E: Too many arguments for "f" + # ideally, the following should error: + f(C) [file m.py] def f() -> None: pass [out] diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 16cdc69ec1b7..23715b24d43e 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -894,7 +894,7 @@ else: reveal_type(y) # N: Revealed type is "__main__.Custom" # No contamination here -if 1 == x == z: # E: Non-overlapping equality check (left operand type: "Union[Literal[1], Literal[2], None]", right operand type: "Default") +if 1 == x == z: # E: Non-overlapping equality check (left operand type: "Optional[Literal[1, 2]]", right operand type: "Default") reveal_type(x) # E: Statement is unreachable reveal_type(z) else: diff --git a/test-data/unit/check-newsemanal.test b/test-data/unit/check-newsemanal.test index 8a039ad278f3..3b4b0303691a 100644 --- a/test-data/unit/check-newsemanal.test +++ b/test-data/unit/check-newsemanal.test @@ -2722,7 +2722,7 @@ import m [file m.py] class C: - from mm import f + from mm import f # E: Unsupported class scoped import @dec(f) def m(self): pass @@ -2742,7 +2742,7 @@ import m [file m/__init__.py] class C: - from m.m import f + from m.m import f # E: Unsupported class scoped import @dec(f) def m(self): pass diff --git a/test-data/unit/check-overloading.test b/test-data/unit/check-overloading.test index d13b5fc4b3e6..591741f3e4e8 100644 --- a/test-data/unit/check-overloading.test +++ b/test-data/unit/check-overloading.test @@ -5421,3 +5421,931 @@ def f_f(arg: str) -> None: ... @Bad2() # E: "Bad2" not callable def f_f(arg): ... [builtins fixtures/dict.pyi] + + +[case testOverloadIfBasic] +# flags: --always-true True --always-false False +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Test basic overload merging +# ----- + +@overload +def f1(g: A) -> A: ... +if True: + @overload + def f1(g: B) -> B: ... +def f1(g): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" + +@overload +def f2(g: A) -> A: ... +@overload +def f2(g: B) -> B: ... +if False: + @overload + def f2(g: C) -> C: ... +def f2(g): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(C())) # E: No overload variant of "f2" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f2(g: A) -> A \ + # N: def f2(g: B) -> B \ + # N: Revealed type is "Any" + +@overload +def f3(g: A) -> A: ... +@overload +def f3(g: B) -> B: ... +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f3(g: C) -> C: ... +def f3(g): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(C())) # E: No overload variant of "f3" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f3(g: A) -> A \ + # N: def f3(g: B) -> B \ + # N: Revealed type is "Any" + +if True: + @overload + def f4(g: A) -> A: ... +if True: + @overload + def f4(g: B) -> B: ... +@overload +def f4(g: C) -> C: ... +def f4(g): ... +reveal_type(f4(A())) # N: Revealed type is "__main__.A" +reveal_type(f4(B())) # N: Revealed type is "__main__.B" +reveal_type(f4(C())) # N: Revealed type is "__main__.C" + +if True: + @overload + def f5(g: A) -> A: ... +@overload +def f5(g: B) -> B: ... +if True: + @overload + def f5(g: C) -> C: ... +@overload +def f5(g: D) -> D: ... +def f5(g): ... +reveal_type(f5(A())) # N: Revealed type is "__main__.A" +reveal_type(f5(B())) # N: Revealed type is "__main__.B" +reveal_type(f5(C())) # N: Revealed type is "__main__.C" +reveal_type(f5(D())) # N: Revealed type is "__main__.D" + +[case testOverloadIfSysVersion] +# flags: --python-version 3.9 +from typing import overload +import sys + +class A: ... +class B: ... +class C: ... + +# ----- +# "Real" world example +# Test overload merging for sys.version_info +# ----- + +@overload +def f1(g: A) -> A: ... +if sys.version_info >= (3, 9): + @overload + def f1(g: B) -> B: ... +def f1(g): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" + +@overload +def f2(g: A) -> A: ... +@overload +def f2(g: B) -> B: ... +if sys.version_info >= (3, 10): + @overload + def f2(g: C) -> C: ... +def f2(g): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(C())) # E: No overload variant of "f2" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f2(g: A) -> A \ + # N: def f2(g: B) -> B \ + # N: Revealed type is "Any" +[builtins fixtures/ops.pyi] + +[case testOverloadIfMerging] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... + +# ----- +# Test overload merging +# ----- + +@overload +def f1(g: A) -> A: ... +if True: + # Some comment + @overload + def f1(g: B) -> B: ... +def f1(g): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" + +@overload +def f2(g: A) -> A: ... +if True: + @overload + def f2(g: bytes) -> B: ... + @overload + def f2(g: B) -> C: ... +def f2(g): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(B())) # N: Revealed type is "__main__.C" + +@overload +def f3(g: A) -> A: ... +@overload +def f3(g: B) -> B: ... +if True: + def f3(g): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(B())) # N: Revealed type is "__main__.B" + +if True: + @overload + def f4(g: A) -> A: ... +@overload +def f4(g: B) -> B: ... +def f4(g): ... +reveal_type(f4(A())) # N: Revealed type is "__main__.A" +reveal_type(f4(B())) # N: Revealed type is "__main__.B" + +if True: + # Some comment + @overload + def f5(g: A) -> A: ... + @overload + def f5(g: B) -> B: ... +def f5(g): ... +reveal_type(f5(A())) # N: Revealed type is "__main__.A" +reveal_type(f5(B())) # N: Revealed type is "__main__.B" + +[case testOverloadIfNotMerging] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... + +# ----- +# Don't merge if IfStmt contains nodes other than overloads +# ----- + +@overload # E: An overloaded function outside a stub file must have an implementation +def f1(g: A) -> A: ... +@overload +def f1(g: B) -> B: ... +if True: + @overload # E: Name "f1" already defined on line 12 \ + # E: Single overload definition, multiple required + def f1(g: C) -> C: ... + pass # Some other action +def f1(g): ... # E: Name "f1" already defined on line 12 +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(C())) # E: No overload variant of "f1" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f1(g: A) -> A \ + # N: def f1(g: B) -> B \ + # N: Revealed type is "Any" + +if True: + pass # Some other action + @overload # E: Single overload definition, multiple required + def f2(g: A) -> A: ... +@overload # E: Name "f2" already defined on line 26 +def f2(g: B) -> B: ... +@overload +def f2(g: C) -> C: ... +def f2(g): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(C())) # N: Revealed type is "__main__.A" \ + # E: Argument 1 to "f2" has incompatible type "C"; expected "A" + +[case testOverloadIfOldStyle] +# flags: --always-false var_false --always-true var_true +from typing import overload + +class A: ... +class B: ... + +# ----- +# Test old style to make sure it still works +# ----- + +var_true = True +var_false = False + +if var_false: + @overload + def f1(g: A) -> A: ... + @overload + def f1(g: B) -> B: ... + def f1(g): ... +elif var_true: + @overload + def f1(g: A) -> A: ... + @overload + def f1(g: B) -> B: ... + def f1(g): ... +else: + @overload + def f1(g: A) -> A: ... + @overload + def f1(g: B) -> B: ... + def f1(g): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" + +[case testOverloadIfElse] +# flags: --always-true True --always-false False +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Match the first always-true block +# ----- + +@overload +def f1(x: A) -> A: ... +if True: + @overload + def f1(x: B) -> B: ... +elif False: + @overload + def f1(x: C) -> C: ... +else: + @overload + def f1(x: D) -> D: ... +def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" +reveal_type(f1(C())) # E: No overload variant of "f1" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f1(x: A) -> A \ + # N: def f1(x: B) -> B \ + # N: Revealed type is "Any" + +@overload +def f2(x: A) -> A: ... +if False: + @overload + def f2(x: B) -> B: ... +elif True: + @overload + def f2(x: C) -> C: ... +else: + @overload + def f2(x: D) -> D: ... +def f2(x): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(B())) # E: No overload variant of "f2" matches argument type "B" \ + # N: Possible overload variants: \ + # N: def f2(x: A) -> A \ + # N: def f2(x: C) -> C \ + # N: Revealed type is "Any" +reveal_type(f2(C())) # N: Revealed type is "__main__.C" + +@overload +def f3(x: A) -> A: ... +if False: + @overload + def f3(x: B) -> B: ... +elif False: + @overload + def f3(x: C) -> C: ... +else: + @overload + def f3(x: D) -> D: ... +def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(C())) # E: No overload variant of "f3" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f3(x: A) -> A \ + # N: def f3(x: D) -> D \ + # N: Revealed type is "Any" +reveal_type(f3(D())) # N: Revealed type is "__main__.D" + +[case testOverloadIfElse2] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Match the first always-true block +# Don't merge overloads if can't be certain about execution of block +# ----- + +@overload +def f1(x: A) -> A: ... +if True: + @overload + def f1(x: B) -> B: ... +else: + @overload + def f1(x: D) -> D: ... +def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" +reveal_type(f1(D())) # E: No overload variant of "f1" matches argument type "D" \ + # N: Possible overload variants: \ + # N: def f1(x: A) -> A \ + # N: def f1(x: B) -> B \ + # N: Revealed type is "Any" + +@overload +def f2(x: A) -> A: ... +if True: + @overload + def f2(x: B) -> B: ... +elif maybe_true: + @overload + def f2(x: C) -> C: ... +else: + @overload + def f2(x: D) -> D: ... +def f2(x): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(B())) # N: Revealed type is "__main__.B" +reveal_type(f2(C())) # E: No overload variant of "f2" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f2(x: A) -> A \ + # N: def f2(x: B) -> B \ + # N: Revealed type is "Any" + +@overload # E: Single overload definition, multiple required +def f3(x: A) -> A: ... +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f3(x: B) -> B: ... +elif True: + @overload + def f3(x: C) -> C: ... +else: + @overload + def f3(x: D) -> D: ... +def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(B())) # E: No overload variant of "f3" matches argument type "B" \ + # N: Possible overload variant: \ + # N: def f3(x: A) -> A \ + # N: Revealed type is "Any" + +@overload # E: Single overload definition, multiple required +def f4(x: A) -> A: ... +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f4(x: B) -> B: ... +else: + @overload + def f4(x: D) -> D: ... +def f4(x): ... +reveal_type(f4(A())) # N: Revealed type is "__main__.A" +reveal_type(f4(B())) # E: No overload variant of "f4" matches argument type "B" \ + # N: Possible overload variant: \ + # N: def f4(x: A) -> A \ + # N: Revealed type is "Any" + +[case testOverloadIfElse3] +# flags: --always-false False +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... +class E: ... + +# ----- +# Match the first always-true block +# Don't merge overloads if can't be certain about execution of block +# ----- + +@overload +def f1(x: A) -> A: ... +if False: + @overload + def f1(x: B) -> B: ... +else: + @overload + def f1(x: D) -> D: ... +def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # E: No overload variant of "f1" matches argument type "B" \ + # N: Possible overload variants: \ + # N: def f1(x: A) -> A \ + # N: def f1(x: D) -> D \ + # N: Revealed type is "Any" +reveal_type(f1(D())) # N: Revealed type is "__main__.D" + +@overload # E: Single overload definition, multiple required +def f2(x: A) -> A: ... +if False: + @overload + def f2(x: B) -> B: ... +elif maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f2(x: C) -> C: ... +else: + @overload + def f2(x: D) -> D: ... +def f2(x): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(C())) # E: No overload variant of "f2" matches argument type "C" \ + # N: Possible overload variant: \ + # N: def f2(x: A) -> A \ + # N: Revealed type is "Any" + +@overload # E: Single overload definition, multiple required +def f3(x: A) -> A: ... +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f3(x: B) -> B: ... +elif False: + @overload + def f3(x: C) -> C: ... +else: + @overload + def f3(x: D) -> D: ... +def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(B())) # E: No overload variant of "f3" matches argument type "B" \ + # N: Possible overload variant: \ + # N: def f3(x: A) -> A \ + # N: Revealed type is "Any" + +def g(bool_var: bool) -> None: + @overload + def f4(x: A) -> A: ... + if bool_var: # E: Condition cannot be inferred, unable to merge overloads + @overload + def f4(x: B) -> B: ... + elif maybe_true: # E: Name "maybe_true" is not defined + # No 'Condition cannot be inferred' error here since it's already + # emitted on the first condition, 'bool_var', above. + @overload + def f4(x: C) -> C: ... + else: + @overload + def f4(x: D) -> D: ... + @overload + def f4(x: E) -> E: ... + def f4(x): ... + reveal_type(f4(E())) # N: Revealed type is "__main__.E" + reveal_type(f4(B())) # E: No overload variant of "f4" matches argument type "B" \ + # N: Possible overload variants: \ + # N: def f4(x: A) -> A \ + # N: def f4(x: E) -> E \ + # N: Revealed type is "Any" + +[case testOverloadIfSkipUnknownExecution] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# If blocks should be skipped if execution can't be certain +# Overload name must match outer name +# ----- + +@overload # E: Single overload definition, multiple required +def f1(x: A) -> A: ... +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f1(x: B) -> B: ... +def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" + +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f2(x: A) -> A: ... +@overload +def f2(x: B) -> B: ... +@overload +def f2(x: C) -> C: ... +def f2(x): ... +reveal_type(f2(A())) # E: No overload variant of "f2" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f2(x: B) -> B \ + # N: def f2(x: C) -> C \ + # N: Revealed type is "Any" + +if True: + @overload # E: Single overload definition, multiple required + def f3(x: A) -> A: ... + if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f3(x: B) -> B: ... + def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" + +if True: + if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f4(x: A) -> A: ... + @overload + def f4(x: B) -> B: ... + @overload + def f4(x: C) -> C: ... + def f4(x): ... +reveal_type(f4(A())) # E: No overload variant of "f4" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f4(x: B) -> B \ + # N: def f4(x: C) -> C \ + # N: Revealed type is "Any" + +[case testOverloadIfDontSkipUnrelatedOverload] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Don't skip if block if overload name doesn't match outer name +# ----- + +@overload # E: Single overload definition, multiple required +def f1(x: A) -> A: ... +if maybe_true: # E: Name "maybe_true" is not defined + @overload # E: Single overload definition, multiple required + def g1(x: B) -> B: ... +def f1(x): ... # E: Name "f1" already defined on line 13 +reveal_type(f1(A())) # N: Revealed type is "__main__.A" + +if maybe_true: # E: Name "maybe_true" is not defined + @overload # E: Single overload definition, multiple required + def g2(x: A) -> A: ... +@overload +def f2(x: B) -> B: ... +@overload +def f2(x: C) -> C: ... +def f2(x): ... +reveal_type(f2(A())) # E: No overload variant of "f2" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f2(x: B) -> B \ + # N: def f2(x: C) -> C \ + # N: Revealed type is "Any" + +if True: + @overload # E: Single overload definition, multiple required + def f3(x: A) -> A: ... + if maybe_true: # E: Name "maybe_true" is not defined + @overload # E: Single overload definition, multiple required + def g3(x: B) -> B: ... + def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" + +if True: + if maybe_true: # E: Name "maybe_true" is not defined + @overload # E: Single overload definition, multiple required + def g4(x: A) -> A: ... + @overload + def f4(x: B) -> B: ... + @overload + def f4(x: C) -> C: ... + def f4(x): ... +reveal_type(f4(A())) # E: No overload variant of "f4" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f4(x: B) -> B \ + # N: def f4(x: C) -> C \ + # N: Revealed type is "Any" + +[case testOverloadIfNotMergingDifferentNames] +# flags: --always-true True +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Don't merge overloads if IfStmts contains overload with different name +# ----- + +@overload # E: An overloaded function outside a stub file must have an implementation +def f1(x: A) -> A: ... +@overload +def f1(x: B) -> B: ... +if True: + @overload # E: Single overload definition, multiple required + def g1(x: C) -> C: ... +def f1(x): ... # E: Name "f1" already defined on line 13 +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(C())) # E: No overload variant of "f1" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f1(x: A) -> A \ + # N: def f1(x: B) -> B \ + # N: Revealed type is "Any" + +if True: + @overload # E: Single overload definition, multiple required + def g2(x: A) -> A: ... +@overload +def f2(x: B) -> B: ... +@overload +def f2(x: C) -> C: ... +def f2(x): ... +reveal_type(f2(A())) # E: No overload variant of "f2" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f2(x: B) -> B \ + # N: def f2(x: C) -> C \ + # N: Revealed type is "Any" +reveal_type(f2(B())) # N: Revealed type is "__main__.B" + +if True: + if True: + @overload # E: Single overload definition, multiple required + def g3(x: A) -> A: ... + @overload + def f3(x: B) -> B: ... + @overload + def f3(x: C) -> C: ... + def f3(x): ... +reveal_type(f3(A())) # E: No overload variant of "f3" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f3(x: B) -> B \ + # N: def f3(x: C) -> C \ + # N: Revealed type is "Any" +reveal_type(f3(B())) # N: Revealed type is "__main__.B" + +[case testOverloadIfSplitFunctionDef] +# flags: --always-true True --always-false False +from typing import overload + +class A: ... +class B: ... +class C: ... +class D: ... + +# ----- +# Test split FuncDefs +# ----- + +@overload +def f1(x: A) -> A: ... +@overload +def f1(x: B) -> B: ... +if True: + def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" + +@overload +def f2(x: A) -> A: ... +@overload +def f2(x: B) -> B: ... +if False: + def f2(x): ... +else: + def f2(x): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" + +@overload # E: An overloaded function outside a stub file must have an implementation +def f3(x: A) -> A: ... +@overload +def f3(x: B) -> B: ... +if True: + def f3(x): ... # E: Name "f3" already defined on line 31 +else: + pass # some other node + def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" + +[case testOverloadIfMixed] +# flags: --always-true True --always-false False +from typing import overload, TYPE_CHECKING + +class A: ... +class B: ... +class C: ... +class D: ... + +if maybe_var: # E: Name "maybe_var" is not defined + pass +if True: + @overload + def f1(x: A) -> A: ... +@overload +def f1(x: B) -> B: ... +def f1(x): ... +reveal_type(f1(A())) # N: Revealed type is "__main__.A" +reveal_type(f1(B())) # N: Revealed type is "__main__.B" + +if True: + @overload + def f2(x: A) -> A: ... + @overload + def f2(x: B) -> B: ... +def f2(x): ... +reveal_type(f2(A())) # N: Revealed type is "__main__.A" +reveal_type(f2(B())) # N: Revealed type is "__main__.B" + +if True: + @overload + def f3(x: A) -> A: ... + @overload + def f3(x: B) -> B: ... + def f3(x): ... +reveal_type(f3(A())) # N: Revealed type is "__main__.A" +reveal_type(f3(B())) # N: Revealed type is "__main__.B" + +# Don't crash with AssignmentStmt if elif +@overload # E: Single overload definition, multiple required +def f4(x: A) -> A: ... +if False: + @overload + def f4(x: B) -> B: ... +elif True: + var = 1 +def f4(x): ... # E: Name "f4" already defined on line 39 + +if TYPE_CHECKING: + @overload + def f5(x: A) -> A: ... + @overload + def f5(x: B) -> B: ... +def f5(x): ... +reveal_type(f5(A())) # N: Revealed type is "__main__.A" +reveal_type(f5(B())) # N: Revealed type is "__main__.B" + +# Test from check-functions - testUnconditionalRedefinitionOfConditionalFunction +# Don't merge If blocks if they appear before any overloads +# and don't contain any overloads themselves. +if maybe_true: # E: Name "maybe_true" is not defined + def f6(x): ... +def f6(x): ... # E: Name "f6" already defined on line 61 + +if maybe_true: # E: Name "maybe_true" is not defined + pass # Some other node + def f7(x): ... +def f7(x): ... # E: Name "f7" already defined on line 66 + +@overload +def f8(x: A) -> A: ... +@overload +def f8(x: B) -> B: ... +if False: + def f8(x: C) -> C: ... +def f8(x): ... +reveal_type(f8(A())) # N: Revealed type is "__main__.A" +reveal_type(f8(C())) # E: No overload variant of "f8" matches argument type "C" \ + # N: Possible overload variants: \ + # N: def f8(x: A) -> A \ + # N: def f8(x: B) -> B \ + # N: Revealed type is "Any" + +if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f9(x: A) -> A: ... +if another_maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "another_maybe_true" is not defined + @overload + def f9(x: B) -> B: ... +@overload +def f9(x: C) -> C: ... +@overload +def f9(x: D) -> D: ... +def f9(x): ... +reveal_type(f9(A())) # E: No overload variant of "f9" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f9(x: C) -> C \ + # N: def f9(x: D) -> D \ + # N: Revealed type is "Any" +reveal_type(f9(C())) # N: Revealed type is "__main__.C" + +if True: + if maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "maybe_true" is not defined + @overload + def f10(x: A) -> A: ... + if another_maybe_true: # E: Condition cannot be inferred, unable to merge overloads \ + # E: Name "another_maybe_true" is not defined + @overload + def f10(x: B) -> B: ... + @overload + def f10(x: C) -> C: ... + @overload + def f10(x: D) -> D: ... + def f10(x): ... +reveal_type(f10(A())) # E: No overload variant of "f10" matches argument type "A" \ + # N: Possible overload variants: \ + # N: def f10(x: C) -> C \ + # N: def f10(x: D) -> D \ + # N: Revealed type is "Any" +reveal_type(f10(C())) # N: Revealed type is "__main__.C" + +if some_var: # E: Name "some_var" is not defined + pass +@overload +def f11(x: A) -> A: ... +@overload +def f11(x: B) -> B: ... +def f11(x): ... +reveal_type(f11(A())) # N: Revealed type is "__main__.A" + +if True: + if some_var: # E: Name "some_var" is not defined + pass + @overload + def f12(x: A) -> A: ... + @overload + def f12(x: B) -> B: ... + def f12(x): ... +reveal_type(f12(A())) # N: Revealed type is "__main__.A" +[typing fixtures/typing-medium.pyi] + +[case testOverloadIfUnconditionalFuncDef] +# flags: --always-true True --always-false False +from typing import overload + +class A: ... +class B: ... + +# ----- +# Don't merge conditional FuncDef after unconditional one +# ----- + +@overload +def f1(x: A) -> A: ... +@overload +def f1(x: B) -> B: ... +def f1(x): ... + +@overload +def f2(x: A) -> A: ... +if True: + @overload + def f2(x: B) -> B: ... +def f2(x): ... +if True: + def f2(x): ... # E: Name "f2" already defined on line 17 + +[case testOverloadItemHasMoreGeneralReturnType] +from typing import overload + +@overload +def f() -> object: ... + +@overload +def f(x: int) -> object: ... + +def f(x: int = 0) -> int: + return x + +@overload +def g() -> object: ... + +@overload +def g(x: int) -> str: ... + +def g(x: int = 0) -> int: # E: Overloaded function implementation cannot produce return type of signature 2 + return x diff --git a/test-data/unit/check-parameter-specification.test b/test-data/unit/check-parameter-specification.test index f6123915aada..f2281babb193 100644 --- a/test-data/unit/check-parameter-specification.test +++ b/test-data/unit/check-parameter-specification.test @@ -3,6 +3,16 @@ from typing_extensions import ParamSpec P = ParamSpec('P') [builtins fixtures/tuple.pyi] +[case testInvalidParamSpecDefinitions] +from typing import ParamSpec + +P1 = ParamSpec("P1", covariant=True) # E: Only the first argument to ParamSpec has defined semantics +P2 = ParamSpec("P2", contravariant=True) # E: Only the first argument to ParamSpec has defined semantics +P3 = ParamSpec("P3", bound=int) # E: Only the first argument to ParamSpec has defined semantics +P4 = ParamSpec("P4", int, str) # E: Only the first argument to ParamSpec has defined semantics +P5 = ParamSpec("P5", covariant=True, bound=int) # E: Only the first argument to ParamSpec has defined semantics +[builtins fixtures/tuple.pyi] + [case testParamSpecLocations] from typing import Callable, List from typing_extensions import ParamSpec, Concatenate diff --git a/test-data/unit/check-protocols.test b/test-data/unit/check-protocols.test index 6768263e9832..65fb30a3547f 100644 --- a/test-data/unit/check-protocols.test +++ b/test-data/unit/check-protocols.test @@ -2382,7 +2382,7 @@ y: PBad = None # E: Incompatible types in assignment (expression has type "None [out] [case testOnlyMethodProtocolUsableWithIsSubclass] -from typing import Protocol, runtime_checkable, Union, Type +from typing import Protocol, runtime_checkable, Union, Type, Sequence, overload @runtime_checkable class P(Protocol): def meth(self) -> int: @@ -2404,6 +2404,17 @@ if issubclass(cls, P): reveal_type(cls) # N: Revealed type is "Type[__main__.C]" else: reveal_type(cls) # N: Revealed type is "Type[__main__.E]" + +@runtime_checkable +class POverload(Protocol): + @overload + def meth(self, a: int) -> float: ... + @overload + def meth(self, a: str) -> Sequence[float]: ... + def meth(self, a): + pass + +reveal_type(issubclass(int, POverload)) # N: Revealed type is "builtins.bool" [builtins fixtures/isinstance.pyi] [typing fixtures/typing-full.pyi] [out] @@ -2795,3 +2806,107 @@ class MyClass: assert isinstance(self, MyProtocol) [builtins fixtures/isinstance.pyi] [typing fixtures/typing-full.pyi] + +[case testProtocolAndTypeVariableSpecialCase] +from typing import TypeVar, Iterable, Optional, Callable, Protocol + +T_co = TypeVar('T_co', covariant=True) + +class SupportsNext(Protocol[T_co]): + def __next__(self) -> T_co: ... + +N = TypeVar("N", bound=SupportsNext, covariant=True) + +class SupportsIter(Protocol[T_co]): + def __iter__(self) -> T_co: ... + +def f(i: SupportsIter[N]) -> N: ... + +I = TypeVar('I', bound=Iterable) + +def g(x: I, y: Iterable) -> None: + f(x) + f(y) + +[case testMatchProtocolAgainstOverloadWithAmbiguity] +from typing import TypeVar, Protocol, Union, Generic, overload + +T = TypeVar("T", covariant=True) + +class slice: pass + +class GetItem(Protocol[T]): + def __getitem__(self, k: int) -> T: ... + +class Str: # Resembles 'str' + def __getitem__(self, k: Union[int, slice]) -> Str: ... + +class Lst(Generic[T]): # Resembles 'list' + def __init__(self, x: T): ... + @overload + def __getitem__(self, k: int) -> T: ... + @overload + def __getitem__(self, k: slice) -> Lst[T]: ... + def __getitem__(self, k): pass + +def f(x: GetItem[GetItem[Str]]) -> None: ... + +a: Lst[Str] +f(Lst(a)) + +class Lst2(Generic[T]): + def __init__(self, x: T): ... + # The overload items are tweaked but still compatible + @overload + def __getitem__(self, k: Str) -> None: ... + @overload + def __getitem__(self, k: slice) -> Lst2[T]: ... + @overload + def __getitem__(self, k: Union[int, str]) -> T: ... + def __getitem__(self, k): pass + +b: Lst2[Str] +f(Lst2(b)) + +class Lst3(Generic[T]): # Resembles 'list' + def __init__(self, x: T): ... + # The overload items are no longer compatible (too narrow argument type) + @overload + def __getitem__(self, k: slice) -> Lst3[T]: ... + @overload + def __getitem__(self, k: bool) -> T: ... + def __getitem__(self, k): pass + +c: Lst3[Str] +f(Lst3(c)) # E: Argument 1 to "f" has incompatible type "Lst3[Lst3[Str]]"; expected "GetItem[GetItem[Str]]" \ +# N: Following member(s) of "Lst3[Lst3[Str]]" have conflicts: \ +# N: Expected: \ +# N: def __getitem__(self, int) -> GetItem[Str] \ +# N: Got: \ +# N: @overload \ +# N: def __getitem__(self, slice) -> Lst3[Lst3[Str]] \ +# N: @overload \ +# N: def __getitem__(self, bool) -> Lst3[Str] + +[builtins fixtures/list.pyi] +[typing fixtures/typing-full.pyi] + +[case testMatchProtocolAgainstOverloadWithMultipleMatchingItems] +from typing import Protocol, overload, TypeVar, Any + +_T_co = TypeVar("_T_co", covariant=True) +_T = TypeVar("_T") + +class SupportsRound(Protocol[_T_co]): + @overload + def __round__(self) -> int: ... + @overload + def __round__(self, __ndigits: int) -> _T_co: ... + +class C: + # This matches both overload items of SupportsRound + def __round__(self, __ndigits: int = ...) -> int: ... + +def round(number: SupportsRound[_T], ndigits: int) -> _T: ... + +round(C(), 1) diff --git a/test-data/unit/check-python2.test b/test-data/unit/check-python2.test index d658fe013401..0481767abd63 100644 --- a/test-data/unit/check-python2.test +++ b/test-data/unit/check-python2.test @@ -68,18 +68,89 @@ A.f(1) A.f('') # E: Argument 1 to "f" of "A" has incompatible type "str"; expected "int" [builtins_py2 fixtures/staticmethod.pyi] -[case testRaiseTuple] -import typing -raise BaseException, "a" -raise BaseException, "a", None -[builtins_py2 fixtures/exception.pyi] - [case testRaiseTupleTypeFail] import typing x = None # type: typing.Type[typing.Tuple[typing.Any, typing.Any, typing.Any]] raise x # E: Exception must be derived from BaseException [builtins_py2 fixtures/exception.pyi] +[case testRaiseTupleOfThreeOnPython2] +from types import TracebackType +from typing import Optional, Tuple, Type + +e = None # type: Optional[TracebackType] + +# Correct raising several items: + +raise BaseException +raise BaseException(1) +raise (BaseException,) +raise (BaseException(1),) +raise BaseException, 1 +raise BaseException, 1, e +raise BaseException, 1, None + +raise Exception +raise Exception(1) +raise Exception() +raise Exception(1), None +raise Exception(), None +raise Exception(1), None, None +raise Exception(1), None, e +raise (Exception,) +raise (Exception(1),) +raise Exception, 1 +raise Exception, 1, e +raise Exception, 1, None + +# Errors: + +raise int, 1 # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise int, None # E: Argument 1 must be "Union[builtins.BaseException, Type[builtins.BaseException]]" subtype +raise Exception(1), 1 # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise Exception(1), 1, None # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise Exception, 1, 1 # E: Argument 3 must be "Union[types.TracebackType, None]" subtype +raise int, 1, 1 # E: Argument 1 must be "Type[builtins.BaseException]" subtype \ + # E: Argument 3 must be "Union[types.TracebackType, None]" subtype + +# Correct raising tuple: + +t1 = (BaseException,) +t2 = (Exception(1), 2, 3, 4) # type: Tuple[Exception, int, int, int] +t3 = (Exception,) # type: Tuple[Type[Exception], ...] +t4 = (Exception(1),) # type: Tuple[Exception, ...] + +raise t1 +raise t2 +raise t3 +raise t4 + +# Errors: + +raise t1, 1, None # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise t2, 1 # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise t3, 1, e # E: Argument 1 must be "Type[builtins.BaseException]" subtype +raise t4, 1, 1 # E: Argument 1 must be "Type[builtins.BaseException]" subtype \ + # E: Argument 3 must be "Union[types.TracebackType, None]" subtype + +w1 = () +w2 = (1, Exception) +w3 = (1,) # type: Tuple[int, ...] + +raise w1 # E: Exception must be derived from BaseException +raise w2 # E: When raising a tuple, first element must by derived from BaseException +raise w3 # E: When raising a tuple, first element must by derived from BaseException + +# Bare raise: + +try: + pass +except Exception: + raise # ok +[builtins_py2 fixtures/exception.pyi] +[file types.pyi] +class TracebackType: pass + [case testTryExceptWithTuple] try: None diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 4c0324b9bec7..6046b7ec7333 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1,5 +1,6 @@ -- Capture Pattern -- -[case testCapturePatternType] + +[case testMatchCapturePatternType] class A: ... m: A @@ -7,23 +8,24 @@ match m: case a: reveal_type(a) # N: Revealed type is "__main__.A" - -- Literal Pattern -- -[case testLiteralPatternNarrows] + +[case testMatchLiteralPatternNarrows] m: object match m: case 1: - reveal_type(m) # N: Revealed type is "Literal[1]?" + reveal_type(m) # N: Revealed type is "Literal[1]" -[case testLiteralPatternAlreadyNarrower] +[case testMatchLiteralPatternAlreadyNarrower-skip] m: bool match m: case 1: - reveal_type(m) # N: Revealed type is "builtins.bool" + reveal_type(m) # This should probably be unreachable, but isn't detected as such. +[builtins fixtures/primitives.pyi] -[case testLiteralPatternUnreachable] +[case testMatchLiteralPatternUnreachable] # primitives are needed because otherwise mypy doesn't see that int and str are incompatible m: int @@ -32,9 +34,9 @@ match m: reveal_type(m) [builtins fixtures/primitives.pyi] - -- Value Pattern -- -[case testValuePatternNarrows] + +[case testMatchValuePatternNarrows] import b m: object @@ -44,7 +46,7 @@ match m: [file b.py] b: int -[case testValuePatternAlreadyNarrower] +[case testMatchValuePatternAlreadyNarrower] import b m: bool @@ -54,7 +56,7 @@ match m: [file b.py] b: int -[case testValuePatternIntersect] +[case testMatchValuePatternIntersect] import b class A: ... @@ -62,12 +64,12 @@ m: A match m: case b.b: - reveal_type(m) # N: Revealed type is "__main__." + reveal_type(m) # N: Revealed type is "__main__.1" [file b.py] class B: ... b: B -[case testValuePatternUnreachable] +[case testMatchValuePatternUnreachable] # primitives are needed because otherwise mypy doesn't see that int and str are incompatible import b @@ -80,9 +82,9 @@ match m: b: str [builtins fixtures/primitives.pyi] - -- Sequence Pattern -- -[case testSequencePatternCaptures] + +[case testMatchSequencePatternCaptures] from typing import List m: List[int] @@ -91,7 +93,7 @@ match m: reveal_type(a) # N: Revealed type is "builtins.int*" [builtins fixtures/list.pyi] -[case testSequencePatternCapturesStarred] +[case testMatchSequencePatternCapturesStarred] from typing import Sequence m: Sequence[int] @@ -101,7 +103,7 @@ match m: reveal_type(b) # N: Revealed type is "builtins.list[builtins.int*]" [builtins fixtures/list.pyi] -[case testSequencePatternNarrowsInner] +[case testMatchSequencePatternNarrowsInner] from typing import Sequence m: Sequence[object] @@ -109,7 +111,7 @@ match m: case [1, True]: reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]" -[case testSequencePatternNarrowsOuter] +[case testMatchSequencePatternNarrowsOuter] from typing import Sequence m: object @@ -117,7 +119,7 @@ match m: case [1, True]: reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]" -[case testSequencePatternAlreadyNarrowerInner] +[case testMatchSequencePatternAlreadyNarrowerInner] from typing import Sequence m: Sequence[bool] @@ -125,7 +127,7 @@ match m: case [1, True]: reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.bool]" -[case testSequencePatternAlreadyNarrowerOuter] +[case testMatchSequencePatternAlreadyNarrowerOuter] from typing import Sequence m: Sequence[object] @@ -133,7 +135,7 @@ match m: case [1, True]: reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]" -[case testSequencePatternAlreadyNarrowerBoth] +[case testMatchSequencePatternAlreadyNarrowerBoth] from typing import Sequence m: Sequence[bool] @@ -141,7 +143,7 @@ match m: case [1, True]: reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.bool]" -[case testNestedSequencePatternNarrowsInner] +[case testMatchNestedSequencePatternNarrowsInner] from typing import Sequence m: Sequence[Sequence[object]] @@ -149,7 +151,7 @@ match m: case [[1], [True]]: reveal_type(m) # N: Revealed type is "typing.Sequence[typing.Sequence[builtins.int]]" -[case testNestedSequencePatternNarrowsOuter] +[case testMatchNestedSequencePatternNarrowsOuter] from typing import Sequence m: object @@ -157,7 +159,7 @@ match m: case [[1], [True]]: reveal_type(m) # N: Revealed type is "typing.Sequence[typing.Sequence[builtins.int]]" -[case testSequencePatternDoesntNarrowInvariant] +[case testMatchSequencePatternDoesntNarrowInvariant] from typing import List m: List[object] @@ -166,7 +168,7 @@ match m: reveal_type(m) # N: Revealed type is "builtins.list[builtins.object]" [builtins fixtures/list.pyi] -[case testSequencePatternMatches] +[case testMatchSequencePatternMatches] import array, collections from typing import Sequence, Iterable @@ -229,8 +231,7 @@ match m11: [builtins fixtures/primitives.pyi] [typing fixtures/typing-full.pyi] - -[case testSequencePatternCapturesTuple] +[case testMatchSequencePatternCapturesTuple] from typing import Tuple m: Tuple[int, str, bool] @@ -242,7 +243,7 @@ match m: reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.bool]" [builtins fixtures/list.pyi] -[case testSequencePatternTupleTooLong] +[case testMatchSequencePatternTupleTooLong] from typing import Tuple m: Tuple[int, str] @@ -253,7 +254,7 @@ match m: reveal_type(c) [builtins fixtures/list.pyi] -[case testSequencePatternTupleTooShort] +[case testMatchSequencePatternTupleTooShort] from typing import Tuple m: Tuple[int, str, bool] @@ -263,16 +264,16 @@ match m: reveal_type(b) [builtins fixtures/list.pyi] -[case testSequencePatternTupleNarrows] +[case testMatchSequencePatternTupleNarrows] from typing import Tuple m: Tuple[object, object] match m: case [1, "str"]: - reveal_type(m) # N: Revealed type is "Tuple[Literal[1]?, Literal['str']?]" + reveal_type(m) # N: Revealed type is "Tuple[Literal[1], Literal['str']]" [builtins fixtures/list.pyi] -[case testSequencePatternTupleStarred] +[case testMatchSequencePatternTupleStarred] from typing import Tuple m: Tuple[int, str, bool] @@ -284,7 +285,7 @@ match m: reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.bool]" [builtins fixtures/list.pyi] -[case testSequencePatternTupleStarredUnion] +[case testMatchSequencePatternTupleStarredUnion] from typing import Tuple m: Tuple[int, str, float, bool] @@ -296,8 +297,7 @@ match m: reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.float, builtins.bool]" [builtins fixtures/list.pyi] - -[case testSequencePatternTupleStarredTooShort] +[case testMatchSequencePatternTupleStarredTooShort] from typing import Tuple m: Tuple[int] reveal_type(m) # N: Revealed type is "Tuple[builtins.int]" @@ -309,7 +309,7 @@ match m: reveal_type(c) [builtins fixtures/list.pyi] -[case testNonMatchingSequencePattern] +[case testMatchNonMatchingSequencePattern] from typing import List x: List[int] @@ -317,7 +317,7 @@ match x: case [str()]: pass -[case testSequenceUnion-skip] +[case testMatchSequenceUnion-skip] from typing import List, Union m: Union[List[List[str]], str] @@ -327,7 +327,8 @@ match m: [builtins fixtures/list.pyi] -- Mapping Pattern -- -[case testMappingPatternCaptures] + +[case testMatchMappingPatternCaptures] from typing import Dict import b m: Dict[str, int] @@ -341,7 +342,7 @@ match m: b: str [builtins fixtures/dict.pyi] -[case testMappingPatternCapturesWrongKeyType] +[case testMatchMappingPatternCapturesWrongKeyType] # This is not actually unreachable, as a subclass of dict could accept keys with different types from typing import Dict import b @@ -356,7 +357,7 @@ match m: b: int [builtins fixtures/dict.pyi] -[case testMappingPatternCapturesTypedDict] +[case testMatchMappingPatternCapturesTypedDict] from typing import TypedDict class A(TypedDict): @@ -377,7 +378,7 @@ match m: reveal_type(v5) # N: Revealed type is "builtins.object*" [typing fixtures/typing-typeddict.pyi] -[case testMappingPatternCapturesTypedDictWithLiteral] +[case testMatchMappingPatternCapturesTypedDictWithLiteral] from typing import TypedDict import b @@ -404,7 +405,7 @@ b: Literal["b"] = "b" o: Final[str] = "o" [typing fixtures/typing-typeddict.pyi] -[case testMappingPatternCapturesTypedDictWithNonLiteral] +[case testMatchMappingPatternCapturesTypedDictWithNonLiteral] from typing import TypedDict import b @@ -422,7 +423,7 @@ from typing import Final, Literal a: str [typing fixtures/typing-typeddict.pyi] -[case testMappingPatternCapturesTypedDictUnreachable] +[case testMatchMappingPatternCapturesTypedDictUnreachable] # TypedDict keys are always str, so this is actually unreachable from typing import TypedDict import b @@ -442,7 +443,7 @@ match m: b: int [typing fixtures/typing-typeddict.pyi] -[case testMappingPatternCaptureRest] +[case testMatchMappingPatternCaptureRest] m: object match m: @@ -450,7 +451,7 @@ match m: reveal_type(r) # N: Revealed type is "builtins.dict[builtins.object, builtins.object]" [builtins fixtures/dict.pyi] -[case testMappingPatternCaptureRestFromMapping] +[case testMatchMappingPatternCaptureRestFromMapping] from typing import Mapping m: Mapping[str, int] @@ -460,10 +461,11 @@ match m: reveal_type(r) # N: Revealed type is "builtins.dict[builtins.str*, builtins.int*]" [builtins fixtures/dict.pyi] --- Mapping patterns currently don't narrow -- +-- Mapping patterns currently do not narrow -- -- Class Pattern -- -[case testClassPatternCapturePositional] + +[case testMatchClassPatternCapturePositional] from typing import Final class A: @@ -479,7 +481,7 @@ match m: reveal_type(j) # N: Revealed type is "builtins.int" [builtins fixtures/tuple.pyi] -[case testClassPatternMemberClassCapturePositional] +[case testMatchClassPatternMemberClassCapturePositional] import b m: b.A @@ -497,7 +499,7 @@ class A: b: int [builtins fixtures/tuple.pyi] -[case testClassPatternCaptureKeyword] +[case testMatchClassPatternCaptureKeyword] class A: a: str b: int @@ -509,7 +511,7 @@ match m: reveal_type(i) # N: Revealed type is "builtins.str" reveal_type(j) # N: Revealed type is "builtins.int" -[case testClassPatternCaptureSelf] +[case testMatchClassPatternCaptureSelf] m: object match m: @@ -537,7 +539,7 @@ match m: reveal_type(k) # N: Revealed type is "builtins.tuple[Any, ...]" [builtins fixtures/primitives.pyi] -[case testClassPatternNarrowSelfCapture] +[case testMatchClassPatternNarrowSelfCapture] m: object match m: @@ -565,7 +567,21 @@ match m: reveal_type(m) # N: Revealed type is "builtins.tuple[Any, ...]" [builtins fixtures/primitives.pyi] -[case testClassPatternCaptureDataclass] +[case testMatchInvalidClassPattern] +m: object + +match m: + case xyz(y): # E: Name "xyz" is not defined + reveal_type(m) # N: Revealed type is "Any" + reveal_type(y) # E: Cannot determine type of "y" \ + # N: Revealed type is "Any" + +match m: + case xyz(z=x): # E: Name "xyz" is not defined + reveal_type(x) # E: Cannot determine type of "x" \ + # N: Revealed type is "Any" + +[case testMatchClassPatternCaptureDataclass] from dataclasses import dataclass @dataclass @@ -581,7 +597,7 @@ match m: reveal_type(j) # N: Revealed type is "builtins.int" [builtins fixtures/dataclasses.pyi] -[case testClassPatternCaptureDataclassNoMatchArgs] +[case testMatchClassPatternCaptureDataclassNoMatchArgs] from dataclasses import dataclass @dataclass(match_args=False) @@ -596,7 +612,7 @@ match m: pass [builtins fixtures/dataclasses.pyi] -[case testClassPatternCaptureDataclassPartialMatchArgs] +[case testMatchClassPatternCaptureDataclassPartialMatchArgs] from dataclasses import dataclass, field @dataclass @@ -613,7 +629,7 @@ match m: reveal_type(k) # N: Revealed type is "builtins.str" [builtins fixtures/dataclasses.pyi] -[case testClassPatternCaptureNamedTupleInline] +[case testMatchClassPatternCaptureNamedTupleInline] from collections import namedtuple A = namedtuple("A", ["a", "b"]) @@ -626,7 +642,7 @@ match m: reveal_type(j) # N: Revealed type is "Any" [builtins fixtures/list.pyi] -[case testClassPatternCaptureNamedTupleInlineTyped] +[case testMatchClassPatternCaptureNamedTupleInlineTyped] from typing import NamedTuple A = NamedTuple("A", [("a", str), ("b", int)]) @@ -639,7 +655,7 @@ match m: reveal_type(j) # N: Revealed type is "builtins.int" [builtins fixtures/list.pyi] -[case testClassPatternCaptureNamedTupleClass] +[case testMatchClassPatternCaptureNamedTupleClass] from typing import NamedTuple class A(NamedTuple): @@ -654,7 +670,7 @@ match m: reveal_type(j) # N: Revealed type is "builtins.int" [builtins fixtures/tuple.pyi] -[case testClassPatternCaptureGeneric] +[case testMatchClassPatternCaptureGeneric] from typing import Generic, TypeVar T = TypeVar('T') @@ -669,7 +685,7 @@ match m: reveal_type(m) # N: Revealed type is "__main__.A[Any]" reveal_type(i) # N: Revealed type is "Any" -[case testClassPatternCaptureGenericAlreadyKnown] +[case testMatchClassPatternCaptureGenericAlreadyKnown] from typing import Generic, TypeVar T = TypeVar('T') @@ -684,7 +700,7 @@ match m: reveal_type(m) # N: Revealed type is "__main__.A[builtins.int]" reveal_type(i) # N: Revealed type is "builtins.int*" -[case testClassPatternCaptureFilledGenericTypeAlias] +[case testMatchClassPatternCaptureFilledGenericTypeAlias] from typing import Generic, TypeVar T = TypeVar('T') @@ -700,7 +716,7 @@ match m: case B(a=i): # E: Class pattern class must not be a type alias with type parameters reveal_type(i) -[case testClassPatternCaptureGenericTypeAlias] +[case testMatchClassPatternCaptureGenericTypeAlias] from typing import Generic, TypeVar T = TypeVar('T') @@ -716,7 +732,7 @@ match m: case B(a=i): pass -[case testClassPatternNarrows] +[case testMatchClassPatternNarrows] from typing import Final class A: @@ -733,7 +749,7 @@ match m: reveal_type(m) # N: Revealed type is "__main__.A" [builtins fixtures/tuple.pyi] -[case testClassPatternNarrowsUnion] +[case testMatchClassPatternNarrowsUnion] from typing import Final, Union class A: @@ -769,7 +785,7 @@ match m: reveal_type(l) # N: Revealed type is "builtins.str" [builtins fixtures/tuple.pyi] -[case testClassPatternAlreadyNarrower] +[case testMatchClassPatternAlreadyNarrower] from typing import Final class A: @@ -789,7 +805,7 @@ match m: reveal_type(m) # N: Revealed type is "__main__.B" [builtins fixtures/tuple.pyi] -[case testClassPatternIntersection] +[case testMatchClassPatternIntersection] from typing import Final class A: @@ -802,12 +818,12 @@ m: B match m: case A(): - reveal_type(m) # N: Revealed type is "__main__." + reveal_type(m) # N: Revealed type is "__main__.2" case A(i, j): - reveal_type(m) # N: Revealed type is "__main__.1" + reveal_type(m) # N: Revealed type is "__main__.3" [builtins fixtures/tuple.pyi] -[case testClassPatternNonexistentKeyword] +[case testMatchClassPatternNonexistentKeyword] class A: ... m: object @@ -817,7 +833,7 @@ match m: reveal_type(m) # N: Revealed type is "__main__.A" reveal_type(j) # N: Revealed type is "Any" -[case testClassPatternDuplicateKeyword] +[case testMatchClassPatternDuplicateKeyword] class A: a: str @@ -827,7 +843,7 @@ match m: case A(a=i, a=j): # E: Duplicate keyword pattern "a" pass -[case testClassPatternDuplicateImplicitKeyword] +[case testMatchClassPatternDuplicateImplicitKeyword] from typing import Final class A: @@ -841,7 +857,7 @@ match m: pass [builtins fixtures/tuple.pyi] -[case testClassPatternTooManyPositionals] +[case testMatchClassPatternTooManyPositionals] from typing import Final class A: @@ -856,7 +872,7 @@ match m: pass [builtins fixtures/tuple.pyi] -[case testClassPatternIsNotType] +[case testMatchClassPatternIsNotType] a = 1 m: object @@ -865,7 +881,7 @@ match m: reveal_type(i) reveal_type(j) -[case testClassPatternNestedGenerics] +[case testMatchClassPatternNestedGenerics] # From cpython test_patma.py x = [[{0: 0}]] match x: @@ -877,9 +893,9 @@ reveal_type(y) # N: Revealed type is "builtins.int" reveal_type(z) # N: Revealed type is "builtins.int*" [builtins fixtures/dict.pyi] -[case testNonFinalMatchArgs] +[case testMatchNonFinalMatchArgs] class A: - __match_args__ = ("a", "b") # N: __match_args__ must be final for checking of match statements to work + __match_args__ = ("a", "b") a: str b: int @@ -887,11 +903,11 @@ m: object match m: case A(i, j): - reveal_type(i) # N: Revealed type is "Any" - reveal_type(j) # N: Revealed type is "Any" + reveal_type(i) # N: Revealed type is "builtins.str" + reveal_type(j) # N: Revealed type is "builtins.int" [builtins fixtures/tuple.pyi] -[case testAnyTupleMatchArgs] +[case testMatchAnyTupleMatchArgs] from typing import Tuple, Any class A: @@ -908,7 +924,7 @@ match m: reveal_type(k) # N: Revealed type is "Any" [builtins fixtures/tuple.pyi] -[case testNonLiteralMatchArgs] +[case testMatchNonLiteralMatchArgs] from typing import Final b: str = "b" @@ -927,7 +943,7 @@ match m: reveal_type(j) # N: Revealed type is "Any" [builtins fixtures/tuple.pyi] -[case testExternalMatchArgs] +[case testMatchExternalMatchArgs] from typing import Final, Literal args: Final = ("a", "b") @@ -946,9 +962,9 @@ class B: [builtins fixtures/tuple.pyi] [typing fixtures/typing-medium.pyi] - -- As Pattern -- -[case testAsPattern] + +[case testMatchAsPattern] m: int match m: @@ -956,51 +972,51 @@ match m: reveal_type(x) # N: Revealed type is "builtins.int" reveal_type(l) # N: Revealed type is "builtins.int" -[case testAsPatternNarrows] +[case testMatchAsPatternNarrows] m: object match m: case int() as l: reveal_type(l) # N: Revealed type is "builtins.int" -[case testAsPatternCapturesOr] +[case testMatchAsPatternCapturesOr] m: object match m: case 1 | 2 as n: - reveal_type(n) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]" + reveal_type(n) # N: Revealed type is "Union[Literal[1], Literal[2]]" -[case testAsPatternAlreadyNarrower] +[case testMatchAsPatternAlreadyNarrower] m: bool match m: case int() as l: reveal_type(l) # N: Revealed type is "builtins.bool" - -- Or Pattern -- -[case testOrPatternNarrows] + +[case testMatchOrPatternNarrows] m: object match m: case 1 | 2: - reveal_type(m) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]" + reveal_type(m) # N: Revealed type is "Union[Literal[1], Literal[2]]" -[case testOrPatternNarrowsStr] +[case testMatchOrPatternNarrowsStr] m: object match m: case "foo" | "bar": - reveal_type(m) # N: Revealed type is "Union[Literal['foo']?, Literal['bar']?]" + reveal_type(m) # N: Revealed type is "Union[Literal['foo'], Literal['bar']]" -[case testOrPatternNarrowsUnion] +[case testMatchOrPatternNarrowsUnion] m: object match m: case 1 | "foo": - reveal_type(m) # N: Revealed type is "Union[Literal[1]?, Literal['foo']?]" + reveal_type(m) # N: Revealed type is "Union[Literal[1], Literal['foo']]" -[case testOrPatterCapturesMissing] +[case testMatchOrPatterCapturesMissing] from typing import List m: List[int] @@ -1010,7 +1026,7 @@ match m: reveal_type(y) # N: Revealed type is "builtins.int*" [builtins fixtures/list.pyi] -[case testOrPatternCapturesJoin] +[case testMatchOrPatternCapturesJoin] m: object match m: @@ -1018,9 +1034,9 @@ match m: reveal_type(x) # N: Revealed type is "typing.Iterable[Any]" [builtins fixtures/dict.pyi] - -- Interactions -- -[case testCapturePatternMultipleCases] + +[case testMatchCapturePatternMultipleCases] m: object match m: @@ -1031,7 +1047,7 @@ match m: reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]" -[case testCapturePatternMultipleCaptures] +[case testMatchCapturePatternMultipleCaptures] from typing import Iterable m: Iterable[int] @@ -1041,7 +1057,7 @@ match m: reveal_type(x) # N: Revealed type is "builtins.int" [builtins fixtures/list.pyi] -[case testCapturePatternPreexistingSame] +[case testMatchCapturePatternPreexistingSame] a: int m: int @@ -1049,7 +1065,19 @@ match m: case a: reveal_type(a) # N: Revealed type is "builtins.int" -[case testCapturePatternPreexistingIncompatible] +[case testMatchCapturePatternPreexistingNarrows] +a: int +m: bool + +match m: + case a: + reveal_type(a) # N: Revealed type is "builtins.bool" + +reveal_type(a) # N: Revealed type is "builtins.bool" +a = 3 +reveal_type(a) # N: Revealed type is "builtins.int" + +[case testMatchCapturePatternPreexistingIncompatible] a: str m: int @@ -1057,7 +1085,9 @@ match m: case a: # E: Incompatible types in capture pattern (pattern captures type "int", variable has type "str") reveal_type(a) # N: Revealed type is "builtins.str" -[case testCapturePatternPreexistingIncompatibleLater] +reveal_type(a) # N: Revealed type is "builtins.str" + +[case testMatchCapturePatternPreexistingIncompatibleLater] a: str m: object @@ -1067,9 +1097,11 @@ match m: case int(a): # E: Incompatible types in capture pattern (pattern captures type "int", variable has type "str") reveal_type(a) # N: Revealed type is "builtins.str" +reveal_type(a) # N: Revealed type is "builtins.str" -- Guards -- -[case testSimplePatternGuard] + +[case testMatchSimplePatternGuard] m: str def guard() -> bool: ... @@ -1078,21 +1110,21 @@ match m: case a if guard(): reveal_type(a) # N: Revealed type is "builtins.str" -[case testAlwaysTruePatternGuard] +[case testMatchAlwaysTruePatternGuard] m: str match m: case a if True: reveal_type(a) # N: Revealed type is "builtins.str" -[case testAlwaysFalsePatternGuard] +[case testMatchAlwaysFalsePatternGuard] m: str match m: case a if False: reveal_type(a) -[case testRedefiningPatternGuard] +[case testMatchRedefiningPatternGuard] # flags: --strict-optional m: str @@ -1100,14 +1132,14 @@ match m: case a if a := 1: # E: Incompatible types in assignment (expression has type "int", variable has type "str") reveal_type(a) # N: Revealed type is "" -[case testAssigningPatternGuard] +[case testMatchAssigningPatternGuard] m: str match m: case a if a := "test": reveal_type(a) # N: Revealed type is "builtins.str" -[case testNarrowingPatternGuard] +[case testMatchNarrowingPatternGuard] m: object match m: @@ -1115,7 +1147,7 @@ match m: reveal_type(a) # N: Revealed type is "builtins.str" [builtins fixtures/isinstancelist.pyi] -[case testIncompatiblePatternGuard] +[case testMatchIncompatiblePatternGuard] class A: ... class B: ... @@ -1126,7 +1158,7 @@ match m: reveal_type(a) # N: Revealed type is "__main__." [builtins fixtures/isinstancelist.pyi] -[case testUnreachablePatternGuard] +[case testMatchUnreachablePatternGuard] m: str match m: @@ -1135,7 +1167,8 @@ match m: [builtins fixtures/isinstancelist.pyi] -- Exhaustiveness -- -[case testUnionNegativeNarrowing-skip] + +[case testMatchUnionNegativeNarrowing] from typing import Union m: Union[str, int] @@ -1148,7 +1181,7 @@ match m: reveal_type(b) # N: Revealed type is "builtins.int" reveal_type(m) # N: Revealed type is "builtins.int" -[case testOrPatternNegativeNarrowing-skip] +[case testMatchOrPatternNegativeNarrowing] from typing import Union m: Union[str, bytes, int] @@ -1160,7 +1193,7 @@ match m: case b: reveal_type(b) # N: Revealed type is "builtins.int" -[case testExhaustiveReturn-skip] +[case testMatchExhaustiveReturn] def foo(value) -> int: match value: case "bar": @@ -1168,10 +1201,378 @@ def foo(value) -> int: case _: return 2 -[case testNoneExhaustiveReturn-skip] +[case testMatchNonExhaustiveReturn] def foo(value) -> int: # E: Missing return statement match value: case "bar": return 1 case 2: return 2 + +[case testMatchMoreExhaustiveReturnCases] +def g(value: int | None) -> int: + match value: + case int(): + return 0 + case None: + return 1 + +def b(value: bool) -> int: + match value: + case True: + return 2 + case False: + return 3 + +[case testMatchMiscNonExhaustiveReturn] +class C: + a: int | str + +def f1(value: int | str | None) -> int: # E: Missing return statement + match value: + case int(): + return 0 + case None: + return 1 + +def f2(c: C) -> int: # E: Missing return statement + match c: + case C(a=int()): + return 0 + case C(a=str()): + return 1 + +def f3(x: list[str]) -> int: # E: Missing return statement + match x: + case [a]: + return 0 + case [a, b]: + return 1 + +def f4(x: dict[str, int]) -> int: # E: Missing return statement + match x: + case {'x': a}: + return 0 + +def f5(x: bool) -> int: # E: Missing return statement + match x: + case True: + return 0 +[builtins fixtures/dict.pyi] + +[case testMatchNonExhaustiveError] +from typing import NoReturn +def assert_never(x: NoReturn) -> None: ... + +def f(value: int) -> int: # E: Missing return statement + match value: + case 1: + return 0 + case 2: + return 1 + case o: + assert_never(o) # E: Argument 1 to "assert_never" has incompatible type "int"; expected "NoReturn" + +[case testMatchExhaustiveNoError] +from typing import NoReturn, Union, Literal +def assert_never(x: NoReturn) -> None: ... + +def f(value: Literal[1] | Literal[2]) -> int: + match value: + case 1: + return 0 + case 2: + return 1 + case o: + assert_never(o) +[typing fixtures/typing-medium.pyi] + +[case testMatchSequencePatternNegativeNarrowing] +from typing import Union, Sequence, Tuple + +m1: Sequence[int | str] + +match m1: + case [int()]: + reveal_type(m1) # N: Revealed type is "typing.Sequence[builtins.int]" + case r: + reveal_type(m1) # N: Revealed type is "typing.Sequence[Union[builtins.int, builtins.str]]" + +m2: Tuple[int | str] + +match m2: + case (int(),): + reveal_type(m2) # N: Revealed type is "Tuple[builtins.int]" + case r2: + reveal_type(m2) # N: Revealed type is "Tuple[builtins.str]" + +m3: Tuple[Union[int, str]] + +match m3: + case (1,): + reveal_type(m3) # N: Revealed type is "Tuple[Literal[1]]" + case r2: + reveal_type(m3) # N: Revealed type is "Tuple[Union[builtins.int, builtins.str]]" +[builtins fixtures/tuple.pyi] + +[case testMatchLiteralPatternEnumNegativeNarrowing] +from enum import Enum +class Medal(Enum): + gold = 1 + silver = 2 + bronze = 3 + +def f(m: Medal) -> int: + match m: + case Medal.gold: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]" + return 0 + case _: + reveal_type(m) # N: Revealed type is "Union[Literal[__main__.Medal.silver], Literal[__main__.Medal.bronze]]" + return 1 + +def g(m: Medal) -> int: + match m: + case Medal.gold: + return 0 + case Medal.silver: + return 1 + case Medal.bronze: + return 2 + +[case testMatchLiteralPatternEnumCustomEquals-skip] +from enum import Enum +class Medal(Enum): + gold = 1 + silver = 2 + bronze = 3 + + def __eq__(self, other) -> bool: ... + +m: Medal + +match m: + case Medal.gold: + reveal_type(m) # N: Revealed type is "Literal[__main__.Medal.gold]" + case _: + reveal_type(m) # N: Revealed type is "__main__.Medal" + +[case testMatchNarrowUsingPatternGuardSpecialCase] +def f(x: int | str) -> int: # E: Missing return statement + match x: + case x if isinstance(x, str): + return 0 + case int(): + return 1 +[builtins fixtures/isinstance.pyi] + +[case testMatchNarrowDownUnionPartially] +# flags: --strict-optional + +def f(x: int | str) -> None: + match x: + case int(): + return + reveal_type(x) # N: Revealed type is "builtins.str" + +def g(x: int | str | None) -> None: + match x: + case int() | None: + return + reveal_type(x) # N: Revealed type is "builtins.str" + +def h(x: int | str | None) -> None: + match x: + case int() | str(): + return + reveal_type(x) # N: Revealed type is "None" + +[case testMatchNarrowDownUsingLiteralMatch] +from enum import Enum +class Medal(Enum): + gold = 1 + silver = 2 + +def b1(x: bool) -> None: + match x: + case True: + return + reveal_type(x) # N: Revealed type is "Literal[False]" + +def b2(x: bool) -> None: + match x: + case False: + return + reveal_type(x) # N: Revealed type is "Literal[True]" + +def e1(x: Medal) -> None: + match x: + case Medal.gold: + return + reveal_type(x) # N: Revealed type is "Literal[__main__.Medal.silver]" + +def e2(x: Medal) -> None: + match x: + case Medal.silver: + return + reveal_type(x) # N: Revealed type is "Literal[__main__.Medal.gold]" + +def i(x: int) -> None: + match x: + case 1: + return + reveal_type(x) # N: Revealed type is "builtins.int" + +def s(x: str) -> None: + match x: + case 'x': + return + reveal_type(x) # N: Revealed type is "builtins.str" + +def union(x: str | bool) -> None: + match x: + case True: + return + reveal_type(x) # N: Revealed type is "Union[builtins.str, Literal[False]]" + +[case testMatchAssertFalseToSilenceFalsePositives] +class C: + a: int | str + +def f(c: C) -> int: + match c: + case C(a=int()): + return 0 + case C(a=str()): + return 1 + case _: + assert False + +def g(c: C) -> int: + match c: + case C(a=int()): + return 0 + case C(a=str()): + return 1 + assert False + +[case testMatchAsPatternExhaustiveness] +def f(x: int | str) -> int: + match x: + case int() as n: + return n + case str() as s: + return 1 + +[case testMatchAsPatternIntersection-skip] +class A: pass +class B: pass +class C: pass + +def f(x: A) -> None: + match x: + case B() as y: + reveal_type(y) # N: Revealed type is "__main__." + case C() as y: + reveal_type(y) # N: Revealed type is "__main__." + reveal_type(y) # N: Revealed type is "Union[__main__., __main__.]" + +[case testMatchWithBreakAndContinue] +# flags: --strict-optional +def f(x: int | str | None) -> None: + i = int() + while i: + match x: + case int(): + continue + case str(): + break + reveal_type(x) # N: Revealed type is "None" + reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str, None]" + +[case testMatchNarrowDownWithStarred-skip] +from typing import List +def f(x: List[int] | int) -> None: + match x: + case [*y]: + reveal_type(y) # N: Revealed type is "builtins.list[builtins.int*]" + return + reveal_type(x) # N: Revealed type is "builtins.int" +[builtins fixtures/list.pyi] + +-- Misc + +[case testMatchAndWithStatementScope] +from m import A, B + +with A() as x: + pass +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +with A() as y: + pass +with B() as y: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +with A() as z: + pass +with B() as z: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +with A() as zz: + pass +with B() as zz: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +match x: + case str(y) as z: + zz = y + +[file m.pyi] +from typing import Any + +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testOverrideMatchArgs] +class AST: + __match_args__ = () + +class stmt(AST): ... + +class AnnAssign(stmt): + __match_args__ = ('target', 'annotation', 'value', 'simple') + target: str + annotation: int + value: str + simple: int + +reveal_type(AST.__match_args__) # N: Revealed type is "Tuple[]" +reveal_type(stmt.__match_args__) # N: Revealed type is "Tuple[]" +reveal_type(AnnAssign.__match_args__) # N: Revealed type is "Tuple[Literal['target']?, Literal['annotation']?, Literal['value']?, Literal['simple']?]" + +AnnAssign.__match_args__ = ('a', 'b', 'c', 'd') # E: Cannot assign to "__match_args__" +__match_args__ = 0 + +def f(x: AST) -> None: + match x: + case AST(): + reveal_type(x) # N: Revealed type is "__main__.AST" + match x: + case stmt(): + reveal_type(x) # N: Revealed type is "__main__.stmt" + match x: + case AnnAssign(a, b, c, d): + reveal_type(a) # N: Revealed type is "builtins.str" + reveal_type(b) # N: Revealed type is "builtins.int" + reveal_type(c) # N: Revealed type is "builtins.str" +[builtins fixtures/tuple.pyi] diff --git a/test-data/unit/check-semanal-error.test b/test-data/unit/check-semanal-error.test index f91e3b1360c7..c6cf45d96691 100644 --- a/test-data/unit/check-semanal-error.test +++ b/test-data/unit/check-semanal-error.test @@ -77,10 +77,47 @@ continue # E: "continue" outside loop [case testYieldOutsideFunction] yield # E: "yield" outside function - -[case testYieldFromOutsideFunction] x = 1 yield from x # E: "yield from" outside function +[(yield 1) for _ in x] # E: "yield" inside comprehension or generator expression +{(yield 1) for _ in x} # E: "yield" inside comprehension or generator expression +{i: (yield 1) for i in x} # E: "yield" inside comprehension or generator expression +((yield 1) for _ in x) # E: "yield" inside comprehension or generator expression +y = 1 +[(yield from x) for _ in y] # E: "yield from" inside comprehension or generator expression +{(yield from x) for _ in y} # E: "yield from" inside comprehension or generator expression +{i: (yield from x) for i in y} # E: "yield from" inside comprehension or generator expression +((yield from x) for _ in y) # E: "yield from" inside comprehension or generator expression +def f(y): + [x for x in (yield y)] + {x for x in (yield y)} + {x: x for x in (yield y)} + (x for x in (yield y)) + [x for x in (yield from y)] + {x for x in (yield from y)} + {x: x for x in (yield from y)} + (x for x in (yield from y)) +def g(y): + [(yield 1) for _ in y] # E: "yield" inside comprehension or generator expression + {(yield 1) for _ in y} # E: "yield" inside comprehension or generator expression + {i: (yield 1) for i in y} # E: "yield" inside comprehension or generator expression + ((yield 1) for _ in y) # E: "yield" inside comprehension or generator expression + lst = 1 + [(yield from lst) for _ in y] # E: "yield from" inside comprehension or generator expression + {(yield from lst) for _ in y} # E: "yield from" inside comprehension or generator expression + {i: (yield from lst) for i in y} # E: "yield from" inside comprehension or generator expression + ((yield from lst) for _ in y) # E: "yield from" inside comprehension or generator expression +def h(y): + lst = 1 + [x for x in lst if (yield y)] # E: "yield" inside comprehension or generator expression + {x for x in lst if (yield y)} # E: "yield" inside comprehension or generator expression + {x: x for x in lst if (yield y)} # E: "yield" inside comprehension or generator expression + (x for x in lst if (yield y)) # E: "yield" inside comprehension or generator expression + lst = 1 + [x for x in lst if (yield from y)] # E: "yield from" inside comprehension or generator expression + {x for x in lst if (yield from y)} # E: "yield from" inside comprehension or generator expression + {x: x for x in lst if (yield from y)} # E: "yield from" inside comprehension or generator expression + (x for x in lst if (yield from y)) # E: "yield from" inside comprehension or generator expression [case testImportFuncDup] diff --git a/test-data/unit/check-statements.test b/test-data/unit/check-statements.test index 62d82f94a6c1..5819ace83603 100644 --- a/test-data/unit/check-statements.test +++ b/test-data/unit/check-statements.test @@ -1555,7 +1555,6 @@ class LiteralReturn: return False [builtins fixtures/bool.pyi] - [case testWithStmtBoolExitReturnInStub] import stub @@ -1572,6 +1571,370 @@ class C3: def __exit__(self, x, y, z) -> Optional[bool]: pass [builtins fixtures/bool.pyi] +[case testWithStmtScopeBasics] +from m import A, B + +def f1() -> None: + with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + with B() as x: + reveal_type(x) # N: Revealed type is "m.B" + +def f2() -> None: + with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + y = x # Use outside with makes the scope function-level + with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndFuncDef] +from m import A, B + +with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + +def f() -> None: + pass # Don't support function definition in the middle + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndFuncDef2] +from m import A, B + +def f() -> None: + pass # function before with is unsupported + +with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndFuncDef3] +from m import A, B + +with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +def f() -> None: + pass # function after with is unsupported + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndFuncDef4] +from m import A, B + +with A() as x: + def f() -> None: + pass # Function within with is unsupported + + reveal_type(x) # N: Revealed type is "m.A" + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndImport1] +from m import A, B, x + +with A() as x: \ + # E: Incompatible types in assignment (expression has type "A", variable has type "B") + reveal_type(x) # N: Revealed type is "m.B" + +with B() as x: + reveal_type(x) # N: Revealed type is "m.B" + +[file m.pyi] +x: B + +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndImport2] +from m import A, B +import m as x + +with A() as x: \ + # E: Incompatible types in assignment (expression has type "A", variable has type Module) + pass + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type Module) + pass + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... +[builtins fixtures/module.pyi] + +[case testWithStmtScopeAndImportStar] +from m import A, B +from m import * + +with A() as x: + pass + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeNestedWith1] +from m import A, B + +with A() as x: + with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + reveal_type(x) # N: Revealed type is "m.A" + +with B() as x: + with A() as x: \ + # E: Incompatible types in assignment (expression has type "A", variable has type "B") + reveal_type(x) # N: Revealed type is "m.B" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeNestedWith2] +from m import A, B + +with A() as x: + with A() as y: + reveal_type(y) # N: Revealed type is "m.A" + with B() as y: + reveal_type(y) # N: Revealed type is "m.B" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeInnerAndOuterScopes] +from m import A, B + +x = A() # Outer scope should have no impact + +with A() as x: + pass + +def f() -> None: + with A() as x: + reveal_type(x) # N: Revealed type is "m.A" + with B() as x: + reveal_type(x) # N: Revealed type is "m.B" + +y = x + +with A() as x: + pass + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeMultipleContextManagers] +from m import A, B + +with A() as x, B() as y: + reveal_type(x) # N: Revealed type is "m.A" + reveal_type(y) # N: Revealed type is "m.B" +with B() as x, A() as y: + reveal_type(x) # N: Revealed type is "m.B" + reveal_type(y) # N: Revealed type is "m.A" + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeMultipleAssignment] +from m import A, B + +with A() as (x, y): + reveal_type(x) # N: Revealed type is "m.A" + reveal_type(y) # N: Revealed type is "builtins.int" +with B() as [x, y]: + reveal_type(x) # N: Revealed type is "m.B" + reveal_type(y) # N: Revealed type is "builtins.str" + +[file m.pyi] +from typing import Tuple + +class A: + def __enter__(self) -> Tuple[A, int]: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> Tuple[B, str]: ... + def __exit__(self, x, y, z) -> None: ... +[builtins fixtures/tuple.pyi] + +[case testWithStmtScopeComplexAssignments] +from m import A, B, f + +with A() as x: + pass +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass +with B() as f(x).x: + pass + +with A() as y: + pass +with B() as y: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass +with B() as f(y)[0]: + pass + +[file m.pyi] +def f(x): ... + +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndClass] +from m import A, B + +with A() as x: + pass + +class C: + with A() as y: + pass + with B() as y: + pass + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass + +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeInnerScopeReference] +from m import A, B + +with A() as x: + def f() -> A: + return x + f() + +with B() as x: \ + # E: Incompatible types in assignment (expression has type "B", variable has type "A") + pass +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + +[case testWithStmtScopeAndLambda] +from m import A, B + +# This is technically not correct, since the lambda can outlive the with +# statement, but this behavior seems more intuitive. + +with A() as x: + lambda: reveal_type(x) # N: Revealed type is "m.A" + +with B() as x: + pass +[file m.pyi] +class A: + def __enter__(self) -> A: ... + def __exit__(self, x, y, z) -> None: ... +class B: + def __enter__(self) -> B: ... + def __exit__(self, x, y, z) -> None: ... + -- Chained assignment -- ------------------ diff --git a/test-data/unit/check-type-aliases.test b/test-data/unit/check-type-aliases.test index cb023fc0ad3f..4c5dacee1b3f 100644 --- a/test-data/unit/check-type-aliases.test +++ b/test-data/unit/check-type-aliases.test @@ -57,7 +57,7 @@ Never = NoReturn a: Never # Used to be an error here def f(a: Never): ... -f(5) # E: Argument 1 to "f" has incompatible type "int"; expected "NoReturn" +f(5) # E: Argument 1 to "f" has incompatible type "int"; expected "NoReturn" [case testImportUnionAlias] import typing from _m import U @@ -702,6 +702,30 @@ x: TypeAlias = list(int) # E: Invalid type alias: expression is not a valid typ a: x [builtins fixtures/tuple.pyi] +[case testAliasedImportPep613] +import typing as tpp +import typing_extensions as tpx +from typing import TypeAlias as TPA +from typing_extensions import TypeAlias as TXA +import typing +import typing_extensions + +Int1: tpp.TypeAlias = int +Int2: tpx.TypeAlias = int +Int3: TPA = int +Int4: TXA = int +Int5: typing.TypeAlias = int +Int6: typing_extensions.TypeAlias = int + +x1: Int1 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +x2: Int2 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +x3: Int3 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +x4: Int4 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +x5: Int5 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +x6: Int6 = "str" # E: Incompatible types in assignment (expression has type "str", variable has type "int") +[builtins fixtures/tuple.pyi] +[typing fixtures/typing-medium.pyi] + [case testFunctionScopePep613] from typing_extensions import TypeAlias diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 921d2ab5c46e..a9321826b3ba 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -2208,6 +2208,12 @@ class Movie(TypedDict, total=False): year: int [typing fixtures/typing-typeddict.pyi] +[case testRequiredExplicitAny] +# flags: --disallow-any-explicit +from typing import TypedDict +from typing import Required +Foo = TypedDict("Foo", {"a.x": Required[int]}) +[typing fixtures/typing-typeddict.pyi] -- NotRequired[] @@ -2271,6 +2277,13 @@ class Movie(TypedDict): year: int [typing fixtures/typing-typeddict.pyi] +[case testNotRequiredExplicitAny] +# flags: --disallow-any-explicit +from typing import TypedDict +from typing import NotRequired +Foo = TypedDict("Foo", {"a.x": NotRequired[int]}) +[typing fixtures/typing-typeddict.pyi] + -- Union dunders [case testTypedDictUnionGetItem] diff --git a/test-data/unit/check-union-or-syntax.test b/test-data/unit/check-union-or-syntax.test index 3e5a19b8fe61..58526cfd0623 100644 --- a/test-data/unit/check-union-or-syntax.test +++ b/test-data/unit/check-union-or-syntax.test @@ -196,3 +196,30 @@ def f(x: Union[int, str, None]) -> None: else: reveal_type(x) # N: Revealed type is "None" [builtins fixtures/isinstance.pyi] + +[case testImplicit604TypeAliasWithCyclicImportInStub] +# flags: --python-version 3.10 +from was_builtins import foo +reveal_type(foo) # N: Revealed type is "Union[builtins.str, was_mmap.mmap]" +[file was_builtins.pyi] +import was_mmap +WriteableBuffer = was_mmap.mmap +ReadableBuffer = str | WriteableBuffer +foo: ReadableBuffer +[file was_mmap.pyi] +from was_builtins import * +class mmap: ... + +# TODO: Get this test to pass +[case testImplicit604TypeAliasWithCyclicImportNotInStub-xfail] +# flags: --python-version 3.10 +from was_builtins import foo +reveal_type(foo) # N: Revealed type is "Union[builtins.str, was_mmap.mmap]" +[file was_builtins.py] +import was_mmap +WriteableBuffer = was_mmap.mmap +ReadableBuffer = str | WriteableBuffer +foo: ReadableBuffer +[file was_mmap.py] +from was_builtins import * +class mmap: ... diff --git a/test-data/unit/check-unreachable-code.test b/test-data/unit/check-unreachable-code.test index de85f5188bb8..ad604b474ad4 100644 --- a/test-data/unit/check-unreachable-code.test +++ b/test-data/unit/check-unreachable-code.test @@ -936,6 +936,26 @@ if False: reveal_type(x) [builtins fixtures/exception.pyi] +[case testNeverVariants] +from typing import Never +from typing_extensions import Never as TENever +from typing import NoReturn +from typing_extensions import NoReturn as TENoReturn +from mypy_extensions import NoReturn as MENoReturn + +bottom1: Never +reveal_type(bottom1) # N: Revealed type is "" +bottom2: TENever +reveal_type(bottom2) # N: Revealed type is "" +bottom3: NoReturn +reveal_type(bottom3) # N: Revealed type is "" +bottom4: TENoReturn +reveal_type(bottom4) # N: Revealed type is "" +bottom5: MENoReturn +reveal_type(bottom5) # N: Revealed type is "" + +[builtins fixtures/tuple.pyi] + [case testUnreachableFlagExpressions] # flags: --warn-unreachable def foo() -> bool: ... diff --git a/test-data/unit/cmdline.pyproject.test b/test-data/unit/cmdline.pyproject.test index ea561ed164e7..831bce2eb63d 100644 --- a/test-data/unit/cmdline.pyproject.test +++ b/test-data/unit/cmdline.pyproject.test @@ -125,3 +125,11 @@ i: int = 0 This isn't even syntatically valid! [file x/please_skipme_.py] Neither is this! + +[case testPyprojectTOMLUnicode] +# cmd: mypy x.py +[file pyproject.toml] +\[project] +description = "Factory ⸻ A code generator 🏭" +\[tool.mypy] +[file x.py] diff --git a/test-data/unit/cmdline.test b/test-data/unit/cmdline.test index 690b0cc06709..f29c183f20ba 100644 --- a/test-data/unit/cmdline.test +++ b/test-data/unit/cmdline.test @@ -59,7 +59,8 @@ undef undef [out] dir/a.py: error: Duplicate module named "a" (also at "dir/subdir/a.py") -dir/a.py: note: Are you missing an __init__.py? Alternatively, consider using --exclude to avoid checking one of them. +dir/a.py: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules for more info +dir/a.py: note: Common resolutions include: a) using `--exclude` to avoid checking one of them, b) adding `__init__.py` somewhere, c) using `--explicit-package-bases` or adjusting MYPYPATH == Return code: 2 [case testCmdlineNonPackageSlash] @@ -125,7 +126,8 @@ mypy: can't decode file 'a.py': unknown encoding: uft-8 # type: ignore [out] two/mod/__init__.py: error: Duplicate module named "mod" (also at "one/mod/__init__.py") -two/mod/__init__.py: note: Are you missing an __init__.py? Alternatively, consider using --exclude to avoid checking one of them. +two/mod/__init__.py: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules for more info +two/mod/__init__.py: note: Common resolutions include: a) using `--exclude` to avoid checking one of them, b) adding `__init__.py` somewhere, c) using `--explicit-package-bases` or adjusting MYPYPATH == Return code: 2 [case testFlagsFile] @@ -1144,6 +1146,7 @@ import foo.bar [out] src/foo/bar.py: error: Source file found twice under different module names: "src.foo.bar" and "foo.bar" src/foo/bar.py: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules for more info +src/foo/bar.py: note: Common resolutions include: a) adding `__init__.py` somewhere, b) using `--explicit-package-bases` or adjusting MYPYPATH == Return code: 2 [case testEnableInvalidErrorCode] diff --git a/test-data/unit/fine-grained-modules.test b/test-data/unit/fine-grained-modules.test index 856eaaad083c..80a2883ee756 100644 --- a/test-data/unit/fine-grained-modules.test +++ b/test-data/unit/fine-grained-modules.test @@ -1509,11 +1509,12 @@ class C: pass main:3: error: Name "f" is not defined main:4: error: Name "C" is not defined == -main:3: error: Missing positional argument "x" in call to "f" +main:2: error: Unsupported class scoped import main:4: error: Name "C" is not defined == -main:3: error: Missing positional argument "x" in call to "f" +main:2: error: Unsupported class scoped import == +main:2: error: Unsupported class scoped import [case testImportStarAddMissingDependencyInsidePackage1] from p.b import f diff --git a/test-data/unit/fine-grained.test b/test-data/unit/fine-grained.test index ad67ff19dfd2..86872277c6e3 100644 --- a/test-data/unit/fine-grained.test +++ b/test-data/unit/fine-grained.test @@ -2084,6 +2084,7 @@ a.py:5: error: "list" expects 1 type argument, but 2 given == [case testPreviousErrorInOverloadedFunction] +# flags: --strict-optional import a [file a.py] from typing import overload diff --git a/test-data/unit/fixtures/any.pyi b/test-data/unit/fixtures/any.pyi new file mode 100644 index 000000000000..d6d90b7b3e98 --- /dev/null +++ b/test-data/unit/fixtures/any.pyi @@ -0,0 +1,8 @@ +from typing import TypeVar, Iterable + +T = TypeVar('T') + +class int: pass +class str: pass + +def any(i: Iterable[T]) -> bool: pass diff --git a/test-data/unit/fixtures/typing-medium.pyi b/test-data/unit/fixtures/typing-medium.pyi index 7717a6bf1749..923ede2f0c00 100644 --- a/test-data/unit/fixtures/typing-medium.pyi +++ b/test-data/unit/fixtures/typing-medium.pyi @@ -26,6 +26,7 @@ Literal = 0 TypedDict = 0 NoReturn = 0 NewType = 0 +TypeAlias = 0 T = TypeVar('T') T_co = TypeVar('T_co', covariant=True) diff --git a/test-data/unit/fixtures/typing-typeddict.pyi b/test-data/unit/fixtures/typing-typeddict.pyi index 72f500707094..378570b4c19c 100644 --- a/test-data/unit/fixtures/typing-typeddict.pyi +++ b/test-data/unit/fixtures/typing-typeddict.pyi @@ -43,7 +43,8 @@ class Iterator(Iterable[T_co], Protocol): def __next__(self) -> T_co: pass class Sequence(Iterable[T_co]): - def __getitem__(self, n: Any) -> T_co: pass + # misc is for explicit Any. + def __getitem__(self, n: Any) -> T_co: pass # type: ignore[misc] class Mapping(Iterable[T], Generic[T, T_co], metaclass=ABCMeta): def __getitem__(self, key: T) -> T_co: pass diff --git a/test-data/unit/lib-stub/attr/__init__.pyi b/test-data/unit/lib-stub/attr/__init__.pyi index 6ce4b3a64ed5..795e5d3f4f69 100644 --- a/test-data/unit/lib-stub/attr/__init__.pyi +++ b/test-data/unit/lib-stub/attr/__init__.pyi @@ -94,6 +94,7 @@ def attrs(maybe_cls: _C, cache_hash: bool = ..., eq: Optional[bool] = ..., order: Optional[bool] = ..., + match_args: bool = ..., ) -> _C: ... @overload def attrs(maybe_cls: None = ..., @@ -112,6 +113,7 @@ def attrs(maybe_cls: None = ..., cache_hash: bool = ..., eq: Optional[bool] = ..., order: Optional[bool] = ..., + match_args: bool = ..., ) -> Callable[[_C], _C]: ... diff --git a/test-data/unit/lib-stub/enum.pyi b/test-data/unit/lib-stub/enum.pyi index 2c1b03532a5b..11adfc597955 100644 --- a/test-data/unit/lib-stub/enum.pyi +++ b/test-data/unit/lib-stub/enum.pyi @@ -43,3 +43,8 @@ class IntFlag(int, Flag): class auto(IntFlag): value: Any + + +# It is python-3.11+ only: +class StrEnum(str, Enum): + def __new__(cls: Type[_T], value: str | _T) -> _T: ... diff --git a/test-data/unit/lib-stub/typing.pyi b/test-data/unit/lib-stub/typing.pyi index b9f1752aee1b..1a6c5d36a367 100644 --- a/test-data/unit/lib-stub/typing.pyi +++ b/test-data/unit/lib-stub/typing.pyi @@ -23,6 +23,7 @@ Type = 0 ClassVar = 0 Final = 0 NoReturn = 0 +Never = 0 NewType = 0 ParamSpec = 0 @@ -47,3 +48,5 @@ class Sequence(Iterable[T_co]): class Mapping(Iterable[T], Generic[T, T_co]): pass def final(meth: T) -> T: pass + +def reveal_type(__obj: T) -> T: pass diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 5b32449e71cf..38ff331f45d8 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -1,4 +1,4 @@ -from typing import TypeVar, Any, Mapping, Iterator, NoReturn, Dict, Type +from typing import TypeVar, Any, Mapping, Iterator, NoReturn as NoReturn, Dict, Type from typing import TYPE_CHECKING as TYPE_CHECKING from typing import NewType as NewType @@ -27,6 +27,7 @@ Concatenate: _SpecialForm TypeAlias: _SpecialForm TypeGuard: _SpecialForm +Never: _SpecialForm # Fallback type for all typed dicts (does not exist at runtime). class _TypedDict(Mapping[str, object]): @@ -44,3 +45,5 @@ class _TypedDict(Mapping[str, object]): def __delitem__(self, k: NoReturn) -> None: ... def TypedDict(typename: str, fields: Dict[str, Type[_T]], *, total: Any = ...) -> Type[dict]: ... + +def reveal_type(__obj: T) -> T: pass diff --git a/test-data/unit/plugins/arg_kinds.py b/test-data/unit/plugins/arg_kinds.py index 5392e64c4f11..7b269a54710b 100644 --- a/test-data/unit/plugins/arg_kinds.py +++ b/test-data/unit/plugins/arg_kinds.py @@ -1,7 +1,7 @@ from typing import Optional, Callable from mypy.plugin import Plugin, MethodContext, FunctionContext from mypy.types import Type - +from mypy.message_registry import ErrorMessage class ArgKindsPlugin(Plugin): def get_function_hook(self, fullname: str @@ -18,12 +18,14 @@ def get_method_hook(self, fullname: str def extract_arg_kinds_from_function(ctx: FunctionContext) -> Type: - ctx.api.fail(str([[x.value for x in y] for y in ctx.arg_kinds]), ctx.context) + error_message = ErrorMessage(str([[x.value for x in y] for y in ctx.arg_kinds])) + ctx.api.fail(error_message, ctx.context) return ctx.default_return_type def extract_arg_kinds_from_method(ctx: MethodContext) -> Type: - ctx.api.fail(str([[x.value for x in y] for y in ctx.arg_kinds]), ctx.context) + error_message = ErrorMessage(str([[x.value for x in y] for y in ctx.arg_kinds])) + ctx.api.fail(error_message, ctx.context) return ctx.default_return_type diff --git a/test-data/unit/plugins/attrhook2.py b/test-data/unit/plugins/attrhook2.py index cc14341a6f97..0030c0d2d470 100644 --- a/test-data/unit/plugins/attrhook2.py +++ b/test-data/unit/plugins/attrhook2.py @@ -1,5 +1,6 @@ from typing import Optional, Callable +from mypy.message_registry import ErrorMessage from mypy.plugin import Plugin, AttributeContext from mypy.types import Type, AnyType, TypeOfAny @@ -18,7 +19,7 @@ def magic_field_callback(ctx: AttributeContext) -> Type: def nonexistent_field_callback(ctx: AttributeContext) -> Type: - ctx.api.fail("Field does not exist", ctx.context) + ctx.api.fail(ErrorMessage("Field does not exist"), ctx.context) return AnyType(TypeOfAny.from_error) diff --git a/test-data/unit/plugins/type_anal_hook.py b/test-data/unit/plugins/type_anal_hook.py index 86d18d8c8611..d54428c59928 100644 --- a/test-data/unit/plugins/type_anal_hook.py +++ b/test-data/unit/plugins/type_anal_hook.py @@ -1,5 +1,6 @@ from typing import Optional, Callable +from mypy.message_registry import ErrorMessage from mypy.plugin import Plugin, AnalyzeTypeContext from mypy.types import Type, TypeList, AnyType, CallableType, TypeOfAny # The official name changed to NoneType but we have an alias for plugin compat reasons @@ -17,7 +18,8 @@ def get_type_analyze_hook(self, fullname: str def signal_type_analyze_callback(ctx: AnalyzeTypeContext) -> Type: if (len(ctx.type.args) != 1 or not isinstance(ctx.type.args[0], TypeList)): - ctx.api.fail('Invalid "Signal" type (expected "Signal[[t, ...]]")', ctx.context) + ctx.api.fail(ErrorMessage('Invalid "Signal" type (expected "Signal[[t, ...]]")'), + ctx.context) return AnyType(TypeOfAny.from_error) args = ctx.type.args[0] diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index ab1593dac754..de15055927ae 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -271,8 +271,8 @@ f.write('x') f.write(b'x') f.foobar() [out] -_program.py:3: error: Argument 1 to "write" of "IO" has incompatible type "bytes"; expected "str" -_program.py:4: error: "TextIO" has no attribute "foobar" +_program.py:3: error: Argument 1 to "write" of "TextIOBase" has incompatible type "bytes"; expected "str" +_program.py:4: error: "TextIOWrapper" has no attribute "foobar" [case testOpenReturnTypeInference] reveal_type(open('x')) @@ -281,9 +281,9 @@ reveal_type(open('x', 'rb')) mode = 'rb' reveal_type(open('x', mode)) [out] -_program.py:1: note: Revealed type is "typing.TextIO" -_program.py:2: note: Revealed type is "typing.TextIO" -_program.py:3: note: Revealed type is "typing.BinaryIO" +_program.py:1: note: Revealed type is "io.TextIOWrapper" +_program.py:2: note: Revealed type is "io.TextIOWrapper" +_program.py:3: note: Revealed type is "io.BufferedReader" _program.py:5: note: Revealed type is "typing.IO[Any]" [case testOpenReturnTypeInferenceSpecialCases] @@ -292,8 +292,8 @@ reveal_type(open(file='x', mode='rb')) mode = 'rb' reveal_type(open(mode=mode, file='r')) [out] -_testOpenReturnTypeInferenceSpecialCases.py:1: note: Revealed type is "typing.BinaryIO" -_testOpenReturnTypeInferenceSpecialCases.py:2: note: Revealed type is "typing.BinaryIO" +_testOpenReturnTypeInferenceSpecialCases.py:1: note: Revealed type is "io.BufferedReader" +_testOpenReturnTypeInferenceSpecialCases.py:2: note: Revealed type is "io.BufferedReader" _testOpenReturnTypeInferenceSpecialCases.py:4: note: Revealed type is "typing.IO[Any]" [case testPathOpenReturnTypeInference] @@ -305,21 +305,21 @@ reveal_type(p.open('rb')) mode = 'rb' reveal_type(p.open(mode)) [out] -_program.py:3: note: Revealed type is "typing.TextIO" -_program.py:4: note: Revealed type is "typing.TextIO" -_program.py:5: note: Revealed type is "typing.BinaryIO" +_program.py:3: note: Revealed type is "io.TextIOWrapper" +_program.py:4: note: Revealed type is "io.TextIOWrapper" +_program.py:5: note: Revealed type is "io.BufferedReader" _program.py:7: note: Revealed type is "typing.IO[Any]" [case testPathOpenReturnTypeInferenceSpecialCases] from pathlib import Path p = Path("x") -reveal_type(p.open(mode='rb', errors='replace')) -reveal_type(p.open(errors='replace', mode='rb')) -mode = 'rb' +reveal_type(p.open(mode='r', errors='replace')) +reveal_type(p.open(errors='replace', mode='r')) +mode = 'r' reveal_type(p.open(mode=mode, errors='replace')) [out] -_program.py:3: note: Revealed type is "typing.BinaryIO" -_program.py:4: note: Revealed type is "typing.BinaryIO" +_program.py:3: note: Revealed type is "io.TextIOWrapper" +_program.py:4: note: Revealed type is "io.TextIOWrapper" _program.py:6: note: Revealed type is "typing.IO[Any]" [case testGenericPatterns] @@ -1112,7 +1112,7 @@ c2 = Cell2() reveal_type(c2.pop('value')) [out] _testTypedDictMappingMethods.py:5: note: Revealed type is "builtins.str*" -_testTypedDictMappingMethods.py:6: note: Revealed type is "typing.Iterator[builtins.str*]" +_testTypedDictMappingMethods.py:6: note: Revealed type is "typing.Iterator*[builtins.str*]" _testTypedDictMappingMethods.py:7: note: Revealed type is "builtins.int" _testTypedDictMappingMethods.py:8: note: Revealed type is "builtins.bool" _testTypedDictMappingMethods.py:9: note: Revealed type is "typing.KeysView[builtins.str]" @@ -1152,7 +1152,8 @@ _testCanConvertTypedDictToAnySuperclassOfMapping.py:11: note: def __iter _testCanConvertTypedDictToAnySuperclassOfMapping.py:11: note: Got: _testCanConvertTypedDictToAnySuperclassOfMapping.py:11: note: def __iter__(self) -> Iterator[str] -[case testAsyncioGatherPreciseType] +[case testAsyncioGatherPreciseType-xfail] +# Mysteriously regressed in #11905 import asyncio from typing import Tuple @@ -1328,7 +1329,7 @@ def f() -> Dict[int, str]: def d() -> Dict[int, int]: return {} [out] -_testDictWithStarStarSpecialCase.py:4: error: Argument 1 to "update" of "dict" has incompatible type "Dict[int, int]"; expected "Mapping[int, str]" +_testDictWithStarStarSpecialCase.py:4: error: Argument 1 to "update" of "MutableMapping" has incompatible type "Dict[int, int]"; expected "SupportsKeysAndGetItem[int, str]" [case testLoadsOfOverloads] from typing import overload, Any, TypeVar, Iterable, List, Dict, Callable, Union diff --git a/test-data/unit/semanal-modules.test b/test-data/unit/semanal-modules.test index 86bb82d7bd69..16b9a9b18250 100644 --- a/test-data/unit/semanal-modules.test +++ b/test-data/unit/semanal-modules.test @@ -568,7 +568,7 @@ MypyFile:1( ImportFrom:2(_x, [y]) AssignmentStmt:3( NameExpr(z* [m]) - NameExpr(y [_x.y])))) + NameExpr(y [__main__.A.y])))) [case testImportInClassBody2] class A: diff --git a/test-data/unit/semanal-statements.test b/test-data/unit/semanal-statements.test index 97dd5f048834..fdc5ca2bbbdd 100644 --- a/test-data/unit/semanal-statements.test +++ b/test-data/unit/semanal-statements.test @@ -1058,3 +1058,59 @@ MypyFile:1( AssignmentStmt:6( NameExpr(x [__main__.x]) StrExpr())) + +[case testSimpleWithRenaming] +with 0 as y: + z = y +with 1 as y: + y = 1 +[out] +MypyFile:1( + WithStmt:1( + Expr( + IntExpr(0)) + Target( + NameExpr(y'* [__main__.y'])) + Block:1( + AssignmentStmt:2( + NameExpr(z* [__main__.z]) + NameExpr(y' [__main__.y'])))) + WithStmt:3( + Expr( + IntExpr(1)) + Target( + NameExpr(y* [__main__.y])) + Block:3( + AssignmentStmt:4( + NameExpr(y [__main__.y]) + IntExpr(1))))) + +[case testSimpleWithRenamingFailure] +with 0 as y: + z = y +zz = y +with 1 as y: + y = 1 +[out] +MypyFile:1( + WithStmt:1( + Expr( + IntExpr(0)) + Target( + NameExpr(y* [__main__.y])) + Block:1( + AssignmentStmt:2( + NameExpr(z* [__main__.z]) + NameExpr(y [__main__.y])))) + AssignmentStmt:3( + NameExpr(zz* [__main__.zz]) + NameExpr(y [__main__.y])) + WithStmt:4( + Expr( + IntExpr(1)) + Target( + NameExpr(y [__main__.y])) + Block:4( + AssignmentStmt:5( + NameExpr(y [__main__.y]) + IntExpr(1))))) diff --git a/test-data/unit/semanal-typeddict.test b/test-data/unit/semanal-typeddict.test index 4a74dc6e1cf3..b9eb6e0c2b13 100644 --- a/test-data/unit/semanal-typeddict.test +++ b/test-data/unit/semanal-typeddict.test @@ -1,17 +1,5 @@ -- Create Type --- TODO: Implement support for this syntax. ---[case testCanCreateTypedDictTypeWithKeywordArguments] ---from mypy_extensions import TypedDict ---Point = TypedDict('Point', x=int, y=int) ---[builtins fixtures/dict.pyi] ---[out] ---MypyFile:1( --- ImportFrom:1(mypy_extensions, [TypedDict]) --- AssignmentStmt:2( --- NameExpr(Point* [__main__.Point]) --- TypedDictExpr:2(Point))) - -- TODO: Implement support for this syntax. --[case testCanCreateTypedDictTypeWithDictCall] --from mypy_extensions import TypedDict diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index e20073027db2..6592791f9aa3 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -2580,3 +2580,8 @@ class A: def f(x: int, y: int) -> int: ... @t.overload def f(x: t.Tuple[int, int]) -> int: ... + +[case testNonDefaultKeywordOnlyArgAfterAsterisk] +def func(*, non_default_kwarg: bool, default_kwarg: bool = True): ... +[out] +def func(*, non_default_kwarg: bool, default_kwarg: bool = ...): ... diff --git a/test-requirements.txt b/test-requirements.txt index d4e21592721b..a3d11872fd5c 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,13 +2,13 @@ -r build-requirements.txt attrs>=18.0 flake8==3.9.2 -flake8-bugbear +flake8-bugbear==22.3.20 flake8-pyi>=20.5 lxml>=4.4.0; python_version<'3.11' psutil>=4.0 # pytest 6.2.3 does not support Python 3.10 -pytest>=6.2.4,<7.0.0 -pytest-xdist>=1.34.0,<2.0.0 +pytest>=6.2.4 +pytest-xdist>=1.34.0 pytest-forked>=1.3.0,<2.0.0 pytest-cov>=2.10.0,<3.0.0 py>=1.5.2