Compare commits

..

9 Commits

Author SHA1 Message Date
David Peter
4247a4d90c [red-knot] Do not merge: Run ecosystem checks with 3.9 2025-04-15 09:48:35 +02:00
github-actions[bot]
4894f52bae Sync vendored typeshed stubs (#17402)
Close and reopen this PR to trigger CI

---------

Co-authored-by: typeshedbot <>
Co-authored-by: David Peter <mail@david-peter.de>
2025-04-15 09:16:42 +02:00
Mike Perlov
3b24fe5c07 [red-knot] improve function/bound method type display (#17294)
## Summary

* Partial #17238
* Flyby from discord discussion - `todo_type!` now statically checks for
no parens in the message to avoid issues between debug & release build
tests

## Test Plan

many mdtests are changing
2025-04-14 15:56:18 -07:00
Dhruv Manilawala
b5d529e976 [red-knot] Move relation methods from CallableType to Signature (#17365)
## Summary

This PR moves all the relation methods from `CallableType` to
`Signature`.

The main reason for this is that `Signature` is going to be the common
denominator between normal and overloaded callables and the core logic
to check a certain relationship is going to just require the information
that would exists on `Signature`. For example, to check whether an
overloaded callable is a subtype of a normal callable, we need to check
whether _every_ overloaded signature is a subtype of the normal
callable's signature. This "every" logic would become part of the
`CallableType` and the core logic of checking the subtyping would exists
on `Signature`.
2025-04-15 03:32:25 +05:30
Brent Westbrook
014bb526f4 [syntax-errors] await outside async functions (#17363)
Summary
--

This PR implements detecting the use of `await` expressions outside of
async functions. This is a reimplementation of
[await-outside-async
(PLE1142)](https://docs.astral.sh/ruff/rules/await-outside-async/) as a
semantic syntax error.

Despite the rule name, PLE1142 also applies to `async for` and `async
with`, so these are covered here too.

Test Plan
--

Existing PLE1142 tests.

I also deleted more code from the `SemanticSyntaxCheckerVisitor` to
avoid changes in other parser tests.
2025-04-14 13:01:48 -04:00
Carl Meyer
e2a38e4c00 [red-knot] optimize is_subtype_of for literals (#17394)
## Summary

Allows us to establish that two literals do not have a subtype
relationship with each other, without having to fallback to a typeshed
Instance type, which is comparatively slow.

Improves the performance of the many-string-literals union benchmark by
5x.

## Test Plan

`cargo test -p red_knot_python_semantic` and `cargo bench --bench
red_knot`.
2025-04-14 09:42:44 -07:00
Carl Meyer
9bee9429de [red-knot] add a large-union-of-string-literals benchmark (#17393)
## Summary

Add a benchmark for a large-union case that currently has exponential
blow-up in execution time.

## Test Plan

`cargo bench --bench red_knot`
2025-04-14 09:40:46 -07:00
renovate[bot]
17e5b61c54 Update pre-commit dependencies (#17383) 2025-04-14 17:14:38 +01:00
David Peter
701aecb2a6 [red-knot] mypy_primer: Fail job on panic or internal errors (#17389)
## Summary

Let the mypy_primer job fail if Red Knot panics or exits with code 2
(indicating an internal error).

Corresponding mypy_primer commit:
90808f4656

In addition, we may also want to make a successful mypy_primer run
required for merging?

## Test Plan

Made sure that mypy_primer exits with code 70 locally on panics, which
should result in a pipeline failure, since we only allow code 0 and 1 in
the pipeline here:
a4d7c6669b/.github/workflows/mypy_primer.yaml (L73)
2025-04-14 11:50:17 +00:00
191 changed files with 2544 additions and 4112 deletions

View File

@@ -45,7 +45,7 @@ jobs:
- name: Install mypy_primer
run: |
uv tool install "git+https://github.com/astral-sh/mypy_primer.git@add-red-knot-support-v4"
uv tool install "git+https://github.com/astral-sh/mypy_primer.git@add-red-knot-support-v5"
- name: Run mypy_primer
shell: bash

View File

@@ -79,7 +79,7 @@ repos:
pass_filenames: false # This makes it a lot faster
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.4
rev: v0.11.5
hooks:
- id: ruff-format
- id: ruff
@@ -102,7 +102,7 @@ repos:
- id: zizmor
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.32.1
rev: 0.33.0
hooks:
- id: check-github-workflows

View File

@@ -3,10 +3,6 @@
/// TODO: unify with the `PythonVersion` enum in the linter/formatter crates?
#[derive(Copy, Clone, Hash, Debug, PartialEq, Eq, PartialOrd, Ord, Default, clap::ValueEnum)]
pub enum PythonVersion {
#[value(name = "3.7")]
Py37,
#[value(name = "3.8")]
Py38,
#[default]
#[value(name = "3.9")]
Py39,
@@ -23,8 +19,6 @@ pub enum PythonVersion {
impl PythonVersion {
const fn as_str(self) -> &'static str {
match self {
Self::Py37 => "3.7",
Self::Py38 => "3.8",
Self::Py39 => "3.9",
Self::Py310 => "3.10",
Self::Py311 => "3.11",
@@ -43,8 +37,6 @@ impl std::fmt::Display for PythonVersion {
impl From<PythonVersion> for ruff_python_ast::PythonVersion {
fn from(value: PythonVersion) -> Self {
match value {
PythonVersion::Py37 => Self::PY37,
PythonVersion::Py38 => Self::PY38,
PythonVersion::Py39 => Self::PY39,
PythonVersion::Py310 => Self::PY310,
PythonVersion::Py311 => Self::PY311,

View File

@@ -421,16 +421,16 @@ mod tests {
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r#"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:4:13
@@ -440,7 +440,7 @@ mod tests {
4 | a
| ^
|
"###);
"#);
}
#[test]
fn goto_type_of_expression_with_literal_node() {
@@ -450,16 +450,16 @@ mod tests {
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r#"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:2:22
@@ -467,7 +467,7 @@ mod tests {
2 | a: str = "test"
| ^^^^^^
|
"###);
"#);
}
#[test]
@@ -532,16 +532,16 @@ mod tests {
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r#"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:4:18
@@ -551,7 +551,7 @@ mod tests {
4 | test(a= "123")
| ^
|
"###);
"#);
}
#[test]
@@ -567,16 +567,16 @@ mod tests {
// TODO: This should jump to `str` and not `int` because
// the keyword is typed as a string. It's only the passed argument that
// is an int. Navigating to `str` would match pyright's behavior.
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:234:7
--> stdlib/builtins.pyi:231:7
|
232 | _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed
233 |
234 | class int:
229 | _LiteralInteger = _PositiveInteger | _NegativeInteger | Literal[0] # noqa: Y026 # TODO: Use TypeAlias once mypy bugs are fixed
230 |
231 | class int:
| ^^^
235 | @overload
236 | def __new__(cls, x: ConvertibleToInt = ..., /) -> Self: ...
232 | @overload
233 | def __new__(cls, x: ConvertibleToInt = ..., /) -> Self: ...
|
info: Source
--> /main.py:4:18
@@ -586,7 +586,7 @@ mod tests {
4 | test(a= 123)
| ^
|
"###);
");
}
#[test]
@@ -601,16 +601,16 @@ f(**kwargs<CURSOR>)
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r#"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:1098:7
--> stdlib/builtins.pyi:1086:7
|
1096 | def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
1097 |
1098 | class dict(MutableMapping[_KT, _VT]):
1084 | def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
1085 |
1086 | class dict(MutableMapping[_KT, _VT]):
| ^^^^
1099 | # __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics
1100 | # Also multiprocessing.managers.SyncManager.dict()
1087 | # __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics
1088 | # Also multiprocessing.managers.SyncManager.dict()
|
info: Source
--> /main.py:6:5
@@ -620,7 +620,7 @@ f(**kwargs<CURSOR>)
6 | f(**kwargs)
| ^^^^^^
|
"###);
"#);
}
#[test]
@@ -632,16 +632,16 @@ f(**kwargs<CURSOR>)
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:3:17
@@ -650,7 +650,7 @@ f(**kwargs<CURSOR>)
3 | a
| ^
|
"###);
");
}
#[test]
@@ -725,16 +725,16 @@ f(**kwargs<CURSOR>)
"#,
);
assert_snapshot!(test.goto_type_definition(), @r###"
assert_snapshot!(test.goto_type_definition(), @r"
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:4:27
@@ -744,7 +744,7 @@ f(**kwargs<CURSOR>)
4 | print(a)
| ^
|
"###);
");
}
#[test]
@@ -758,13 +758,13 @@ f(**kwargs<CURSOR>)
assert_snapshot!(test.goto_type_definition(), @r"
info: lint:goto-type-definition: Type definition
--> stdlib/types.pyi:677:11
--> stdlib/types.pyi:671:11
|
675 | if sys.version_info >= (3, 10):
676 | @final
677 | class NoneType:
669 | if sys.version_info >= (3, 10):
670 | @final
671 | class NoneType:
| ^^^^^^^^
678 | def __bool__(self) -> Literal[False]: ...
672 | def __bool__(self) -> Literal[False]: ...
|
info: Source
--> /main.py:3:17
@@ -775,14 +775,14 @@ f(**kwargs<CURSOR>)
|
info: lint:goto-type-definition: Type definition
--> stdlib/builtins.pyi:443:7
--> stdlib/builtins.pyi:438:7
|
441 | def __getitem__(self, key: int, /) -> str | int | None: ...
442 |
443 | class str(Sequence[str]):
436 | def __getitem__(self, key: int, /) -> str | int | None: ...
437 |
438 | class str(Sequence[str]):
| ^^^
444 | @overload
445 | def __new__(cls, object: object = ...) -> Self: ...
439 | @overload
440 | def __new__(cls, object: object = ...) -> Self: ...
|
info: Source
--> /main.py:3:17

View File

@@ -214,11 +214,11 @@ mod tests {
"#,
);
assert_snapshot!(test.hover(), @r"
Literal[foo]
assert_snapshot!(test.hover(), @r###"
def foo(a, b) -> Unknown
---------------------------------------------
```text
Literal[foo]
def foo(a, b) -> Unknown
```
---------------------------------------------
info: lint:hover: Hovered content is
@@ -231,7 +231,7 @@ mod tests {
| |
| source
|
");
"###);
}
#[test]
@@ -312,11 +312,11 @@ mod tests {
"#,
);
assert_snapshot!(test.hover(), @r"
Literal[foo, bar]
assert_snapshot!(test.hover(), @r###"
(def foo(a, b) -> Unknown) | (def bar(a, b) -> Unknown)
---------------------------------------------
```text
Literal[foo, bar]
(def foo(a, b) -> Unknown) | (def bar(a, b) -> Unknown)
```
---------------------------------------------
info: lint:hover: Hovered content is
@@ -329,7 +329,7 @@ mod tests {
| |
| source
|
");
"###);
}
#[test]

View File

@@ -96,7 +96,10 @@ impl Project {
return Ok(None);
};
let minor = versions.next().copied().unwrap_or_default();
let mut minor = versions.next().copied().unwrap_or_default();
// Ensure minor is at least 9
minor = minor.max(9);
tracing::debug!("Resolved requires-python constraint to: {major}.{minor}");

View File

@@ -289,7 +289,7 @@ def _(c: Callable[[int, Unpack[Ts]], int]):
from typing import Callable
def _(c: Callable[[int], int]):
reveal_type(c.__init__) # revealed: Literal[__init__]
reveal_type(c.__init__) # revealed: def __init__(self) -> None
reveal_type(c.__class__) # revealed: type
# TODO: The member lookup for `Callable` uses `object` which does not have a `__call__`

View File

@@ -1373,7 +1373,7 @@ from typing import Any
class Foo(Any): ...
reveal_type(Foo.bar) # revealed: Any
reveal_type(Foo.__repr__) # revealed: Literal[__repr__] & Any
reveal_type(Foo.__repr__) # revealed: (def __repr__(self) -> str) & Any
```
Similar principles apply if `Any` appears in the middle of an inheritance hierarchy:
@@ -1672,7 +1672,7 @@ Some attributes are special-cased, however:
```py
reveal_type(f.__get__) # revealed: <method-wrapper `__get__` of `f`>
reveal_type(f.__call__) # revealed: <bound method `__call__` of `Literal[f]`>
reveal_type(f.__call__) # revealed: <method-wrapper `__call__` of `f`>
```
### Int-literal attributes
@@ -1681,7 +1681,7 @@ Most attribute accesses on int-literal types are delegated to `builtins.int`, si
integers are instances of that class:
```py
reveal_type((2).bit_length) # revealed: <bound method `bit_length` of `Literal[2]`>
reveal_type((2).bit_length) # revealed: bound method Literal[2].bit_length() -> int
reveal_type((2).denominator) # revealed: Literal[1]
```
@@ -1698,8 +1698,10 @@ Most attribute accesses on bool-literal types are delegated to `builtins.bool`,
bools are instances of that class:
```py
reveal_type(True.__and__) # revealed: <bound method `__and__` of `Literal[True]`>
reveal_type(False.__or__) # revealed: <bound method `__or__` of `Literal[False]`>
# revealed: bound method Literal[True].__and__(**kwargs: @Todo(todo signature **kwargs)) -> @Todo(return type of overloaded function)
reveal_type(True.__and__)
# revealed: bound method Literal[False].__or__(**kwargs: @Todo(todo signature **kwargs)) -> @Todo(return type of overloaded function)
reveal_type(False.__or__)
```
Some attributes are special-cased, however:
@@ -1714,8 +1716,9 @@ reveal_type(False.real) # revealed: Literal[0]
All attribute access on literal `bytes` types is currently delegated to `builtins.bytes`:
```py
reveal_type(b"foo".join) # revealed: <bound method `join` of `Literal[b"foo"]`>
reveal_type(b"foo".endswith) # revealed: <bound method `endswith` of `Literal[b"foo"]`>
reveal_type(b"foo".join) # revealed: bound method Literal[b"foo"].join(iterable_of_bytes: @Todo(generics), /) -> bytes
# revealed: bound method Literal[b"foo"].endswith(suffix: @Todo(Support for `typing.TypeAlias`), start: SupportsIndex | None = ellipsis, end: SupportsIndex | None = ellipsis, /) -> bool
reveal_type(b"foo".endswith)
```
## Instance attribute edge cases

View File

@@ -350,30 +350,30 @@ reveal_type(no() + no()) # revealed: Unknown
def f():
pass
# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `+` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f + f) # revealed: Unknown
# error: [unsupported-operator] "Operator `-` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `-` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f - f) # revealed: Unknown
# error: [unsupported-operator] "Operator `*` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `*` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f * f) # revealed: Unknown
# error: [unsupported-operator] "Operator `@` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `@` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f @ f) # revealed: Unknown
# error: [unsupported-operator] "Operator `/` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `/` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f / f) # revealed: Unknown
# error: [unsupported-operator] "Operator `%` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `%` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f % f) # revealed: Unknown
# error: [unsupported-operator] "Operator `**` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `**` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f**f) # revealed: Unknown
# error: [unsupported-operator] "Operator `<<` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `<<` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f << f) # revealed: Unknown
# error: [unsupported-operator] "Operator `>>` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `>>` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f >> f) # revealed: Unknown
# error: [unsupported-operator] "Operator `|` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `|` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f | f) # revealed: Unknown
# error: [unsupported-operator] "Operator `^` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `^` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f ^ f) # revealed: Unknown
# error: [unsupported-operator] "Operator `&` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `&` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f & f) # revealed: Unknown
# error: [unsupported-operator] "Operator `//` is unsupported between objects of type `Literal[f]` and `Literal[f]`"
# error: [unsupported-operator] "Operator `//` is unsupported between objects of type `def f() -> Unknown` and `def f() -> Unknown`"
reveal_type(f // f) # revealed: Unknown
```

View File

@@ -57,7 +57,8 @@ We can access attributes on objects of all kinds:
import sys
reveal_type(inspect.getattr_static(sys, "dont_write_bytecode")) # revealed: bool
reveal_type(inspect.getattr_static(inspect, "getattr_static")) # revealed: Literal[getattr_static]
# revealed: def getattr_static(obj: object, attr: str, default: Any | None = ellipsis) -> Any
reveal_type(inspect.getattr_static(inspect, "getattr_static"))
reveal_type(inspect.getattr_static(1, "real")) # revealed: property
```
@@ -143,8 +144,9 @@ from typing import Any
def _(a: Any, tuple_of_any: tuple[Any]):
reveal_type(inspect.getattr_static(a, "x", "default")) # revealed: Any | Literal["default"]
# TODO: Ideally, this would just be `Literal[index]`
reveal_type(inspect.getattr_static(tuple_of_any, "index", "default")) # revealed: Literal[index] | Literal["default"]
# TODO: Ideally, this would just be `def index(self, value: Any, start: SupportsIndex = Literal[0], stop: SupportsIndex = int, /) -> int`
# revealed: (def index(self, value: Any, start: SupportsIndex = Literal[0], stop: SupportsIndex = int, /) -> int) | Literal["default"]
reveal_type(inspect.getattr_static(tuple_of_any, "index", "default"))
```
[official documentation]: https://docs.python.org/3/library/inspect.html#inspect.getattr_static

View File

@@ -32,20 +32,20 @@ the latter case, it returns a *bound method* object:
```py
from inspect import getattr_static
reveal_type(getattr_static(C, "f")) # revealed: Literal[f]
reveal_type(getattr_static(C, "f")) # revealed: def f(self, x: int) -> str
reveal_type(getattr_static(C, "f").__get__) # revealed: <method-wrapper `__get__` of `f`>
reveal_type(getattr_static(C, "f").__get__(None, C)) # revealed: Literal[f]
reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: <bound method `f` of `C`>
reveal_type(getattr_static(C, "f").__get__(None, C)) # revealed: def f(self, x: int) -> str
reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: bound method C.f(x: int) -> str
```
In conclusion, this is why we see the following two types when accessing the `f` attribute on the
class object `C` and on an instance `C()`:
```py
reveal_type(C.f) # revealed: Literal[f]
reveal_type(C().f) # revealed: <bound method `f` of `C`>
reveal_type(C.f) # revealed: def f(self, x: int) -> str
reveal_type(C().f) # revealed: bound method C.f(x: int) -> str
```
A bound method is a callable object that contains a reference to the `instance` that it was called
@@ -56,7 +56,7 @@ via `__func__`):
bound_method = C().f
reveal_type(bound_method.__self__) # revealed: C
reveal_type(bound_method.__func__) # revealed: Literal[f]
reveal_type(bound_method.__func__) # revealed: def f(self, x: int) -> str
```
When we call the bound method, the `instance` is implicitly passed as the first argument (`self`):
@@ -80,13 +80,13 @@ When we access methods from derived classes, they will be bound to instances of
class D(C):
pass
reveal_type(D().f) # revealed: <bound method `f` of `D`>
reveal_type(D().f) # revealed: bound method D.f(x: int) -> str
```
If we access an attribute on a bound method object itself, it will defer to `types.MethodType`:
```py
reveal_type(bound_method.__hash__) # revealed: <bound method `__hash__` of `MethodType`>
reveal_type(bound_method.__hash__) # revealed: bound method MethodType.__hash__() -> int
```
If an attribute is not available on the bound method object, it will be looked up on the underlying
@@ -181,10 +181,10 @@ class B:
return "a"
def f(a_or_b: A | B, any_or_a: Any | A):
reveal_type(a_or_b.f) # revealed: <bound method `f` of `A`> | <bound method `f` of `B`>
reveal_type(a_or_b.f) # revealed: (bound method A.f() -> int) | (bound method B.f() -> str)
reveal_type(a_or_b.f()) # revealed: int | str
reveal_type(any_or_a.f) # revealed: Any | <bound method `f` of `A`>
reveal_type(any_or_a.f) # revealed: Any | (bound method A.f() -> int)
reveal_type(any_or_a.f()) # revealed: Any | int
```
@@ -198,7 +198,7 @@ python-version = "3.12"
```py
type IntOrStr = int | str
reveal_type(IntOrStr.__or__) # revealed: <bound method `__or__` of `typing.TypeAliasType`>
reveal_type(IntOrStr.__or__) # revealed: bound method typing.TypeAliasType.__or__(right: Any) -> _SpecialForm
```
## Error cases: Calling `__get__` for methods
@@ -270,7 +270,7 @@ class Meta(type):
class C(metaclass=Meta):
pass
reveal_type(C.f) # revealed: <bound method `f` of `Literal[C]`>
reveal_type(C.f) # revealed: bound method Literal[C].f(arg: int) -> str
reveal_type(C.f(1)) # revealed: str
```
@@ -322,8 +322,8 @@ class C:
def f(cls: type[C], x: int) -> str:
return "a"
reveal_type(C.f) # revealed: <bound method `f` of `Literal[C]`>
reveal_type(C().f) # revealed: <bound method `f` of `type[C]`>
reveal_type(C.f) # revealed: bound method Literal[C].f(x: int) -> str
reveal_type(C().f) # revealed: bound method type[C].f(x: int) -> str
```
The `cls` method argument is then implicitly passed as the first argument when calling the method:
@@ -360,8 +360,8 @@ When a class method is accessed on a derived class, it is bound to that derived
class Derived(C):
pass
reveal_type(Derived.f) # revealed: <bound method `f` of `Literal[Derived]`>
reveal_type(Derived().f) # revealed: <bound method `f` of `type[Derived]`>
reveal_type(Derived.f) # revealed: bound method Literal[Derived].f(x: int) -> str
reveal_type(Derived().f) # revealed: bound method type[Derived].f(x: int) -> str
reveal_type(Derived.f(1)) # revealed: str
reveal_type(Derived().f(1)) # revealed: str
@@ -379,22 +379,22 @@ class C:
@classmethod
def f(cls): ...
reveal_type(getattr_static(C, "f")) # revealed: Literal[f]
reveal_type(getattr_static(C, "f")) # revealed: def f(cls) -> Unknown
reveal_type(getattr_static(C, "f").__get__) # revealed: <method-wrapper `__get__` of `f`>
```
But we correctly model how the `classmethod` descriptor works:
```py
reveal_type(getattr_static(C, "f").__get__(None, C)) # revealed: <bound method `f` of `Literal[C]`>
reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: <bound method `f` of `Literal[C]`>
reveal_type(getattr_static(C, "f").__get__(C())) # revealed: <bound method `f` of `type[C]`>
reveal_type(getattr_static(C, "f").__get__(None, C)) # revealed: bound method Literal[C].f() -> Unknown
reveal_type(getattr_static(C, "f").__get__(C(), C)) # revealed: bound method Literal[C].f() -> Unknown
reveal_type(getattr_static(C, "f").__get__(C())) # revealed: bound method type[C].f() -> Unknown
```
The `owner` argument takes precedence over the `instance` argument:
```py
reveal_type(getattr_static(C, "f").__get__("dummy", C)) # revealed: <bound method `f` of `Literal[C]`>
reveal_type(getattr_static(C, "f").__get__("dummy", C)) # revealed: bound method Literal[C].f() -> Unknown
```
### Classmethods mixed with other decorators

View File

@@ -207,7 +207,7 @@ first argument:
def wrong_signature(f: int) -> str:
return "a"
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `Literal[f]`"
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `int`, found `def f(x) -> Unknown`"
@wrong_signature
def f(x): ...

View File

@@ -563,18 +563,18 @@ from inspect import getattr_static
def f(x: object) -> str:
return "a"
reveal_type(f) # revealed: Literal[f]
reveal_type(f) # revealed: def f(x: object) -> str
reveal_type(f.__get__) # revealed: <method-wrapper `__get__` of `f`>
reveal_type(f.__get__(None, type(f))) # revealed: Literal[f]
reveal_type(f.__get__(None, type(f))) # revealed: def f(x: object) -> str
reveal_type(f.__get__(None, type(f))(1)) # revealed: str
wrapper_descriptor = getattr_static(f, "__get__")
reveal_type(wrapper_descriptor) # revealed: <wrapper-descriptor `__get__` of `function` objects>
reveal_type(wrapper_descriptor(f, None, type(f))) # revealed: Literal[f]
reveal_type(wrapper_descriptor(f, None, type(f))) # revealed: def f(x: object) -> str
# Attribute access on the method-wrapper `f.__get__` falls back to `MethodWrapperType`:
reveal_type(f.__get__.__hash__) # revealed: <bound method `__hash__` of `MethodWrapperType`>
reveal_type(f.__get__.__hash__) # revealed: bound method MethodWrapperType.__hash__() -> int
# Attribute access on the wrapper-descriptor falls back to `WrapperDescriptorType`:
reveal_type(wrapper_descriptor.__qualname__) # revealed: str
@@ -587,7 +587,7 @@ class C: ...
bound_method = wrapper_descriptor(f, C(), C)
reveal_type(bound_method) # revealed: <bound method `f` of `C`>
reveal_type(bound_method) # revealed: bound method C.f() -> str
```
We can then call it, and the instance of `C` is implicitly passed to the first parameter of `f`

View File

@@ -591,9 +591,9 @@ try:
reveal_type(x) # revealed: B | D
reveal_type(x) # revealed: B | D
x = foo
reveal_type(x) # revealed: Literal[foo]
reveal_type(x) # revealed: def foo(param=A) -> Unknown
except:
reveal_type(x) # revealed: Literal[1] | Literal[foo]
reveal_type(x) # revealed: Literal[1] | (def foo(param=A) -> Unknown)
class Bar:
x = could_raise_returns_E()
@@ -603,9 +603,9 @@ except:
reveal_type(x) # revealed: Literal[Bar]
finally:
# TODO: should be `Literal[1] | Literal[foo] | Literal[Bar]`
reveal_type(x) # revealed: Literal[foo] | Literal[Bar]
reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | Literal[Bar]
reveal_type(x) # revealed: Literal[foo] | Literal[Bar]
reveal_type(x) # revealed: (def foo(param=A) -> Unknown) | Literal[Bar]
```
[1]: https://astral-sh.notion.site/Exception-handler-control-flow-11348797e1ca80bb8ce1e9aedbbe439d

View File

@@ -102,18 +102,18 @@ class C[T]:
def f(self, x: T) -> str:
return "a"
reveal_type(getattr_static(C[int], "f")) # revealed: Literal[f[int]]
reveal_type(getattr_static(C[int], "f")) # revealed: def f(self, x: int) -> str
reveal_type(getattr_static(C[int], "f").__get__) # revealed: <method-wrapper `__get__` of `f[int]`>
reveal_type(getattr_static(C[int], "f").__get__(None, C[int])) # revealed: Literal[f[int]]
# revealed: <bound method `f` of `C[int]`>
reveal_type(getattr_static(C[int], "f").__get__(None, C[int])) # revealed: def f(self, x: int) -> str
# revealed: bound method C[int].f(x: int) -> str
reveal_type(getattr_static(C[int], "f").__get__(C[int](), C[int]))
reveal_type(C[int].f) # revealed: Literal[f[int]]
reveal_type(C[int]().f) # revealed: <bound method `f` of `C[int]`>
reveal_type(C[int].f) # revealed: def f(self, x: int) -> str
reveal_type(C[int]().f) # revealed: bound method C[int].f(x: int) -> str
bound_method = C[int]().f
reveal_type(bound_method.__self__) # revealed: C[int]
reveal_type(bound_method.__func__) # revealed: Literal[f[int]]
reveal_type(bound_method.__func__) # revealed: def f(self, x: int) -> str
reveal_type(C[int]().f(1)) # revealed: str
reveal_type(bound_method(1)) # revealed: str
@@ -124,7 +124,7 @@ reveal_type(C[int].f(C[int](), 1)) # revealed: str
class D[U](C[U]):
pass
reveal_type(D[int]().f) # revealed: <bound method `f` of `D[int]`>
reveal_type(D[int]().f) # revealed: bound method D[int].f(x: int) -> str
```
## Methods can mention other typevars

View File

@@ -7,7 +7,7 @@ Builtin symbols can be explicitly imported:
```py
import builtins
reveal_type(builtins.chr) # revealed: Literal[chr]
reveal_type(builtins.chr) # revealed: def chr(i: int | SupportsIndex, /) -> str
```
## Implicit use of builtin
@@ -15,7 +15,7 @@ reveal_type(builtins.chr) # revealed: Literal[chr]
Or used implicitly:
```py
reveal_type(chr) # revealed: Literal[chr]
reveal_type(chr) # revealed: def chr(i: int | SupportsIndex, /) -> str
reveal_type(str) # revealed: Literal[str]
```

View File

@@ -103,8 +103,8 @@ else:
```py
from b import f
# TODO: We should disambiguate in such cases, showing `Literal[b.f, c.f]`.
reveal_type(f) # revealed: Literal[f, f]
# TODO: We should disambiguate in such cases between `b.f` and `c.f`.
reveal_type(f) # revealed: (def f() -> Unknown) | (def f() -> Unknown)
```
## Reimport with stub declaration

View File

@@ -1034,8 +1034,8 @@ from exporter import *
# At runtime, `f` is imported but `g` is not; to avoid false positives, however,
# we treat `a` as though it does not have `__all__` at all,
# which would imply that both symbols would be present.
reveal_type(f) # revealed: Literal[f]
reveal_type(g) # revealed: Literal[g]
reveal_type(f) # revealed: def f() -> str
reveal_type(g) # revealed: def g() -> int
```
### `__all__` conditionally defined in a statically known branch
@@ -1198,7 +1198,7 @@ f()
```py
from a import *
reveal_type(f) # revealed: Literal[f]
reveal_type(f) # revealed: def f() -> Unknown
# TODO: we're undecided about whether we should consider this a false positive or not.
# Mutating the global scope to add a symbol from an inner scope will not *necessarily* result

View File

@@ -321,7 +321,7 @@ def _(flag: bool):
# TODO... `int` might be ideal here?
reveal_type(x) # revealed: int | Unknown
# error: [not-iterable] "Object of type `Iterable2` may not be iterable because its `__iter__` attribute (with type `<bound method `__iter__` of `Iterable2`> | None`) may not be callable"
# error: [not-iterable] "Object of type `Iterable2` may not be iterable because its `__iter__` attribute (with type `(bound method Iterable2.__iter__() -> Iterator) | None`) may not be callable"
for y in Iterable2():
# TODO... `int` might be ideal here?
reveal_type(y) # revealed: int | Unknown

View File

@@ -63,7 +63,7 @@ def bar(world: str, *args, **kwargs) -> float:
x = foo if flag() else bar
if x:
reveal_type(x) # revealed: Literal[foo, bar]
reveal_type(x) # revealed: (def foo(hello: int) -> bytes) | (def bar(world: str, *args, **kwargs) -> int | float)
else:
reveal_type(x) # revealed: Never
```

View File

@@ -146,7 +146,7 @@ class C:
@property
def attr(self) -> int:
return 1
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `(Any, Any, /) -> None`, found `Literal[attr]`"
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `(Any, Any, /) -> None`, found `def attr(self) -> None`"
@attr.setter
def attr(self) -> None:
pass
@@ -156,7 +156,7 @@ class C:
```py
class C:
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `((Any, /) -> Any) | None`, found `Literal[attr]`"
# error: [invalid-argument-type] "Argument to this function is incorrect: Expected `((Any, /) -> Any) | None`, found `def attr(self, x: int) -> int`"
@property
def attr(self, x: int) -> int:
return 1
@@ -294,10 +294,10 @@ Properties also have `fget` and `fset` attributes that can be used to retrieve t
and setter functions, respectively.
```py
reveal_type(attr_property.fget) # revealed: Literal[attr]
reveal_type(attr_property.fget) # revealed: def attr(self) -> int
reveal_type(attr_property.fget(c)) # revealed: int
reveal_type(attr_property.fset) # revealed: Literal[attr]
reveal_type(attr_property.fset) # revealed: def attr(self, value: str) -> None
reveal_type(attr_property.fset(c, "a")) # revealed: None
# error: [invalid-argument-type]

View File

@@ -13,7 +13,7 @@ if returns_bool():
chr: int = 1
def f():
reveal_type(chr) # revealed: int | Literal[chr]
reveal_type(chr) # revealed: int | (def chr(i: int | SupportsIndex, /) -> str)
```
## Conditionally global or builtin, with annotation
@@ -28,5 +28,5 @@ if returns_bool():
chr: int = 1
def f():
reveal_type(chr) # revealed: int | Literal[chr]
reveal_type(chr) # revealed: int | (def chr(i: int | SupportsIndex, /) -> str)
```

View File

@@ -51,10 +51,10 @@ inside the module:
import typing
reveal_type(typing.__name__) # revealed: str
reveal_type(typing.__init__) # revealed: <bound method `__init__` of `ModuleType`>
reveal_type(typing.__init__) # revealed: bound method ModuleType.__init__(name: str, doc: str | None = ellipsis) -> None
# These come from `builtins.object`, not `types.ModuleType`:
reveal_type(typing.__eq__) # revealed: <bound method `__eq__` of `ModuleType`>
reveal_type(typing.__eq__) # revealed: bound method ModuleType.__eq__(value: object, /) -> bool
reveal_type(typing.__class__) # revealed: Literal[ModuleType]

View File

@@ -37,17 +37,17 @@ reveal_type(f) # revealed: Literal[1]
def f(): ...
reveal_type(f) # revealed: Literal[f]
reveal_type(f) # revealed: def f() -> Unknown
def f(x: int) -> int:
raise NotImplementedError
reveal_type(f) # revealed: Literal[f]
reveal_type(f) # revealed: def f(x: int) -> int
f: int = 1
reveal_type(f) # revealed: Literal[1]
def f(): ...
reveal_type(f) # revealed: Literal[f]
reveal_type(f) # revealed: def f() -> Unknown
```

View File

@@ -78,7 +78,7 @@ error: lint:not-iterable
|
26 | # error: [not-iterable]
27 | for y in Iterable2():
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it has no `__iter__` method and its `__getitem__` attribute (with type `<bound method `__getitem__` of `Iterable2`> | None`) may not be callable
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it has no `__iter__` method and its `__getitem__` attribute (with type `(bound method Iterable2.__getitem__(key: int) -> int) | None`) may not be callable
28 | # TODO... `int` might be ideal here?
29 | reveal_type(y) # revealed: int | Unknown
|

View File

@@ -48,7 +48,7 @@ error: lint:not-iterable
|
19 | # error: [not-iterable]
20 | for x in Iterable1():
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because it has no `__iter__` method and its `__getitem__` attribute (with type `<bound method `__getitem__` of `Iterable1`> | None`) may not be callable
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because it has no `__iter__` method and its `__getitem__` attribute (with type `(bound method Iterable1.__getitem__(item: int) -> str) | None`) may not be callable
21 | # TODO: `str` might be better
22 | reveal_type(x) # revealed: str | Unknown
|
@@ -75,7 +75,7 @@ error: lint:not-iterable
|
24 | # error: [not-iterable]
25 | for y in Iterable2():
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it has no `__iter__` method and its `__getitem__` method (with type `<bound method `__getitem__` of `Iterable2`> | <bound method `__getitem__` of `Iterable2`>`) may have an incorrect signature for the old-style iteration protocol (expected a signature at least as permissive as `def __getitem__(self, key: int): ...`)
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it has no `__iter__` method and its `__getitem__` method (with type `(bound method Iterable2.__getitem__(item: int) -> str) | (bound method Iterable2.__getitem__(item: str) -> int)`) may have an incorrect signature for the old-style iteration protocol (expected a signature at least as permissive as `def __getitem__(self, key: int): ...`)
26 | reveal_type(y) # revealed: str | int
|

View File

@@ -52,7 +52,7 @@ error: lint:not-iterable
|
16 | # error: [not-iterable]
17 | for x in Iterable1():
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because its `__iter__` method (with type `<bound method `__iter__` of `Iterable1`> | <bound method `__iter__` of `Iterable1`>`) may have an invalid signature (expected `def __iter__(self): ...`)
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because its `__iter__` method (with type `(bound method Iterable1.__iter__() -> Iterator) | (bound method Iterable1.__iter__(invalid_extra_arg) -> Iterator)`) may have an invalid signature (expected `def __iter__(self): ...`)
18 | reveal_type(x) # revealed: int
|
@@ -78,7 +78,7 @@ error: lint:not-iterable
|
27 | # error: [not-iterable]
28 | for x in Iterable2():
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because its `__iter__` attribute (with type `<bound method `__iter__` of `Iterable2`> | None`) may not be callable
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because its `__iter__` attribute (with type `(bound method Iterable2.__iter__() -> Iterator) | None`) may not be callable
29 | # TODO: `int` would probably be better here:
30 | reveal_type(x) # revealed: int | Unknown
|

View File

@@ -59,7 +59,7 @@ error: lint:not-iterable
|
30 | # error: [not-iterable]
31 | for x in Iterable1():
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because it may not have an `__iter__` method and its `__getitem__` attribute (with type `<bound method `__getitem__` of `Iterable1`> | None`) may not be callable
| ^^^^^^^^^^^ Object of type `Iterable1` may not be iterable because it may not have an `__iter__` method and its `__getitem__` attribute (with type `(bound method Iterable1.__getitem__(item: int) -> str) | None`) may not be callable
32 | # TODO: `bytes | str` might be better
33 | reveal_type(x) # revealed: bytes | str | Unknown
|
@@ -86,7 +86,7 @@ error: lint:not-iterable
|
35 | # error: [not-iterable]
36 | for y in Iterable2():
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it may not have an `__iter__` method and its `__getitem__` method (with type `<bound method `__getitem__` of `Iterable2`> | <bound method `__getitem__` of `Iterable2`>`) may have an incorrect signature for the old-style iteration protocol (expected a signature at least as permissive as `def __getitem__(self, key: int): ...`)
| ^^^^^^^^^^^ Object of type `Iterable2` may not be iterable because it may not have an `__iter__` method and its `__getitem__` method (with type `(bound method Iterable2.__getitem__(item: int) -> str) | (bound method Iterable2.__getitem__(item: str) -> int)`) may have an incorrect signature for the old-style iteration protocol (expected a signature at least as permissive as `def __getitem__(self, key: int): ...`)
37 | reveal_type(y) # revealed: bytes | str | int
|

View File

@@ -35,7 +35,7 @@ in strict mode.
```py
def f(x: type):
reveal_type(x) # revealed: type
reveal_type(x.__repr__) # revealed: <bound method `__repr__` of `type`>
reveal_type(x.__repr__) # revealed: bound method type.__repr__() -> str
class A: ...
@@ -50,7 +50,7 @@ x: type = A() # error: [invalid-assignment]
```py
def f(x: type[object]):
reveal_type(x) # revealed: type
reveal_type(x.__repr__) # revealed: <bound method `__repr__` of `type`>
reveal_type(x.__repr__) # revealed: bound method type.__repr__() -> str
class A: ...

View File

@@ -500,7 +500,7 @@ def g(x: Any) -> int:
c: Callable[[Any], str] = f
# error: [invalid-assignment] "Object of type `Literal[g]` is not assignable to `(Any, /) -> str`"
# error: [invalid-assignment] "Object of type `def g(x: Any) -> int` is not assignable to `(Any, /) -> str`"
c: Callable[[Any], str] = g
```

View File

@@ -80,11 +80,11 @@ reveal_type(~No) # revealed: Unknown
def f():
pass
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `Literal[f]`"
# error: [unsupported-operator] "Unary operator `+` is unsupported for type `def f() -> Unknown`"
reveal_type(+f) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `Literal[f]`"
# error: [unsupported-operator] "Unary operator `-` is unsupported for type `def f() -> Unknown`"
reveal_type(-f) # revealed: Unknown
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `Literal[f]`"
# error: [unsupported-operator] "Unary operator `~` is unsupported for type `def f() -> Unknown`"
reveal_type(~f) # revealed: Unknown
```

View File

@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::slice::Iter;
use std::str::FromStr;
@@ -6,7 +5,6 @@ use bitflags::bitflags;
use call::{CallDunderError, CallError, CallErrorKind};
use context::InferContext;
use diagnostic::{CALL_POSSIBLY_UNBOUND_METHOD, INVALID_CONTEXT_MANAGER, NOT_ITERABLE};
use itertools::EitherOrBoth;
use ruff_db::files::{File, FileRange};
use ruff_python_ast as ast;
use ruff_python_ast::name::Name;
@@ -39,7 +37,7 @@ use crate::types::generics::Specialization;
use crate::types::infer::infer_unpack_types;
use crate::types::mro::{Mro, MroError, MroIterator};
pub(crate) use crate::types::narrow::infer_narrowing_constraint;
use crate::types::signatures::{Parameter, ParameterForm, ParameterKind, Parameters};
use crate::types::signatures::{Parameter, ParameterForm, Parameters};
use crate::{Db, FxOrderSet, Module, Program};
pub(crate) use class::{
Class, ClassLiteralType, ClassType, GenericAlias, GenericClass, InstanceType, KnownClass,
@@ -246,11 +244,31 @@ impl std::fmt::Display for TodoType {
/// It can be created by specifying a custom message: `todo_type!("PEP 604 not supported")`.
#[cfg(debug_assertions)]
macro_rules! todo_type {
($message:literal) => {
($message:literal) => {{
const _: () = {
let s = $message;
if !s.is_ascii() {
panic!("todo_type! message must be ASCII");
}
let bytes = s.as_bytes();
let mut i = 0;
while i < bytes.len() {
// Check each byte for '(' or ')'
let ch = bytes[i];
assert!(
!40u8.eq_ignore_ascii_case(&ch) && !41u8.eq_ignore_ascii_case(&ch),
"todo_type! message must not contain parentheses",
);
i += 1;
}
};
$crate::types::Type::Dynamic($crate::types::DynamicType::Todo($crate::types::TodoType(
$message,
)))
};
}};
($message:ident) => {
$crate::types::Type::Dynamic($crate::types::DynamicType::Todo($crate::types::TodoType(
$message,
@@ -886,6 +904,27 @@ impl<'db> Type<'db> {
target.is_equivalent_to(db, Type::object(db))
}
// No literal type is a subtype of any other literal type, unless they are the same
// type (which is handled above). This case is not necessary from a correctness
// perspective (the fallback cases below will handle it correctly), but it is important
// for performance of simplifying large unions of literal types.
(
Type::StringLiteral(_)
| Type::IntLiteral(_)
| Type::BytesLiteral(_)
| Type::ClassLiteral(_)
| Type::FunctionLiteral(_)
| Type::ModuleLiteral(_)
| Type::SliceLiteral(_),
Type::StringLiteral(_)
| Type::IntLiteral(_)
| Type::BytesLiteral(_)
| Type::ClassLiteral(_)
| Type::FunctionLiteral(_)
| Type::ModuleLiteral(_)
| Type::SliceLiteral(_),
) => false,
// All `StringLiteral` types are a subtype of `LiteralString`.
(Type::StringLiteral(_), Type::LiteralString) => true,
@@ -936,9 +975,9 @@ impl<'db> Type<'db> {
.to_instance(db)
.is_subtype_of(db, target),
(Type::Callable(self_callable), Type::Callable(other_callable)) => {
self_callable.is_subtype_of(db, other_callable)
}
(Type::Callable(self_callable), Type::Callable(other_callable)) => self_callable
.signature(db)
.is_subtype_of(db, other_callable.signature(db)),
(Type::Callable(_), _) => {
// TODO: Implement subtyping between callable types and other types like
@@ -1255,9 +1294,9 @@ impl<'db> Type<'db> {
)
}
(Type::Callable(self_callable), Type::Callable(target_callable)) => {
self_callable.is_assignable_to(db, target_callable)
}
(Type::Callable(self_callable), Type::Callable(target_callable)) => self_callable
.signature(db)
.is_assignable_to(db, target_callable.signature(db)),
(Type::FunctionLiteral(self_function_literal), Type::Callable(_)) => {
self_function_literal
@@ -1284,7 +1323,9 @@ impl<'db> Type<'db> {
left.is_equivalent_to(db, right)
}
(Type::Tuple(left), Type::Tuple(right)) => left.is_equivalent_to(db, right),
(Type::Callable(left), Type::Callable(right)) => left.is_equivalent_to(db, right),
(Type::Callable(left), Type::Callable(right)) => {
left.signature(db).is_equivalent_to(db, right.signature(db))
}
_ => self == other && self.is_fully_static(db) && other.is_fully_static(db),
}
}
@@ -1345,9 +1386,9 @@ impl<'db> Type<'db> {
first.is_gradual_equivalent_to(db, second)
}
(Type::Callable(first), Type::Callable(second)) => {
first.is_gradual_equivalent_to(db, second)
}
(Type::Callable(first), Type::Callable(second)) => first
.signature(db)
.is_gradual_equivalent_to(db, second.signature(db)),
_ => false,
}
@@ -1782,7 +1823,7 @@ impl<'db> Type<'db> {
.elements(db)
.iter()
.all(|elem| elem.is_fully_static(db)),
Type::Callable(callable) => callable.is_fully_static(db),
Type::Callable(callable) => callable.signature(db).is_fully_static(db),
}
}
@@ -2500,6 +2541,10 @@ impl<'db> Type<'db> {
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderGet(function)),
)
.into(),
Type::FunctionLiteral(function) if name == "__call__" => Symbol::bound(
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderCall(function)),
)
.into(),
Type::PropertyInstance(property) if name == "__get__" => Symbol::bound(
Type::MethodWrapper(MethodWrapperKind::PropertyDunderGet(property)),
)
@@ -3858,7 +3903,7 @@ impl<'db> Type<'db> {
}
Some(builder.build())
}
Type::Intersection(_) => Some(todo_type!("Type::Intersection.to_instance()")),
Type::Intersection(_) => Some(todo_type!("Type::Intersection.to_instance")),
Type::BooleanLiteral(_)
| Type::BytesLiteral(_)
| Type::FunctionLiteral(_)
@@ -4220,6 +4265,12 @@ impl<'db> Type<'db> {
))
}
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderCall(function)) => {
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderCall(
function.apply_specialization(db, specialization),
))
}
Type::MethodWrapper(MethodWrapperKind::PropertyDunderGet(property)) => {
Type::MethodWrapper(MethodWrapperKind::PropertyDunderGet(
property.apply_specialization(db, specialization),
@@ -5666,529 +5717,6 @@ impl<'db> CallableType<'db> {
signature.apply_specialization(db, specialization);
Self::new(db, signature)
}
/// Returns `true` if this is a fully static callable type.
///
/// A callable type is fully static if all of its parameters and return type are fully static
/// and if it does not use gradual form (`...`) for its parameters.
pub(crate) fn is_fully_static(self, db: &'db dyn Db) -> bool {
let signature = self.signature(db);
if signature.parameters().is_gradual() {
return false;
}
if signature.parameters().iter().any(|parameter| {
parameter
.annotated_type()
.is_none_or(|annotated_type| !annotated_type.is_fully_static(db))
}) {
return false;
}
signature
.return_ty
.is_some_and(|return_type| return_type.is_fully_static(db))
}
/// Return `true` if `self` has exactly the same set of possible static materializations as
/// `other` (if `self` represents the same set of possible sets of possible runtime objects as
/// `other`).
pub(crate) fn is_gradual_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
self.is_equivalent_to_impl(db, other, |self_type, other_type| {
self_type
.unwrap_or(Type::unknown())
.is_gradual_equivalent_to(db, other_type.unwrap_or(Type::unknown()))
})
}
/// Return `true` if `self` represents the exact same set of possible runtime objects as `other`.
pub(crate) fn is_equivalent_to(self, db: &'db dyn Db, other: Self) -> bool {
self.is_equivalent_to_impl(db, other, |self_type, other_type| {
match (self_type, other_type) {
(Some(self_type), Some(other_type)) => self_type.is_equivalent_to(db, other_type),
// We need the catch-all case here because it's not guaranteed that this is a fully
// static type.
_ => false,
}
})
}
/// Implementation for the [`is_equivalent_to`] and [`is_gradual_equivalent_to`] for callable
/// types.
///
/// [`is_equivalent_to`]: Self::is_equivalent_to
/// [`is_gradual_equivalent_to`]: Self::is_gradual_equivalent_to
fn is_equivalent_to_impl<F>(self, db: &'db dyn Db, other: Self, check_types: F) -> bool
where
F: Fn(Option<Type<'db>>, Option<Type<'db>>) -> bool,
{
let self_signature = self.signature(db);
let other_signature = other.signature(db);
// N.B. We don't need to explicitly check for the use of gradual form (`...`) in the
// parameters because it is internally represented by adding `*Any` and `**Any` to the
// parameter list.
let self_parameters = self_signature.parameters();
let other_parameters = other_signature.parameters();
if self_parameters.len() != other_parameters.len() {
return false;
}
if !check_types(self_signature.return_ty, other_signature.return_ty) {
return false;
}
for (self_parameter, other_parameter) in self_parameters.iter().zip(other_parameters) {
match (self_parameter.kind(), other_parameter.kind()) {
(
ParameterKind::PositionalOnly {
default_type: self_default,
..
},
ParameterKind::PositionalOnly {
default_type: other_default,
..
},
) if self_default.is_some() == other_default.is_some() => {}
(
ParameterKind::PositionalOrKeyword {
name: self_name,
default_type: self_default,
},
ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
},
) if self_default.is_some() == other_default.is_some()
&& self_name == other_name => {}
(ParameterKind::Variadic { .. }, ParameterKind::Variadic { .. }) => {}
(
ParameterKind::KeywordOnly {
name: self_name,
default_type: self_default,
},
ParameterKind::KeywordOnly {
name: other_name,
default_type: other_default,
},
) if self_default.is_some() == other_default.is_some()
&& self_name == other_name => {}
(ParameterKind::KeywordVariadic { .. }, ParameterKind::KeywordVariadic { .. }) => {}
_ => return false,
}
if !check_types(
self_parameter.annotated_type(),
other_parameter.annotated_type(),
) {
return false;
}
}
true
}
/// Return `true` if `self` is assignable to `other`.
pub(crate) fn is_assignable_to(self, db: &'db dyn Db, other: Self) -> bool {
self.is_assignable_to_impl(db, other, |type1, type2| {
// In the context of a callable type, the `None` variant represents an `Unknown` type.
type1
.unwrap_or(Type::unknown())
.is_assignable_to(db, type2.unwrap_or(Type::unknown()))
})
}
/// Return `true` if `self` is a subtype of `other`.
///
/// # Panics
///
/// Panics if `self` or `other` is not a fully static type.
pub(crate) fn is_subtype_of(self, db: &'db dyn Db, other: Self) -> bool {
self.is_assignable_to_impl(db, other, |type1, type2| {
// SAFETY: Subtype relation is only checked for fully static types.
type1.unwrap().is_subtype_of(db, type2.unwrap())
})
}
/// Implementation for the [`is_assignable_to`] and [`is_subtype_of`] for callable types.
///
/// [`is_assignable_to`]: Self::is_assignable_to
/// [`is_subtype_of`]: Self::is_subtype_of
fn is_assignable_to_impl<F>(self, db: &'db dyn Db, other: Self, check_types: F) -> bool
where
F: Fn(Option<Type<'db>>, Option<Type<'db>>) -> bool,
{
/// A helper struct to zip two slices of parameters together that provides control over the
/// two iterators individually. It also keeps track of the current parameter in each
/// iterator.
struct ParametersZip<'a, 'db> {
current_self: Option<&'a Parameter<'db>>,
current_other: Option<&'a Parameter<'db>>,
iter_self: Iter<'a, Parameter<'db>>,
iter_other: Iter<'a, Parameter<'db>>,
}
impl<'a, 'db> ParametersZip<'a, 'db> {
/// Move to the next parameter in both the `self` and `other` parameter iterators,
/// [`None`] if both iterators are exhausted.
fn next(&mut self) -> Option<EitherOrBoth<&'a Parameter<'db>, &'a Parameter<'db>>> {
match (self.next_self(), self.next_other()) {
(Some(self_param), Some(other_param)) => {
Some(EitherOrBoth::Both(self_param, other_param))
}
(Some(self_param), None) => Some(EitherOrBoth::Left(self_param)),
(None, Some(other_param)) => Some(EitherOrBoth::Right(other_param)),
(None, None) => None,
}
}
/// Move to the next parameter in the `self` parameter iterator, [`None`] if the
/// iterator is exhausted.
fn next_self(&mut self) -> Option<&'a Parameter<'db>> {
self.current_self = self.iter_self.next();
self.current_self
}
/// Move to the next parameter in the `other` parameter iterator, [`None`] if the
/// iterator is exhausted.
fn next_other(&mut self) -> Option<&'a Parameter<'db>> {
self.current_other = self.iter_other.next();
self.current_other
}
/// Peek at the next parameter in the `other` parameter iterator without consuming it.
fn peek_other(&mut self) -> Option<&'a Parameter<'db>> {
self.iter_other.clone().next()
}
/// Consumes the `ParametersZip` and returns a two-element tuple containing the
/// remaining parameters in the `self` and `other` iterators respectively.
///
/// The returned iterators starts with the current parameter, if any, followed by the
/// remaining parameters in the respective iterators.
fn into_remaining(
self,
) -> (
impl Iterator<Item = &'a Parameter<'db>>,
impl Iterator<Item = &'a Parameter<'db>>,
) {
(
self.current_self.into_iter().chain(self.iter_self),
self.current_other.into_iter().chain(self.iter_other),
)
}
}
let self_signature = self.signature(db);
let other_signature = other.signature(db);
// Return types are covariant.
if !check_types(self_signature.return_ty, other_signature.return_ty) {
return false;
}
if self_signature.parameters().is_gradual() || other_signature.parameters().is_gradual() {
// If either of the parameter lists contains a gradual form (`...`), then it is
// assignable / subtype to and from any other callable type.
return true;
}
let mut parameters = ParametersZip {
current_self: None,
current_other: None,
iter_self: self_signature.parameters().iter(),
iter_other: other_signature.parameters().iter(),
};
// Collect all the standard parameters that have only been matched against a variadic
// parameter which means that the keyword variant is still unmatched.
let mut other_keywords = Vec::new();
loop {
let Some(next_parameter) = parameters.next() else {
// All parameters have been checked or both the parameter lists were empty. In
// either case, `self` is a subtype of `other`.
return true;
};
match next_parameter {
EitherOrBoth::Left(self_parameter) => match self_parameter.kind() {
ParameterKind::KeywordOnly { .. } | ParameterKind::KeywordVariadic { .. }
if !other_keywords.is_empty() =>
{
// If there are any unmatched keyword parameters in `other`, they need to
// be checked against the keyword-only / keyword-variadic parameters that
// will be done after this loop.
break;
}
ParameterKind::PositionalOnly { default_type, .. }
| ParameterKind::PositionalOrKeyword { default_type, .. }
| ParameterKind::KeywordOnly { default_type, .. } => {
// For `self <: other` to be valid, if there are no more parameters in
// `other`, then the non-variadic parameters in `self` must have a default
// value.
if default_type.is_none() {
return false;
}
}
ParameterKind::Variadic { .. } | ParameterKind::KeywordVariadic { .. } => {
// Variadic parameters don't have any restrictions in this context, so
// we'll just continue to the next parameter set.
}
},
EitherOrBoth::Right(_) => {
// If there are more parameters in `other` than in `self`, then `self` is not a
// subtype of `other`.
return false;
}
EitherOrBoth::Both(self_parameter, other_parameter) => {
match (self_parameter.kind(), other_parameter.kind()) {
(
ParameterKind::PositionalOnly {
default_type: self_default,
..
}
| ParameterKind::PositionalOrKeyword {
default_type: self_default,
..
},
ParameterKind::PositionalOnly {
default_type: other_default,
..
},
) => {
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
ParameterKind::PositionalOrKeyword {
name: self_name,
default_type: self_default,
},
ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
},
) => {
if self_name != other_name {
return false;
}
// The following checks are the same as positional-only parameters.
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
ParameterKind::Variadic { .. },
ParameterKind::PositionalOnly { .. }
| ParameterKind::PositionalOrKeyword { .. },
) => {
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
if matches!(
other_parameter.kind(),
ParameterKind::PositionalOrKeyword { .. }
) {
other_keywords.push(other_parameter);
}
// We've reached a variadic parameter in `self` which means there can
// be no more positional parameters after this in a valid AST. But, the
// current parameter in `other` is a positional-only which means there
// can be more positional parameters after this which could be either
// more positional-only parameters, standard parameters or a variadic
// parameter.
//
// So, any remaining positional parameters in `other` would need to be
// checked against the variadic parameter in `self`. This loop does
// that by only moving the `other` iterator forward.
loop {
let Some(other_parameter) = parameters.peek_other() else {
break;
};
match other_parameter.kind() {
ParameterKind::PositionalOrKeyword { .. } => {
other_keywords.push(other_parameter);
}
ParameterKind::PositionalOnly { .. }
| ParameterKind::Variadic { .. } => {}
_ => {
// Any other parameter kind cannot be checked against a
// variadic parameter and is deferred to the next iteration.
break;
}
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
parameters.next_other();
}
}
(ParameterKind::Variadic { .. }, ParameterKind::Variadic { .. }) => {
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
_,
ParameterKind::KeywordOnly { .. }
| ParameterKind::KeywordVariadic { .. },
) => {
// Keyword parameters are not considered in this loop as the order of
// parameters is not important for them and so they are checked by
// doing name-based lookups.
break;
}
_ => return false,
}
}
}
}
// At this point, the remaining parameters in `other` are keyword-only or keyword variadic.
// But, `self` could contain any unmatched positional parameters.
let (self_parameters, other_parameters) = parameters.into_remaining();
// Collect all the keyword-only parameters and the unmatched standard parameters.
let mut self_keywords = HashMap::new();
// Type of the variadic keyword parameter in `self`.
//
// This is a nested option where the outer option represents the presence of a keyword
// variadic parameter in `self` and the inner option represents the annotated type of the
// keyword variadic parameter.
let mut self_keyword_variadic: Option<Option<Type<'db>>> = None;
for self_parameter in self_parameters {
match self_parameter.kind() {
ParameterKind::KeywordOnly { name, .. }
| ParameterKind::PositionalOrKeyword { name, .. } => {
self_keywords.insert(name.clone(), self_parameter);
}
ParameterKind::KeywordVariadic { .. } => {
self_keyword_variadic = Some(self_parameter.annotated_type());
}
ParameterKind::PositionalOnly { .. } => {
// These are the unmatched positional-only parameters in `self` from the
// previous loop. They cannot be matched against any parameter in `other` which
// only contains keyword-only and keyword-variadic parameters so the subtype
// relation is invalid.
return false;
}
ParameterKind::Variadic { .. } => {}
}
}
for other_parameter in other_keywords.into_iter().chain(other_parameters) {
match other_parameter.kind() {
ParameterKind::KeywordOnly {
name: other_name,
default_type: other_default,
}
| ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
} => {
if let Some(self_parameter) = self_keywords.remove(other_name) {
match self_parameter.kind() {
ParameterKind::PositionalOrKeyword {
default_type: self_default,
..
}
| ParameterKind::KeywordOnly {
default_type: self_default,
..
} => {
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
_ => unreachable!(
"`self_keywords` should only contain keyword-only or standard parameters"
),
}
} else if let Some(self_keyword_variadic_type) = self_keyword_variadic {
if !check_types(
other_parameter.annotated_type(),
self_keyword_variadic_type,
) {
return false;
}
} else {
return false;
}
}
ParameterKind::KeywordVariadic { .. } => {
let Some(self_keyword_variadic_type) = self_keyword_variadic else {
// For a `self <: other` relationship, if `other` has a keyword variadic
// parameter, `self` must also have a keyword variadic parameter.
return false;
};
if !check_types(other_parameter.annotated_type(), self_keyword_variadic_type) {
return false;
}
}
_ => {
// This can only occur in case of a syntax error.
return false;
}
}
}
// If there are still unmatched keyword parameters from `self`, then they should be
// optional otherwise the subtype relation is invalid.
for (_, self_parameter) in self_keywords {
if self_parameter.default_type().is_none() {
return false;
}
}
true
}
}
/// Represents a specific instance of `types.MethodWrapperType`
@@ -6196,6 +5724,8 @@ impl<'db> CallableType<'db> {
pub enum MethodWrapperKind<'db> {
/// Method wrapper for `some_function.__get__`
FunctionTypeDunderGet(FunctionType<'db>),
/// Method wrapper for `some_function.__call__`
FunctionTypeDunderCall(FunctionType<'db>),
/// Method wrapper for `some_property.__get__`
PropertyDunderGet(PropertyInstanceType<'db>),
/// Method wrapper for `some_property.__set__`

View File

@@ -528,7 +528,7 @@ impl<'db> Bindings<'db> {
}
Some(KnownFunction::Overload) => {
overload.set_return_type(todo_type!("overload(..) return type"));
overload.set_return_type(todo_type!("overload[..] return type"));
}
Some(KnownFunction::GetattrStatic) => {

View File

@@ -44,8 +44,7 @@ impl Display for DisplayType<'_> {
| Type::StringLiteral(_)
| Type::BytesLiteral(_)
| Type::ClassLiteral(_)
| Type::GenericAlias(_)
| Type::FunctionLiteral(_) => {
| Type::GenericAlias(_) => {
write!(f, "Literal[{representation}]")
}
_ => representation.fmt(f),
@@ -95,35 +94,32 @@ impl Display for DisplayRepresentation<'_> {
},
Type::KnownInstance(known_instance) => f.write_str(known_instance.repr(self.db)),
Type::FunctionLiteral(function) => {
f.write_str(function.name(self.db))?;
if let Some(specialization) = function.specialization(self.db) {
specialization.display_short(self.db).fmt(f)?;
}
Ok(())
let signature = function.signature(self.db);
// TODO: when generic function types are supported, we should add
// the generic type parameters to the signature, i.e.
// show `def foo[T](x: T) -> T`.
write!(
f,
// "def {name}{specialization}{signature}",
"def {name}{signature}",
name = function.name(self.db),
signature = signature.display(self.db)
)
}
Type::Callable(callable) => callable.signature(self.db).display(self.db).fmt(f),
Type::BoundMethod(bound_method) => {
let function = bound_method.function(self.db);
let self_instance = bound_method.self_instance(self.db);
let self_instance_specialization = match self_instance {
Type::Instance(InstanceType {
class: ClassType::Generic(alias),
}) => Some(alias.specialization(self.db)),
_ => None,
};
let specialization = match function.specialization(self.db) {
Some(specialization)
if self_instance_specialization.is_none_or(|sis| specialization == sis) =>
{
specialization.display_short(self.db).to_string()
}
_ => String::new(),
};
// TODO: use the specialization from the method. Similar to the comment above
// about the function specialization,
write!(
f,
"<bound method `{method}{specialization}` of `{instance}`>",
"bound method {instance}.{method}{signature}",
method = function.name(self.db),
instance = bound_method.self_instance(self.db).display(self.db),
signature = function.signature(self.db).bind_self().display(self.db)
)
}
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderGet(function)) => {
@@ -139,6 +135,19 @@ impl Display for DisplayRepresentation<'_> {
},
)
}
Type::MethodWrapper(MethodWrapperKind::FunctionTypeDunderCall(function)) => {
write!(
f,
"<method-wrapper `__call__` of `{function}{specialization}`>",
function = function.name(self.db),
specialization = if let Some(specialization) = function.specialization(self.db)
{
specialization.display_short(self.db).to_string()
} else {
String::new()
},
)
}
Type::MethodWrapper(MethodWrapperKind::PropertyDunderGet(_)) => {
write!(f, "<method-wrapper `__get__` of `property` object>",)
}
@@ -463,7 +472,6 @@ impl Display for DisplayLiteralGroup<'_> {
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
enum CondensedDisplayTypeKind {
Class,
Function,
LiteralExpression,
}
@@ -473,7 +481,6 @@ impl TryFrom<Type<'_>> for CondensedDisplayTypeKind {
fn try_from(value: Type<'_>) -> Result<Self, Self::Error> {
match value {
Type::ClassLiteral(_) => Ok(Self::Class),
Type::FunctionLiteral(_) => Ok(Self::Function),
Type::IntLiteral(_)
| Type::StringLiteral(_)
| Type::BytesLiteral(_)
@@ -551,7 +558,11 @@ struct DisplayMaybeParenthesizedType<'db> {
impl Display for DisplayMaybeParenthesizedType<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if let Type::Callable(_) | Type::MethodWrapper(_) = self.ty {
if let Type::Callable(_)
| Type::MethodWrapper(_)
| Type::FunctionLiteral(_)
| Type::BoundMethod(_) = self.ty
{
write!(f, "({})", self.ty.display(self.db))
} else {
self.ty.display(self.db).fmt(f)

View File

@@ -3086,7 +3086,7 @@ impl<'db> TypeInferenceBuilder<'db> {
let iterable_type = self.infer_standalone_expression(iterable);
let loop_var_value_type = if for_stmt.is_async() {
panic!("async iterables/iterators") // Test to see if mypy_primer run fails
todo_type!("async iterables/iterators")
} else {
match for_stmt.target_kind() {
TargetKind::Sequence(unpack_position, unpack) => {

View File

@@ -10,6 +10,9 @@
//! argument types and return types. For each callable type in the union, the call expression's
//! arguments must match _at least one_ overload.
use std::{collections::HashMap, slice::Iter};
use itertools::EitherOrBoth;
use smallvec::{smallvec, SmallVec};
use super::{definition_expression_type, DynamicType, Type};
@@ -284,6 +287,519 @@ impl<'db> Signature<'db> {
return_ty: self.return_ty,
}
}
/// Returns `true` if this is a fully static signature.
///
/// A signature is fully static if all of its parameters and return type are fully static and
/// if it does not use gradual form (`...`) for its parameters.
pub(crate) fn is_fully_static(&self, db: &'db dyn Db) -> bool {
if self.parameters.is_gradual() {
return false;
}
if self.parameters.iter().any(|parameter| {
parameter
.annotated_type()
.is_none_or(|annotated_type| !annotated_type.is_fully_static(db))
}) {
return false;
}
self.return_ty
.is_some_and(|return_type| return_type.is_fully_static(db))
}
/// Return `true` if `self` has exactly the same set of possible static materializations as
/// `other` (if `self` represents the same set of possible sets of possible runtime objects as
/// `other`).
pub(crate) fn is_gradual_equivalent_to(&self, db: &'db dyn Db, other: &Signature<'db>) -> bool {
self.is_equivalent_to_impl(other, |self_type, other_type| {
self_type
.unwrap_or(Type::unknown())
.is_gradual_equivalent_to(db, other_type.unwrap_or(Type::unknown()))
})
}
/// Return `true` if `self` represents the exact same set of possible runtime objects as `other`.
pub(crate) fn is_equivalent_to(&self, db: &'db dyn Db, other: &Signature<'db>) -> bool {
self.is_equivalent_to_impl(other, |self_type, other_type| {
match (self_type, other_type) {
(Some(self_type), Some(other_type)) => self_type.is_equivalent_to(db, other_type),
// We need the catch-all case here because it's not guaranteed that this is a fully
// static type.
_ => false,
}
})
}
/// Implementation for the [`is_equivalent_to`] and [`is_gradual_equivalent_to`] for signature.
///
/// [`is_equivalent_to`]: Self::is_equivalent_to
/// [`is_gradual_equivalent_to`]: Self::is_gradual_equivalent_to
fn is_equivalent_to_impl<F>(&self, other: &Signature<'db>, check_types: F) -> bool
where
F: Fn(Option<Type<'db>>, Option<Type<'db>>) -> bool,
{
// N.B. We don't need to explicitly check for the use of gradual form (`...`) in the
// parameters because it is internally represented by adding `*Any` and `**Any` to the
// parameter list.
if self.parameters.len() != other.parameters.len() {
return false;
}
if !check_types(self.return_ty, other.return_ty) {
return false;
}
for (self_parameter, other_parameter) in self.parameters.iter().zip(&other.parameters) {
match (self_parameter.kind(), other_parameter.kind()) {
(
ParameterKind::PositionalOnly {
default_type: self_default,
..
},
ParameterKind::PositionalOnly {
default_type: other_default,
..
},
) if self_default.is_some() == other_default.is_some() => {}
(
ParameterKind::PositionalOrKeyword {
name: self_name,
default_type: self_default,
},
ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
},
) if self_default.is_some() == other_default.is_some()
&& self_name == other_name => {}
(ParameterKind::Variadic { .. }, ParameterKind::Variadic { .. }) => {}
(
ParameterKind::KeywordOnly {
name: self_name,
default_type: self_default,
},
ParameterKind::KeywordOnly {
name: other_name,
default_type: other_default,
},
) if self_default.is_some() == other_default.is_some()
&& self_name == other_name => {}
(ParameterKind::KeywordVariadic { .. }, ParameterKind::KeywordVariadic { .. }) => {}
_ => return false,
}
if !check_types(
self_parameter.annotated_type(),
other_parameter.annotated_type(),
) {
return false;
}
}
true
}
/// Return `true` if a callable with signature `self` is assignable to a callable with
/// signature `other`.
pub(crate) fn is_assignable_to(&self, db: &'db dyn Db, other: &Signature<'db>) -> bool {
self.is_assignable_to_impl(other, |type1, type2| {
// In the context of a callable type, the `None` variant represents an `Unknown` type.
type1
.unwrap_or(Type::unknown())
.is_assignable_to(db, type2.unwrap_or(Type::unknown()))
})
}
/// Return `true` if a callable with signature `self` is a subtype of a callable with signature
/// `other`.
///
/// # Panics
///
/// Panics if `self` or `other` is not a fully static signature.
pub(crate) fn is_subtype_of(&self, db: &'db dyn Db, other: &Signature<'db>) -> bool {
self.is_assignable_to_impl(other, |type1, type2| {
// SAFETY: Subtype relation is only checked for fully static types.
type1.unwrap().is_subtype_of(db, type2.unwrap())
})
}
/// Implementation for the [`is_assignable_to`] and [`is_subtype_of`] for signature.
///
/// [`is_assignable_to`]: Self::is_assignable_to
/// [`is_subtype_of`]: Self::is_subtype_of
fn is_assignable_to_impl<F>(&self, other: &Signature<'db>, check_types: F) -> bool
where
F: Fn(Option<Type<'db>>, Option<Type<'db>>) -> bool,
{
/// A helper struct to zip two slices of parameters together that provides control over the
/// two iterators individually. It also keeps track of the current parameter in each
/// iterator.
struct ParametersZip<'a, 'db> {
current_self: Option<&'a Parameter<'db>>,
current_other: Option<&'a Parameter<'db>>,
iter_self: Iter<'a, Parameter<'db>>,
iter_other: Iter<'a, Parameter<'db>>,
}
impl<'a, 'db> ParametersZip<'a, 'db> {
/// Move to the next parameter in both the `self` and `other` parameter iterators,
/// [`None`] if both iterators are exhausted.
fn next(&mut self) -> Option<EitherOrBoth<&'a Parameter<'db>, &'a Parameter<'db>>> {
match (self.next_self(), self.next_other()) {
(Some(self_param), Some(other_param)) => {
Some(EitherOrBoth::Both(self_param, other_param))
}
(Some(self_param), None) => Some(EitherOrBoth::Left(self_param)),
(None, Some(other_param)) => Some(EitherOrBoth::Right(other_param)),
(None, None) => None,
}
}
/// Move to the next parameter in the `self` parameter iterator, [`None`] if the
/// iterator is exhausted.
fn next_self(&mut self) -> Option<&'a Parameter<'db>> {
self.current_self = self.iter_self.next();
self.current_self
}
/// Move to the next parameter in the `other` parameter iterator, [`None`] if the
/// iterator is exhausted.
fn next_other(&mut self) -> Option<&'a Parameter<'db>> {
self.current_other = self.iter_other.next();
self.current_other
}
/// Peek at the next parameter in the `other` parameter iterator without consuming it.
fn peek_other(&mut self) -> Option<&'a Parameter<'db>> {
self.iter_other.clone().next()
}
/// Consumes the `ParametersZip` and returns a two-element tuple containing the
/// remaining parameters in the `self` and `other` iterators respectively.
///
/// The returned iterators starts with the current parameter, if any, followed by the
/// remaining parameters in the respective iterators.
fn into_remaining(
self,
) -> (
impl Iterator<Item = &'a Parameter<'db>>,
impl Iterator<Item = &'a Parameter<'db>>,
) {
(
self.current_self.into_iter().chain(self.iter_self),
self.current_other.into_iter().chain(self.iter_other),
)
}
}
// Return types are covariant.
if !check_types(self.return_ty, other.return_ty) {
return false;
}
if self.parameters.is_gradual() || other.parameters.is_gradual() {
// If either of the parameter lists contains a gradual form (`...`), then it is
// assignable / subtype to and from any other callable type.
return true;
}
let mut parameters = ParametersZip {
current_self: None,
current_other: None,
iter_self: self.parameters.iter(),
iter_other: other.parameters.iter(),
};
// Collect all the standard parameters that have only been matched against a variadic
// parameter which means that the keyword variant is still unmatched.
let mut other_keywords = Vec::new();
loop {
let Some(next_parameter) = parameters.next() else {
// All parameters have been checked or both the parameter lists were empty. In
// either case, `self` is a subtype of `other`.
return true;
};
match next_parameter {
EitherOrBoth::Left(self_parameter) => match self_parameter.kind() {
ParameterKind::KeywordOnly { .. } | ParameterKind::KeywordVariadic { .. }
if !other_keywords.is_empty() =>
{
// If there are any unmatched keyword parameters in `other`, they need to
// be checked against the keyword-only / keyword-variadic parameters that
// will be done after this loop.
break;
}
ParameterKind::PositionalOnly { default_type, .. }
| ParameterKind::PositionalOrKeyword { default_type, .. }
| ParameterKind::KeywordOnly { default_type, .. } => {
// For `self <: other` to be valid, if there are no more parameters in
// `other`, then the non-variadic parameters in `self` must have a default
// value.
if default_type.is_none() {
return false;
}
}
ParameterKind::Variadic { .. } | ParameterKind::KeywordVariadic { .. } => {
// Variadic parameters don't have any restrictions in this context, so
// we'll just continue to the next parameter set.
}
},
EitherOrBoth::Right(_) => {
// If there are more parameters in `other` than in `self`, then `self` is not a
// subtype of `other`.
return false;
}
EitherOrBoth::Both(self_parameter, other_parameter) => {
match (self_parameter.kind(), other_parameter.kind()) {
(
ParameterKind::PositionalOnly {
default_type: self_default,
..
}
| ParameterKind::PositionalOrKeyword {
default_type: self_default,
..
},
ParameterKind::PositionalOnly {
default_type: other_default,
..
},
) => {
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
ParameterKind::PositionalOrKeyword {
name: self_name,
default_type: self_default,
},
ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
},
) => {
if self_name != other_name {
return false;
}
// The following checks are the same as positional-only parameters.
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
ParameterKind::Variadic { .. },
ParameterKind::PositionalOnly { .. }
| ParameterKind::PositionalOrKeyword { .. },
) => {
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
if matches!(
other_parameter.kind(),
ParameterKind::PositionalOrKeyword { .. }
) {
other_keywords.push(other_parameter);
}
// We've reached a variadic parameter in `self` which means there can
// be no more positional parameters after this in a valid AST. But, the
// current parameter in `other` is a positional-only which means there
// can be more positional parameters after this which could be either
// more positional-only parameters, standard parameters or a variadic
// parameter.
//
// So, any remaining positional parameters in `other` would need to be
// checked against the variadic parameter in `self`. This loop does
// that by only moving the `other` iterator forward.
loop {
let Some(other_parameter) = parameters.peek_other() else {
break;
};
match other_parameter.kind() {
ParameterKind::PositionalOrKeyword { .. } => {
other_keywords.push(other_parameter);
}
ParameterKind::PositionalOnly { .. }
| ParameterKind::Variadic { .. } => {}
_ => {
// Any other parameter kind cannot be checked against a
// variadic parameter and is deferred to the next iteration.
break;
}
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
parameters.next_other();
}
}
(ParameterKind::Variadic { .. }, ParameterKind::Variadic { .. }) => {
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
(
_,
ParameterKind::KeywordOnly { .. }
| ParameterKind::KeywordVariadic { .. },
) => {
// Keyword parameters are not considered in this loop as the order of
// parameters is not important for them and so they are checked by
// doing name-based lookups.
break;
}
_ => return false,
}
}
}
}
// At this point, the remaining parameters in `other` are keyword-only or keyword variadic.
// But, `self` could contain any unmatched positional parameters.
let (self_parameters, other_parameters) = parameters.into_remaining();
// Collect all the keyword-only parameters and the unmatched standard parameters.
let mut self_keywords = HashMap::new();
// Type of the variadic keyword parameter in `self`.
//
// This is a nested option where the outer option represents the presence of a keyword
// variadic parameter in `self` and the inner option represents the annotated type of the
// keyword variadic parameter.
let mut self_keyword_variadic: Option<Option<Type<'db>>> = None;
for self_parameter in self_parameters {
match self_parameter.kind() {
ParameterKind::KeywordOnly { name, .. }
| ParameterKind::PositionalOrKeyword { name, .. } => {
self_keywords.insert(name.clone(), self_parameter);
}
ParameterKind::KeywordVariadic { .. } => {
self_keyword_variadic = Some(self_parameter.annotated_type());
}
ParameterKind::PositionalOnly { .. } => {
// These are the unmatched positional-only parameters in `self` from the
// previous loop. They cannot be matched against any parameter in `other` which
// only contains keyword-only and keyword-variadic parameters so the subtype
// relation is invalid.
return false;
}
ParameterKind::Variadic { .. } => {}
}
}
for other_parameter in other_keywords.into_iter().chain(other_parameters) {
match other_parameter.kind() {
ParameterKind::KeywordOnly {
name: other_name,
default_type: other_default,
}
| ParameterKind::PositionalOrKeyword {
name: other_name,
default_type: other_default,
} => {
if let Some(self_parameter) = self_keywords.remove(other_name) {
match self_parameter.kind() {
ParameterKind::PositionalOrKeyword {
default_type: self_default,
..
}
| ParameterKind::KeywordOnly {
default_type: self_default,
..
} => {
if self_default.is_none() && other_default.is_some() {
return false;
}
if !check_types(
other_parameter.annotated_type(),
self_parameter.annotated_type(),
) {
return false;
}
}
_ => unreachable!(
"`self_keywords` should only contain keyword-only or standard parameters"
),
}
} else if let Some(self_keyword_variadic_type) = self_keyword_variadic {
if !check_types(
other_parameter.annotated_type(),
self_keyword_variadic_type,
) {
return false;
}
} else {
return false;
}
}
ParameterKind::KeywordVariadic { .. } => {
let Some(self_keyword_variadic_type) = self_keyword_variadic else {
// For a `self <: other` relationship, if `other` has a keyword variadic
// parameter, `self` must also have a keyword variadic parameter.
return false;
};
if !check_types(other_parameter.annotated_type(), self_keyword_variadic_type) {
return false;
}
}
_ => {
// This can only occur in case of a syntax error.
return false;
}
}
}
// If there are still unmatched keyword parameters from `self`, then they should be
// optional otherwise the subtype relation is invalid.
for (_, self_parameter) in self_keywords {
if self_parameter.default_type().is_none() {
return false;
}
}
true
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update)]

View File

@@ -19,7 +19,7 @@ it before submitting pull requests; do not report issues with annotations to
the project the stubs are for, but instead report them here to typeshed.**
Further documentation on stub files, typeshed, and Python's typing system in
general, can also be found at https://typing.python.org/en/latest/.
general, can also be found at https://typing.readthedocs.io/en/latest/.
Typeshed supports Python versions 3.9 to 3.13.

View File

@@ -1 +1 @@
bfd032156c59bbf851f62174014f24f4f89b96af
f65bdc1acde54fda93c802459280da74518d2eef

View File

@@ -36,8 +36,6 @@ _curses: 3.0-
_curses_panel: 3.0-
_dbm: 3.0-
_decimal: 3.3-
_dummy_thread: 3.0-3.8
_dummy_threading: 3.0-3.8
_frozen_importlib: 3.0-
_frozen_importlib_external: 3.5-
_gdbm: 3.0-
@@ -140,7 +138,6 @@ distutils: 3.0-3.11
distutils.command.bdist_msi: 3.0-3.10
distutils.command.bdist_wininst: 3.0-3.9
doctest: 3.0-
dummy_threading: 3.0-3.8
email: 3.0-
encodings: 3.0-
encodings.cp1125: 3.4-
@@ -148,7 +145,6 @@ encodings.cp273: 3.4-
encodings.cp858: 3.2-
encodings.koi8_t: 3.5-
encodings.kz1048: 3.5-
encodings.mac_centeuro: 3.0-3.8
ensurepip: 3.0-
enum: 3.4-
errno: 3.0-

View File

@@ -130,17 +130,6 @@ if sys.version_info >= (3, 10):
pattern as pattern,
)
if sys.version_info < (3, 9):
from ast import (
AugLoad as AugLoad,
AugStore as AugStore,
ExtSlice as ExtSlice,
Index as Index,
Param as Param,
Suite as Suite,
slice as slice,
)
PyCF_ALLOW_TOP_LEVEL_AWAIT: Literal[8192]
PyCF_ONLY_AST: Literal[1024]
PyCF_TYPE_COMMENTS: Literal[4096]

View File

@@ -2,13 +2,10 @@ import sys
from asyncio.events import AbstractEventLoop
from collections.abc import Awaitable, Callable, Coroutine, Generator
from contextvars import Context
from types import FrameType
from types import FrameType, GenericAlias
from typing import Any, Literal, TextIO, TypeVar
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_TaskYieldType: TypeAlias = Future[object] | None
@@ -29,11 +26,7 @@ class Future(Awaitable[_T]):
@property
def _callbacks(self) -> list[tuple[Callable[[Self], Any], Context]]: ...
def add_done_callback(self, fn: Callable[[Self], object], /, *, context: Context | None = None) -> None: ...
if sys.version_info >= (3, 9):
def cancel(self, msg: Any | None = None) -> bool: ...
else:
def cancel(self) -> bool: ...
def cancel(self, msg: Any | None = None) -> bool: ...
def cancelled(self) -> bool: ...
def done(self) -> bool: ...
def result(self) -> _T: ...
@@ -45,15 +38,12 @@ class Future(Awaitable[_T]):
def __await__(self) -> Generator[Any, None, _T]: ...
@property
def _loop(self) -> AbstractEventLoop: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 12):
_TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co]
elif sys.version_info >= (3, 9):
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co]
else:
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Awaitable[_T_co]
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co]
# mypy and pyright complain that a subclass of an invariant class shouldn't be covariant.
# While this is true in general, here it's sort-of okay to have a covariant subclass,
@@ -99,13 +89,8 @@ class Task(Future[_T_co]): # type: ignore[type-var] # pyright: ignore[reportIn
if sys.version_info >= (3, 11):
def cancelling(self) -> int: ...
def uncancel(self) -> int: ...
if sys.version_info < (3, 9):
@classmethod
def current_task(cls, loop: AbstractEventLoop | None = None) -> Task[Any] | None: ...
@classmethod
def all_tasks(cls, loop: AbstractEventLoop | None = None) -> set[Task[Any]]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def get_event_loop() -> AbstractEventLoop: ...
def get_running_loop() -> AbstractEventLoop: ...

View File

@@ -1,4 +1,3 @@
import sys
from _typeshed import ReadableBuffer
from typing import ClassVar, final
from typing_extensions import Self
@@ -21,44 +20,24 @@ class blake2b:
block_size: int
digest_size: int
name: str
if sys.version_info >= (3, 9):
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 64,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
usedforsecurity: bool = True,
) -> Self: ...
else:
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 64,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
) -> Self: ...
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 64,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
usedforsecurity: bool = True,
) -> Self: ...
def copy(self) -> Self: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
@@ -73,44 +52,24 @@ class blake2s:
block_size: int
digest_size: int
name: str
if sys.version_info >= (3, 9):
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 32,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
usedforsecurity: bool = True,
) -> Self: ...
else:
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 32,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
) -> Self: ...
def __new__(
cls,
data: ReadableBuffer = b"",
/,
*,
digest_size: int = 32,
key: ReadableBuffer = b"",
salt: ReadableBuffer = b"",
person: ReadableBuffer = b"",
fanout: int = 1,
depth: int = 1,
leaf_size: int = 0,
node_offset: int = 0,
node_depth: int = 0,
inner_size: int = 0,
last_node: bool = False,
usedforsecurity: bool = True,
) -> Self: ...
def copy(self) -> Self: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...

View File

@@ -81,26 +81,12 @@ def escape_decode(data: str | ReadableBuffer, errors: str | None = None, /) -> t
def escape_encode(data: bytes, errors: str | None = None, /) -> tuple[bytes, int]: ...
def latin_1_decode(data: ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ...
def latin_1_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...
if sys.version_info >= (3, 9):
def raw_unicode_escape_decode(
data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /
) -> tuple[str, int]: ...
else:
def raw_unicode_escape_decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ...
def raw_unicode_escape_decode(
data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /
) -> tuple[str, int]: ...
def raw_unicode_escape_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...
def readbuffer_encode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[bytes, int]: ...
if sys.version_info >= (3, 9):
def unicode_escape_decode(
data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /
) -> tuple[str, int]: ...
else:
def unicode_escape_decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ...
def unicode_escape_decode(data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /) -> tuple[str, int]: ...
def unicode_escape_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...
def utf_16_be_decode(data: ReadableBuffer, errors: str | None = None, final: bool = False, /) -> tuple[str, int]: ...
def utf_16_be_encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...

View File

@@ -1,7 +1,7 @@
import sys
from abc import abstractmethod
from types import MappingProxyType
from typing import ( # noqa: Y022,Y038
from typing import ( # noqa: Y022,Y038,UP035
AbstractSet as Set,
AsyncGenerator as AsyncGenerator,
AsyncIterable as AsyncIterable,
@@ -61,7 +61,7 @@ __all__ = [
"MutableSequence",
]
if sys.version_info < (3, 14):
from typing import ByteString as ByteString # noqa: Y057
from typing import ByteString as ByteString # noqa: Y057,UP035
__all__ += ["ByteString"]

View File

@@ -1,11 +1,8 @@
import sys
from collections.abc import Callable, Iterator, Mapping
from types import GenericAlias
from typing import Any, ClassVar, Generic, TypeVar, final, overload
from typing_extensions import ParamSpec, Self
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
_D = TypeVar("_D")
_P = ParamSpec("_P")
@@ -27,8 +24,7 @@ class ContextVar(Generic[_T]):
def get(self, default: _D, /) -> _D | _T: ...
def set(self, value: _T, /) -> Token[_T]: ...
def reset(self, token: Token[_T], /) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
@final
class Token(Generic[_T]):
@@ -38,8 +34,7 @@ class Token(Generic[_T]):
def old_value(self) -> Any: ... # returns either _T or MISSING, but that's hard to express
MISSING: ClassVar[object]
__hash__: ClassVar[None] # type: ignore[assignment]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def copy_context() -> Context: ...

View File

@@ -4,12 +4,10 @@ from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer
from abc import abstractmethod
from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from ctypes import CDLL, ArgumentError as ArgumentError, c_void_p
from types import GenericAlias
from typing import Any, ClassVar, Generic, TypeVar, final, overload, type_check_only
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
_CT = TypeVar("_CT", bound=_CData)
@@ -292,7 +290,7 @@ class Array(_CData, Generic[_CT], metaclass=_PyCArrayType):
@raw.setter
def raw(self, value: ReadableBuffer) -> None: ...
value: Any # Note: bytes if _CT == c_char, str if _CT == c_wchar, unavailable otherwise
# TODO These methods cannot be annotated correctly at the moment.
# TODO: These methods cannot be annotated correctly at the moment.
# All of these "Any"s stand for the array's element type, but it's not possible to use _CT
# here, because of a special feature of ctypes.
# By default, when accessing an element of an Array[_CT], the returned object has type _CT.
@@ -317,8 +315,7 @@ class Array(_CData, Generic[_CT], metaclass=_PyCArrayType):
# Can't inherit from Sized because the metaclass conflict between
# Sized and _CData prevents using _CDataMeta.
def __len__(self) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def addressof(obj: _CData | _CDataType, /) -> int: ...
def alignment(obj_or_type: _CData | _CDataType | type[_CData | _CDataType], /) -> int: ...

View File

@@ -95,13 +95,14 @@ 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
# Darwin ncurses doesn't provide BUTTON5_* constants prior to 3.12.10 and 3.13.3
if sys.version_info >= (3, 10):
if sys.version_info >= (3, 12) or 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
@@ -292,11 +293,8 @@ 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 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], /) -> window: ...
@@ -341,11 +339,8 @@ 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 set_escdelay(ms: int, /) -> None: ...
def set_tabsize(size: int, /) -> None: ...
def setsyx(y: int, x: int, /) -> None: ...
def setupterm(term: str | None = None, fd: int = -1) -> None: ...
def start_color() -> None: ...

View File

@@ -1,33 +0,0 @@
from collections.abc import Callable
from types import TracebackType
from typing import Any, NoReturn, overload
from typing_extensions import TypeVarTuple, Unpack
__all__ = ["error", "start_new_thread", "exit", "get_ident", "allocate_lock", "interrupt_main", "LockType", "RLock"]
_Ts = TypeVarTuple("_Ts")
TIMEOUT_MAX: int
error = RuntimeError
@overload
def start_new_thread(function: Callable[[Unpack[_Ts]], object], args: tuple[Unpack[_Ts]]) -> None: ...
@overload
def start_new_thread(function: Callable[..., object], args: tuple[Any, ...], kwargs: dict[str, Any]) -> None: ...
def exit() -> NoReturn: ...
def get_ident() -> int: ...
def allocate_lock() -> LockType: ...
def stack_size(size: int | None = None) -> int: ...
class LockType:
locked_status: bool
def acquire(self, waitflag: bool | None = None, timeout: int = -1) -> bool: ...
def __enter__(self, waitflag: bool | None = None, timeout: int = -1) -> bool: ...
def __exit__(self, typ: type[BaseException] | None, val: BaseException | None, tb: TracebackType | None) -> None: ...
def release(self) -> bool: ...
def locked(self) -> bool: ...
class RLock(LockType):
def release(self) -> None: ... # type: ignore[override]
def interrupt_main() -> None: ...

View File

@@ -1,56 +0,0 @@
from _threading_local import local as local
from _typeshed import ProfileFunction, TraceFunction
from threading import (
TIMEOUT_MAX as TIMEOUT_MAX,
Barrier as Barrier,
BoundedSemaphore as BoundedSemaphore,
BrokenBarrierError as BrokenBarrierError,
Condition as Condition,
Event as Event,
ExceptHookArgs as ExceptHookArgs,
Lock as Lock,
RLock as RLock,
Semaphore as Semaphore,
Thread as Thread,
ThreadError as ThreadError,
Timer as Timer,
_DummyThread as _DummyThread,
_RLock as _RLock,
excepthook as excepthook,
)
__all__ = [
"get_ident",
"active_count",
"Condition",
"current_thread",
"enumerate",
"main_thread",
"TIMEOUT_MAX",
"Event",
"Lock",
"RLock",
"Semaphore",
"BoundedSemaphore",
"Thread",
"Barrier",
"BrokenBarrierError",
"Timer",
"ThreadError",
"setprofile",
"settrace",
"local",
"stack_size",
"ExceptHookArgs",
"excepthook",
]
def active_count() -> int: ...
def current_thread() -> Thread: ...
def currentThread() -> Thread: ...
def get_ident() -> int: ...
def enumerate() -> list[Thread]: ...
def main_thread() -> Thread: ...
def settrace(func: TraceFunction) -> None: ...
def setprofile(func: ProfileFunction | None) -> None: ...
def stack_size(size: int | None = None) -> int: ...

View File

@@ -37,53 +37,42 @@ class HASH:
if sys.version_info >= (3, 10):
class UnsupportedDigestmodError(ValueError): ...
if sys.version_info >= (3, 9):
class HASHXOF(HASH):
def digest(self, length: int) -> bytes: ... # type: ignore[override]
def hexdigest(self, length: int) -> str: ... # type: ignore[override]
class HASHXOF(HASH):
def digest(self, length: int) -> bytes: ... # type: ignore[override]
def hexdigest(self, length: int) -> str: ... # type: ignore[override]
@final
class HMAC:
@property
def digest_size(self) -> int: ...
@property
def block_size(self) -> int: ...
@property
def name(self) -> str: ...
def copy(self) -> Self: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def update(self, msg: ReadableBuffer) -> None: ...
@overload
def compare_digest(a: ReadableBuffer, b: ReadableBuffer, /) -> bool: ...
@overload
def compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ...
def get_fips_mode() -> int: ...
def hmac_new(key: bytes | bytearray, msg: ReadableBuffer = b"", digestmod: _DigestMod = None) -> HMAC: ...
def new(name: str, string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_md5(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha1(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha224(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha384(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha512(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_224(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_384(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_512(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_shake_128(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASHXOF: ...
def openssl_shake_256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASHXOF: ...
else:
def new(name: str, string: ReadableBuffer = b"") -> HASH: ...
def openssl_md5(string: ReadableBuffer = b"") -> HASH: ...
def openssl_sha1(string: ReadableBuffer = b"") -> HASH: ...
def openssl_sha224(string: ReadableBuffer = b"") -> HASH: ...
def openssl_sha256(string: ReadableBuffer = b"") -> HASH: ...
def openssl_sha384(string: ReadableBuffer = b"") -> HASH: ...
def openssl_sha512(string: ReadableBuffer = b"") -> HASH: ...
@final
class HMAC:
@property
def digest_size(self) -> int: ...
@property
def block_size(self) -> int: ...
@property
def name(self) -> str: ...
def copy(self) -> Self: ...
def digest(self) -> bytes: ...
def hexdigest(self) -> str: ...
def update(self, msg: ReadableBuffer) -> None: ...
@overload
def compare_digest(a: ReadableBuffer, b: ReadableBuffer, /) -> bool: ...
@overload
def compare_digest(a: AnyStr, b: AnyStr, /) -> bool: ...
def get_fips_mode() -> int: ...
def hmac_new(key: bytes | bytearray, msg: ReadableBuffer = b"", digestmod: _DigestMod = None) -> HMAC: ...
def new(name: str, string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_md5(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha1(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha224(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha384(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha512(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_224(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_384(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_sha3_512(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASH: ...
def openssl_shake_128(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASHXOF: ...
def openssl_shake_256(string: ReadableBuffer = b"", *, usedforsecurity: bool = True) -> HASHXOF: ...
def hmac_digest(key: bytes | bytearray, msg: ReadableBuffer, digest: str) -> bytes: ...
def pbkdf2_hmac(
hash_name: str, password: ReadableBuffer, salt: ReadableBuffer, iterations: int, dklen: int | None = None

View File

@@ -1,4 +1,3 @@
import sys
from _typeshed import ReadableBuffer, SupportsWrite
from collections.abc import Callable, Iterable, Iterator, Mapping
from pickle import PickleBuffer as PickleBuffer
@@ -75,10 +74,9 @@ class Pickler:
def memo(self, value: PicklerMemoProxy | dict[int, tuple[int, Any]]) -> None: ...
def dump(self, obj: Any, /) -> None: ...
def clear_memo(self) -> None: ...
if sys.version_info >= (3, 13):
def persistent_id(self, obj: Any, /) -> Any: ...
else:
persistent_id: Callable[[Any], Any]
# this method has no default implementation for Python < 3.13
def persistent_id(self, obj: Any, /) -> Any: ...
@type_check_only
class UnpicklerMemoProxy:
@@ -101,7 +99,6 @@ class Unpickler:
def memo(self, value: UnpicklerMemoProxy | dict[int, tuple[int, Any]]) -> None: ...
def load(self) -> Any: ...
def find_class(self, module_name: str, global_name: str, /) -> Any: ...
if sys.version_info >= (3, 13):
def persistent_load(self, pid: Any, /) -> Any: ...
else:
persistent_load: Callable[[Any], Any]
# this method has no default implementation for Python < 3.13
def persistent_load(self, pid: Any, /) -> Any: ...

View File

@@ -1,9 +1,6 @@
import sys
from types import GenericAlias
from typing import Any, Generic, TypeVar
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
class Empty(Exception): ...
@@ -16,5 +13,4 @@ class SimpleQueue(Generic[_T]):
def put(self, item: _T, block: bool = True, timeout: float | None = None) -> None: ...
def put_nowait(self, item: _T) -> None: ...
def qsize(self) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

View File

@@ -78,7 +78,7 @@ if sys.platform == "win32":
SO_EXCLUSIVEADDRUSE: int
if sys.platform != "win32":
SO_REUSEPORT: int
if sys.platform != "darwin":
if sys.platform != "darwin" or sys.version_info >= (3, 13):
SO_BINDTODEVICE: int
if sys.platform != "win32" and sys.platform != "darwin":
@@ -192,7 +192,7 @@ if sys.platform != "win32" and sys.platform != "darwin" and sys.platform != "lin
IPPROTO_BIP: int # Not FreeBSD either
IPPROTO_MOBILE: int # Not FreeBSD either
IPPROTO_VRRP: int # Not FreeBSD either
if sys.version_info >= (3, 9) and sys.platform == "linux":
if sys.platform == "linux":
# Availability: Linux >= 2.6.20, FreeBSD >= 10.1
IPPROTO_UDPLITE: int
if sys.version_info >= (3, 10) and sys.platform == "linux":
@@ -250,29 +250,26 @@ IPV6_RECVTCLASS: int
IPV6_TCLASS: int
IPV6_UNICAST_HOPS: int
IPV6_V6ONLY: int
if sys.version_info >= (3, 9) or sys.platform != "darwin":
IPV6_DONTFRAG: int
IPV6_HOPLIMIT: int
IPV6_HOPOPTS: int
IPV6_PKTINFO: int
IPV6_RECVRTHDR: int
IPV6_RTHDR: int
IPV6_DONTFRAG: int
IPV6_HOPLIMIT: int
IPV6_HOPOPTS: int
IPV6_PKTINFO: int
IPV6_RECVRTHDR: int
IPV6_RTHDR: int
if sys.platform != "win32":
IPV6_RTHDR_TYPE_0: int
if sys.version_info >= (3, 9) or sys.platform != "darwin":
IPV6_DSTOPTS: int
IPV6_NEXTHOP: int
IPV6_PATHMTU: int
IPV6_RECVDSTOPTS: int
IPV6_RECVHOPLIMIT: int
IPV6_RECVHOPOPTS: int
IPV6_RECVPATHMTU: int
IPV6_RECVPKTINFO: int
IPV6_RTHDRDSTOPTS: int
IPV6_DSTOPTS: int
IPV6_NEXTHOP: int
IPV6_PATHMTU: int
IPV6_RECVDSTOPTS: int
IPV6_RECVHOPLIMIT: int
IPV6_RECVHOPOPTS: int
IPV6_RECVPATHMTU: int
IPV6_RECVPKTINFO: int
IPV6_RTHDRDSTOPTS: int
if sys.platform != "win32" and sys.platform != "linux":
if sys.version_info >= (3, 9) or sys.platform != "darwin":
IPV6_USE_MIN_MTU: int
IPV6_USE_MIN_MTU: int
EAI_AGAIN: int
EAI_BADFLAGS: int
@@ -414,16 +411,10 @@ if sys.platform == "linux":
if sys.platform == "linux":
# Availability: Linux >= 3.6
CAN_RAW_FD_FRAMES: int
if sys.platform == "linux" and sys.version_info >= (3, 9):
# Availability: Linux >= 4.1
CAN_RAW_JOIN_FILTERS: int
if sys.platform == "linux":
# Availability: Linux >= 2.6.25
CAN_ISOTP: int
if sys.platform == "linux" and sys.version_info >= (3, 9):
# Availability: Linux >= 5.4
CAN_J1939: int
@@ -566,18 +557,16 @@ if sys.platform == "linux":
SO_VM_SOCKETS_BUFFER_MIN_SIZE: int
VM_SOCKETS_INVALID_VERSION: int # undocumented
if sys.platform != "win32" or sys.version_info >= (3, 9):
# Documented as only available on BSD, macOS, but empirically sometimes
# available on Windows
if sys.platform != "linux":
AF_LINK: int
# Documented as only available on BSD, macOS, but empirically sometimes
# available on Windows
if sys.platform != "linux":
AF_LINK: int
has_ipv6: bool
if sys.platform != "darwin" and sys.platform != "linux":
if sys.platform != "win32" or sys.version_info >= (3, 9):
BDADDR_ANY: str
BDADDR_LOCAL: str
BDADDR_ANY: str
BDADDR_LOCAL: str
if sys.platform != "win32" and sys.platform != "darwin" and sys.platform != "linux":
HCI_FILTER: int # not in NetBSD or DragonFlyBSD
@@ -649,8 +638,7 @@ if sys.platform == "darwin":
SYSPROTO_CONTROL: int
if sys.platform != "darwin" and sys.platform != "linux":
if sys.version_info >= (3, 9) or sys.platform != "win32":
AF_BLUETOOTH: int
AF_BLUETOOTH: int
if sys.platform != "win32" and sys.platform != "darwin" and sys.platform != "linux":
# Linux and some BSD support is explicit in the docs
@@ -659,10 +647,9 @@ if sys.platform != "win32" and sys.platform != "darwin" and sys.platform != "lin
BTPROTO_L2CAP: int
BTPROTO_SCO: int # not in FreeBSD
if sys.platform != "darwin" and sys.platform != "linux":
if sys.version_info >= (3, 9) or sys.platform != "win32":
BTPROTO_RFCOMM: int
BTPROTO_RFCOMM: int
if sys.version_info >= (3, 9) and sys.platform == "linux":
if sys.platform == "linux":
UDPLITE_RECV_CSCOV: int
UDPLITE_SEND_CSCOV: int

View File

@@ -1,4 +1,3 @@
import sys
from collections.abc import Sequence
from tracemalloc import _FrameTuple, _TraceTuple
@@ -9,9 +8,6 @@ def get_traceback_limit() -> int: ...
def get_traced_memory() -> tuple[int, int]: ...
def get_tracemalloc_memory() -> int: ...
def is_tracing() -> bool: ...
if sys.version_info >= (3, 9):
def reset_peak() -> None: ...
def reset_peak() -> None: ...
def start(nframe: int = 1, /) -> None: ...
def stop() -> None: ...

View File

@@ -22,7 +22,7 @@ from typing import (
final,
overload,
)
from typing_extensions import Buffer, LiteralString, TypeAlias
from typing_extensions import Buffer, LiteralString, Self as _Self, TypeAlias
_KT = TypeVar("_KT")
_KT_co = TypeVar("_KT_co", covariant=True)
@@ -328,9 +328,9 @@ class structseq(Generic[_T_co]):
# 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[Self], sequence: Iterable[_T_co], dict: dict[str, Any] = ...) -> Self: ...
def __new__(cls, sequence: Iterable[_T_co], dict: dict[str, Any] = ...) -> _Self: ...
if sys.version_info >= (3, 13):
def __replace__(self: Self, **kwargs: Any) -> Self: ...
def __replace__(self, **kwargs: Any) -> _Self: ...
# Superset of typing.AnyStr that also includes LiteralString
AnyOrLiteralStr = TypeVar("AnyOrLiteralStr", str, bytes, LiteralString) # noqa: Y001

View File

@@ -1,11 +1,8 @@
import sys
from collections.abc import Iterable, Iterator, MutableSet
from types import GenericAlias
from typing import Any, ClassVar, TypeVar, overload
from typing_extensions import Self
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = ["WeakSet"]
_S = TypeVar("_S")
@@ -48,5 +45,4 @@ class WeakSet(MutableSet[_T]):
def union(self, other: Iterable[_S]) -> WeakSet[_S | _T]: ...
def __or__(self, other: Iterable[_S]) -> WeakSet[_S | _T]: ...
def isdisjoint(self, other: Iterable[_T]) -> bool: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...

View File

@@ -1,12 +1,8 @@
import sys
from types import TracebackType
from typing import IO, Any, Literal, NamedTuple, overload
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 9):
__all__ = ["Error", "open"]
else:
__all__ = ["Error", "open", "openfp"]
__all__ = ["Error", "open"]
class Error(Exception): ...
@@ -81,11 +77,3 @@ def open(f: _File, mode: Literal["r", "rb"]) -> Aifc_read: ...
def open(f: _File, mode: Literal["w", "wb"]) -> Aifc_write: ...
@overload
def open(f: _File, mode: str | None = None) -> Any: ...
if sys.version_info < (3, 9):
@overload
def openfp(f: _File, mode: Literal["r", "rb"]) -> Aifc_read: ...
@overload
def openfp(f: _File, mode: Literal["w", "wb"]) -> Aifc_write: ...
@overload
def openfp(f: _File, mode: str | None = None) -> Any: ...

View File

@@ -17,6 +17,7 @@ __all__ = [
"MetavarTypeHelpFormatter",
"Namespace",
"Action",
"BooleanOptionalAction",
"ONE_OR_MORE",
"OPTIONAL",
"PARSER",
@@ -25,9 +26,6 @@ __all__ = [
"ZERO_OR_MORE",
]
if sys.version_info >= (3, 9):
__all__ += ["BooleanOptionalAction"]
_T = TypeVar("_T")
_ActionT = TypeVar("_ActionT", bound=Action)
_ArgumentParserT = TypeVar("_ArgumentParserT", bound=ArgumentParser)
@@ -132,40 +130,22 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
_subparsers: _ArgumentGroup | None
# Note: the constructor arguments are also used in _SubParsersAction.add_parser.
if sys.version_info >= (3, 9):
def __init__(
self,
prog: str | None = None,
usage: str | None = None,
description: str | None = None,
epilog: str | None = None,
parents: Sequence[ArgumentParser] = [],
formatter_class: _FormatterClass = ...,
prefix_chars: str = "-",
fromfile_prefix_chars: str | None = None,
argument_default: Any = None,
conflict_handler: str = "error",
add_help: bool = True,
allow_abbrev: bool = True,
exit_on_error: bool = True,
) -> None: ...
else:
def __init__(
self,
prog: str | None = None,
usage: str | None = None,
description: str | None = None,
epilog: str | None = None,
parents: Sequence[ArgumentParser] = [],
formatter_class: _FormatterClass = ...,
prefix_chars: str = "-",
fromfile_prefix_chars: str | None = None,
argument_default: Any = None,
conflict_handler: str = "error",
add_help: bool = True,
allow_abbrev: bool = True,
) -> None: ...
def __init__(
self,
prog: str | None = None,
usage: str | None = None,
description: str | None = None,
epilog: str | None = None,
parents: Sequence[ArgumentParser] = [],
formatter_class: _FormatterClass = ...,
prefix_chars: str = "-",
fromfile_prefix_chars: str | None = None,
argument_default: Any = None,
conflict_handler: str = "error",
add_help: bool = True,
allow_abbrev: bool = True,
exit_on_error: bool = True,
) -> None: ...
@overload
def parse_args(self, args: Sequence[str] | None = None, namespace: None = None) -> Namespace: ...
@overload
@@ -352,8 +332,7 @@ class Action(_AttributeHolder):
def __call__(
self, parser: ArgumentParser, namespace: Namespace, values: str | Sequence[Any] | None, option_string: str | None = None
) -> None: ...
if sys.version_info >= (3, 9):
def format_usage(self) -> str: ...
def format_usage(self) -> str: ...
if sys.version_info >= (3, 12):
class BooleanOptionalAction(Action):
@@ -418,7 +397,7 @@ if sys.version_info >= (3, 12):
metavar: str | tuple[str, ...] | None = sentinel,
) -> None: ...
elif sys.version_info >= (3, 9):
else:
class BooleanOptionalAction(Action):
@overload
def __init__(
@@ -713,7 +692,7 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]):
exit_on_error: bool = ...,
**kwargs: Any, # Accepting any additional kwargs for custom parser classes
) -> _ArgumentParserT: ...
elif sys.version_info >= (3, 9):
else:
def add_parser(
self,
name: str,
@@ -736,28 +715,6 @@ class _SubParsersAction(Action, Generic[_ArgumentParserT]):
exit_on_error: bool = ...,
**kwargs: Any, # Accepting any additional kwargs for custom parser classes
) -> _ArgumentParserT: ...
else:
def add_parser(
self,
name: str,
*,
help: str | None = ...,
aliases: Sequence[str] = ...,
# Kwargs from ArgumentParser constructor
prog: str | None = ...,
usage: str | None = ...,
description: str | None = ...,
epilog: str | None = ...,
parents: Sequence[_ArgumentParserT] = ...,
formatter_class: _FormatterClass = ...,
prefix_chars: str = ...,
fromfile_prefix_chars: str | None = ...,
argument_default: Any = ...,
conflict_handler: str = ...,
add_help: bool = ...,
allow_abbrev: bool = ...,
**kwargs: Any, # Accepting any additional kwargs for custom parser classes
) -> _ArgumentParserT: ...
def _get_subactions(self) -> list[Action]: ...

View File

@@ -1,14 +1,10 @@
import sys
from _typeshed import ReadableBuffer, SupportsRead, SupportsWrite
from collections.abc import Iterable
# pytype crashes if array inherits from collections.abc.MutableSequence instead of typing.MutableSequence
from typing import Any, ClassVar, Literal, MutableSequence, SupportsIndex, TypeVar, overload # noqa: Y022
from collections.abc import Iterable, MutableSequence
from types import GenericAlias
from typing import Any, ClassVar, Literal, SupportsIndex, TypeVar, overload
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 12):
from types import GenericAlias
_IntTypeCode: TypeAlias = Literal["b", "B", "h", "H", "i", "I", "l", "L", "q", "Q"]
_FloatTypeCode: TypeAlias = Literal["f", "d"]
_UnicodeTypeCode: TypeAlias = Literal["u"]
@@ -60,9 +56,6 @@ class array(MutableSequence[_T]):
def tofile(self, f: SupportsWrite[bytes], /) -> None: ...
def tolist(self) -> list[_T]: ...
def tounicode(self) -> str: ...
if sys.version_info < (3, 9):
def fromstring(self, buffer: str | ReadableBuffer, /) -> None: ...
def tostring(self) -> bytes: ...
__hash__: ClassVar[None] # type: ignore[assignment]
def __len__(self) -> int: ...

View File

@@ -1144,8 +1144,7 @@ class Tuple(expr):
__match_args__ = ("elts", "ctx")
elts: list[expr]
ctx: expr_context # Not present in Python < 3.13 if not passed to `__init__`
if sys.version_info >= (3, 9):
dims: list[expr]
dims: list[expr]
if sys.version_info >= (3, 13):
def __init__(self, elts: list[expr] = ..., ctx: expr_context = ..., **kwargs: Unpack[_Attributes]) -> None: ...
else:
@@ -1155,16 +1154,10 @@ class Tuple(expr):
def __replace__(self, *, elts: list[expr] = ..., ctx: expr_context = ..., **kwargs: Unpack[_Attributes]) -> Self: ...
@deprecated("Deprecated since Python 3.9.")
class slice(AST): ... # deprecated and moved to ast.py for >= (3, 9)
class slice(AST): ...
if sys.version_info >= (3, 9):
_Slice: typing_extensions.TypeAlias = expr
_SliceAttributes: typing_extensions.TypeAlias = _Attributes
else:
# alias for use with variables named slice
_Slice: typing_extensions.TypeAlias = slice
class _SliceAttributes(TypedDict): ...
_Slice: typing_extensions.TypeAlias = expr
_SliceAttributes: typing_extensions.TypeAlias = _Attributes
class Slice(_Slice):
if sys.version_info >= (3, 10):
@@ -1187,37 +1180,26 @@ class Slice(_Slice):
) -> Self: ...
@deprecated("Deprecated since Python 3.9. Use ast.Tuple instead.")
class ExtSlice(slice): # deprecated and moved to ast.py if sys.version_info >= (3, 9)
if sys.version_info >= (3, 9):
def __new__(cls, dims: Iterable[slice] = (), **kwargs: Unpack[_SliceAttributes]) -> Tuple: ... # type: ignore[misc]
else:
dims: list[slice]
def __init__(self, dims: list[slice], **kwargs: Unpack[_SliceAttributes]) -> None: ...
class ExtSlice(slice):
def __new__(cls, dims: Iterable[slice] = (), **kwargs: Unpack[_SliceAttributes]) -> Tuple: ... # type: ignore[misc]
@deprecated("Deprecated since Python 3.9. Use the index value directly instead.")
class Index(slice): # deprecated and moved to ast.py if sys.version_info >= (3, 9)
if sys.version_info >= (3, 9):
def __new__(cls, value: expr, **kwargs: Unpack[_SliceAttributes]) -> expr: ... # type: ignore[misc]
else:
value: expr
def __init__(self, value: expr, **kwargs: Unpack[_SliceAttributes]) -> None: ...
class Index(slice):
def __new__(cls, value: expr, **kwargs: Unpack[_SliceAttributes]) -> expr: ... # type: ignore[misc]
class expr_context(AST): ...
@deprecated("Deprecated since Python 3.9. Unused in Python 3.")
class AugLoad(expr_context): ... # deprecated and moved to ast.py if sys.version_info >= (3, 9)
class AugLoad(expr_context): ...
@deprecated("Deprecated since Python 3.9. Unused in Python 3.")
class AugStore(expr_context): ... # deprecated and moved to ast.py if sys.version_info >= (3, 9)
class AugStore(expr_context): ...
@deprecated("Deprecated since Python 3.9. Unused in Python 3.")
class Param(expr_context): ... # deprecated and moved to ast.py if sys.version_info >= (3, 9)
class Param(expr_context): ...
@deprecated("Deprecated since Python 3.9. Unused in Python 3.")
class Suite(mod): # deprecated and moved to ast.py if sys.version_info >= (3, 9)
if sys.version_info < (3, 9):
body: list[stmt]
def __init__(self, body: list[stmt]) -> None: ...
class Suite(mod): ...
class Load(expr_context): ...
class Store(expr_context): ...
@@ -1702,8 +1684,7 @@ if sys.version_info >= (3, 12):
) -> Self: ...
class _ABC(type):
if sys.version_info >= (3, 9):
def __init__(cls, *args: Unused) -> None: ...
def __init__(cls, *args: Unused) -> None: ...
if sys.version_info < (3, 14):
@deprecated("Replaced by ast.Constant; removed in Python 3.14")
@@ -1894,14 +1875,11 @@ if sys.version_info >= (3, 13):
show_empty: bool = False,
) -> str: ...
elif sys.version_info >= (3, 9):
else:
def dump(
node: AST, annotate_fields: bool = True, include_attributes: bool = False, *, indent: int | str | None = None
) -> str: ...
else:
def dump(node: AST, annotate_fields: bool = True, include_attributes: bool = False) -> str: ...
def copy_location(new_node: _T, old_node: AST) -> _T: ...
def fix_missing_locations(node: _T) -> _T: ...
def increment_lineno(node: _T, n: int = 1) -> _T: ...
@@ -2059,8 +2037,5 @@ class NodeTransformer(NodeVisitor):
# The usual return type is AST | None, but Iterable[AST]
# is also allowed in some cases -- this needs to be mapped.
if sys.version_info >= (3, 9):
def unparse(ast_obj: AST) -> str: ...
if sys.version_info >= (3, 9):
def main() -> None: ...
def unparse(ast_obj: AST) -> str: ...
def main() -> None: ...

View File

@@ -18,11 +18,9 @@ from .runners import *
from .streams import *
from .subprocess import *
from .tasks import *
from .threads import *
from .transports import *
if sys.version_info >= (3, 9):
from .threads import *
if sys.version_info >= (3, 11):
from .taskgroups import *
from .timeouts import *
@@ -412,7 +410,7 @@ if sys.platform == "win32":
"WindowsSelectorEventLoopPolicy", # from windows_events
"WindowsProactorEventLoopPolicy", # from windows_events
)
elif sys.version_info >= (3, 9):
else:
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
@@ -499,91 +497,6 @@ if sys.platform == "win32":
"WindowsSelectorEventLoopPolicy", # from windows_events
"WindowsProactorEventLoopPolicy", # from windows_events
)
else:
__all__ = (
"BaseEventLoop", # from base_events
"coroutine", # from coroutines
"iscoroutinefunction", # from coroutines
"iscoroutine", # from coroutines
"AbstractEventLoopPolicy", # from events
"AbstractEventLoop", # from events
"AbstractServer", # from events
"Handle", # from events
"TimerHandle", # from events
"get_event_loop_policy", # from events
"set_event_loop_policy", # from events
"get_event_loop", # from events
"set_event_loop", # from events
"new_event_loop", # from events
"get_child_watcher", # from events
"set_child_watcher", # from events
"_set_running_loop", # from events
"get_running_loop", # from events
"_get_running_loop", # from events
"CancelledError", # from exceptions
"InvalidStateError", # from exceptions
"TimeoutError", # from exceptions
"IncompleteReadError", # from exceptions
"LimitOverrunError", # from exceptions
"SendfileNotAvailableError", # from exceptions
"Future", # from futures
"wrap_future", # from futures
"isfuture", # from futures
"Lock", # from locks
"Event", # from locks
"Condition", # from locks
"Semaphore", # from locks
"BoundedSemaphore", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"StreamReader", # from streams
"StreamWriter", # from streams
"StreamReaderProtocol", # from streams
"open_connection", # from streams
"start_server", # from streams
"create_subprocess_exec", # from subprocess
"create_subprocess_shell", # from subprocess
"Task", # from tasks
"create_task", # from tasks
"FIRST_COMPLETED", # from tasks
"FIRST_EXCEPTION", # from tasks
"ALL_COMPLETED", # from tasks
"wait", # from tasks
"wait_for", # from tasks
"as_completed", # from tasks
"sleep", # from tasks
"gather", # from tasks
"shield", # from tasks
"ensure_future", # from tasks
"run_coroutine_threadsafe", # from tasks
"current_task", # from tasks
"all_tasks", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"BaseTransport", # from transports
"ReadTransport", # from transports
"WriteTransport", # from transports
"Transport", # from transports
"DatagramTransport", # from transports
"SubprocessTransport", # from transports
"SelectorEventLoop", # from windows_events
"ProactorEventLoop", # from windows_events
"IocpProactor", # from windows_events
"DefaultEventLoopPolicy", # from windows_events
"WindowsSelectorEventLoopPolicy", # from windows_events
"WindowsProactorEventLoopPolicy", # from windows_events
)
else:
if sys.version_info >= (3, 14):
__all__ = (
@@ -974,7 +887,7 @@ else:
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
elif sys.version_info >= (3, 9):
else:
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
@@ -1065,94 +978,6 @@ else:
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
else:
__all__ = (
"BaseEventLoop", # from base_events
"coroutine", # from coroutines
"iscoroutinefunction", # from coroutines
"iscoroutine", # from coroutines
"AbstractEventLoopPolicy", # from events
"AbstractEventLoop", # from events
"AbstractServer", # from events
"Handle", # from events
"TimerHandle", # from events
"get_event_loop_policy", # from events
"set_event_loop_policy", # from events
"get_event_loop", # from events
"set_event_loop", # from events
"new_event_loop", # from events
"get_child_watcher", # from events
"set_child_watcher", # from events
"_set_running_loop", # from events
"get_running_loop", # from events
"_get_running_loop", # from events
"CancelledError", # from exceptions
"InvalidStateError", # from exceptions
"TimeoutError", # from exceptions
"IncompleteReadError", # from exceptions
"LimitOverrunError", # from exceptions
"SendfileNotAvailableError", # from exceptions
"Future", # from futures
"wrap_future", # from futures
"isfuture", # from futures
"Lock", # from locks
"Event", # from locks
"Condition", # from locks
"Semaphore", # from locks
"BoundedSemaphore", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"StreamReader", # from streams
"StreamWriter", # from streams
"StreamReaderProtocol", # from streams
"open_connection", # from streams
"start_server", # from streams
"open_unix_connection", # from streams
"start_unix_server", # from streams
"create_subprocess_exec", # from subprocess
"create_subprocess_shell", # from subprocess
"Task", # from tasks
"create_task", # from tasks
"FIRST_COMPLETED", # from tasks
"FIRST_EXCEPTION", # from tasks
"ALL_COMPLETED", # from tasks
"wait", # from tasks
"wait_for", # from tasks
"as_completed", # from tasks
"sleep", # from tasks
"gather", # from tasks
"shield", # from tasks
"ensure_future", # from tasks
"run_coroutine_threadsafe", # from tasks
"current_task", # from tasks
"all_tasks", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"BaseTransport", # from transports
"ReadTransport", # from transports
"WriteTransport", # from transports
"Transport", # from transports
"DatagramTransport", # from transports
"SubprocessTransport", # from transports
"SelectorEventLoop", # from unix_events
"AbstractChildWatcher", # from unix_events
"SafeChildWatcher", # from unix_events
"FastChildWatcher", # from unix_events
"MultiLoopChildWatcher", # from unix_events
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
_T_co = TypeVar("_T_co", covariant=True)

View File

@@ -15,10 +15,7 @@ from typing import IO, Any, Literal, TypeVar, overload
from typing_extensions import TypeAlias, TypeVarTuple, Unpack
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 9):
__all__ = ("BaseEventLoop", "Server")
else:
__all__ = ("BaseEventLoop",)
__all__ = ("BaseEventLoop", "Server")
_T = TypeVar("_T")
_Ts = TypeVarTuple("_Ts")
@@ -485,7 +482,7 @@ class BaseEventLoop(AbstractEventLoop):
def set_debug(self, enabled: bool) -> None: ...
if sys.version_info >= (3, 12):
async def shutdown_default_executor(self, timeout: float | None = None) -> None: ...
elif sys.version_info >= (3, 9):
else:
async def shutdown_default_executor(self) -> None: ...
def __del__(self) -> None: ...

View File

@@ -138,27 +138,19 @@ class AbstractEventLoop:
@abstractmethod
async def shutdown_asyncgens(self) -> None: ...
# Methods scheduling callbacks. All these return Handles.
if sys.version_info >= (3, 9): # "context" added in 3.9.10/3.10.2
@abstractmethod
def call_soon(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
@abstractmethod
def call_later(
self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
@abstractmethod
def call_at(
self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
else:
@abstractmethod
def call_soon(self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> Handle: ...
@abstractmethod
def call_later(self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> TimerHandle: ...
@abstractmethod
def call_at(self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> TimerHandle: ...
# "context" added in 3.9.10/3.10.2 for call_*
@abstractmethod
def call_soon(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
@abstractmethod
def call_later(
self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
@abstractmethod
def call_at(
self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
@abstractmethod
def time(self) -> float: ...
# Future methods
@@ -179,15 +171,11 @@ class AbstractEventLoop:
@abstractmethod
def get_task_factory(self) -> _TaskFactory | None: ...
# Methods for interacting with threads
if sys.version_info >= (3, 9): # "context" added in 3.9.10/3.10.2
@abstractmethod
def call_soon_threadsafe(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
else:
@abstractmethod
def call_soon_threadsafe(self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> Handle: ...
# "context" added in 3.9.10/3.10.2
@abstractmethod
def call_soon_threadsafe(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
@abstractmethod
def run_in_executor(self, executor: Executor | None, func: Callable[[Unpack[_Ts]], _T], *args: Unpack[_Ts]) -> Future[_T]: ...
@abstractmethod
@@ -607,9 +595,8 @@ class AbstractEventLoop:
def get_debug(self) -> bool: ...
@abstractmethod
def set_debug(self, enabled: bool) -> None: ...
if sys.version_info >= (3, 9):
@abstractmethod
async def shutdown_default_executor(self) -> None: ...
@abstractmethod
async def shutdown_default_executor(self) -> None: ...
class AbstractEventLoopPolicy:
@abstractmethod

View File

@@ -2,7 +2,7 @@ import enum
import sys
from _typeshed import Unused
from collections import deque
from collections.abc import Callable, Generator
from collections.abc import Callable
from types import TracebackType
from typing import Any, Literal, TypeVar
from typing_extensions import Self
@@ -23,29 +23,11 @@ else:
_T = TypeVar("_T")
if sys.version_info >= (3, 9):
class _ContextManagerMixin:
async def __aenter__(self) -> None: ...
async def __aexit__(
self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None
) -> None: ...
else:
class _ContextManager:
def __init__(self, lock: Lock | Semaphore) -> None: ...
def __enter__(self) -> None: ...
def __exit__(self, *args: Unused) -> None: ...
class _ContextManagerMixin:
# Apparently this exists to *prohibit* use as a context manager.
# def __enter__(self) -> NoReturn: ... see: https://github.com/python/typing/issues/1043
# def __exit__(self, *args: Any) -> None: ...
def __iter__(self) -> Generator[Any, None, _ContextManager]: ...
def __await__(self) -> Generator[Any, None, _ContextManager]: ...
async def __aenter__(self) -> None: ...
async def __aexit__(
self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None
) -> None: ...
class _ContextManagerMixin:
async def __aenter__(self) -> None: ...
async def __aexit__(
self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None
) -> None: ...
class Lock(_ContextManagerMixin, _LoopBoundMixin):
_waiters: deque[Future[Any]] | None

View File

@@ -1,10 +1,8 @@
import sys
from asyncio.events import AbstractEventLoop
from types import GenericAlias
from typing import Any, Generic, TypeVar
if sys.version_info >= (3, 9):
from types import GenericAlias
if sys.version_info >= (3, 10):
from .mixins import _LoopBoundMixin
else:
@@ -48,8 +46,7 @@ class Queue(Generic[_T], _LoopBoundMixin): # noqa: Y059
def get_nowait(self) -> _T: ...
async def join(self) -> None: ...
def task_done(self) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, type: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, type: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 13):
def shutdown(self, immediate: bool = False) -> None: ...

View File

@@ -407,10 +407,8 @@ else:
if sys.version_info >= (3, 12):
_TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co]
elif sys.version_info >= (3, 9):
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co]
else:
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Awaitable[_T_co]
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co]
def all_tasks(loop: AbstractEventLoop | None = None) -> set[Task[Any]]: ...

View File

@@ -30,7 +30,7 @@ if sys.platform != "win32":
"DefaultEventLoopPolicy",
"EventLoop",
)
elif sys.version_info >= (3, 9):
else:
# adds PidfdChildWatcher
__all__ = (
"SelectorEventLoop",
@@ -42,16 +42,6 @@ if sys.platform != "win32":
"ThreadedChildWatcher",
"DefaultEventLoopPolicy",
)
else:
__all__ = (
"SelectorEventLoop",
"AbstractChildWatcher",
"SafeChildWatcher",
"FastChildWatcher",
"MultiLoopChildWatcher",
"ThreadedChildWatcher",
"DefaultEventLoopPolicy",
)
# This is also technically not available on Win,
# but other parts of typeshed need this definition.
@@ -239,16 +229,15 @@ if sys.platform != "win32":
def remove_child_handler(self, pid: int) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
if sys.version_info >= (3, 9):
class PidfdChildWatcher(AbstractChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
) -> None: ...
def is_active(self) -> bool: ...
def close(self) -> None: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
class PidfdChildWatcher(AbstractChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
) -> None: ...
def is_active(self) -> bool: ...
def close(self) -> None: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...

View File

@@ -56,10 +56,6 @@ def encode(input: IO[bytes], output: IO[bytes]) -> None: ...
def encodebytes(s: ReadableBuffer) -> bytes: ...
def decodebytes(s: ReadableBuffer) -> bytes: ...
if sys.version_info < (3, 9):
def encodestring(s: ReadableBuffer) -> bytes: ...
def decodestring(s: ReadableBuffer) -> bytes: ...
if sys.version_info >= (3, 13):
def z85encode(s: ReadableBuffer) -> bytes: ...
def z85decode(s: str | ReadableBuffer) -> bytes: ...

View File

@@ -32,11 +32,11 @@ from _typeshed import (
)
from collections.abc import Awaitable, Callable, Iterable, Iterator, MutableSet, Reversible, Set as AbstractSet, Sized
from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper
from types import CellType, CodeType, TracebackType
from types import CellType, CodeType, GenericAlias, TracebackType
# mypy crashes if any of {ByteString, Sequence, MutableSequence, Mapping, MutableMapping}
# are imported from collections.abc in builtins.pyi
from typing import ( # noqa: Y022
from typing import ( # noqa: Y022,UP035
IO,
Any,
BinaryIO,
@@ -72,9 +72,6 @@ from typing_extensions import ( # noqa: Y023
deprecated,
)
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
_I = TypeVar("_I", default=int)
_T_co = TypeVar("_T_co", covariant=True)
@@ -377,10 +374,8 @@ class float:
def __rpow__(self, value: float, mod: None = None, /) -> Any: ...
def __getnewargs__(self) -> tuple[float]: ...
def __trunc__(self) -> int: ...
if sys.version_info >= (3, 9):
def __ceil__(self) -> int: ...
def __floor__(self) -> int: ...
def __ceil__(self) -> int: ...
def __floor__(self) -> int: ...
@overload
def __round__(self, ndigits: None = None, /) -> int: ...
@overload
@@ -519,16 +514,15 @@ class str(Sequence[str]):
) -> LiteralString: ...
@overload
def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc]
if sys.version_info >= (3, 9):
@overload
def removeprefix(self: LiteralString, prefix: LiteralString, /) -> LiteralString: ...
@overload
def removeprefix(self, prefix: str, /) -> str: ... # type: ignore[misc]
@overload
def removesuffix(self: LiteralString, suffix: LiteralString, /) -> LiteralString: ...
@overload
def removesuffix(self, suffix: str, /) -> str: ... # type: ignore[misc]
@overload
def removeprefix(self: LiteralString, prefix: LiteralString, /) -> LiteralString: ...
@overload
def removeprefix(self, prefix: str, /) -> str: ... # type: ignore[misc]
@overload
def removesuffix(self: LiteralString, suffix: LiteralString, /) -> LiteralString: ...
@overload
def removesuffix(self, suffix: str, /) -> str: ... # type: ignore[misc]
def rfind(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
def rindex(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
@overload
@@ -666,10 +660,8 @@ class bytes(Sequence[int]):
def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ...
def partition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ...
def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytes: ...
if sys.version_info >= (3, 9):
def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ...
def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ...
def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ...
def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ...
def rfind(
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
) -> int: ...
@@ -771,10 +763,8 @@ class bytearray(MutableSequence[int]):
def partition(self, sep: ReadableBuffer, /) -> tuple[bytearray, bytearray, bytearray]: ...
def pop(self, index: int = -1, /) -> int: ...
def remove(self, value: int, /) -> None: ...
if sys.version_info >= (3, 9):
def removeprefix(self, prefix: ReadableBuffer, /) -> bytearray: ...
def removesuffix(self, suffix: ReadableBuffer, /) -> bytearray: ...
def removeprefix(self, prefix: ReadableBuffer, /) -> bytearray: ...
def removesuffix(self, suffix: ReadableBuffer, /) -> bytearray: ...
def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytearray: ...
def rfind(
self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /
@@ -1009,8 +999,7 @@ class tuple(Sequence[_T_co]):
def __rmul__(self, value: SupportsIndex, /) -> tuple[_T_co, ...]: ...
def count(self, value: Any, /) -> int: ...
def index(self, value: Any, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
# Doesn't exist at runtime, but deleting this breaks mypy and pyright. See:
# https://github.com/python/typeshed/issues/7580
@@ -1092,8 +1081,7 @@ class list(MutableSequence[_T]):
def __lt__(self, value: list[_T], /) -> bool: ...
def __le__(self, value: list[_T], /) -> bool: ...
def __eq__(self, value: object, /) -> bool: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class dict(MutableMapping[_KT, _VT]):
# __init__ should be kept roughly in line with `collections.UserDict.__init__`, which has similar semantics
@@ -1162,21 +1150,20 @@ class dict(MutableMapping[_KT, _VT]):
def __eq__(self, value: object, /) -> bool: ...
def __reversed__(self) -> Iterator[_KT]: ...
__hash__: ClassVar[None] # type: ignore[assignment]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
@overload
def __or__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ...
# dict.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, value: SupportsKeysAndGetItem[_KT, _VT], /) -> Self: ...
@overload
def __ior__(self, value: Iterable[tuple[_KT, _VT]], /) -> Self: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
@overload
def __or__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> dict[_KT, _VT]: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ...
# dict.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, value: SupportsKeysAndGetItem[_KT, _VT], /) -> Self: ...
@overload
def __ior__(self, value: Iterable[tuple[_KT, _VT]], /) -> Self: ...
class set(MutableSet[_T]):
@overload
@@ -1215,8 +1202,7 @@ class set(MutableSet[_T]):
def __gt__(self, value: AbstractSet[object], /) -> bool: ...
def __eq__(self, value: object, /) -> bool: ...
__hash__: ClassVar[None] # type: ignore[assignment]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class frozenset(AbstractSet[_T_co]):
@overload
@@ -1244,15 +1230,13 @@ class frozenset(AbstractSet[_T_co]):
def __gt__(self, value: AbstractSet[object], /) -> bool: ...
def __eq__(self, value: object, /) -> bool: ...
def __hash__(self) -> int: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class enumerate(Generic[_T]):
def __new__(cls, iterable: Iterable[_T], start: int = 0) -> Self: ...
def __iter__(self) -> Self: ...
def __next__(self) -> tuple[int, _T]: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
@final
class range(Sequence[int]):
@@ -1297,6 +1281,9 @@ class property:
def getter(self, fget: Callable[[Any], Any], /) -> property: ...
def setter(self, fset: Callable[[Any, Any], None], /) -> property: ...
def deleter(self, fdel: Callable[[Any], None], /) -> property: ...
@overload
def __get__(self, instance: None, owner: type, /) -> Self: ...
@overload
def __get__(self, instance: Any, owner: type | None = None, /) -> Any: ...
def __set__(self, instance: Any, value: Any, /) -> None: ...
def __delete__(self, instance: Any, /) -> None: ...

View File

@@ -1,10 +1,9 @@
import _compression
import sys
from _bz2 import BZ2Compressor as BZ2Compressor, BZ2Decompressor as BZ2Decompressor
from _compression import BaseStream
from _typeshed import ReadableBuffer, StrOrBytesPath, WriteableBuffer
from collections.abc import Iterable
from typing import IO, Any, Literal, Protocol, SupportsIndex, TextIO, overload
from typing import IO, Literal, Protocol, SupportsIndex, TextIO, overload
from typing_extensions import Self, TypeAlias
__all__ = ["BZ2File", "BZ2Compressor", "BZ2Decompressor", "open", "compress", "decompress"]
@@ -94,33 +93,14 @@ def open(
class BZ2File(BaseStream, IO[bytes]):
def __enter__(self) -> Self: ...
if sys.version_info >= (3, 9):
@overload
def __init__(self, filename: _WritableFileobj, mode: _WriteBinaryMode, *, compresslevel: int = 9) -> None: ...
@overload
def __init__(self, filename: _ReadableFileobj, mode: _ReadBinaryMode = "r", *, compresslevel: int = 9) -> None: ...
@overload
def __init__(
self, filename: StrOrBytesPath, mode: _ReadBinaryMode | _WriteBinaryMode = "r", *, compresslevel: int = 9
) -> None: ...
else:
@overload
def __init__(
self, filename: _WritableFileobj, mode: _WriteBinaryMode, buffering: Any | None = None, compresslevel: int = 9
) -> None: ...
@overload
def __init__(
self, filename: _ReadableFileobj, mode: _ReadBinaryMode = "r", buffering: Any | None = None, compresslevel: int = 9
) -> None: ...
@overload
def __init__(
self,
filename: StrOrBytesPath,
mode: _ReadBinaryMode | _WriteBinaryMode = "r",
buffering: Any | None = None,
compresslevel: int = 9,
) -> None: ...
@overload
def __init__(self, filename: _WritableFileobj, mode: _WriteBinaryMode, *, compresslevel: int = 9) -> None: ...
@overload
def __init__(self, filename: _ReadableFileobj, mode: _ReadBinaryMode = "r", *, compresslevel: int = 9) -> None: ...
@overload
def __init__(
self, filename: StrOrBytesPath, mode: _ReadBinaryMode | _WriteBinaryMode = "r", *, compresslevel: int = 9
) -> None: ...
def read(self, size: int | None = -1) -> bytes: ...
def read1(self, size: int = -1) -> bytes: ...
def readline(self, size: SupportsIndex = -1) -> bytes: ... # type: ignore[override]

View File

@@ -1,15 +1,15 @@
import sys
from codeop import CommandCompiler
from collections.abc import Callable, Mapping
from collections.abc import Callable
from types import CodeType
from typing import Any
__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", "compile_command"]
class InteractiveInterpreter:
locals: Mapping[str, Any] # undocumented
locals: dict[str, Any] # undocumented
compile: CommandCompiler # undocumented
def __init__(self, locals: Mapping[str, Any] | None = None) -> None: ...
def __init__(self, locals: dict[str, Any] | None = None) -> None: ...
def runsource(self, source: str, filename: str = "<input>", symbol: str = "single") -> bool: ...
def runcode(self, code: CodeType) -> None: ...
if sys.version_info >= (3, 13):
@@ -25,11 +25,11 @@ class InteractiveConsole(InteractiveInterpreter):
filename: str # undocumented
if sys.version_info >= (3, 13):
def __init__(
self, locals: Mapping[str, Any] | None = None, filename: str = "<console>", *, local_exit: bool = False
self, locals: dict[str, Any] | None = None, filename: str = "<console>", *, local_exit: bool = False
) -> None: ...
def push(self, line: str, filename: str | None = None) -> bool: ...
else:
def __init__(self, locals: Mapping[str, Any] | None = None, filename: str = "<console>") -> None: ...
def __init__(self, locals: dict[str, Any] | None = None, filename: str = "<console>") -> None: ...
def push(self, line: str) -> bool: ...
def interact(self, banner: str | None = None, exitmsg: str | None = None) -> None: ...
@@ -40,7 +40,7 @@ if sys.version_info >= (3, 13):
def interact(
banner: str | None = None,
readfunc: Callable[[str], str] | None = None,
local: Mapping[str, Any] | None = None,
local: dict[str, Any] | None = None,
exitmsg: str | None = None,
local_exit: bool = False,
) -> None: ...
@@ -49,7 +49,7 @@ else:
def interact(
banner: str | None = None,
readfunc: Callable[[str], str] | None = None,
local: Mapping[str, Any] | None = None,
local: dict[str, Any] | None = None,
exitmsg: str | None = None,
) -> None: ...

View File

@@ -1,12 +1,10 @@
import sys
from _collections_abc import dict_items, dict_keys, dict_values
from _typeshed import SupportsItems, SupportsKeysAndGetItem, SupportsRichComparison, SupportsRichComparisonT
from types import GenericAlias
from typing import Any, ClassVar, Generic, NoReturn, SupportsIndex, TypeVar, final, overload
from typing_extensions import Self
if sys.version_info >= (3, 9):
from types import GenericAlias
if sys.version_info >= (3, 10):
from collections.abc import (
Callable,
@@ -93,20 +91,19 @@ class UserDict(MutableMapping[_KT, _VT]):
@classmethod
@overload
def fromkeys(cls, iterable: Iterable[_T], value: _S) -> UserDict[_T, _S]: ...
if sys.version_info >= (3, 9):
@overload
def __or__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ...
@overload
def __or__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ...
@overload
def __ror__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ...
# UserDict.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ...
@overload
def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ...
@overload
def __or__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ...
@overload
def __or__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, other: UserDict[_KT, _VT] | dict[_KT, _VT]) -> Self: ...
@overload
def __ror__(self, other: UserDict[_T1, _T2] | dict[_T1, _T2]) -> UserDict[_KT | _T1, _VT | _T2]: ...
# UserDict.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ...
@overload
def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ...
if sys.version_info >= (3, 12):
@overload
def get(self, key: _KT, default: None = None) -> _VT | None: ...
@@ -213,10 +210,8 @@ class UserString(Sequence[UserString]):
def lstrip(self, chars: str | None = None) -> Self: ...
maketrans = str.maketrans
def partition(self, sep: str) -> tuple[str, str, str]: ...
if sys.version_info >= (3, 9):
def removeprefix(self, prefix: str | UserString, /) -> Self: ...
def removesuffix(self, suffix: str | UserString, /) -> Self: ...
def removeprefix(self, prefix: str | UserString, /) -> Self: ...
def removesuffix(self, suffix: str | UserString, /) -> Self: ...
def replace(self, old: str | UserString, new: str | UserString, maxsplit: int = -1) -> Self: ...
def rfind(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ...
def rindex(self, sub: str | UserString, start: int = 0, end: int = sys.maxsize) -> int: ...
@@ -271,8 +266,7 @@ class deque(MutableSequence[_T]):
def __gt__(self, value: deque[_T], /) -> bool: ...
def __ge__(self, value: deque[_T], /) -> bool: ...
def __eq__(self, value: object, /) -> bool: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class Counter(dict[_T, int], Generic[_T]):
@overload
@@ -387,15 +381,14 @@ class OrderedDict(dict[_KT, _VT]):
@overload
def pop(self, key: _KT, default: _T) -> _VT | _T: ...
def __eq__(self, value: object, /) -> bool: ...
if sys.version_info >= (3, 9):
@overload
def __or__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc]
@overload
def __or__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc]
class defaultdict(dict[_KT, _VT]):
default_factory: Callable[[], _VT] | None
@@ -435,15 +428,14 @@ class defaultdict(dict[_KT, _VT]):
def __missing__(self, key: _KT, /) -> _VT: ...
def __copy__(self) -> Self: ...
def copy(self) -> Self: ...
if sys.version_info >= (3, 9):
@overload
def __or__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc]
@overload
def __or__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __or__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, value: dict[_KT, _VT], /) -> Self: ...
@overload
def __ror__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc]
class ChainMap(MutableMapping[_KT, _VT]):
maps: list[MutableMapping[_KT, _VT]]
@@ -488,17 +480,16 @@ class ChainMap(MutableMapping[_KT, _VT]):
@classmethod
@overload
def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> ChainMap[_T, _S]: ...
if sys.version_info >= (3, 9):
@overload
def __or__(self, other: Mapping[_KT, _VT]) -> Self: ...
@overload
def __or__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, other: Mapping[_KT, _VT]) -> Self: ...
@overload
def __ror__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ...
# ChainMap.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ...
@overload
def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ...
@overload
def __or__(self, other: Mapping[_KT, _VT]) -> Self: ...
@overload
def __or__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ...
@overload
def __ror__(self, other: Mapping[_KT, _VT]) -> Self: ...
@overload
def __ror__(self, other: Mapping[_T1, _T2]) -> ChainMap[_KT | _T1, _VT | _T2]: ...
# ChainMap.__ior__ should be kept roughly in line with MutableMapping.update()
@overload # type: ignore[misc]
def __ior__(self, other: SupportsKeysAndGetItem[_KT, _VT]) -> Self: ...
@overload
def __ior__(self, other: Iterable[tuple[_KT, _VT]]) -> Self: ...

View File

@@ -7,7 +7,7 @@ def hls_to_rgb(h: float, l: float, s: float) -> tuple[float, float, float]: ...
def rgb_to_hsv(r: float, g: float, b: float) -> tuple[float, float, float]: ...
def hsv_to_rgb(h: float, s: float, v: float) -> tuple[float, float, float]: ...
# TODO undocumented
# TODO: undocumented
ONE_SIXTH: float
ONE_THIRD: float
TWO_THIRD: float

View File

@@ -42,7 +42,7 @@ if sys.version_info >= (3, 10):
hardlink_dupes: bool = False,
) -> bool: ...
elif sys.version_info >= (3, 9):
else:
def compile_dir(
dir: StrPath,
maxlevels: int | None = None,
@@ -76,30 +76,6 @@ elif sys.version_info >= (3, 9):
hardlink_dupes: bool = False,
) -> bool: ...
else:
def compile_dir(
dir: StrPath,
maxlevels: int = 10,
ddir: StrPath | None = None,
force: bool = False,
rx: _SupportsSearch | None = None,
quiet: int = 0,
legacy: bool = False,
optimize: int = -1,
workers: int = 1,
invalidation_mode: PycInvalidationMode | None = None,
) -> bool: ...
def compile_file(
fullname: StrPath,
ddir: StrPath | None = None,
force: bool = False,
rx: _SupportsSearch | None = None,
quiet: int = 0,
legacy: bool = False,
optimize: int = -1,
invalidation_mode: PycInvalidationMode | None = None,
) -> bool: ...
def compile_path(
skip_curdir: bool = ...,
maxlevels: int = 0,

View File

@@ -1,15 +1,12 @@
import sys
import threading
from _typeshed import Unused
from collections.abc import Callable, Collection, Iterable, Iterator
from collections.abc import Callable, Iterable, Iterator
from logging import Logger
from types import TracebackType
from types import GenericAlias, TracebackType
from typing import Any, Final, Generic, NamedTuple, Protocol, TypeVar
from typing_extensions import ParamSpec, Self
if sys.version_info >= (3, 9):
from types import GenericAlias
FIRST_COMPLETED: Final = "FIRST_COMPLETED"
FIRST_EXCEPTION: Final = "FIRST_EXCEPTION"
ALL_COMPLETED: Final = "ALL_COMPLETED"
@@ -53,23 +50,14 @@ class Future(Generic[_T]):
def set_result(self, result: _T) -> None: ...
def exception(self, timeout: float | None = None) -> BaseException | None: ...
def set_exception(self, exception: BaseException | None) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class Executor:
if sys.version_info >= (3, 9):
def submit(self, fn: Callable[_P, _T], /, *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ...
else:
def submit(self, fn: Callable[_P, _T], *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ...
def submit(self, fn: Callable[_P, _T], /, *args: _P.args, **kwargs: _P.kwargs) -> Future[_T]: ...
def map(
self, fn: Callable[..., _T], *iterables: Iterable[Any], timeout: float | None = None, chunksize: int = 1
) -> Iterator[_T]: ...
if sys.version_info >= (3, 9):
def shutdown(self, wait: bool = True, *, cancel_futures: bool = False) -> None: ...
else:
def shutdown(self, wait: bool = True) -> None: ...
def shutdown(self, wait: bool = True, *, cancel_futures: bool = False) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
@@ -91,15 +79,9 @@ class DoneAndNotDoneFutures(NamedTuple, Generic[_T]):
done: set[Future[_T]]
not_done: set[Future[_T]]
if sys.version_info >= (3, 9):
def wait(
fs: Iterable[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> DoneAndNotDoneFutures[_T]: ...
else:
def wait(
fs: Collection[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> DoneAndNotDoneFutures[_T]: ...
def wait(
fs: Iterable[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> DoneAndNotDoneFutures[_T]: ...
class _Waiter:
event: threading.Event

View File

@@ -84,7 +84,7 @@ class _SafeQueue(Queue[Future[Any]]):
pending_work_items: dict[int, _WorkItem[Any]],
thread_wakeup: _ThreadWakeup,
) -> None: ...
elif sys.version_info >= (3, 9):
else:
def __init__(
self,
max_size: int | None = 0,
@@ -94,10 +94,6 @@ class _SafeQueue(Queue[Future[Any]]):
shutdown_lock: Lock,
thread_wakeup: _ThreadWakeup,
) -> None: ...
else:
def __init__(
self, max_size: int | None = 0, *, ctx: BaseContext, pending_work_items: dict[int, _WorkItem[Any]]
) -> None: ...
def _on_queue_feeder_error(self, e: Exception, obj: _CallItem) -> None: ...
@@ -135,27 +131,26 @@ else:
initargs: tuple[Unpack[_Ts]],
) -> None: ...
if sys.version_info >= (3, 9):
class _ExecutorManagerThread(Thread):
thread_wakeup: _ThreadWakeup
shutdown_lock: Lock
executor_reference: ref[Any]
processes: MutableMapping[int, Process]
call_queue: Queue[_CallItem]
result_queue: SimpleQueue[_ResultItem]
work_ids_queue: Queue[int]
pending_work_items: dict[int, _WorkItem[Any]]
def __init__(self, executor: ProcessPoolExecutor) -> None: ...
def run(self) -> None: ...
def add_call_item_to_queue(self) -> None: ...
def wait_result_broken_or_wakeup(self) -> tuple[Any, bool, str]: ...
def process_result_item(self, result_item: int | _ResultItem) -> None: ...
def is_shutting_down(self) -> bool: ...
def terminate_broken(self, cause: str) -> None: ...
def flag_executor_shutting_down(self) -> None: ...
def shutdown_workers(self) -> None: ...
def join_executor_internals(self) -> None: ...
def get_n_children_alive(self) -> int: ...
class _ExecutorManagerThread(Thread):
thread_wakeup: _ThreadWakeup
shutdown_lock: Lock
executor_reference: ref[Any]
processes: MutableMapping[int, Process]
call_queue: Queue[_CallItem]
result_queue: SimpleQueue[_ResultItem]
work_ids_queue: Queue[int]
pending_work_items: dict[int, _WorkItem[Any]]
def __init__(self, executor: ProcessPoolExecutor) -> None: ...
def run(self) -> None: ...
def add_call_item_to_queue(self) -> None: ...
def wait_result_broken_or_wakeup(self) -> tuple[Any, bool, str]: ...
def process_result_item(self, result_item: int | _ResultItem) -> None: ...
def is_shutting_down(self) -> bool: ...
def terminate_broken(self, cause: str) -> None: ...
def flag_executor_shutting_down(self) -> None: ...
def shutdown_workers(self) -> None: ...
def join_executor_internals(self) -> None: ...
def get_n_children_alive(self) -> int: ...
_system_limits_checked: bool
_system_limited: bool | None
@@ -238,7 +233,6 @@ class ProcessPoolExecutor(Executor):
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
if sys.version_info >= (3, 9):
def _start_executor_manager_thread(self) -> None: ...
def _start_executor_manager_thread(self) -> None: ...
def _adjust_process_count(self) -> None: ...

View File

@@ -1,7 +1,7 @@
import queue
import sys
from collections.abc import Callable, Iterable, Mapping, Set as AbstractSet
from threading import Lock, Semaphore, Thread
from types import GenericAlias
from typing import Any, Generic, TypeVar, overload
from typing_extensions import TypeVarTuple, Unpack
from weakref import ref
@@ -16,9 +16,6 @@ _global_shutdown_lock: Lock
def _python_exit() -> None: ...
if sys.version_info >= (3, 9):
from types import GenericAlias
_S = TypeVar("_S")
class _WorkItem(Generic[_S]):
@@ -28,8 +25,7 @@ class _WorkItem(Generic[_S]):
kwargs: Mapping[str, Any]
def __init__(self, future: Future[_S], fn: Callable[..., _S], args: Iterable[Any], kwargs: Mapping[str, Any]) -> None: ...
def run(self) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def _worker(
executor_reference: ref[Any],

View File

@@ -81,14 +81,9 @@ class _GeneratorContextManager(
AbstractContextManager[_T_co, bool | None],
ContextDecorator,
):
if sys.version_info >= (3, 9):
def __exit__(
self, typ: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
) -> bool | None: ...
else:
def __exit__(
self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
) -> bool | None: ...
def __exit__(
self, typ: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
) -> bool | None: ...
def contextmanager(func: Callable[_P, Iterator[_T_co]]) -> Callable[_P, _GeneratorContextManager[_T_co]]: ...

View File

@@ -26,12 +26,10 @@ else:
from _typeshed import SupportsWrite
from collections.abc import Collection, Iterable, Mapping, Sequence
from types import GenericAlias
from typing import Any, Generic, Literal, TypeVar, overload
from typing_extensions import Self
if sys.version_info >= (3, 12):
from types import GenericAlias
__all__ = [
"QUOTE_MINIMAL",
"QUOTE_ALL",

View File

@@ -26,7 +26,8 @@ from _ctypes import (
)
from _typeshed import StrPath
from ctypes._endian import BigEndianStructure as BigEndianStructure, LittleEndianStructure as LittleEndianStructure
from typing import Any, ClassVar, Generic, TypeVar, type_check_only
from types import GenericAlias
from typing import Any, ClassVar, Generic, Literal, TypeVar, type_check_only
from typing_extensions import Self, TypeAlias, deprecated
if sys.platform == "win32":
@@ -35,10 +36,7 @@ if sys.platform == "win32":
if sys.version_info >= (3, 11):
from ctypes._endian import BigEndianUnion as BigEndianUnion, LittleEndianUnion as LittleEndianUnion
if sys.version_info >= (3, 9):
from types import GenericAlias
_T = TypeVar("_T")
_T = TypeVar("_T", default=Any)
_DLLT = TypeVar("_DLLT", bound=CDLL)
_CT = TypeVar("_CT", bound=_CData)
@@ -92,8 +90,7 @@ class LibraryLoader(Generic[_DLLT]):
def __getattr__(self, name: str) -> _DLLT: ...
def __getitem__(self, name: str) -> _DLLT: ...
def LoadLibrary(self, name: str) -> _DLLT: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
cdll: LibraryLoader[CDLL]
if sys.platform == "win32":
@@ -151,14 +148,12 @@ c_buffer = create_string_buffer
def create_unicode_buffer(init: int | str, size: int | None = None) -> Array[c_wchar]: ...
@deprecated("Deprecated in Python 3.13; removal scheduled for Python 3.15")
def SetPointerType(
pointer: type[_Pointer[Any]], cls: Any # noqa: F811 # Redefinition of unused `pointer` from line 22
) -> None: ...
def SetPointerType(pointer: type[_Pointer[Any]], cls: Any) -> None: ... # noqa: F811
def ARRAY(typ: _CT, len: int) -> Array[_CT]: ... # Soft Deprecated, no plans to remove
if sys.platform == "win32":
def DllCanUnloadNow() -> int: ...
def DllGetClassObject(rclsid: Any, riid: Any, ppv: Any) -> int: ... # TODO not documented
def DllGetClassObject(rclsid: Any, riid: Any, ppv: Any) -> int: ... # TODO: not documented
# Actually just an instance of _NamedFuncPointer (aka _CDLLFuncPointer),
# but we want to set a more specific __call__
@@ -191,73 +186,121 @@ if sys.platform == "win32":
def wstring_at(ptr: _CVoidConstPLike, size: int = -1) -> str: ...
class c_byte(_SimpleCData[int]): ...
class py_object(_CanCastTo, _SimpleCData[_T]):
_type_: ClassVar[Literal["O"]]
class c_bool(_SimpleCData[bool]):
_type_: ClassVar[Literal["?"]]
def __init__(self, value: bool = ...) -> None: ...
class c_byte(_SimpleCData[int]):
_type_: ClassVar[Literal["b"]]
class c_ubyte(_SimpleCData[int]):
_type_: ClassVar[Literal["B"]]
class c_short(_SimpleCData[int]):
_type_: ClassVar[Literal["h"]]
class c_ushort(_SimpleCData[int]):
_type_: ClassVar[Literal["H"]]
class c_long(_SimpleCData[int]):
_type_: ClassVar[Literal["l"]]
class c_ulong(_SimpleCData[int]):
_type_: ClassVar[Literal["L"]]
class c_int(_SimpleCData[int]): # can be an alias for c_long
_type_: ClassVar[Literal["i", "l"]]
class c_uint(_SimpleCData[int]): # can be an alias for c_ulong
_type_: ClassVar[Literal["I", "L"]]
class c_longlong(_SimpleCData[int]): # can be an alias for c_long
_type_: ClassVar[Literal["q", "l"]]
class c_ulonglong(_SimpleCData[int]): # can be an alias for c_ulong
_type_: ClassVar[Literal["Q", "L"]]
c_int8 = c_byte
c_uint8 = c_ubyte
class c_int16(_SimpleCData[int]): # can be an alias for c_short or c_int
_type_: ClassVar[Literal["h", "i"]]
class c_uint16(_SimpleCData[int]): # can be an alias for c_ushort or c_uint
_type_: ClassVar[Literal["H", "I"]]
class c_int32(_SimpleCData[int]): # can be an alias for c_int or c_long
_type_: ClassVar[Literal["i", "l"]]
class c_uint32(_SimpleCData[int]): # can be an alias for c_uint or c_ulong
_type_: ClassVar[Literal["I", "L"]]
class c_int64(_SimpleCData[int]): # can be an alias for c_long or c_longlong
_type_: ClassVar[Literal["l", "q"]]
class c_uint64(_SimpleCData[int]): # can be an alias for c_ulong or c_ulonglong
_type_: ClassVar[Literal["L", "Q"]]
class c_ssize_t(_SimpleCData[int]): # alias for c_int, c_long, or c_longlong
_type_: ClassVar[Literal["i", "l", "q"]]
class c_size_t(_SimpleCData[int]): # alias for c_uint, c_ulong, or c_ulonglong
_type_: ClassVar[Literal["I", "L", "Q"]]
class c_float(_SimpleCData[float]):
_type_: ClassVar[Literal["f"]]
class c_double(_SimpleCData[float]):
_type_: ClassVar[Literal["d"]]
class c_longdouble(_SimpleCData[float]): # can be an alias for c_double
_type_: ClassVar[Literal["d", "g"]]
if sys.version_info >= (3, 14):
class c_float_complex(_SimpleCData[complex]):
_type_: ClassVar[Literal["E"]]
class c_double_complex(_SimpleCData[complex]):
_type_: ClassVar[Literal["C"]]
class c_longdouble_complex(_SimpleCData[complex]):
_type_: ClassVar[Literal["F"]]
class c_char(_SimpleCData[bytes]):
_type_: ClassVar[Literal["c"]]
def __init__(self, value: int | bytes | bytearray = ...) -> None: ...
class c_char_p(_PointerLike, _SimpleCData[bytes | None]):
_type_: ClassVar[Literal["z"]]
def __init__(self, value: int | bytes | None = ...) -> None: ...
@classmethod
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
class c_double(_SimpleCData[float]): ...
class c_longdouble(_SimpleCData[float]): ... # can be an alias for c_double
class c_float(_SimpleCData[float]): ...
class c_int(_SimpleCData[int]): ... # can be an alias for c_long
class c_long(_SimpleCData[int]): ...
class c_longlong(_SimpleCData[int]): ... # can be an alias for c_long
class c_short(_SimpleCData[int]): ...
class c_size_t(_SimpleCData[int]): ... # alias for c_uint, c_ulong, or c_ulonglong
class c_ssize_t(_SimpleCData[int]): ... # alias for c_int, c_long, or c_longlong
class c_ubyte(_SimpleCData[int]): ...
class c_uint(_SimpleCData[int]): ... # can be an alias for c_ulong
class c_ulong(_SimpleCData[int]): ...
class c_ulonglong(_SimpleCData[int]): ... # can be an alias for c_ulong
class c_ushort(_SimpleCData[int]): ...
class c_void_p(_PointerLike, _SimpleCData[int | None]):
_type_: ClassVar[Literal["P"]]
@classmethod
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
c_voidp = c_void_p # backwards compatibility (to a bug)
class c_wchar(_SimpleCData[str]): ...
c_int8 = c_byte
# these are actually dynamic aliases for c_short, c_int, c_long, or c_longlong
class c_int16(_SimpleCData[int]): ...
class c_int32(_SimpleCData[int]): ...
class c_int64(_SimpleCData[int]): ...
c_uint8 = c_ubyte
# these are actually dynamic aliases for c_ushort, c_uint, c_ulong, or c_ulonglong
class c_uint16(_SimpleCData[int]): ...
class c_uint32(_SimpleCData[int]): ...
class c_uint64(_SimpleCData[int]): ...
class c_wchar(_SimpleCData[str]):
_type_: ClassVar[Literal["u"]]
class c_wchar_p(_PointerLike, _SimpleCData[str | None]):
_type_: ClassVar[Literal["Z"]]
def __init__(self, value: int | str | None = ...) -> None: ...
@classmethod
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
class c_bool(_SimpleCData[bool]):
def __init__(self, value: bool = ...) -> None: ...
if sys.platform == "win32":
class HRESULT(_SimpleCData[int]): ... # TODO undocumented
class HRESULT(_SimpleCData[int]): # TODO: undocumented
_type_: ClassVar[Literal["l"]]
if sys.version_info >= (3, 12):
# At runtime, this is an alias for either c_int32 or c_int64,
# which are themselves an alias for one of c_short, c_int, c_long, or c_longlong
# which are themselves an alias for one of c_int, c_long, or c_longlong
# This covers all our bases.
c_time_t: type[c_int32 | c_int64 | c_short | c_int | c_long | c_longlong]
class py_object(_CanCastTo, _SimpleCData[_T]): ...
if sys.version_info >= (3, 14):
class c_float_complex(_SimpleCData[complex]): ...
class c_double_complex(_SimpleCData[complex]): ...
class c_longdouble_complex(_SimpleCData[complex]): ...
c_time_t: type[c_int32 | c_int64 | c_int | c_long | c_longlong]

View File

@@ -1,10 +1,10 @@
import sys
from _ctypes import _CArgObject, _CField
from ctypes import (
Array,
Structure,
_Pointer,
_SimpleCData,
c_byte,
c_char,
c_char_p,
c_double,
@@ -24,7 +24,15 @@ from ctypes import (
from typing import Any, TypeVar
from typing_extensions import Self, TypeAlias
BYTE = c_byte
if sys.version_info >= (3, 12):
from ctypes import c_ubyte
BYTE = c_ubyte
else:
from ctypes import c_byte
BYTE = c_byte
WORD = c_ushort
DWORD = c_ulong
CHAR = c_char

View File

@@ -4,11 +4,9 @@ import types
from _typeshed import DataclassInstance
from builtins import type as Type # alias to avoid name clashes with fields named "type"
from collections.abc import Callable, Iterable, Mapping
from types import GenericAlias
from typing import Any, Generic, Literal, Protocol, TypeVar, overload
from typing_extensions import Never, TypeAlias, TypeIs
if sys.version_info >= (3, 9):
from types import GenericAlias
from typing_extensions import Never, TypeIs
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
@@ -142,8 +140,7 @@ class Field(Generic[_T]):
) -> None: ...
def __set_name__(self, owner: Type[Any], name: str) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
# NOTE: Actual return type is 'Field[_T]', but we want to help type checkers
# to understand the magic that happens at runtime.
@@ -232,22 +229,13 @@ def is_dataclass(obj: object) -> TypeIs[DataclassInstance | type[DataclassInstan
class FrozenInstanceError(AttributeError): ...
if sys.version_info >= (3, 9):
_InitVarMeta: TypeAlias = type
else:
class _InitVarMeta(type):
# Not used, instead `InitVar.__class_getitem__` is called.
# pyright (not unreasonably) thinks this is an invalid use of InitVar.
def __getitem__(self, params: Any) -> InitVar[Any]: ... # pyright: ignore[reportInvalidTypeForm]
class InitVar(Generic[_T], metaclass=_InitVarMeta):
class InitVar(Generic[_T], metaclass=type):
type: Type[_T]
def __init__(self, type: Type[_T]) -> None: ...
if sys.version_info >= (3, 9):
@overload
def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... # pyright: ignore[reportInvalidTypeForm]
@overload
def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... # pyright: ignore[reportInvalidTypeForm]
@overload
def __class_getitem__(cls, type: Type[_T]) -> InitVar[_T]: ... # pyright: ignore[reportInvalidTypeForm]
@overload
def __class_getitem__(cls, type: Any) -> InitVar[Any]: ... # pyright: ignore[reportInvalidTypeForm]
if sys.version_info >= (3, 12):
def make_dataclass(

View File

@@ -6,7 +6,7 @@ from typing_extensions import CapsuleType, Self, TypeAlias, deprecated
if sys.version_info >= (3, 11):
__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR", "UTC")
elif sys.version_info >= (3, 9):
else:
__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", "MINYEAR", "MAXYEAR")
MINYEAR: Final = 1
@@ -39,18 +39,17 @@ class timezone(tzinfo):
if sys.version_info >= (3, 11):
UTC: timezone
if sys.version_info >= (3, 9):
# This class calls itself datetime.IsoCalendarDate. It's neither
# NamedTuple nor structseq.
@final
@type_check_only
class _IsoCalendarDate(tuple[int, int, int]):
@property
def year(self) -> int: ...
@property
def week(self) -> int: ...
@property
def weekday(self) -> int: ...
# This class calls itself datetime.IsoCalendarDate. It's neither
# NamedTuple nor structseq.
@final
@type_check_only
class _IsoCalendarDate(tuple[int, int, int]):
@property
def year(self) -> int: ...
@property
def week(self) -> int: ...
@property
def weekday(self) -> int: ...
class date:
min: ClassVar[date]
@@ -106,10 +105,7 @@ class date:
def __hash__(self) -> int: ...
def weekday(self) -> int: ...
def isoweekday(self) -> int: ...
if sys.version_info >= (3, 9):
def isocalendar(self) -> _IsoCalendarDate: ...
else:
def isocalendar(self) -> tuple[int, int, int]: ...
def isocalendar(self) -> _IsoCalendarDate: ...
class time:
min: ClassVar[time]

View File

@@ -1,10 +1,7 @@
import sys
from collections.abc import Callable, Iterable, Iterator, Sequence
from types import GenericAlias
from typing import Any, AnyStr, Generic, Literal, NamedTuple, TypeVar, overload
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = [
"get_close_matches",
"ndiff",
@@ -43,19 +40,14 @@ class SequenceMatcher(Generic[_T]):
def set_seqs(self, a: Sequence[_T], b: Sequence[_T]) -> None: ...
def set_seq1(self, a: Sequence[_T]) -> None: ...
def set_seq2(self, b: Sequence[_T]) -> None: ...
if sys.version_info >= (3, 9):
def find_longest_match(self, alo: int = 0, ahi: int | None = None, blo: int = 0, bhi: int | None = None) -> Match: ...
else:
def find_longest_match(self, alo: int, ahi: int, blo: int, bhi: int) -> Match: ...
def find_longest_match(self, alo: int = 0, ahi: int | None = None, blo: int = 0, bhi: int | None = None) -> Match: ...
def get_matching_blocks(self) -> list[Match]: ...
def get_opcodes(self) -> list[tuple[Literal["replace", "delete", "insert", "equal"], int, int, int, int]]: ...
def get_grouped_opcodes(self, n: int = 3) -> Iterable[list[tuple[str, int, int, int, int]]]: ...
def ratio(self) -> float: ...
def quick_ratio(self) -> float: ...
def real_quick_ratio(self) -> float: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
@overload
def get_close_matches(word: AnyStr, possibilities: Iterable[AnyStr], n: int = 3, cutoff: float = 0.6) -> list[AnyStr]: ...

View File

@@ -21,8 +21,7 @@ if sys.platform == "win32":
boolean_options: ClassVar[list[str]]
all_versions: Incomplete
other_version: str
if sys.version_info >= (3, 9):
def __init__(self, *args, **kw) -> None: ...
def __init__(self, *args, **kw) -> None: ...
bdist_dir: Incomplete
plat_name: Incomplete
keep_temp: int

View File

@@ -13,7 +13,7 @@ longopt_xlate: Final[dict[int, int]]
class FancyGetopt:
def __init__(self, option_table: list[_Option] | None = None) -> None: ...
# TODO kinda wrong, `getopt(object=object())` is invalid
# TODO: kinda wrong, `getopt(object=object())` is invalid
@overload
def getopt(
self, args: _SliceableT[_StrSequenceT_co] | None = None, object: None = None

View File

@@ -1,2 +0,0 @@
from _dummy_threading import *
from _dummy_threading import __all__ as __all__

View File

@@ -22,7 +22,8 @@ NLSET: Final[set[str]]
# Added in Python 3.8.20, 3.9.20, 3.10.15, 3.11.10, 3.12.5
SPECIALSNL: Final[set[str]]
if sys.version_info >= (3, 12):
if sys.version_info >= (3, 10):
# Added in Python 3.10.17, 3.11.12, 3.12.9, 3.13.2 (may still be backported to 3.9)
def make_quoted_pairs(value: Any) -> str: ...
def quote_string(value: Any) -> str: ...
@@ -349,7 +350,7 @@ ListSeparator: Final[ValueTerminal]
RouteComponentMarker: Final[ValueTerminal]
def get_fws(value: str) -> tuple[WhiteSpaceTerminal, str]: ...
def get_encoded_word(value: str) -> tuple[EncodedWord, str]: ...
def get_encoded_word(value: str, terminal_type: str = "vtext") -> tuple[EncodedWord, str]: ...
def get_unstructured(value: str) -> UnstructuredTokenList: ...
def get_qp_ctext(value: str) -> tuple[WhiteSpaceTerminal, str]: ...
def get_qcontent(value: str) -> tuple[ValueTerminal, str]: ...

View File

@@ -1,21 +0,0 @@
import codecs
from _codecs import _EncodingMap
from _typeshed import ReadableBuffer
class Codec(codecs.Codec):
def encode(self, input: str, errors: str = "strict") -> tuple[bytes, int]: ...
def decode(self, input: bytes, errors: str = "strict") -> tuple[str, int]: ...
class IncrementalEncoder(codecs.IncrementalEncoder):
def encode(self, input: str, final: bool = False) -> bytes: ...
class IncrementalDecoder(codecs.IncrementalDecoder):
def decode(self, input: ReadableBuffer, final: bool = False) -> str: ...
class StreamWriter(Codec, codecs.StreamWriter): ...
class StreamReader(Codec, codecs.StreamReader): ...
def getregentry() -> codecs.CodecInfo: ...
decoding_table: str
encoding_table: _EncodingMap

View File

@@ -1,5 +1,4 @@
import codecs
import sys
from _typeshed import ReadableBuffer
class Codec(codecs.Codec):
@@ -7,28 +6,18 @@ class Codec(codecs.Codec):
@staticmethod
def encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...
# At runtime, this is codecs.raw_unicode_escape_decode
if sys.version_info >= (3, 9):
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /) -> tuple[str, int]: ...
else:
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ...
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /) -> tuple[str, int]: ...
class IncrementalEncoder(codecs.IncrementalEncoder):
def encode(self, input: str, final: bool = False) -> bytes: ...
if sys.version_info >= (3, 9):
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, input: str | ReadableBuffer, errors: str | None, final: bool) -> tuple[str, int]: ...
else:
class IncrementalDecoder(codecs.IncrementalDecoder):
def decode(self, input: str | ReadableBuffer, final: bool = False) -> str: ...
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, input: str | ReadableBuffer, errors: str | None, final: bool) -> tuple[str, int]: ...
class StreamWriter(Codec, codecs.StreamWriter): ...
class StreamReader(Codec, codecs.StreamReader):
if sys.version_info >= (3, 9):
def decode(self, input: str | ReadableBuffer, errors: str = "strict") -> tuple[str, int]: ... # type: ignore[override]
def decode(self, input: str | ReadableBuffer, errors: str = "strict") -> tuple[str, int]: ... # type: ignore[override]
def getregentry() -> codecs.CodecInfo: ...

View File

@@ -1,5 +1,4 @@
import codecs
import sys
from _typeshed import ReadableBuffer
class Codec(codecs.Codec):
@@ -7,28 +6,18 @@ class Codec(codecs.Codec):
@staticmethod
def encode(str: str, errors: str | None = None, /) -> tuple[bytes, int]: ...
# At runtime, this is codecs.unicode_escape_decode
if sys.version_info >= (3, 9):
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /) -> tuple[str, int]: ...
else:
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, /) -> tuple[str, int]: ...
@staticmethod
def decode(data: str | ReadableBuffer, errors: str | None = None, final: bool = True, /) -> tuple[str, int]: ...
class IncrementalEncoder(codecs.IncrementalEncoder):
def encode(self, input: str, final: bool = False) -> bytes: ...
if sys.version_info >= (3, 9):
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, input: str | ReadableBuffer, errors: str | None, final: bool) -> tuple[str, int]: ...
else:
class IncrementalDecoder(codecs.IncrementalDecoder):
def decode(self, input: str | ReadableBuffer, final: bool = False) -> str: ...
class IncrementalDecoder(codecs.BufferedIncrementalDecoder):
def _buffer_decode(self, input: str | ReadableBuffer, errors: str | None, final: bool) -> tuple[str, int]: ...
class StreamWriter(Codec, codecs.StreamWriter): ...
class StreamReader(Codec, codecs.StreamReader):
if sys.version_info >= (3, 9):
def decode(self, input: str | ReadableBuffer, errors: str = "strict") -> tuple[str, int]: ... # type: ignore[override]
def decode(self, input: str | ReadableBuffer, errors: str = "strict") -> tuple[str, int]: ... # type: ignore[override]
def getregentry() -> codecs.CodecInfo: ...

View File

@@ -100,20 +100,13 @@ class EnumMeta(type):
_simple: bool = False,
**kwds: Any,
) -> _typeshed.Self: ...
elif sys.version_info >= (3, 9):
else:
def __new__(
metacls: type[_typeshed.Self], cls: str, bases: tuple[type, ...], classdict: _EnumDict, **kwds: Any
) -> _typeshed.Self: ...
else:
def __new__(metacls: type[_typeshed.Self], cls: str, bases: tuple[type, ...], classdict: _EnumDict) -> _typeshed.Self: ...
if sys.version_info >= (3, 9):
@classmethod
def __prepare__(metacls, cls: str, bases: tuple[type, ...], **kwds: Any) -> _EnumDict: ... # type: ignore[override]
else:
@classmethod
def __prepare__(metacls, cls: str, bases: tuple[type, ...]) -> _EnumDict: ... # type: ignore[override]
@classmethod
def __prepare__(metacls, cls: str, bases: tuple[type, ...], **kwds: Any) -> _EnumDict: ... # type: ignore[override]
def __iter__(self: type[_EnumMemberT]) -> Iterator[_EnumMemberT]: ...
def __reversed__(self: type[_EnumMemberT]) -> Iterator[_EnumMemberT]: ...
if sys.version_info >= (3, 12):

View File

@@ -26,8 +26,7 @@ if sys.platform != "win32":
if sys.platform == "darwin":
F_FULLFSYNC: int
F_NOCACHE: int
if sys.version_info >= (3, 9):
F_GETPATH: int
F_GETPATH: int
if sys.platform == "linux":
F_SETLKW64: int
F_SETSIG: int
@@ -43,10 +42,9 @@ if sys.platform != "win32":
F_SEAL_SEAL: int
F_SEAL_SHRINK: int
F_SEAL_WRITE: int
if sys.version_info >= (3, 9):
F_OFD_GETLK: Final[int]
F_OFD_SETLK: Final[int]
F_OFD_SETLKW: Final[int]
F_OFD_GETLK: Final[int]
F_OFD_SETLK: Final[int]
F_OFD_SETLKW: Final[int]
if sys.version_info >= (3, 10):
F_GETPIPE_SZ: int

View File

@@ -1,11 +1,9 @@
import sys
from _typeshed import GenericPath, StrOrBytesPath
from collections.abc import Callable, Iterable, Sequence
from types import GenericAlias
from typing import Any, AnyStr, Final, Generic, Literal
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = ["clear_cache", "cmp", "dircmp", "cmpfiles", "DEFAULT_IGNORES"]
DEFAULT_IGNORES: list[str]
@@ -62,7 +60,6 @@ class dircmp(Generic[AnyStr]):
def phase3(self) -> None: ...
def phase4(self) -> None: ...
def phase4_closure(self) -> None: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def clear_cache() -> None: ...

View File

@@ -1,13 +1,10 @@
import sys
from _typeshed import AnyStr_co, StrOrBytesPath
from collections.abc import Callable, Iterable
from types import TracebackType
from types import GenericAlias, TracebackType
from typing import IO, Any, AnyStr, Generic, Literal, Protocol, overload
from typing_extensions import Self, TypeAlias
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = [
"input",
"close",
@@ -199,8 +196,7 @@ class FileInput(Generic[AnyStr]):
def fileno(self) -> int: ...
def isfirstline(self) -> bool: ...
def isstdin(self) -> bool: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 10):
def hook_compressed(

View File

@@ -1,24 +1,13 @@
import sys
from collections.abc import Callable
from decimal import Decimal
from numbers import Integral, Rational, Real
from numbers import Rational, Real
from typing import Any, Literal, Protocol, SupportsIndex, overload
from typing_extensions import Self, TypeAlias
_ComparableNum: TypeAlias = int | float | Decimal | Real
if sys.version_info >= (3, 9):
__all__ = ["Fraction"]
else:
__all__ = ["Fraction", "gcd"]
@overload
def gcd(a: int, b: int) -> int: ...
@overload
def gcd(a: Integral, b: int) -> Integral: ...
@overload
def gcd(a: int, b: Integral) -> Integral: ...
@overload
def gcd(a: Integral, b: Integral) -> Integral: ...
__all__ = ["Fraction"]
class _ConvertibleToIntegerRatio(Protocol):
def as_integer_ratio(self) -> tuple[int | Rational, int | Rational]: ...

View File

@@ -41,29 +41,17 @@ class FTP:
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
) -> None: ...
source_address: tuple[str, int] | None
if sys.version_info >= (3, 9):
def __init__(
self,
host: str = "",
user: str = "",
passwd: str = "",
acct: str = "",
timeout: float | None = ...,
source_address: tuple[str, int] | None = None,
*,
encoding: str = "utf-8",
) -> None: ...
else:
def __init__(
self,
host: str = "",
user: str = "",
passwd: str = "",
acct: str = "",
timeout: float | None = ...,
source_address: tuple[str, int] | None = None,
) -> None: ...
def __init__(
self,
host: str = "",
user: str = "",
passwd: str = "",
acct: str = "",
timeout: float | None = ...,
source_address: tuple[str, int] | None = None,
*,
encoding: str = "utf-8",
) -> None: ...
def connect(
self, host: str = "", port: int = 0, timeout: float = -999, source_address: tuple[str, int] | None = None
) -> str: ...
@@ -131,7 +119,7 @@ class FTP_TLS(FTP):
source_address: tuple[str, int] | None = None,
encoding: str = "utf-8",
) -> None: ...
elif sys.version_info >= (3, 9):
else:
def __init__(
self,
host: str = "",
@@ -146,19 +134,6 @@ class FTP_TLS(FTP):
*,
encoding: str = "utf-8",
) -> None: ...
else:
def __init__(
self,
host: str = "",
user: str = "",
passwd: str = "",
acct: str = "",
keyfile: str | None = None,
certfile: str | None = None,
context: SSLContext | None = None,
timeout: float | None = ...,
source_address: tuple[str, int] | None = None,
) -> None: ...
ssl_version: int
keyfile: str | None
certfile: str | None

View File

@@ -2,12 +2,10 @@ import sys
import types
from _typeshed import SupportsAllComparisons, SupportsItems
from collections.abc import Callable, Hashable, Iterable, Sized
from types import GenericAlias
from typing import Any, Generic, Literal, NamedTuple, TypedDict, TypeVar, final, overload
from typing_extensions import ParamSpec, Self, TypeAlias
if sys.version_info >= (3, 9):
from types import GenericAlias
__all__ = [
"update_wrapper",
"wraps",
@@ -22,11 +20,9 @@ __all__ = [
"singledispatch",
"cached_property",
"singledispatchmethod",
"cache",
]
if sys.version_info >= (3, 9):
__all__ += ["cache"]
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_S = TypeVar("_S")
@@ -46,10 +42,9 @@ class _CacheInfo(NamedTuple):
maxsize: int | None
currsize: int
if sys.version_info >= (3, 9):
class _CacheParameters(TypedDict):
maxsize: int
typed: bool
class _CacheParameters(TypedDict):
maxsize: int
typed: bool
@final
class _lru_cache_wrapper(Generic[_T]):
@@ -57,9 +52,7 @@ class _lru_cache_wrapper(Generic[_T]):
def __call__(self, *args: Hashable, **kwargs: Hashable) -> _T: ...
def cache_info(self) -> _CacheInfo: ...
def cache_clear(self) -> None: ...
if sys.version_info >= (3, 9):
def cache_parameters(self) -> _CacheParameters: ...
def cache_parameters(self) -> _CacheParameters: ...
def __copy__(self) -> _lru_cache_wrapper[_T]: ...
def __deepcopy__(self, memo: Any, /) -> _lru_cache_wrapper[_T]: ...
@@ -131,8 +124,7 @@ class partial(Generic[_T]):
def keywords(self) -> dict[str, Any]: ...
def __new__(cls, func: Callable[..., _T], /, *args: Any, **kwargs: Any) -> Self: ...
def __call__(self, /, *args: Any, **kwargs: Any) -> _T: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
# With protocols, this could change into a generic protocol that defines __get__ and returns _T
_Descriptor: TypeAlias = Any
@@ -148,8 +140,7 @@ class partialmethod(Generic[_T]):
def __get__(self, obj: Any, cls: type[Any] | None = None) -> Callable[..., _T]: ...
@property
def __isabstractmethod__(self) -> bool: ...
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 11):
_RegType: TypeAlias = type[Any] | types.UnionType
@@ -200,12 +191,9 @@ class cached_property(Generic[_T_co]):
def __set_name__(self, owner: type[Any], name: str) -> None: ...
# __set__ is not defined at runtime, but @cached_property is designed to be settable
def __set__(self, instance: object, value: _T_co) -> None: ... # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
if sys.version_info >= (3, 9):
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 9):
def cache(user_function: Callable[..., _T], /) -> _lru_cache_wrapper[_T]: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def cache(user_function: Callable[..., _T], /) -> _lru_cache_wrapper[_T]: ...
def _make_key(
args: tuple[Hashable, ...],
kwds: SupportsItems[Any, Any],

View File

@@ -1,4 +1,3 @@
import sys
from collections.abc import Callable
from typing import Any, Final, Literal
from typing_extensions import TypeAlias
@@ -28,10 +27,7 @@ def get_referrers(*objs: Any) -> list[Any]: ...
def get_stats() -> list[dict[str, Any]]: ...
def get_threshold() -> tuple[int, int, int]: ...
def is_tracked(obj: Any, /) -> bool: ...
if sys.version_info >= (3, 9):
def is_finalized(obj: Any, /) -> bool: ...
def is_finalized(obj: Any, /) -> bool: ...
def isenabled() -> bool: ...
def set_debug(flags: int, /) -> None: ...
def set_threshold(threshold0: int, threshold1: int = ..., threshold2: int = ..., /) -> None: ...

View File

@@ -5,16 +5,22 @@ from _hashlib import (
_HashObject,
openssl_md5 as md5,
openssl_sha1 as sha1,
openssl_sha3_224 as sha3_224,
openssl_sha3_256 as sha3_256,
openssl_sha3_384 as sha3_384,
openssl_sha3_512 as sha3_512,
openssl_sha224 as sha224,
openssl_sha256 as sha256,
openssl_sha384 as sha384,
openssl_sha512 as sha512,
openssl_shake_128 as shake_128,
openssl_shake_256 as shake_256,
pbkdf2_hmac as pbkdf2_hmac,
scrypt as scrypt,
)
from _typeshed import ReadableBuffer
from collections.abc import Callable, Set as AbstractSet
from typing import Protocol, type_check_only
from typing import Protocol
if sys.version_info >= (3, 11):
__all__ = (
@@ -60,31 +66,7 @@ else:
"pbkdf2_hmac",
)
if sys.version_info >= (3, 9):
def new(name: str, data: ReadableBuffer = b"", *, usedforsecurity: bool = ...) -> HASH: ...
from _hashlib import (
openssl_sha3_224 as sha3_224,
openssl_sha3_256 as sha3_256,
openssl_sha3_384 as sha3_384,
openssl_sha3_512 as sha3_512,
openssl_shake_128 as shake_128,
openssl_shake_256 as shake_256,
)
else:
@type_check_only
class _VarLenHash(HASH):
def digest(self, length: int) -> bytes: ... # type: ignore[override]
def hexdigest(self, length: int) -> str: ... # type: ignore[override]
def new(name: str, data: ReadableBuffer = b"") -> HASH: ...
# At runtime these aren't functions but classes imported from _sha3
def sha3_224(string: ReadableBuffer = b"") -> HASH: ...
def sha3_256(string: ReadableBuffer = b"") -> HASH: ...
def sha3_384(string: ReadableBuffer = b"") -> HASH: ...
def sha3_512(string: ReadableBuffer = b"") -> HASH: ...
def shake_128(string: ReadableBuffer = b"") -> _VarLenHash: ...
def shake_256(string: ReadableBuffer = b"") -> _VarLenHash: ...
def new(name: str, data: ReadableBuffer = b"", *, usedforsecurity: bool = ...) -> HASH: ...
algorithms_guaranteed: AbstractSet[str]
algorithms_available: AbstractSet[str]

Some files were not shown because too many files have changed in this diff Show More