Compare commits

...

277 Commits

Author SHA1 Message Date
Micha Reiser
90d16987b7 Reduce repro 2025-05-14 10:20:11 +02:00
Alex Waygood
a9d3e2e253 [ty] Call into type inference more when resolving __all__ 2025-05-08 12:33:05 +01:00
David Peter
4f890b2867 [ty] Update salsa (#17937)
## Summary

* Update salsa to pull in https://github.com/salsa-rs/salsa/pull/850.
* Some refactoring of salsa event callbacks in various `Db`'s due to
https://github.com/salsa-rs/salsa/pull/849

closes https://github.com/astral-sh/ty/issues/108

## Test Plan

Ran `cargo run --bin ty -- -vvv` on a test file to make sure that salsa
Events are still logged.
2025-05-08 12:02:53 +02:00
Shaygan Hooshyari
d566636ca5 Support typing.Self in methods (#17689)
## Summary

Fixes: astral-sh/ty#159 

This PR adds support for using `Self` in methods.
When the type of an annotation is `TypingSelf` it is converted to a type
var based on:
https://typing.python.org/en/latest/spec/generics.html#self

I just skipped Protocols because it had more problems and the tests was
not useful.
Also I need to create a follow up PR that implicitly assumes `self`
argument has type `Self`.

In order to infer the type in the `in_type_expression` method I needed
to have scope id and semantic index available. I used the idea from
[this PR](https://github.com/astral-sh/ruff/pull/17589/files) to pass
additional context to this method.
Also I think in all places that `in_type_expression` is called we need
to have this context because `Self` can be there so I didn't split the
method into one version with context and one without.

## Test Plan

Added new tests from spec.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-05-07 15:58:00 -07:00
Alex Waygood
51cef5a72b [ty] Recognise functions containing yield from expressions as being generator functions (#17930) 2025-05-07 23:29:44 +01:00
Douglas Creager
2cf5cba7ff [ty] Check base classes when determining subtyping etc for generic aliases (#17927)
#17897 added variance handling for legacy typevars — but they were only
being considered when checking generic aliases of the same class:

```py
class A: ...
class B(A): ...

class C[T]: ...

static_assert(is_subtype_of(C[B], C[A]))
```

and not for generic subclasses:

```py
class D[U](C[U]): ...

static_assert(is_subtype_of(D[B], C[A]))
```

Now we check those too!

Closes https://github.com/astral-sh/ty/issues/101
2025-05-07 15:21:11 -04:00
yunchi
ce0800fccf [pylint] add fix safety section (PLC2801) (#17825)
parent: #15584 
fix was introduced at: #9587 
reasoning: #9572
2025-05-07 14:34:34 -04:00
Micha Reiser
d03a7069ad Add instructions on how to upgrade to a newer Rust version (#17928) 2025-05-07 20:11:58 +02:00
Abhijeet Prasad Bodas
f5096f2050 [parser] Flag single unparenthesized generator expr with trailing comma in arguments. (#17893)
Fixes #17867

## Summary

The CPython parser does not allow generator expressions which are the
sole arguments in an argument list to have a trailing comma.
With this change, we start flagging such instances.

## Test Plan

Added new inline tests.
2025-05-07 14:11:35 -04:00
Alex Waygood
895b6161a6 [ty] Ensure that T is disjoint from ~T even when T is a TypeVar (#17922)
Same as https://github.com/astral-sh/ruff/pull/17910 but for
disjointness
2025-05-07 10:59:16 -07:00
Alex Waygood
74fe7982ba [ty] Sort collected diagnostics before snapshotting them in mdtest (#17926) 2025-05-07 18:23:22 +01:00
Micha Reiser
51386b3c7a [ty] Add basic file watching to server (#17912) 2025-05-07 19:03:30 +02:00
Charlie Marsh
51e2effd2d Make completions an opt-in LSP feature (#17921)
## Summary

We now expect the client to send initialization options to opt-in to
experimental (but LSP-standardized) features, like completion support.
Specifically, the client should set `"experimental.completions.enable":
true`.

Closes https://github.com/astral-sh/ty/issues/74.
2025-05-07 16:39:35 +00:00
Dhruv Manilawala
82d31a6014 Add link to ty issue tracker (#17924)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-05-07 16:33:27 +00:00
Dhruv Manilawala
78054824c0 [ty] Add support for __all__ (#17856)
## Summary

This PR adds support for the `__all__` module variable.

Reference spec:
https://typing.python.org/en/latest/spec/distributing.html#library-interface-public-and-private-symbols

This PR adds a new `dunder_all_names` query that returns a set of
`Name`s defined in the `__all__` variable of the given `File`. The query
works by implementing the `StatementVisitor` and collects all the names
by recognizing the supported idioms as mentioned in the spec. Any idiom
that's not recognized are ignored.

The current implementation is minimum to what's required for us to
remove all the false positives that this is causing. Refer to the
"Follow-ups" section below to see what we can do next. I'll a open
separate issue to keep track of them.

Closes: astral-sh/ty#106 
Closes: astral-sh/ty#199

### Follow-ups

* Diagnostics:
* Add warning diagnostics for unrecognized `__all__` idioms, `__all__`
containing non-string element
* Add an error diagnostic for elements that are present in `__all__` but
not defined in the module. This could lead to runtime error
* Maybe we should return `<type>` instead of `Unknown | <type>` for
`module.__all__`. For example:
https://playknot.ruff.rs/2a6fe5d7-4e16-45b1-8ec3-d79f2d4ca894
* Mark a symbol that's mentioned in `__all__` as used otherwise it could
raise (possibly in the future) "unused-name" diagnostic

Supporting diagnostics will require that we update the return type of
the query to be something other than `Option<FxHashSet<Name>>`,
something that behaves like a result and provides a way to check whether
a name exists in `__all__`, loop over elements in `__all__`, loop over
the invalid elements, etc.

## Ecosystem analysis

The following are the maximum amount of diagnostics **removed** in the
ecosystem:

* "Type <module '...'> has no attribute ..."
    * `collections.abc` - 14
    * `numpy` - 35534
    * `numpy.ma` - 296
    * `numpy.char` - 37
    * `numpy.testing` - 175
    * `hashlib` - 311
    * `scipy.fft` - 2
    * `scipy.stats` - 38
* "Module '...' has no member ..."
    * `collections.abc` - 85
    * `numpy` - 508
    * `numpy.testing` - 741
    * `hashlib` - 36
    * `scipy.stats` - 68
    * `scipy.interpolate` - 7
    * `scipy.signal` - 5

The following modules have dynamic `__all__` definition, so `ty` assumes
that `__all__` doesn't exists in that module:
* `scipy.stats`
(95a5d6ea8b/scipy/stats/__init__.py (L665))
* `scipy.interpolate`
(95a5d6ea8b/scipy/interpolate/__init__.py (L221))
* `scipy.signal` (indirectly via
95a5d6ea8b/scipy/signal/_signal_api.py (L30))
* `numpy.testing`
(de784cd6ee/numpy/testing/__init__.py (L16-L18))

~There's this one category of **false positives** that have been added:~
Fixed the false positives by also ignoring `__all__` from a module that
uses unrecognized idioms.

<details><summary>Details about the false postivie:</summary>
<p>

The `scipy.stats` module has dynamic `__all__` and it imports a bunch of
symbols via star imports. Some of those modules have a mix of valid and
invalid `__all__` idioms. For example, in
95a5d6ea8b/scipy/stats/distributions.py (L18-L24),
2 out of 4 `__all__` idioms are invalid but currently `ty` recognizes
two of them and says that the module has a `__all__` with 5 values. This
leads to around **2055** newly added false positives of the form:
```
Type <module 'scipy.stats'> has no attribute ...
```

I think the fix here is to completely ignore `__all__`, not only if
there are invalid elements in it, but also if there are unrecognized
idioms used in the module.

</p>
</details> 

## Test Plan

Add a bunch of test cases using the new `ty_extensions.dunder_all_names`
function to extract a module's `__all__` names.

Update various test cases to remove false positives around `*` imports
and re-export convention.

Add new test cases for named import behavior as `*` imports covers all
of it already (thanks Alex!).
2025-05-07 21:42:42 +05:30
Alex Waygood
c6f4929cdc [ty] fix assigning a typevar to a union with itself (#17910)
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-05-07 15:50:22 +00:00
Alex Waygood
2ec0d7e072 [ty] Improve UX for [duplicate-base] diagnostics (#17914) 2025-05-07 15:27:37 +00:00
Charlie Marsh
ad658f4d68 Clean up some Ruff references in the ty server (#17920)
## Summary

Anything user-facing, etc.
2025-05-07 10:55:16 -04:00
Abhijeet Prasad Bodas
3dedd70a92 [ty] Detect overloads decorated with @dataclass_transform (#17835)
## Summary

Fixes #17541

Before this change, in the case of overloaded functions,
`@dataclass_transform` was detected only when applied to the
implementation, not the overloads.
However, the spec also allows this decorator to be applied to any of the
overloads as well.
With this PR, we start handling `@dataclass_transform`s applied to
overloads.

## Test Plan

Fixed existing TODOs in the test suite.
2025-05-07 15:51:13 +02:00
David Peter
fab862c8cd [ty] Ecosystem checks: activate running on 'manticore' (#17916)
## Summary

This is sort of an anticlimactic resolution to #17863, but now that we
understand what the root cause for the stack overflows was, I think it's
fine to enable running on this project. See the linked ticket for the
full analysis.

closes #17863

## Test Plan

Ran lots of times locally and never observed a crash at worker thread
stack sizes > 8 MiB.
2025-05-07 06:27:36 -07:00
Douglas Creager
0d9b6a0975 [ty] Handle explicit variance in legacy typevars (#17897)
We now track the variance of each typevar, and obey the `covariant` and
`contravariant` parameters to the legacy `TypeVar` constructor. We still
don't yet infer variance for PEP-695 typevars or for the
`infer_variance` legacy constructor parameter.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Carl Meyer <carl@astral.sh>
2025-05-07 08:44:51 -04:00
Micha Reiser
c5e299e796 Update salsa (#17895) 2025-05-07 09:51:15 +02:00
Victor Hugo Gomes
c504001b32 [pyupgrade] Add spaces between tokens as necessary to avoid syntax errors in UP018 autofix (#17648)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-05-07 09:34:08 +02:00
David Peter
04457f99b6 [ty] Protocols: Fixpoint iteration for fully-static check (#17880)
## Summary

A recursive protocol like the following would previously lead to stack
overflows when attempting to create the union type for the `P | None`
member, because `UnionBuilder` checks if element types are fully static,
and the fully-static check on `P` would in turn list all members and
check whether all of them were fully static, leading to a cycle.

```py
from __future__ import annotations

from typing import Protocol

class P(Protocol):
    parent: P | None
```

Here, we make the fully-static check on protocols a salsa query and add
fixpoint iteration, starting with `true` as the initial value (assume
that the recursive protocol is fully-static). If the recursive protocol
has any non-fully-static members, we still return `false` when
re-executing the query (see newly added tests).

closes #17861

## Test Plan

Added regression test
2025-05-07 08:55:21 +02:00
InSync
a33d0d4bf4 [ty] Support generate-shell-completion (#17879)
## Summary

Resolves #15502.

`ty generate-shell-completion` now works in a similar manner to `ruff
generate-shell-completion`.

## Test Plan

Manually:

<details>

```shell
$ cargo run --package ty generate-shell-completion nushell
module completions {

  # An extremely fast Python type checker.
  export extern ty [
    --help(-h)                # Print help
    --version(-V)             # Print version
  ]
  
  # ...

}

export use completions *
```
</details>
2025-05-06 18:04:57 -07:00
Charlie Marsh
443f62e98d Remove condensed display type enum (#17902)
## Summary

See: https://github.com/astral-sh/ruff/pull/17889#discussion_r2076556002
2025-05-06 18:04:03 -07:00
Charlie Marsh
a2e9a7732a Update class literal display to use <class 'Foo'> style (#17889)
## Summary

Closes https://github.com/astral-sh/ruff/issues/17238.
2025-05-06 20:11:25 -04:00
Micha Reiser
b2de749c32 Add a note to diagnostics why the rule is enabled (#17854) 2025-05-06 20:29:03 +02:00
Douglas Creager
9085f18353 [ty] Propagate specializations to ancestor base classes (#17892)
@AlexWaygood discovered that even though we've been propagating
specializations to _parent_ base classes correctly, we haven't been
passing them on to _grandparent_ base classes:
https://github.com/astral-sh/ruff/pull/17832#issuecomment-2854360969

```py
class Bar[T]:
    x: T

class Baz[T](Bar[T]): ...
class Spam[T](Baz[T]): ...

reveal_type(Spam[int]().x) # revealed: `T`, but should be `int`
```

This PR updates the MRO machinery to apply the current specialization
when starting to iterate the MRO of each base class.
2025-05-06 14:25:21 -04:00
Dylan
8152ba7cb7 [ty] Add minimal docs for a few lints (#17874)
Just the bare minimum to remove a few TODOs - omitted examples, and only
did 9 but I will check back tomorrow and try to knock out a few more!
2025-05-06 10:36:47 -07:00
Aria Desires
3d01d3be3e update the repository for ty (#17891)
This metadata is used by cargo-dist for artifact URLs (in curl-sh
expressions)
2025-05-06 12:03:38 -04:00
Brent Westbrook
4510a236d3 Default to latest supported Python version for version-related syntax errors (#17529)
## Summary

This PR partially addresses #16418 via the following:

- `LinterSettings::unresolved_python_version` is now a `TargetVersion`,
which is a thin wrapper around an `Option<PythonVersion>`
- `Checker::target_version` now calls `TargetVersion::linter_version`
internally, which in turn uses `unwrap_or_default` to preserve the
current default behavior
- Calls to the parser now call `TargetVersion::parser_version`, which
calls `unwrap_or_else(PythonVersion::latest)`
- The `Checker`'s implementation of
`SemanticSyntaxContext::python_version` also uses
`TargetVersion::parser_version` to use `PythonVersion::latest` for
semantic errors

In short, all lint rule behavior should be unchanged, but we default to
the latest Python version for the new syntax errors, which should
minimize confusing version-related syntax errors for users without a
version configured.

## Test Plan

Existing tests, which showed no changes (except for printing default
settings).
2025-05-06 10:19:13 -04:00
Marcus Näslund
76b6d53d8b Add new rule InEmptyCollection (#16480)
## Summary

Introducing a new rule based on discussions in #15732 and #15729 that
checks for unnecessary in with empty collections.

I called it in_empty_collection and gave the rule number RUF060.

Rule is in preview group.
2025-05-06 13:52:07 +00:00
Zanie Blue
f82b72882b Display ty version for ty --version and ty -V (#17888)
e.g.,

```
❯ uv run -q -- ty -V
ty 0.0.0-alpha.4 (08881edba 2025-05-05)
❯ uv run -q -- ty --version
ty 0.0.0-alpha.4 (08881edba 2025-05-05)
```

Previously, this just displayed `ty 0.0.0` because it didn't use our
custom version implementation. We no longer have a short version —
matching the interface in uv. We could add a variant for it, if it seems
important to people. However, I think we found it more confusing than
not over there and didn't get any complaints about the change.

Closes https://github.com/astral-sh/ty/issues/54
2025-05-06 08:06:41 -05:00
Zanie Blue
d07eefc408 Parse dist-workspace.toml for version (#17868)
Extends https://github.com/astral-sh/ruff/pull/17866, using
`dist-workspace.toml` as a source of truth for versions to enable
version retrieval in distributions that are not Git repositories (i.e.,
Python source distributions and source tarballs consumed by Linux
distros).

I retain the Git tag lookup from
https://github.com/astral-sh/ruff/pull/17866 as a fallback — it seems
harmless, but we could drop it to simplify things here.

I confirmed this works from the repository as well as Python source and
binary distributions:

```
❯ uv run --refresh-package ty --reinstall-package ty -q --  ty version
ty 0.0.1-alpha.1+5 (2eadc9e61 2025-05-05)
❯ uv build
...
❯ uvx --from ty@dist/ty-0.0.0a1.tar.gz --no-cache -q -- ty version
ty 0.0.1-alpha.1
❯ uvx --from ty@dist/ty-0.0.0a1-py3-none-macosx_11_0_arm64.whl -q -- ty version
ty 0.0.1-alpha.1
```

Requires https://github.com/astral-sh/ty/pull/36

cc @Gankra and @MichaReiser for review.
2025-05-06 12:18:17 +00:00
Zanie Blue
f7237e3b69 Update ty version to use parent Git repository information (#17866)
Currently, `ty version` pulls its information from the Ruff repository —
but we want this to pull from the repository in the directory _above_
when Ruff is a submodule.

I tested this in the `ty` repository after tagging an arbitrary commit:

```
❯ uv run --refresh-package ty --reinstall-package ty ty version
      Built ty @ file:///Users/zb/workspace/ty
Uninstalled 1 package in 2ms
Installed 1 package in 1ms
ty 0.0.0+3 (34253b1d4 2025-05-05)
```

We also use the last Git tag as the source of truth for the version,
instead of the crate version. However, we'll need a way to set the
version for releases still, as the tag is published _after_ the build.
We can either tag early (without pushing the tag to the remote), or add
another environment variable. (**Note, this approach is changed in a
follow-up. See https://github.com/astral-sh/ruff/pull/17868**)

From this repository, the version will be `unknown`:

```
❯ cargo run -q --bin ty -- version
ty unknown
```

We could add special handling like... `ty unknown (ruff@...)` but I see
that as a secondary goal.

Closes https://github.com/astral-sh/ty/issues/5

The reviewer situation in this repository is unhinged, cc @Gankra and
@MichaReiser for review.
2025-05-06 07:14:30 -05:00
Alex Waygood
2f9992b6ef [ty] Fix duplicate diagnostics for unresolved module when an import from statement imports multiple members (#17886) 2025-05-06 12:37:10 +01:00
Alex Waygood
457ec4dddd Generalize special-casing for enums constructed with the functional syntax (#17885) 2025-05-06 11:02:55 +01:00
Micha Reiser
aa0614509b Update salsa to pull in fixpoint fixes (#17847) 2025-05-06 11:27:51 +02:00
Micha Reiser
9000eb3bfd Update favicon and URL for playground (#17860) 2025-05-06 10:51:45 +02:00
Micha Reiser
7f50b503cf Allowlist play.ty.dev (#17857) 2025-05-06 10:16:17 +02:00
Micha Reiser
24d3fc27fb Fixup wording of fatal error warning (#17881) 2025-05-06 09:44:23 +02:00
Micha Reiser
6f821ac846 Show a warning at the end of the diagnostic list if there are any fatal warnings (#17855) 2025-05-06 07:14:21 +00:00
Charlie Marsh
d410d12bc5 Update code of conduct email address (#17875)
## Summary

For consistency with the `pyproject.toml`, etc.
2025-05-05 21:34:45 -04:00
Alex Waygood
89424cce5f [ty] Do not emit errors if enums or NamedTuples constructed using functional syntax are used in type expressions (#17873)
## Summary

This fixes some false positives that showed up in the primer diff for
https://github.com/astral-sh/ruff/pull/17832

## Test Plan

new mdtests added that fail with false-positive diagnostics on `main`
2025-05-06 00:37:24 +01:00
Shunsuke Shibayama
fd76d70a31 [red-knot] fix narrowing in nested scopes (#17630)
## Summary

This PR fixes #17595.

## Test Plan

New test cases are added to `mdtest/narrow/conditionals/nested.md`.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-05-05 16:28:42 -07:00
yunchi
a4c8e43c5f [pylint] Add fix safety section (PLR1722) (#17826)
parent: #15584 
fix introduced at: #816
2025-05-05 19:13:04 -04:00
Douglas Creager
ada4c4cb1f [ty] Don't require default typevars when specializing (#17872)
If a typevar is declared as having a default, we shouldn't require a
type to be specified for that typevar when explicitly specializing a
generic class:

```py
class WithDefault[T, U = int]: ...

reveal_type(WithDefault[str]())  # revealed: WithDefault[str, int]
```

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-05-05 18:29:30 -04:00
Alex Waygood
bb6c7cad07 [ty] Fix false-positive [invalid-return-type] diagnostics on generator functions (#17871) 2025-05-05 21:44:59 +00:00
Douglas Creager
47e3aa40b3 [ty] Specialize bound methods and nominal instances (#17865)
Fixes
https://github.com/astral-sh/ruff/pull/17832#issuecomment-2851224968. We
had a comment that we did not need to apply specializations to generic
aliases, or to the bound `self` of a bound method, because they were
already specialized. But they might be specialized with a type variable,
which _does_ need to be specialized, in the case of a "multi-step"
specialization, such as:

```py
class LinkedList[T]: ...

class C[U]:
    def method(self) -> LinkedList[U]:
        return LinkedList[U]()
```

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-05-05 17:17:36 -04:00
David Peter
9a6633da0b [ty] ecosystem: activate running on 'sympy' (#17870)
## Summary

Following #17869, we can now run `ty` on `sympy`.
2025-05-05 21:50:13 +02:00
David Peter
de78da5ee6 [ty] Increase worker-thread stack size (#17869)
## Summary

closes #17472 

This is obviously just a band-aid solution to this problem (in that you
can always make your [pathological
inputs](28994edd82/sympy/polys/numberfields/resolvent_lookup.py)
bigger and it will still crash), but I think this is not an unreasonable
change — even if we add more sophisticated solutions later. I tried
using `stacker` as suggested by @MichaReiser, and it works. But it's
unclear where exactly would be the right place to put it, and even for
the `sympy` problem, we would need to add it both in the semantic index
builder AST traversal and in type inference. Increasing the default
stack size for worker threads, as proposed here, doesn't solve the
underlying problem (that there is a hard limit), but it is more
universal in the sense that it is not specific to large binary-operator
expression chains.

To determine a reasonable stack size, I created files that look like

*right associative*:
```py
from typing import reveal_type
total = (1 + (1 + (1 + (1 + (… + 1)))))
reveal_type(total)
```

*left associative*
```py
from typing import reveal_type
total = 1 + 1 + 1 + 1 + … + 1
reveal_type(total)
```

with a variable amount of operands (`N`). I then chose the stack size
large enough to still be able to handle cases that existing type
checkers can not:

```
right

  N = 20: mypy takes ~ 1min
  N = 350: pyright crashes with a stack overflow (mypy fails with "too many nested parentheses")
  N = 800: ty(main) infers Literal[800] instantly
  N = 1000: ty(main) crashes with "thread '<unknown>' has overflowed its stack"

  N = 7000: ty(this branch) infers Literal[7000] instantly
  N = 8000+: ty(this branch) crashes


left

  N = 300: pyright emits "Maximum parse depth exceeded; break expression into smaller sub-expressions"
           total is inferred as Unknown
  N = 5500: mypy crashes with "INTERNAL ERROR"
  N = 2500: ty(main) infers Literal[2500] instantly
  N = 3000: ty(main) crashes with "thread '<unknown>' has overflowed its stack"

  N = 22000: ty(this branch) infers Literal[22000] instantly
  N = 23000+: ty(this branch) crashes
```

## Test Plan

New regression test.
2025-05-05 21:31:55 +02:00
Carl Meyer
20d64b9c85 [ty] add passing projects to primer (#17834)
Add projects to primer that now pass, with
https://github.com/astral-sh/ruff/pull/17833
2025-05-05 12:21:06 -07:00
Carl Meyer
4850c187ea [ty] add cycle handling for FunctionType::signature query (#17833)
This fixes cycle panics in several ecosystem projects (moved to
`good.txt` in a following PR
https://github.com/astral-sh/ruff/pull/17834 because our mypy-primer job
doesn't handle it well if we move projects to `good.txt` in the same PR
that fixes `ty` to handle them), as well as in the minimal case in the
added mdtest. It also fixes a number of panicking fuzzer seeds. It
doesn't appear to cause any regression in any ecosystem project or any
fuzzer seed.
2025-05-05 12:12:38 -07:00
Vasco Schiavo
3f32446e16 [ruff] add fix safety section (RUF013) (#17759)
The PR add the fix safety section for rule `RUF013`
(https://github.com/astral-sh/ruff/issues/15584 )
The fix was introduced here #4831

The rule as a lot of False Negative (as it is explained in the docs of
the rule).

The main reason because the fix is unsafe is that it could change code
generation tools behaviour, as in the example here:

```python
def generate_api_docs(func):
    hints = get_type_hints(func)
    for param, hint in hints.items():
        if is_optional_type(hint):
            print(f"Parameter '{param}' is optional")
        else:
            print(f"Parameter '{param}' is required")

# Before fix
def create_user(name: str, roles: list[str] = None):
    pass

# After fix
def create_user(name: str, roles: Optional[list[str]] = None):
    pass

# Generated docs would change from "roles is required" to "roles is optional"
```
2025-05-05 13:47:56 -05:00
Aria Desires
784daae497 migrate to dist-workspace.toml, use new workspace.packages config (#17864) 2025-05-05 14:07:46 -04:00
Max Mynter
178c882740 [semantic-syntax-tests] Add test fixtures for AwaitOutsideAsyncFunction (#17785)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
Re: #17526 
## Summary
Add test fixtures for `AwaitOutsideAsync` and
`AsyncComprehensionOutsideAsyncFunction` errors.

<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
This is a test. 

<!-- How was it tested? -->
2025-05-05 14:02:06 -04:00
Max Mynter
101e1a5ddd [semantic-syntax-tests] for for InvalidStarExpression, DuplicateMatchKey, and DuplicateMatchClassAttribute (#17754)
Re: #17526 

## Summary
Add integration tests for Python Semantic Syntax for
`InvalidStarExpression`, `DuplicateMatchKey`, and
`DuplicateMatchClassAttribute`.

## Note
- Red knot integration tests for `DuplicateMatchKey` exist already in
line 89-101.
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
This is a test.
<!-- How was it tested? -->
2025-05-05 17:30:16 +00:00
Dylan
965a4dd731 [isort] Check full module path against project root(s) when categorizing first-party (#16565)
When attempting to determine whether `import foo.bar.baz` is a known
first-party import relative to [user-provided source
paths](https://docs.astral.sh/ruff/settings/#src), when `preview` is
enabled we now check that `SRC/foo/bar/baz` is a directory or
`SRC/foo/bar/baz.py` or `SRC/foo/bar/baz.pyi` exist.

Previously, we just checked the analogous thing for `SRC/foo`, but this
can be misleading in situations with disjoint namespace packages that
share a common base name (e.g. we may be working inside the namespace
package `foo.buzz` and importing `foo.bar` from elsewhere).

Supersedes #12987 
Closes #12984
2025-05-05 11:40:01 -05:00
Victor Hugo Gomes
5e2c818417 [flake8-bandit] Mark tuples of string literals as trusted input in S603 (#17801)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

Fixes #17798
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

Snapshot tests
<!-- How was it tested? -->
2025-05-05 10:50:44 -04:00
David Peter
90c12f4177 [ty] ecosystem: Activate running on 'materialize' (#17862) 2025-05-05 16:34:23 +02:00
Wei Lee
6e9fb9af38 [airflow] Skip attribute check in try catch block (AIR301) (#17790)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Skip attribute check in try catch block (`AIR301`)

## Test Plan

<!-- How was it tested? -->
update
`crates/ruff_linter/resources/test/fixtures/airflow/AIR301_names_try.py`
2025-05-05 10:01:05 -04:00
Wei Lee
a507c1b8b3 [airflow] Remove airflow.utils.dag_parsing_context.get_parsing_context (AIR301) (#17852)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
Remove `airflow.utils.dag_parsing_context.get_parsing_context` from
AIR301 as it has been moved to AIR311

## Test Plan

<!-- How was it tested? -->

the test fixture was updated in the previous PR
2025-05-05 09:31:57 -04:00
David Peter
5a91badb8b [ty] Move 'scipy' to list of 'good' projects (#17850)
## Summary

Adds `scipy` as a new project to `good.txt` as a follow-up to #17849.
2025-05-05 13:52:57 +02:00
David Peter
1945bfdb84 [ty] Fix standalone expression type retrieval in presence of cycles (#17849)
## Summary

When entering an `infer_expression_types` cycle from
`TypeInferenceBuilder::infer_standalone_expression`, we might get back a
`TypeInference::cycle_fallback(…)` that doesn't actually contain any new
types, but instead it contains a `cycle_fallback_type` which is set to
`Some(Type::Never)`. When calling `self.extend(…)`, we therefore don't
really pull in a type for the expression we're interested in. This
caused us to panic if we tried to call `self.expression_type(…)` after
`self.extend(…)`.

The proposed fix here is to retrieve that type from the nested
`TypeInferenceBuilder` directly, which will correctly fall back to
`cycle_fallback_type`.

## Details

I minimized the second example from #17792 a bit further and used this
example for debugging:

```py
from __future__ import annotations

class C: ...

def f(arg: C):
    pass

x, _ = f(1)

assert x
```

This is self-referential because when we check the assignment statement
`x, _ = f(1)`, we need to look up the signature of `f`. Since evaluation
of annotations is deferred, we look up the public type of `C` for the
`arg` parameter. The public use of `C` is visibility-constraint by "`x`"
via the `assert` statement. While evaluating this constraint, we need to
look up the type of `x`, which in turn leads us back to the `x, _ =
f(1)` definition.

The reason why this only showed up in the relatively peculiar case with
unpack assignments is the code here:


78b4c3ccf1/crates/ty_python_semantic/src/types/infer.rs (L2709-L2718)

For a non-unpack assignment like `x = f(1)`, we would not try to infer
the right-hand side eagerly. Instead, we would enter a
`infer_definition_types` cycle that handles the situation correctly. For
unpack assignments, however, we try to infer the type of `value`
(`f(1)`) and therefore enter the cycle via `standalone_expression_type
=> infer_expression_type`.

closes #17792 

## Test Plan

* New regression test
* Made sure that we can now run successfully on scipy => see #17850
2025-05-05 13:52:08 +02:00
Dylan
a95c73d5d0 Implement deferred annotations for Python 3.14 (#17658)
This PR updates the semantic model for Python 3.14 by essentially
equating "run using Python 3.14" with "uses `from __future__ import
annotations`".

While this is not technically correct under the hood, it appears to be
correct for the purposes of our semantic model. That is: from the point
of view of deciding when to parse, bind, etc. annotations, these two
contexts behave the same. More generally these contexts behave the same
unless you are performing some kind of introspection like the following:


Without future import:
```pycon
>>> from annotationlib import get_annotations,Format
>>> def foo()->Bar:...
...
>>> get_annotations(foo,format=Format.FORWARDREF)
{'return': ForwardRef('Bar')}
>>> get_annotations(foo,format=Format.STRING)
{'return': 'Bar'}
>>> get_annotations(foo,format=Format.VALUE)
Traceback (most recent call last):
[...]
NameError: name 'Bar' is not defined
>>> get_annotations(foo)
Traceback (most recent call last):
[...]
NameError: name 'Bar' is not defined
```

With future import:
```
>>> from __future__ import annotations
>>> from annotationlib import get_annotations,Format
>>> def foo()->Bar:...
...
>>> get_annotations(foo,format=Format.FORWARDREF)
{'return': 'Bar'}
>>> get_annotations(foo,format=Format.STRING)
{'return': 'Bar'}
>>> get_annotations(foo,format=Format.VALUE)
{'return': 'Bar'}
>>> get_annotations(foo)
{'return': 'Bar'}
```

(Note: the result of the last call to `get_annotations` in these
examples relies on the fact that, as of this writing, the default value
for `format` is `Format.VALUE`).

If one day we support lint rules targeting code that introspects using
the new `annotationlib`, then it is possible we will need to revisit our
approximation.

Closes #15100
2025-05-05 06:40:36 -05:00
David Peter
78b4c3ccf1 [ty] Minor typo in environment variable name (#17848) 2025-05-05 10:25:48 +00:00
renovate[bot]
2485afe640 Update pre-commit dependencies (#17840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-05-05 07:36:09 +00:00
renovate[bot]
b8ed729f59 Update taiki-e/install-action digest to 86c23ee (#17838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 07:43:54 +02:00
renovate[bot]
108c470348 Update actions/download-artifact action to v4.3.0 (#17845)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 07:43:33 +02:00
renovate[bot]
87c64c9eab Update actions/setup-python action to v5.6.0 (#17846)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-05 07:43:01 +02:00
renovate[bot]
a10606dda2 Update Rust crate jiff to v0.2.12 (#17843) 2025-05-05 07:34:09 +02:00
renovate[bot]
d1c6dd9ac1 Update Rust crate toml to v0.8.22 (#17844) 2025-05-05 07:32:50 +02:00
renovate[bot]
073b993ab0 Update Rust crate assert_fs to v1.1.3 (#17841) 2025-05-05 07:31:02 +02:00
renovate[bot]
6a36cd6f02 Update Rust crate hashbrown to v0.15.3 (#17842) 2025-05-05 07:30:46 +02:00
renovate[bot]
3b15af6d4f Update dependency ruff to v0.11.8 (#17839) 2025-05-05 07:29:36 +02:00
Micha Reiser
e95130ad80 Introduce TY_MAX_PARALLELISM environment variable (#17830) 2025-05-04 16:27:15 +02:00
Micha Reiser
68e32c103f Ignore PRs labeled with ty for Ruff changelog (#17831) 2025-05-04 14:42:10 +01:00
Brent Westbrook
fe4051b2e6 Fix missing combine call for lint.typing-extensions setting (#17823)
## Summary

Fixes #17821.

## Test Plan

New CLI test. This might be overkill for such a simple fix, but it made
me feel better to add a test.
2025-05-03 18:19:19 -04:00
Micha Reiser
fa628018b2 Use #[expect(lint)] over #[allow(lint)] where possible (#17822) 2025-05-03 21:20:31 +02:00
Eric Botti
8535af8516 [red-knot] Add support for the LSP diagnostic tag (#17657)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-05-03 20:35:03 +02:00
Micha Reiser
b51c4f82ea Rename Red Knot (#17820) 2025-05-03 19:49:15 +02:00
Alex Waygood
e6a798b962 [red-knot] Recurse into the types of protocol members when normalizing a protocol's interface (#17808)
## Summary

Currently red-knot does not understand `Foo` and `Bar` here as being
equivalent:

```py
from typing import Protocol

class A: ...
class B: ...
class C: ...

class Foo(Protocol):
    x: A | B | C

class Bar(Protocol):
    x: B | A | C
```

Nor does it understand `A | B | Foo` as being equivalent to `Bar | B |
A`. This PR fixes that.

## Test Plan

new mdtest assertions added that fail on `main`
2025-05-03 16:43:37 +01:00
Alex Waygood
52b0470870 [red-knot] Synthesize a __call__ attribute for Callable types (#17809)
## Summary

Currently this assertion fails on `main`, because we do not synthesize a
`__call__` attribute for Callable types:

```py
from typing import Protocol, Callable
from knot_extensions import static_assert, is_assignable_to

class Foo(Protocol):
    def __call__(self, x: int, /) -> str: ...

static_assert(is_assignable_to(Callable[[int], str], Foo))
```

This PR fixes that.

See previous discussion about this in
https://github.com/astral-sh/ruff/pull/16493#discussion_r1985098508 and
https://github.com/astral-sh/ruff/pull/17682#issuecomment-2839527750

## Test Plan

Existing mdtests updated; a couple of new ones added.
2025-05-03 16:43:18 +01:00
Brent Westbrook
c4a08782cc Add regression test for parent noqa (#17783)
Summary
--

Adds a regression test for #2253 after I tried to delete the fix from
#2464.
2025-05-03 11:38:31 -04:00
Alex Waygood
91481a8be7 [red-knot] Minor simplifications to types/display.rs (#17813) 2025-05-03 15:29:05 +01:00
Victor Hugo Gomes
097af060c9 [refurb] Fix false positive for float and complex numbers in FURB116 (#17661) 2025-05-03 15:59:46 +02:00
Alex Waygood
b7d0b3f9e5 [red-knot] Add tests asserting that subclasses of Any are assignable to arbitrary protocol types (#17810) 2025-05-03 12:41:55 +00:00
Alex Waygood
084352f72c [red-knot] Distinguish fully static protocols from non-fully-static protocols (#17795) 2025-05-03 11:12:23 +01:00
Carl Meyer
78d4356301 [red-knot] add tracing of salsa events in mdtests (#17803) 2025-05-03 09:00:11 +02:00
Douglas Creager
96697c98f3 [red-knot] Legacy generic classes (#17721)
This adds support for legacy generic classes, which use a
`typing.Generic` base class, or which inherit from another generic class
that has been specialized with legacy typevars.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-05-02 20:34:20 -04:00
Micha Reiser
f7cae4ffb5 [red-knot] Don't panic when primary-span is missing while panicking (#17799) 2025-05-02 21:19:03 +01:00
Douglas Creager
675a5af89a [red-knot] Use Vec in CallArguments; reuse self when we can (#17793)
Quick follow-on to #17788. If there is no bound `self` parameter, we can
reuse the existing `CallArgument{,Type}s`, and we can use a straight
`Vec` instead of a `VecDeque`.
2025-05-02 12:00:02 -04:00
David Peter
ea3f4ac059 [red-knot] Refactor: no mutability in call APIs (#17788)
## Summary

Remove mutability in parameter types for a few functions such as
`with_self` and `try_call`. I tried the `Rc`-approach with cheap cloning
[suggest
here](https://github.com/astral-sh/ruff/pull/17733#discussion_r2068722860)
first, but it turns out we need a whole stack of prepended arguments
(there can be [both `self` *and*
`cls`](3cf44e401a/crates/red_knot_python_semantic/resources/mdtest/call/constructor.md (L113))),
and we would need the same construct not just for `CallArguments` but
also for `CallArgumentTypes`. At that point we're cloning `VecDeque`s
anyway, so the overhead of cloning the whole `VecDeque` with all
arguments didn't seem to justify the additional code complexity.

## Benchmarks

Benchmarks on tomllib, black, jinja, isort seem neutral.
2025-05-02 13:53:19 +02:00
David Peter
6d2c10cca2 [red-knot] Fix panic for tuple[x[y]] string annotation (#17787)
## Summary

closes #17775

## Test Plan

Added corpus regression test
2025-05-02 12:11:47 +02:00
David Peter
3cf44e401a [red-knot] Implicit instance attributes in generic methods (#17769)
## Summary

Add the ability to detect instance attribute assignments in class
methods that are generic.

This does not address the code duplication mentioned in #16928. I can
open a ticket for this after this has been merged.

closes #16928

## Test Plan

Added regression test.
2025-05-02 08:20:37 +00:00
Micha Reiser
17050e2ec5 doc: Add link to check-typed-exception from S110 and S112 (#17786) 2025-05-02 09:25:58 +02:00
Micha Reiser
a6dc04f96e Fix module name in ASYNC110, 115, and 116 fixes (#17774) 2025-05-01 23:37:09 +02:00
David Peter
e515899141 [red-knot] More informative hover-types for assignments (#17762)
## Summary

closes https://github.com/astral-sh/ruff/issues/17122

## Test Plan

* New hover tests
* Opened the playground locally and saw that new hover-types are shown
as expected.
2025-05-01 20:33:51 +02:00
Abhijeet Prasad Bodas
0c80c56afc [syntax-errors] Use consistent message for bad starred expression usage. (#17772) 2025-05-01 20:18:35 +02:00
Andrew Gallant
b7ce694162 red_knot_server: add auto-completion MVP
This PR does the wiring necessary to respond to completion requests from
LSP clients.

As far as the actual completion results go, they are nearly about the
dumbest and simplest thing we can do: we simply return a de-duplicated
list of all identifiers from the current module.
2025-05-01 12:08:10 -04:00
Brent Westbrook
163d526407 Allow passing a virtual environment to ruff analyze graph (#17743)
Summary
--

Fixes #16598 by adding the `--python` flag to `ruff analyze graph`,
which adds a `PythonPath` to the `SearchPathSettings` for module
resolution. For the [albatross-virtual-workspace] example from the uv
repo, this updates the output from the initial issue:

```shell
> ruff analyze graph packages/albatross
{
  "packages/albatross/check_installed_albatross.py": [
    "packages/albatross/src/albatross/__init__.py"
  ],
  "packages/albatross/src/albatross/__init__.py": []
}
```

To include both the the workspace `bird_feeder` import _and_ the
third-party `tqdm` import in the output:

```shell
> myruff analyze graph packages/albatross --python .venv
{
  "packages/albatross/check_installed_albatross.py": [
    "packages/albatross/src/albatross/__init__.py"
  ],
  "packages/albatross/src/albatross/__init__.py": [
    ".venv/lib/python3.12/site-packages/tqdm/__init__.py",
    "packages/bird-feeder/src/bird_feeder/__init__.py"
  ]
}
```

Note the hash in the uv link! I was temporarily very confused why my
local tests were showing an `iniconfig` import instead of `tqdm` until I
realized that the example has been updated on the uv main branch, which
I had locally.

Test Plan
--

A new integration test with a stripped down venv based on the
`albatross` example.

[albatross-virtual-workspace]:
aa629c4a54/scripts/workspaces/albatross-virtual-workspace
2025-05-01 11:29:52 -04:00
Brent Westbrook
75effb8ed7 Bump 0.11.8 (#17766) 2025-05-01 10:19:58 -04:00
Victor Hugo Gomes
3353d07938 [flake8-use-pathlib] Fix PTH104false positive when rename is passed a file descriptor (#17712)
## Summary
Contains the same changes to the semantic type inference as
https://github.com/astral-sh/ruff/pull/17705.

Fixes #17694
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

<!-- How was it tested? -->
Snapshot tests.

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-05-01 10:01:17 -04:00
Alex Waygood
41f3f21629 Improve messages outputted by py-fuzzer (#17764) 2025-05-01 12:32:45 +00:00
Hans
76ec64d535 [red-knot] Allow subclasses of Any to be assignable to Callable types (#17717)
## Summary

Fixes #17701.

## Test plan

New Markdown test.

---------

Co-authored-by: David Peter <mail@david-peter.de>
2025-05-01 10:18:12 +02:00
Micha Reiser
b7e69ecbfc [red-knot] Increase durability of read-only File fields (#17757) 2025-05-01 09:25:48 +02:00
Micha Reiser
9c57862262 [red-knot] Cache source type during semanic index building (#17756)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-05-01 08:51:53 +02:00
Victor Hugo Gomes
67ef370733 [flake8-use-pathlib] Fix PTH116 false positive when stat is passed a file descriptor (#17709)
Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2025-05-01 08:16:28 +02:00
github-actions[bot]
e17e1e860b Sync vendored typeshed stubs (#17753)
Co-authored-by: typeshedbot <>
2025-05-01 07:57:03 +02:00
David Peter
03d8679adf [red-knot] Preliminary NamedTuple support (#17738)
## Summary

Adds preliminary support for `NamedTuple`s, including:
* No false positives when constructing a `NamedTuple` object
* Correct signature for the synthesized `__new__` method, i.e. proper
checking of constructor calls
* A patched MRO (`NamedTuple` => `tuple`), mainly to make type inference
of named attributes possible, but also to better reflect the runtime
MRO.

All of this works:
```py
from typing import NamedTuple

class Person(NamedTuple):
    id: int
    name: str
    age: int | None = None

alice = Person(1, "Alice", 42)
alice = Person(id=1, name="Alice", age=42)

reveal_type(alice.id)  # revealed: int
reveal_type(alice.name)  # revealed: str
reveal_type(alice.age)  # revealed: int | None

# error: [missing-argument]
Person(3)

# error: [too-many-positional-arguments]
Person(3, "Eve", 99, "extra")

# error: [invalid-argument-type]
Person(id="3", name="Eve")
```

Not included:
* type inference for index-based access.
* support for the functional `MyTuple = NamedTuple("MyTuple", […])`
syntax

## Test Plan

New Markdown tests

## Ecosystem analysis

```
                          Diagnostic Analysis Report                           
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┓
┃ Diagnostic ID                     ┃ Severity ┃ Removed ┃ Added ┃ Net Change ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━┩
│ lint:call-non-callable            │ error    │       0 │     3 │         +3 │
│ lint:call-possibly-unbound-method │ warning  │       0 │     4 │         +4 │
│ lint:invalid-argument-type        │ error    │       0 │    72 │        +72 │
│ lint:invalid-context-manager      │ error    │       0 │     2 │         +2 │
│ lint:invalid-return-type          │ error    │       0 │     2 │         +2 │
│ lint:missing-argument             │ error    │       0 │    46 │        +46 │
│ lint:no-matching-overload         │ error    │   19121 │     0 │     -19121 │
│ lint:not-iterable                 │ error    │       0 │     6 │         +6 │
│ lint:possibly-unbound-attribute   │ warning  │      13 │    32 │        +19 │
│ lint:redundant-cast               │ warning  │       0 │     1 │         +1 │
│ lint:unresolved-attribute         │ error    │       0 │    10 │        +10 │
│ lint:unsupported-operator         │ error    │       3 │     9 │         +6 │
│ lint:unused-ignore-comment        │ warning  │      15 │     4 │        -11 │
├───────────────────────────────────┼──────────┼─────────┼───────┼────────────┤
│ TOTAL                             │          │   19152 │   191 │     -18961 │
└───────────────────────────────────┴──────────┴─────────┴───────┴────────────┘

Analysis complete. Found 13 unique diagnostic IDs.
Total diagnostics removed: 19152
Total diagnostics added: 191
Net change: -18961
```

I uploaded the ecosystem full diff (ignoring the 19k
`no-matching-overload` diagnostics)
[here](https://shark.fish/diff-namedtuple.html).

* There are some new `missing-argument` false positives which come from
the fact that named tuples are often created using unpacking as in
`MyNamedTuple(*fields)`, which we do not understand yet.
* There are some new `unresolved-attribute` false positives, because
methods like `_replace` are not available.
* Lots of the `invalid-argument-type` diagnostics look like true
positives

---------

Co-authored-by: Douglas Creager <dcreager@dcreager.net>
2025-04-30 22:52:04 +02:00
Victor Hugo Gomes
d33a503686 [red-knot] Add tests for classes that have incompatible __new__ and __init__ methods (#17747)
Closes #17737
2025-04-30 20:40:16 +00:00
renovate[bot]
650cbdd296 Update dependency vite to v6.2.7 (#17746) 2025-04-30 22:12:03 +02:00
Dhruv Manilawala
d2a238dfad [red-knot] Update call binding to return all matching overloads (#17618)
## Summary

This PR updates the existing overload matching methods to return an
iterator of all the matched overloads instead.

This would be useful once the overload call evaluation algorithm is
implemented which should provide an accurate picture of all the matched
overloads. The return type would then be picked from either the only
matched overload or the first overload from the ones that are matched.

In an earlier version of this PR, it tried to check if using an
intersection of return types from the matched overload would help reduce
the false positives but that's not enough. [This
comment](https://github.com/astral-sh/ruff/pull/17618#issuecomment-2842891696)
keep the ecosystem analysis for that change for prosperity.

> [!NOTE]
>
> The best way to review this PR is by hiding the whitespace changes
because there are two instances where a large match expression is
indented to be inside a loop over matching overlods
>
> <img width="1207" alt="Screenshot 2025-04-28 at 15 12 16"
src="https://github.com/user-attachments/assets/e06cbfa4-04fa-435f-84ef-4e5c3c5626d1"
/>

## Test Plan

Make sure existing test cases are unaffected and no ecosystem changes.
2025-05-01 01:33:21 +05:30
Wei Lee
6e765b4527 [airflow] apply Replacement::AutoImport to AIR312 (#17570)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

This is not yet fixing anything as the names are not changed, but it
lays down the foundation for fixing.

## Test Plan

<!-- How was it tested? -->

the existing test fixture should already cover this change
2025-04-30 15:53:10 -04:00
Vasco Schiavo
c5e41c278c [ruff] Add fix safety section (RUF028) (#17722)
The PR add the fix safety section for rule `RUF028`
(https://github.com/astral-sh/ruff/issues/15584 )

See also
[here](https://github.com/astral-sh/ruff/issues/15584#issuecomment-2820424485)
for the reason behind the _unsafe_ of the fix.
2025-04-30 15:06:25 -04:00
Abhijeet Prasad Bodas
0eeb02c0c1 [syntax-errors] Detect single starred expression assignment x = *y (#17624)
## Summary

Part of #17412

Starred expressions cannot be used as values in assignment expressions.
Add a new semantic syntax error to catch such instances.
Note that we already have
`ParseErrorType::InvalidStarredExpressionUsage` to catch some starred
expression errors during parsing, but that does not cover top level
assignment expressions.

## Test Plan

- Added new inline tests for the new rule
- Found some examples marked as "valid" in existing tests (`_ = *data`),
which are not really valid (per this new rule) and updated them
- There was an existing inline test - `assign_stmt_invalid_value_expr`
which had instances of `*` expression which would be deemed invalid by
this new rule. Converted these to tuples, so that they do not trigger
this new rule.
2025-04-30 15:04:00 -04:00
Alex Waygood
f31b1c695c py-fuzzer: fix minimization logic when --only-new-bugs is passed (#17739) 2025-04-30 18:48:31 +01:00
Brendan Cooley
5679bf00bc Fix example syntax for pydocstyle ignore_var_parameters option (#17740)
Co-authored-by: Brendan Cooley <brendanc@ladodgers.com>
2025-04-30 18:19:41 +02:00
Micha Reiser
a7c358ab5c [red-knot] Update salsa to prevent panic in custom panic-handler (#17742) 2025-04-30 18:19:07 +02:00
Alex Waygood
b6de01b9a5 [red-knot] Ban direct instantiation of generic protocols as well as non-generic ones (#17741) 2025-04-30 16:01:28 +00:00
David Peter
18bac94226 [red-knot] Lookup of __new__ (#17733)
## Summary

Model the lookup of `__new__` without going through
`Type::try_call_dunder`. The `__new__` method is only looked up on the
constructed type itself, not on the meta-type.

This now removes ~930 false positives across the ecosystem (vs 255 for
https://github.com/astral-sh/ruff/pull/17662). It introduces 30 new
false positives related to the construction of enums via something like
`Color = enum.Enum("Color", ["RED", "GREEN"])`. This is expected,
because we don't handle custom metaclass `__call__` methods. The fact
that we previously didn't emit diagnostics there was a coincidence (we
incorrectly called `EnumMeta.__new__`, and since we don't fully
understand its signature, that happened to work with `str`, `list`
arguments).

closes #17462

## Test Plan

Regression test
2025-04-30 17:27:09 +02:00
Dhruv Manilawala
7568eeb7a5 [red-knot] Check decorator consistency on overloads (#17684)
## Summary

Part of #15383.

As per the spec
(https://typing.python.org/en/latest/spec/overload.html#invalid-overload-definitions):

For `@staticmethod` and `@classmethod`:

> If one overload signature is decorated with `@staticmethod` or
`@classmethod`, all overload signatures must be similarly decorated. The
implementation, if present, must also have a consistent decorator. Type
checkers should report an error if these conditions are not met.

For `@final` and `@override`:

> If a `@final` or `@override` decorator is supplied for a function with
overloads, the decorator should be applied only to the overload
implementation if it is present. If an overload implementation isn’t
present (for example, in a stub file), the `@final` or `@override`
decorator should be applied only to the first overload. Type checkers
should enforce these rules and generate an error when they are violated.
If a `@final` or `@override` decorator follows these rules, a type
checker should treat the decorator as if it is present on all overloads.

## Test Plan

Update existing tests; add snapshots.
2025-04-30 20:34:21 +05:30
Hans
0e85cbdd91 [flake8-use-pathlib] Avoid suggesting Path.iterdir() for os.listdir with file descriptor (PTH208) (#17715)
## Summary

Fixes: #17695

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2025-04-30 20:08:57 +05:30
Dhruv Manilawala
7825975972 [red-knot] Check overloads without an implementation (#17681)
## Summary

As mentioned in the spec
(https://typing.python.org/en/latest/spec/overload.html#invalid-overload-definitions),
part of #15383:

> The `@overload`-decorated definitions must be followed by an overload
implementation, which does not include an `@overload` decorator. Type
checkers should report an error or warning if an implementation is
missing. Overload definitions within stub files, protocols, and on
abstract methods within abstract base classes are exempt from this
check.

## Test Plan

Remove TODOs from the test; create one diagnostic snapshot.
2025-04-30 19:54:21 +05:30
Max Mynter
f584b66824 Expand Semantic Syntax Coverage (#17725)
Re: #17526 

## Summary
Adds tests to red knot and `linter.rs` for the semantic syntax. 

Specifically add tests for `ReboundComprehensionVariable`,
`DuplicateTypeParameter`, and `MultipleCaseAssignment`.

Refactor the `test_async_comprehension_in_sync_comprehension` →
`test_semantic_error` to be more general for all semantic syntax test
cases.

## Test Plan
This is a test.

## Question
I'm happy to contribute more tests the coming days. 

Should that happen here or should we merge this PR such that the
refactor `test_async_comprehension_in_sync_comprehension` →
`test_semantic_error` is available on main and others can chime in, too?
2025-04-30 10:14:08 -04:00
Dhruv Manilawala
ad1a8da4d1 [red-knot] Check for invalid overload usages (#17609)
## Summary

Part of #15383, this PR adds the core infrastructure to check for
invalid overloads and adds a diagnostic to raise if there are < 2
overloads for a given definition.

### Design notes

The requirements to check the overloads are:
* Requires `FunctionType` which has the `to_overloaded` method
* The `FunctionType` **should** be for the function that is either the
implementation or the last overload if the implementation doesn't exists
* Avoid checking any `FunctionType` that are part of an overload chain
* Consider visibility constraints

This required a couple of iteration to make sure all of the above
requirements are fulfilled.

#### 1. Use a set to deduplicate

The logic would first collect all the `FunctionType` that are part of
the overload chain except for the implementation or the last overload if
the implementation doesn't exists. Then, when iterating over all the
function declarations within the scope, we'd avoid checking these
functions. But, this approach would fail to consider visibility
constraints as certain overloads _can_ be behind a version check. Those
aren't part of the overload chain but those aren't a separate overload
chain either.

<details><summary>Implementation:</summary>
<p>

```rs
fn check_overloaded_functions(&mut self) {
    let function_definitions = || {
        self.types
            .declarations
            .iter()
            .filter_map(|(definition, ty)| {
                // Filter out function literals that result from anything other than a function
                // definition e.g., imports.
                if let DefinitionKind::Function(function) = definition.kind(self.db()) {
                    ty.inner_type()
                        .into_function_literal()
                        .map(|ty| (ty, definition.symbol(self.db()), function.node()))
                } else {
                    None
                }
            })
    };

    // A set of all the functions that are part of an overloaded function definition except for
    // the implementation function and the last overload in case the implementation doesn't
    // exists. This allows us to collect all the function definitions that needs to be skipped
    // when checking for invalid overload usages.
    let mut overloads: HashSet<FunctionType<'db>> = HashSet::default();

    for (function, _) in function_definitions() {
        let Some(overloaded) = function.to_overloaded(self.db()) else {
            continue;
        };
        if overloaded.implementation.is_some() {
            overloads.extend(overloaded.overloads.iter().copied());
        } else if let Some((_, previous_overloads)) = overloaded.overloads.split_last() {
            overloads.extend(previous_overloads.iter().copied());
        }
    }

    for (function, function_node) in function_definitions() {
        let Some(overloaded) = function.to_overloaded(self.db()) else {
            continue;
        };
        if overloads.contains(&function) {
            continue;
        }

        // At this point, the `function` variable is either the implementation function or the
        // last overloaded function if the implementation doesn't exists.

        if overloaded.overloads.len() < 2 {
            if let Some(builder) = self
                .context
                .report_lint(&INVALID_OVERLOAD, &function_node.name)
            {
                let mut diagnostic = builder.into_diagnostic(format_args!(
                    "Function `{}` requires at least two overloads",
                    &function_node.name
                ));
                if let Some(first_overload) = overloaded.overloads.first() {
                    diagnostic.annotate(
                        self.context
                            .secondary(first_overload.focus_range(self.db()))
                            .message(format_args!("Only one overload defined here")),
                    );
                }
            }
        }
    }
 }
```

</p>
</details> 

#### 2. Define a `predecessor` query

The `predecessor` query would return the previous `FunctionType` for the
given `FunctionType` i.e., the current logic would be extracted to be a
query instead. This could then be used to make sure that we're checking
the entire overload chain once. The way this would've been implemented
is to have a `to_overloaded` implementation which would take the root of
the overload chain instead of the leaf. But, this would require updates
to the use-def map to somehow be able to return the _following_
functions for a given definition.

#### 3. Create a successor link

This is what Pyrefly uses, we'd create a forward link between two
functions that are involved in an overload chain. This means that for a
given function, we can get the successor function. This could be used to
find the _leaf_ of the overload chain which can then be used with the
`to_overloaded` method to get the entire overload chain. But, this would
also require updating the use-def map to be able to "see" the
_following_ function.

### Implementation 

This leads us to the final implementation that this PR implements which
is to consider the overloaded functions using:
* Collect all the **function symbols** that are defined **and** called
within the same file. This could potentially be an overloaded function
* Use the public bindings to get the leaf of the overload chain and use
that to get the entire overload chain via `to_overloaded` and perform
the check

This has a limitation that in case a function redefines an overload,
then that overload will not be checked. For example:

```py
from typing import overload

@overload
def f() -> None: ...
@overload
def f(x: int) -> int: ...

# The above overload will not be checked as the below function with the same name
# shadows it

def f(*args: int) -> int: ...
```

## Test Plan

Update existing mdtest and add snapshot diagnostics.
2025-04-30 19:37:42 +05:30
Micha Reiser
0861ecfa55 [red-knot] Use 'full' salsa backtrace output that includes durability and revisions (#17735) 2025-04-30 11:04:06 +00:00
Alex Waygood
d1f359afbb [red-knot] Initial support for protocol types (#17682) 2025-04-30 11:03:10 +00:00
Alex Waygood
b84b58760e [red-knot] Computing a type ordering for two non-normalized types is meaningless (#17734) 2025-04-30 11:58:55 +01:00
Micha Reiser
d94be0e780 [red-knot] Include salsa backtrace in check and mdtest panic messages (#17732)
Co-authored-by: David Peter <sharkdp@users.noreply.github.com>
2025-04-30 10:26:40 +02:00
Alex Waygood
8a6787b39e [red-knot] Fix control flow for assert statements (#17702)
## Summary

@sharkdp and I realised in our 1:1 this morning that our control flow
for `assert` statements isn't quite accurate at the moment. Namely, for
something like this:

```py
def _(x: int | None):
    assert x is None, reveal_type(x)
```

we currently reveal `None` for `x` here, but this is incorrect. In
actual fact, the `msg` expression of an `assert` statement (the
expression after the comma) will only be evaluated if the test (`x is
None`) evaluates to `False`. As such, we should be adding a constraint
of `~None` to `x` in the `msg` expression, which should simplify the
inferred type of `x` to `int` in that context (`(int | None) & ~None` ->
`int`).

## Test Plan

Mdtests added.

---------

Co-authored-by: David Peter <mail@david-peter.de>
2025-04-30 09:57:49 +02:00
David Peter
4a621c2c12 [red-knot] Fix recording of negative visibility constraints (#17731)
## Summary

We were previously recording wrong reachability constraints for negative
branches. Instead of `[cond] AND (NOT [True])` below, we were recording
`[cond] AND (NOT ([cond] AND [True]))`, i.e. we were negating not just
the last predicate, but the `AND`-ed reachability constraint from last
clause. With this fix, we now record the correct constraints for the
example from #17723:

```py
def _(cond: bool):
    if cond:
        # reachability: [cond]
        if True:
            # reachability: [cond] AND [True]
            pass
        else:
            # reachability: [cond] AND (NOT [True])
            x
```

closes #17723 

## Test Plan

* Regression test.
* Verified the ecosystem changes
2025-04-30 09:32:13 +02:00
Micha Reiser
2bb99df394 [red-knot] Update salsa (#17730) 2025-04-30 08:58:31 +02:00
Dhruv Manilawala
f11d9cb509 [red-knot] Support overloads for callable equivalence (#17698)
## Summary

Part of #15383, this PR adds `is_equivalent_to` support for overloaded
callables.

This is mainly done by delegating it to the subtyping check in that two
types A and B are considered equivalent if A is a subtype of B and B is
a subtype of A.

## Test Plan

Add test cases for overloaded callables in `is_equivalent_to.md`
2025-04-30 02:53:59 +05:30
Alex Waygood
549ab74bd6 [red-knot] Run py-fuzzer in CI to check for new panics (#17719) 2025-04-29 21:19:29 +00:00
Alex Waygood
81fc7d7d3a Upload red-knot binaries in CI on completion of linux tests (#17720) 2025-04-29 22:15:26 +01:00
Victor Hugo Gomes
8c68d30c3a [flake8-use-pathlib] Fix PTH123 false positive when open is passed a file descriptor from a function call (#17705)
## Summary
Includes minor changes to the semantic type inference to help detect the
return type of function call.

Fixes #17691

## Test Plan

Snapshot tests
2025-04-29 16:51:38 -04:00
Alex Waygood
93d6a3567b [red-knot] mdtest.py: Watch for changes in red_knot_vendored and red_knot_test as well as in red_knot_python_semantic (#17718) 2025-04-29 18:27:49 +00:00
Micha Reiser
1d788981cd [red-knot] Capture backtrace in "check-failed" diagnostic (#17641)
Co-authored-by: David Peter <sharkdp@users.noreply.github.com>
2025-04-29 16:58:58 +00:00
Hans
7d46579808 [docs] fix duplicated 'are' in comment for PTH123 rule (#17714) 2025-04-29 17:58:39 +02:00
Alex Waygood
c9a6b1a9d0 [red-knot] Make Type::signatures() exhaustive (#17706) 2025-04-29 15:14:08 +01:00
Hans
9b9d16c3ba [red-knot] colorize concise output diagnostics (#17232) (#17479)
Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Andrew Gallant <andrew@astral.sh>
2025-04-29 16:07:16 +02:00
David Peter
79f8473e51 [red-knot] Assignability of class literals to Callables (#17704)
## Summary

Subtyping was already modeled, but assignability also needs an explicit
branch. Removes 921 ecosystem false positives.

## Test Plan

New Markdown tests.
2025-04-29 15:04:22 +02:00
Douglas Creager
ca4fdf452d Create TypeVarInstance type for legacy typevars (#16538)
We are currently representing type variables using a `KnownInstance`
variant, which wraps a `TypeVarInstance` that contains the information
about the typevar (name, bounds, constraints, default type). We were
previously only constructing that type for PEP 695 typevars. This PR
constructs that type for legacy typevars as well.

It also detects functions that are generic because they use legacy
typevars in their parameter list. With the existing logic for inferring
specializations of function calls (#17301), that means that we are
correctly detecting that the definition of `reveal_type` in the typeshed
is generic, and inferring the correct specialization of `_T` for each
call site.

This does not yet handle legacy generic classes; that will come in a
follow-on PR.
2025-04-29 09:03:06 -04:00
Dylan
3c460a7b9a Make syntax error for unparenthesized except tuples version specific to before 3.14 (#17660)
What it says on the tin 😄
2025-04-29 07:55:30 -05:00
Alex Waygood
31e6576971 [red-knot] micro-optimise ClassLiteral::is_protocol (#17703) 2025-04-29 12:35:53 +00:00
Micha Reiser
c953e7d143 [red-knot] Improve log message for default python platform (#17700) 2025-04-29 08:26:41 +00:00
Vasco Schiavo
5096824793 [ruff] add fix safety section (RUF017) (#17480)
The PR add the `fix safety` section for rule `RUF017` (#15584 )
2025-04-28 22:07:22 +00:00
Dylan
ae7691b026 Add Python 3.14 to configuration options (#17647)
A small PR that just updates the various settings/configurations to
allow Python 3.14. At the moment selecting that target version will
have no impact compared to Python 3.13 - except that a warning
is emitted if the user does so with `preview` disabled.
2025-04-28 16:29:00 -05:00
Wei Lee
504fa20057 [airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR302) (#17553)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Apply auto fixes to cases where the names have changed in Airflow 3 in
AIR302 and split the huge test cases into different test cases based on
proivder

## Test Plan

<!-- How was it tested? -->

the test cases has been split into multiple for easier checking
2025-04-28 16:35:17 -04:00
David Peter
f0868ac0c9 [red-knot] Revert blanket clippy::too_many_arguments allow (#17688)
## Summary

Now that https://github.com/salsa-rs/salsa/issues/808 has been fixed, we
can revert this global change in `Cargo.toml`.
2025-04-28 21:21:53 +02:00
Brent Westbrook
01a31c08f5 Add config option to disable typing_extensions imports (#17611)
Summary
--

This PR resolves https://github.com/astral-sh/ruff/issues/9761 by adding
a linter configuration option to disable
`typing_extensions` imports. As mentioned [here], it would be ideal if
we could
detect whether or not `typing_extensions` is available as a dependency
automatically, but this seems like a much easier fix in the meantime.

The default for the new option, `typing-extensions`, is `true`,
preserving the current behavior. Setting it to `false` will bail out of
the new
`Checker::typing_importer` method, which has been refactored from the 
`Checker::import_from_typing` method in
https://github.com/astral-sh/ruff/pull/17340),
with `None`, which is then handled specially by each rule that calls it.

I considered some alternatives to a config option, such as checking if
`typing_extensions` has been imported or checking for a `TYPE_CHECKING`
block we could use, but I think defaulting to allowing
`typing_extensions` imports and allowing the user to disable this with
an option is both simple to implement and pretty intuitive.

[here]:
https://github.com/astral-sh/ruff/issues/9761#issuecomment-2790492853

Test Plan
--

New linter tests exercising several combinations of Python versions and
the new config option for PYI019. I also added tests for the other
affected rules, but only in the case where the new config option is
enabled. The rules' existing tests also cover the default case.
2025-04-28 14:57:36 -04:00
Andrew Gallant
405878a128 ruff_db: render file paths in diagnostics as relative paths if possible
This is done in what appears to be the same way as Ruff: we get the CWD,
strip the prefix from the path if possible, and use that. If stripping
the prefix fails, then we print the full path as-is.

Fixes #17233
2025-04-28 14:32:34 -04:00
Alex Waygood
80103a179d Bump mypy_primer pin (#17685) 2025-04-28 16:13:07 +00:00
Andrew Gallant
9a8f3cf247 red_knot_python_semantic: improve not-iterable diagnostic
This cleans up one particular TODO by splitting the "because" part of
the `not-iterable` diagnostic out into an info sub-diagnostic.
2025-04-28 11:03:41 -04:00
David Peter
07718f4788 [red-knot] Allow all callables to be assignable to @Todo-signatures (#17680)
## Summary

Removes ~850 diagnostics related to assignability of callable types,
where the callable-being-assigned-to has a "Todo signature", which
should probably accept any left hand side callable/signature.
2025-04-28 16:40:35 +02:00
Dylan
1e8881f9af [refurb] Mark fix as safe for readlines-in-for (FURB129) (#17644)
This PR promotes the fix applicability of [readlines-in-for
(FURB129)](https://docs.astral.sh/ruff/rules/readlines-in-for/#readlines-in-for-furb129)
to always safe.

In the original PR (https://github.com/astral-sh/ruff/pull/9880), the
author marked the rule as unsafe because Ruff's type inference couldn't
quite guarantee that we had an `IOBase` object in hand. Some false
positives were recorded in the test fixture. However, before the PR was
merged, Charlie added the necessary type inference and the false
positives went away.

According to the [Python
documentation](https://docs.python.org/3/library/io.html#io.IOBase), I
believe this fix is safe for any proper implementation of `IOBase`:

>[IOBase](https://docs.python.org/3/library/io.html#io.IOBase) (and its
subclasses) supports the iterator protocol, meaning that an
[IOBase](https://docs.python.org/3/library/io.html#io.IOBase) object can
be iterated over yielding the lines in a stream. Lines are defined
slightly differently depending on whether the stream is a binary stream
(yielding bytes), or a text stream (yielding character strings). See
[readline()](https://docs.python.org/3/library/io.html#io.IOBase.readline)
below.

and then in the [documentation for
`readlines`](https://docs.python.org/3/library/io.html#io.IOBase.readlines):

>Read and return a list of lines from the stream. hint can be specified
to control the number of lines read: no more lines will be read if the
total size (in bytes/characters) of all lines so far exceeds hint. [...]
>Note that it’s already possible to iterate on file objects using for
line in file: ... without calling file.readlines().

I believe that a careful reading of our [versioning
policy](https://docs.astral.sh/ruff/versioning/#version-changes)
requires that this change be deferred to a minor release - but please
correct me if I'm wrong!
2025-04-28 09:39:55 -05:00
Dylan
152a0b6585 Collect preview lint behaviors in separate module (#17646)
This PR collects all behavior gated under preview into a new module
`ruff_linter::preview` that exposes functions like
`is_my_new_feature_enabled` - just as is done in the formatter crate.
2025-04-28 09:12:24 -05:00
Alex Waygood
1ad5015e19 Upgrade Salsa to a more recent commit (#17678) 2025-04-28 13:32:19 +01:00
David Peter
92f95ff494 [red-knot] TypedDict: No errors for introspection dunder attributes (#17677)
## Summary

Do not emit errors when accessing introspection dunder attributes such
as `__required_keys__` on `TypedDict`s.
2025-04-28 13:28:43 +02:00
Victor Hugo Gomes
ceb2bf1168 [flake8-pyi] Ensure Literal[None,] | Literal[None,] is not autofixed to None | None (PYI061) (#17659)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-28 12:23:29 +01:00
David Peter
f521358033 [red-knot] No errors for definitions of TypedDicts (#17674)
## Summary

Do not emit errors when defining `TypedDict`s:

```py
from typing_extensions import TypedDict

# No error here
class Person(TypedDict):
    name: str
    age: int | None

# No error for this alternative syntax
Message = TypedDict("Message", {"id": int, "content": str})
```

## Ecosystem analysis

* Removes ~ 450 false positives for `TypedDict` definitions.
* Changes a few diagnostic messages.
* Adds a few (< 10) false positives, for example:
  ```diff
+ error[lint:unresolved-attribute]
/tmp/mypy_primer/projects/hydra-zen/src/hydra_zen/structured_configs/_utils.py:262:5:
Type `Literal[DataclassOptions]` has no attribute `__required_keys__`
+ error[lint:unresolved-attribute]
/tmp/mypy_primer/projects/hydra-zen/src/hydra_zen/structured_configs/_utils.py:262:42:
Type `Literal[DataclassOptions]` has no attribute `__optional_keys__`
  ```
* New true positive

4f8263cd7f/corporate/lib/remote_billing_util.py (L155-L157)
  ```diff
+ error[lint:invalid-assignment]
/tmp/mypy_primer/projects/zulip/corporate/lib/remote_billing_util.py:155:5:
Object of type `RemoteBillingIdentityDict | LegacyServerIdentityDict |
None` is not assignable to `LegacyServerIdentityDict | None`
  ```

## Test Plan

New Markdown tests
2025-04-28 13:13:28 +02:00
renovate[bot]
74081032d9 Update actions/download-artifact digest to d3f86a1 (#17664)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-28 10:51:59 +00:00
Micha Reiser
dbc137c951 [red-knot] Use 101 exit code when there's at least one diagnostic with severity 'fatal' (#17640) 2025-04-28 10:03:14 +02:00
Victor Hugo Gomes
826b2c9ff3 [pycodestyle] Fix duplicated diagnostic in E712 (#17651) 2025-04-28 08:31:16 +01:00
jie211
a3e55cfd8f [airflow] fix typos AIR312 (#17673) 2025-04-28 08:31:41 +02:00
justin
d2246278e6 [red-knot] Don't ignore hidden files by default (#17655) 2025-04-28 08:21:11 +02:00
renovate[bot]
6bd1863bf0 Update pre-commit hook astral-sh/ruff-pre-commit to v0.11.7 (#17670)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:16:10 +02:00
renovate[bot]
97dc58fc77 Update docker/build-push-action digest to 14487ce (#17665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:15:54 +02:00
renovate[bot]
53a9448fb5 Update taiki-e/install-action digest to ab3728c (#17666)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:15:01 +02:00
renovate[bot]
516291b693 Update dependency react-resizable-panels to v2.1.9 (#17667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:10:24 +02:00
renovate[bot]
b09f00a4ef Update dependency ruff to v0.11.7 (#17668)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:09:50 +02:00
renovate[bot]
03065c245c Update dependency smol-toml to v1.3.4 (#17669)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:09:33 +02:00
renovate[bot]
b45598389d Update Rust crate jiff to v0.2.10 (#17671)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:09:10 +02:00
renovate[bot]
4729ff2bc8 Update Rust crate syn to v2.0.101 (#17672)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-28 08:08:41 +02:00
Micha Reiser
1bdb22c139 [red-knot] Fix offset handling in playground for 2-code-point UTF16 characters (#17520) 2025-04-27 11:44:55 +01:00
Micha Reiser
1c65e0ad25 Split SourceLocation into LineColumn and SourceLocation (#17587) 2025-04-27 11:27:33 +01:00
justin
4443f6653c [red-knot] Add --respect-ignore-files flag (#17645)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-04-27 10:55:41 +01:00
Vasco Schiavo
b0d475f353 [ruff] add fix safety section (RUF027) (#17485)
The PR add the `fix safety` section for rule `RUF027` (#15584 ).

Actually, I have an example of a false positive. Should I include it in
the` fix safety` section?

---------

Co-authored-by: Dylan <dylwil3@gmail.com>
2025-04-26 16:43:53 -05:00
Vasco Schiavo
b578a828ef [ruff] add fix safety section (RUF005) (#17484)
The PR add the `fix safety` section for rule `RUF005` (#15584 ).

---------

Co-authored-by: Dylan <dylwil3@gmail.com>
2025-04-26 16:43:02 -05:00
Vasco Schiavo
64ba39a385 [flynt] add fix safety section (FLY002) (#17496)
The PR add the fix safety section for rule `FLY002` (#15584 )

The motivation for the content of the fix safety section is given by the
following example

```python
foo = 1
bar = [2, 3]

try:
    result_join = " ".join((foo, bar))
    print(f"Join result: {result_join}")
except TypeError as e:
    print(f"Join error: {e}")
```

which print `Join error: sequence item 0: expected str instance, int
found`

But after the fix is applied, we have

```python
foo = 1
bar = [2, 3]

try:
    result_join = f"{foo} {bar}"
    print(f"Join result: {result_join}")
except TypeError as e:
    print(f"Join error: {e}")
```

which print `Join result: 1 [2, 3]`

---------

Co-authored-by: dylwil3 <dylwil3@gmail.com>
2025-04-26 16:00:01 +00:00
Hans
a4e225ee8a [flake8-async] Add fix safety section (ASYNC116) (#17497)
## Summary

This PR add the `fix safety` section for rule `ASYNC116` in
`long_sleep_not_forever.rs` for #15584

---------

Co-authored-by: dylwil3 <dylwil3@gmail.com>
2025-04-26 10:40:51 -05:00
Vasco Schiavo
45d0634b01 [pydocstyle] add fix safety section (D200) (#17502)
The PR add the fix safety section for rule `D200` (#15584 )
2025-04-26 08:59:05 -05:00
Vasco Schiavo
4bcf1778fa [ruff] add fix safety section (RUF057) (#17483)
The PR add the `fix safety` section for rule `RUF057` (#15584 )
2025-04-26 06:58:52 -05:00
Micha Reiser
6044f04137 Revert "[red-knot] Add --respect-ignore-files flag (#17569)" (#17642) 2025-04-26 10:30:50 +00:00
justin
2e95475f57 [red-knot] Add --respect-ignore-files flag (#17569)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-04-26 10:02:03 +00:00
Micha Reiser
cfa1505068 [red-knot] Fix CLI hang when a dependent query panics (#17631) 2025-04-26 06:28:45 +00:00
Dhruv Manilawala
0251679f87 [red-knot] Add new property tests for subtyping with "bottom" callable (#17635)
## Summary

I remember we discussed about adding this as a property tests so here I
am.

## Test Plan

```console
❯ QUICKCHECK_TESTS=10000000 cargo test --locked --release --package red_knot_python_semantic -- --ignored types::property_tests::stable::bottom_callable_is_subtype_of_all_fully_static_callable
    Finished `release` profile [optimized] target(s) in 0.10s
     Running unittests src/lib.rs (target/release/deps/red_knot_python_semantic-e41596ca2dbd0e98)
running 1 test
test types::property_tests::stable::bottom_callable_is_subtype_of_all_fully_static_callable ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 233 filtered out; finished in 30.91s
```
2025-04-26 03:58:13 +05:30
Douglas Creager
6ab32a7746 [red-knot] Create generic context for generic classes lazily (#17617)
As discussed today, this is needed to handle legacy generic classes
without having to infer the types of the class's explicit bases eagerly
at class construction time. Pulling this out into a separate PR so
there's a smaller diff to review.

This also makes our representation of generic classes and functions more
consistent — before, we had separate Rust types and enum variants for
generic/non-generic classes, but a single type for generic functions.
Now we each a single (respective) type for each.

There were very few places we were differentiation between generic and
non-generic _class literals_, and these are handled now by calling the
(salsa cached) `generic_context` _accessor function_.

Note that _`ClassType`_ is still an enum with distinct variants for
non-generic classes and specialized generic classes.
2025-04-25 14:10:03 -04:00
Andrew Gallant
bc0a5aa409 ruff_db: add tests for annotations with no ranges
... and fix the case where an annotation with a `Span` but no
`TextRange` or message gets completely dropped.
2025-04-25 13:25:20 -04:00
Wei Lee
aba21a5d47 [airflow] Extend AIR301 rule (#17598)
## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Add "airflow.operators.python.get_current_context" →
"airflow.sdk.get_current_context" rule

## Test Plan

<!-- How was it tested? -->

the test fixture has been updated accordingly
2025-04-25 12:49:32 -04:00
Wei Lee
b6281a8805 [airflow] update existing AIR302 rules with better suggestions (#17542)
## Summary

Even though the original suggestion works, they've been removed in later
version and is no longer the best practices.

e.g., many sql realted operators have been removed and are now suggested
to use SQLExecuteQueryOperator instead

## Test Plan

The existing test fixtures have been updated
2025-04-25 12:44:28 -04:00
Andrew Gallant
049280a3bc red_knot_project: sort diagnostics from checking files
Previously, we could iterate over files in an unspecified order (via
`HashSet` iteration) and we could accumulate diagnostics from files in
an unspecified order (via parallelism).

Here, we change the status quo so that diagnostics collected from files
are sorted after checking is complete. For now, we sort by severity
(with higher severity diagnostics appearing first) and then by
diagnostic ID to give a stable ordering.

I'm not sure if this is the best ordering.
2025-04-25 12:38:31 -04:00
Carl Meyer
fa88989ef0 [red-knot] fix detecting a metaclass on a not-explicitly-specialized generic base (#17621)
## Summary

After https://github.com/astral-sh/ruff/pull/17620 (which this PR is
based on), I was looking at other call sites of `Type::into_class_type`,
and I began to feel that _all_ of them were currently buggy due to
silently skipping unspecialized generic class literal types (though in
some cases the bug hadn't shown up yet because we don't understand
legacy generic classes from typeshed), and in every case they would be
better off if an unspecialized generic class literal were implicitly
specialized with the default specialization (which is the usual Python
typing semantics for an unspecialized reference to a generic class),
instead of silently skipped.

So I changed the method to implicitly apply the default specialization,
and added a test that previously failed for detecting metaclasses on an
unspecialized generic base.

I also renamed the method to `to_class_type`, because I feel we have a
strong naming convention where `Type::into_foo` is always a trivial
`const fn` that simply returns `Some()` if the type is of variant `Foo`
and `None` otherwise. Even the existing method (with it handling both
`GenericAlias` and `ClassLiteral`, and distinguishing kinds of
`ClassLiteral`) was stretching this convention, and the new version
definitely breaks that envelope.

## Test Plan

Added a test that failed before this PR.
2025-04-25 06:55:54 -07:00
Carl Meyer
4c3f389598 [red-knot] fix inheritance-cycle detection for generic classes (#17620)
## Summary

The `ClassLiteralType::inheritance_cycle` method is intended to detect
inheritance cycles that would result in cyclic MROs, emit a diagnostic,
and skip actually trying to create the cyclic MRO, falling back to an
"error" MRO instead with just `Unknown` and `object`.

This method didn't work properly for generic classes. It used
`fully_static_explicit_bases`, which filter-maps `explicit_bases` over
`Type::into_class_type`, which returns `None` for an unspecialized
generic class literal. So in a case like `class C[T](C): ...`, because
the explicit base is an unspecialized generic, we just skipped it, and
failed to detect the class as cyclically defined.

Instead, iterate directly over all `explicit_bases`, and explicitly
handle both the specialized (`GenericAlias`) and unspecialized
(`ClassLiteral`) cases, so that we check all bases and correctly detect
cyclic inheritance.

## Test Plan

Added mdtests.
2025-04-25 06:55:00 -07:00
Brent Westbrook
6d3b1d13d6 [pylint] Detect global declarations in module scope (PLE0118) (#17411)
Summary
--

While going through the syntax errors in [this comment], I was surprised
to see the error `name 'x' is assigned to before global declaration`,
which corresponds to [load-before-global-declaration (PLE0118)] and has
also been reimplemented as a syntax error (#17135). However, it looks
like neither of the implementations consider `global` declarations in
the top-level module scope, which is a syntax error in CPython:

```python
# try.py
x = None
global x
```

```shell
> python -m compileall -f try.py
Compiling 'try.py'...
***   File "try.py", line 2
    global x
    ^^^^^^^^
SyntaxError: name 'x' is assigned to before global declaration
```

I'm not sure this is the best or most elegant solution, but it was a
quick fix that passed all of our tests.

Test Plan
--

New PLE0118 test case.

[this comment]:
https://github.com/astral-sh/ruff/issues/7633#issuecomment-1740424031
[load-before-global-declaration (PLE0118)]:
https://docs.astral.sh/ruff/rules/load-before-global-declaration/#load-before-global-declaration-ple0118
2025-04-25 08:37:16 -04:00
Max Mynter
3f84e75e20 Add Semantic Error Test for LateFutureImport (#17612)
Adresses a question in #17526.

## Summary
Adds a syntax error test for `__future__` import not at top of file. 

## Question: 
Is this a redundant with
8d2c79276d/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_0.py (L1-L8)
and
8d2c79276d/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_1.py (L1-L5)

which test pyflake `F404`?
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
This is a test
<!-- How was it tested? -->
2025-04-25 08:32:57 -04:00
Carl Meyer
afc18ff1a1 [red-knot] change TypeVarInstance to be interned, not tracked (#17616)
## Summary

Tracked structs have some issues with fixpoint iteration in Salsa, and
there's not actually any need for this to be tracked, it should be
interned like most of our type structs.

The removed comment was probably never correct (in that we could have
disambiguated sufficiently), and is definitely not relevant now that
`TypeVarInstance` also holds its `Definition`.

## Test Plan

Existing tests.
2025-04-24 14:52:25 -07:00
Dhruv Manilawala
f1a539dac6 [red-knot] Special case @final, @override (#17608)
## Summary

This PR adds special-casing for `@final` and `@override` decorator for a
similar reason as https://github.com/astral-sh/ruff/pull/17591 to
support the invalid overload check.

Both `final` and `override` are identity functions which can be removed
once `TypeVar` support is added.
2025-04-25 03:15:23 +05:30
Carl Meyer
ef0343189c [red-knot] add TODO comment in specialization code (#17615)
## Summary

As promised, this just adds a TODO comment to document something we
discussed today that should probably be improved at some point, but
isn't a priority right now (since it's an issue that in practice would
only affect generic classes with both `__init__` and `__new__` methods,
where some typevar is bound to `Unknown` in one and to some other type
in another.)
2025-04-24 14:41:19 -07:00
Vasco Schiavo
4eecc40110 [semantic-syntax-errors] test for LoadBeforeGlobalDeclaration - ruff linter (#17592)
Hey @ntBre 

just one easy case to see if I understood the issue #17526 

Let me know if is this what you had in mind.
2025-04-24 16:14:33 -04:00
Abhijeet Prasad Bodas
cf59cee928 [syntax-errors] nonlocal declaration at module level (#17559)
## Summary

Part of #17412

Add a new compile-time syntax error for detecting `nonlocal`
declarations at a module level.

## Test Plan

- Added new inline tests for the syntax error
- Updated existing tests for `nonlocal` statement parsing to be inside a
function scope

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2025-04-24 16:11:46 -04:00
Wei Lee
538393d1f3 [airflow] Apply auto fix to cases where name has been changed in Airflow 3 (AIR311) (#17571)
## Summary

Apply auto fix to cases where the name has been changed in Airflow 3
(`AIR311`)

## Test Plan

The test features has been updated
2025-04-24 15:48:54 -04:00
Brent Westbrook
92ecfc908b [syntax-errors] Make async-comprehension-in-sync-comprehension more specific (#17460)
## Summary

While adding semantic error support to red-knot, I noticed duplicate
diagnostics for code like this:

```py
# error: [invalid-syntax] "cannot use an asynchronous comprehension outside of an asynchronous function on Python 3.9 (syntax was added in 3.11)"
# error: [invalid-syntax] "`asynchronous comprehension` outside of an asynchronous function"
 [reveal_type(x) async for x in AsyncIterable()]
```

Beyond the duplication, the first error message doesn't make much sense
because this syntax is _not_ allowed on Python 3.11 either.

To fix this, this PR renames the
`async-comprehension-outside-async-function` semantic syntax error to
`async-comprehension-in-sync-comprehension` and fixes the rule to avoid
applying outside of sync comprehensions at all.

## Test Plan

New linter test demonstrating the false positive. The mdtests from my red-knot 
PR also reflect this change.
2025-04-24 15:45:54 -04:00
Dylan
f7b48510b5 Bump 0.11.7 (#17613) 2025-04-24 13:06:38 -05:00
Dhruv Manilawala
9937064761 [red-knot] Use iterative approach to collect overloads (#17607)
## Summary

This PR updates the `to_overloaded` method to use an iterative approach
instead of a recursive one.

Refer to
https://github.com/astral-sh/ruff/pull/17585#discussion_r2056804587 for
context.

The main benefit here is that it avoids calling the `to_overloaded`
function in a recursive manner which is a salsa query. So, this is a bit
hand wavy but we should also see less memory used because the cache will
only contain a single entry which should be the entire overload chain.
Previously, the recursive approach would mean that each of the function
involved in an overload chain would have a cache entry. This reduce in
memory shouldn't be too much and I haven't looked at the actual data for
it.

## Test Plan

Existing test cases should pass.
2025-04-24 22:23:50 +05:30
Andrew Gallant
8d2c79276d red_knot_python_semantic: avoid Rust's screaming snake case convention in mdtest 2025-04-24 11:43:01 -04:00
Andrew Gallant
0f47810768 red_knot_python_semantic: improve diagnostics for unsupported boolean conversions
This mostly only improves things for incorrect arguments and for an
incorrect return type. It doesn't do much to improve the case where
`__bool__` isn't callable and leaves the union/other cases untouched
completely.

I picked this one because, at first glance, this _looked_ like a lower
hanging fruit. The conceptual improvement here is pretty
straight-forward: add annotations for relevant data. But it took me a
bit to figure out how to connect all of the pieces.
2025-04-24 11:43:01 -04:00
Andrew Gallant
eb1d2518c1 red_knot_python_semantic: add "return type span" helper method
This is very similar to querying for the span of a parameter
in a function definition, but instead we look for the span of
a return type.
2025-04-24 11:43:01 -04:00
Andrew Gallant
a45a0a92bd red_knot_python_semantic: move parameter span helper method
I wanted to use this method in other places, so I moved it
to what appears to be a God-type. I also made it slightly
more versatile: callers can ask for the entire parameter list
by omitting a specific parameter index.
2025-04-24 11:43:01 -04:00
Andrew Gallant
43bd043755 ruff_db: add a From impl for FileRange to Span
These types are almost equivalent. The only difference
is that a `Span`'s range is optional.
2025-04-24 11:43:01 -04:00
Andrew Gallant
9a54ee3a1c red_knot_python_semantic: add snapshot tests for unsupported boolean conversions
This just captures the status quo before we try to improve them.
2025-04-24 11:43:01 -04:00
Carl Meyer
25c3be51d2 [red-knot] simplify != narrowing (#17610)
## Summary

Follow-up from review comment in
https://github.com/astral-sh/ruff/pull/17567#discussion_r2058649527

## Test Plan

Existing tests.
2025-04-24 15:11:45 +00:00
Matthew Mckee
e71f3ed2c5 [red-knot] Update == and != narrowing (#17567)
## Summary

Historically we have avoided narrowing on `==` tests because in many
cases it's unsound, since subclasses of a type could compare equal to
who-knows-what. But there are a lot of types (literals and unions of
them, as well as some known instances like `None` -- single-valued
types) whose `__eq__` behavior we know, and which we can safely narrow
away based on equality comparisons.

This PR implements equality narrowing in the cases where it is sound.
The most elegant way to do this (and the way that is most in-line with
our approach up until now) would be to introduce new Type variants
`NeverEqualTo[...]` and `AlwaysEqualTo[...]`, and then implement all
type relations for those variants, narrow by intersection, and let union
and intersection simplification sort it all out. This is analogous to
our existing handling for `AlwaysFalse` and `AlwaysTrue`.

But I'm reluctant to add new `Type` variants for this, mostly because
they could end up un-simplified in some types and make types even more
complex. So let's try this approach, where we handle more of the
narrowing logic as a special case.

## Test Plan

Updated and added tests.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
Co-authored-by: Carl Meyer <carl@oddbird.net>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-24 07:56:39 -07:00
Carl Meyer
ac6219ec38 [red-knot] fix collapsing literal and its negation to object (#17605)
## Summary

Another follow-up to the unions-of-large-literals optimization. Restore
the behavior that e.g. `Literal[""] | ~Literal[""]` collapses to
`object`.

## Test Plan

Added mdtests.
2025-04-24 13:55:05 +00:00
Alex Waygood
e93fa7062c [red-knot] Add more tests for protocols (#17603) 2025-04-24 13:11:31 +01:00
Alex Waygood
21fd28d713 [red-knot] Ban direct instantiations of Protocol classes (#17597) 2025-04-24 09:31:35 +00:00
Max Mynter
a01f25107a [pyupgrade] Preserve parenthesis when fixing native literals containing newlines (UP018) (#17220) 2025-04-24 08:48:02 +02:00
camper42
48a85c4ed4 [airflow] fix typos (AIR302, AIR312) (#17574) 2025-04-24 08:06:32 +02:00
Dhruv Manilawala
1796ca97d5 [red-knot] Special case @abstractmethod for function type (#17591)
## Summary

This is required because otherwise the inferred type is not going to be
`Type::FunctionLiteral` but a todo type because we don't recognize
`TypeVar` yet:

```py
_FuncT = TypeVar("_FuncT", bound=Callable[..., Any])

def abstractmethod(funcobj: _FuncT) -> _FuncT: ...
```

This is mainly required to raise diagnostic when only some (and not all)
`@overload`-ed functions are decorated with `@abstractmethod`.
2025-04-24 03:54:52 +05:30
Alex Waygood
e897f37911 [red-knot] Emit diagnostics for isinstance() and issubclass() calls where a non-runtime-checkable protocol is the second argument (#17561) 2025-04-23 21:40:23 +00:00
Alex Waygood
00e73dc331 [red-knot] Infer the members of a protocol class (#17556) 2025-04-23 21:36:12 +00:00
Dhruv Manilawala
7b6222700b [red-knot] Add FunctionType::to_overloaded (#17585)
## Summary

This PR adds a new method `FunctionType::to_overloaded` which converts a
`FunctionType` into an `OverloadedFunction` which contains all the
`@overload`-ed `FunctionType` and the implementation `FunctionType` if
it exists.

There's a big caveat here (it's the way overloads work) which is that
this method can only "see" all the overloads that comes _before_ itself.
Consider the following example:

```py
from typing import overload

@overload
def foo() -> None: ...
@overload
def foo(x: int) -> int: ...
def foo(x: int | None) -> int | None:
	return x
```

Here, when the `to_overloaded` method is invoked on the
1. first `foo` definition, it would only contain a single overload which
is itself and no implementation.
2. second `foo` definition, it would contain both overloads and still no
implementation
3. third `foo` definition, it would contain both overloads and the
implementation which is itself

### Usages

This method will be used in the logic for checking invalid overload
usages. It can also be used for #17541.

## Test Plan

Make sure that existing tests pass.
2025-04-24 02:57:05 +05:30
Brent Westbrook
bfc1650198 [red-knot] Add mdtests for global statement (#17563)
## Summary

This is a first step toward `global` support in red-knot (#15385). I
went through all the matches for `global` in the `mypy/test-data`
directory, but I didn't find anything too interesting that wasn't
already covered by @carljm's suggestions on Discord. I still pulled in a
couple of cases for a little extra variety. I also included a section
from the
[PLE0118](https://docs.astral.sh/ruff/rules/load-before-global-declaration/)
tests in ruff that will become syntax errors once #17463 is merged and
we handle `global` statements.

I don't think I figured out how to use `@Todo` properly, so please let
me know if I need to fix that. I hope this is a good start to the test
suite otherwise.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-04-23 17:18:42 -04:00
Brent Westbrook
d5410ef9fe [syntax-errors] Make duplicate parameter names a semantic error (#17131)
Status
--

This is a pretty minor change, but it was breaking a red-knot mdtest
until #17463 landed. Now this should close #11934 as the last syntax
error being tracked there!

Summary
--

Moves `Parser::validate_parameters` to
`SemanticSyntaxChecker::duplicate_parameter_name`.

Test Plan
--

Existing tests, with `## Errors` replaced with `## Semantic Syntax
Errors`.
2025-04-23 15:45:51 -04:00
Douglas Creager
9db63fc58c [red-knot] Handle generic constructors of generic classes (#17552)
We now handle generic constructor methods on generic classes correctly:

```py
class C[T]:
    def __init__[S](self, t: T, s: S): ...

x = C(1, "str")
```

Here, constructing `C` requires us to infer a specialization for the
generic contexts of `C` and `__init__` at the same time.

At first I thought I would need to track the full stack of nested
generic contexts here (since the `[S]` context is nested within the
`[T]` context). But I think this is the only way that we might need to
specialize more than one generic context at once — in all other cases, a
containing generic context must be specialized before we get to a nested
one, and so we can just special-case this.

While we're here, we also construct the generic context for a generic
function lazily, when its signature is accessed, instead of eagerly when
inferring the function body.
2025-04-23 15:06:18 -04:00
David Peter
61e73481fe [red-knot] Assignability of class instances to Callable (#17590)
## Summary

Model assignability of class instances with a `__call__` method to
`Callable` types. This should solve some false positives related to
`functools.partial` (yes, 1098 fewer diagnostics!).

Reference:
https://github.com/astral-sh/ruff/issues/17343#issuecomment-2824618483

## Test Plan

New Markdown tests.
2025-04-23 20:34:13 +02:00
David Peter
e170fe493d [red-knot] Trust all symbols in stub files (#17588)
## Summary

*Generally* trust undeclared symbols in stubs, not just at the module
level.

Follow-up on the discussion
[here](https://github.com/astral-sh/ruff/pull/17577#discussion_r2055945909).

## Test Plan

New Markdown test.
2025-04-23 20:07:29 +02:00
David Peter
e91e2f49db [red-knot] Trust module-level undeclared symbols in stubs (#17577)
## Summary

Many symbols in typeshed are defined without being declared. For
example:
```pyi
# builtins:
IOError = OSError

# types
LambdaType = FunctionType
NotImplementedType = _NotImplementedType

# typing
Text = str

# random
uniform = _inst.uniform

# optparse
make_option = Option

# all over the place:
_T = TypeVar("_T")
```

Here, we introduce a change that skips widening the public type of these
symbols (by unioning with `Unknown`).

fixes #17032

## Ecosystem analysis

This is difficult to analyze in detail, but I went over most changes and
it looks very favorable to me overall. The diff on the overall numbers
is:
```
errors: 1287 -> 859 (reduction by 428)
warnings: 45 -> 59 (increase by 14)
```

### Removed false positives

`invalid-base` examples:

```diff
- error[lint:invalid-base] /tmp/mypy_primer/projects/pip/src/pip/_vendor/rich/console.py:548:27: Invalid class base with type `Unknown | Literal[_local]` (all bases must be a class, `Any`, `Unknown` or `Todo`)
- error[lint:invalid-base] /tmp/mypy_primer/projects/tornado/tornado/iostream.py:84:25: Invalid class base with type `Unknown | Literal[OSError]` (all bases must be a class, `Any`, `Unknown` or `Todo`)
- error[lint:invalid-base] /tmp/mypy_primer/projects/mitmproxy/test/conftest.py:35:40: Invalid class base with type `Unknown | Literal[_UnixDefaultEventLoopPolicy]` (all bases must be a class, `Any`, `Unknown` or `Todo`)
```

`invalid-exception-caught` examples:

```diff
- error[lint:invalid-exception-caught] /tmp/mypy_primer/projects/cloud-init/cloudinit/cmd/status.py:334:16: Cannot catch object of type `Literal[ProcessExecutionError]` in an exception handler (must be a `BaseException` subclass or a tuple of `BaseException` subclasses)
- error[lint:invalid-exception-caught] /tmp/mypy_primer/projects/jinja/src/jinja2/loaders.py:537:16: Cannot catch object of type `Literal[TemplateNotFound]` in an exception handler (must be a `BaseException` subclass or a tuple of `BaseException` subclasses)
```

`unresolved-reference` examples


7a0265d36e/cloudinit/handlers/jinja_template.py (L120-L123)
(we now understand the `isinstance` narrowing)

```diff
- error[lint:unresolved-attribute] /tmp/mypy_primer/projects/cloud-init/cloudinit/handlers/jinja_template.py:123:16: Type `Exception` has no attribute `errno`
```

`unknown-argument` examples


https://github.com/hauntsaninja/boostedblob/blob/master/boostedblob/request.py#L53

```diff
- error[lint:unknown-argument] /tmp/mypy_primer/projects/boostedblob/boostedblob/request.py:53:17: Argument `connect` does not match any known parameter of bound method `__init__`
```

`unknown-argument`

There are a lot of `__init__`-related changes because we now understand
[`@attr.s`](3d42a6978a/src/attr/__init__.pyi (L387))
as a `@dataclass_transform` annotated symbol. For example:

```diff
- error[lint:unknown-argument] /tmp/mypy_primer/projects/attrs/tests/test_hooks.py:72:18: Argument `x` does not match any known parameter of bound method `__init__`
```

### New false positives

This can happen if a symbol that previously was inferred as `X |
Unknown` was assigned-to, but we don't yet understand the assignability
to `X`:


https://github.com/strawberry-graphql/strawberry/blob/main/strawberry/exceptions/handler.py#L90

```diff
+ error[lint:invalid-assignment] /tmp/mypy_primer/projects/strawberry/strawberry/exceptions/handler.py:90:9: Object of type `def strawberry_threading_exception_handler(args: tuple[type[BaseException], BaseException | None, TracebackType | None, Thread | None]) -> None` is not assignable to attribute `excepthook` of type `(_ExceptHookArgs, /) -> Any`
```

### New true positives


6bbb5519fe/tests/tracer/test_span.py (L714)

```diff
+ error[lint:invalid-argument-type] /tmp/mypy_primer/projects/dd-trace-py/tests/tracer/test_span.py:714:33: Argument to this function is incorrect: Expected `str`, found `Literal[b"\xf0\x9f\xa4\x94"]`
```

### Changed diagnostics

A lot of changed diagnostics because we now show `@Todo(Support for
`typing.TypeVar` instances in type expressions)` instead of `Unknown`
for all kinds of symbols that used a `_T = TypeVar("_T")` as a type. One
prominent example is the `list.__getitem__` method:

`builtins.pyi`:
```pyi
_T = TypeVar("_T")  # previously `TypeVar | Unknown`, now just `TypeVar`

# …

class list(MutableSequence[_T]):
    # …
    @overload
    def __getitem__(self, i: SupportsIndex, /) -> _T: ...
    # …
```

which causes this change in diagnostics:
```py
xs = [1, 2]
reveal_type(xs[0])  # previously `Unknown`, now `@Todo(Support for `typing.TypeVar` instances in type expressions)`
```

## Test Plan

Updated Markdown tests
2025-04-23 19:31:14 +02:00
Wei Lee
b537552927 [airflow] Apply auto fixes to cases where the names have changed in Airflow 3 (AIR301) (#17355)
## Summary

Apply auto fixes to cases where the names have changed in Airflow 3

## Test Plan

Add `AIR301_names_fix.py` and `AIR301_provider_names_fix.py` test fixtures
2025-04-23 12:43:41 -04:00
Navdeep K
5a719f2d60 [pycodestyle] Auto-fix redundant boolean comparison (E712) (#17090)
This pull request fixes https://github.com/astral-sh/ruff/issues/17014

changes this
```python
from __future__ import annotations

flag1 = True
flag2 = True

if flag1 == True or flag2 == True:
    pass

if flag1 == False and flag2 == False:
    pass

flag3 = True
if flag1 == flag3 and (flag2 == False or flag3 == True):  # Should become: if flag1==flag3 and (not flag2 or flag3)
    pass

if flag1 == True and (flag2 == False or not flag3 == True):  # Should become: if flag1 and (not flag2 or not flag3)
    pass

if flag1 != True and (flag2 != False or not flag3 == True):  # Should become: if not flag1 and (flag2 or not flag3)
    pass


flag = True
while flag == True:  # Should become: while flag
    flag = False

flag = True
x = 5
if flag == True and x > 0:  # Should become: if flag and x > 0
    print("ok")

flag = True
result = "yes" if flag == True else "no"  # Should become: result = "yes" if flag else "no"

x = flag == True < 5

x = (flag == True) == False < 5
```

to this 
```python
from __future__ import annotations

flag1 = True
flag2 = True

if flag1 or flag2:
    pass

if not flag1 and not flag2:
    pass

flag3 = True
if flag1 == flag3 and (not flag2 or flag3):  # Should become: if flag1 == flag3 and (not flag2 or flag3)
    pass

if flag1 and (not flag2 or not flag3):  # Should become: if flag1 and (not flag2 or not flag3)
    pass

if not flag1 and (flag2 or not flag3):  # Should become: if not flag1 and (flag2 or not flag3)
    pass


flag = True
while flag:  # Should become: while flag
    flag = False

flag = True
x = 5
if flag and x > 0:  # Should become: if flag and x > 0
    print("ok")

flag = True
result = "yes" if flag else "no"  # Should become: result = "yes" if flag else "no"

x = flag is True < 5

x = (flag) is False < 5
```

---------

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
2025-04-23 11:49:20 -04:00
Brent Westbrook
e7f38fe74b [red-knot] Detect semantic syntax errors (#17463)
Summary
--

This PR extends semantic syntax error detection to red-knot. The main
changes here are:

1. Adding `SemanticSyntaxChecker` and `Vec<SemanticSyntaxError>` fields
to the `SemanticIndexBuilder`
2. Calling `SemanticSyntaxChecker::visit_stmt` and `visit_expr` in the
`SemanticIndexBuilder`'s `visit_stmt` and `visit_expr` methods
3. Implementing `SemanticSyntaxContext` for `SemanticIndexBuilder`
4. Adding new mdtests to test the context implementation and show
diagnostics

(3) is definitely the trickiest and required (I think) a minor addition
to the `SemanticIndexBuilder`. I tried to look around for existing code
performing the necessary checks, but I definitely could have missed
something or misused the existing code even when I found it.

There's still one TODO around `global` statement handling. I don't think
there's an existing way to look this up, but I'm happy to work on that
here or in a separate PR. This currently only affects detection of one
error (`LoadBeforeGlobalDeclaration` or
[PLE0118](https://docs.astral.sh/ruff/rules/load-before-global-declaration/)
in ruff), so it's not too big of a problem even if we leave the TODO.

Test Plan
--

New mdtests, as well as new errors for existing mdtests

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-23 09:52:58 -04:00
Micha Reiser
624f5c6c22 Fix stale diagnostics in Ruff playground (#17583) 2025-04-23 15:47:54 +02:00
Micha Reiser
8abf93f5fb [red-knot] Early return from project.is_file_open for vendored files (#17580) 2025-04-23 15:32:41 +02:00
Micha Reiser
5407249467 [red-knot] Make BoundMethodType a salsa interned (#17581) 2025-04-23 15:11:20 +02:00
Alex Waygood
0a1f9d090e [red-knot] Emit a diagnostic if a non-protocol is passed to get_protocol_members (#17551) 2025-04-23 10:13:20 +00:00
Alex Waygood
f9c7908bb7 [red-knot] Add more tests for protocol members (#17550) 2025-04-23 11:03:52 +01:00
David Peter
99fa850e53 [red-knot] Assignability for subclasses of Any and Unknown (#17557)
## Summary

Allow (instances of) subclasses of `Any` and `Unknown` to be assignable
to (instances of) other classes, unless they are final. This allows us
to get rid of ~1000 false positives, mostly when mock-objects like
`unittest.mock.MagicMock` are assigned to various targets.

## Test Plan

Adapted and new Markdown tests.
2025-04-23 11:37:30 +02:00
David Peter
a241321735 [red-knot] mypy_primer: add strawberry, print compilation errors to stderr (#17578)
## Summary

mypy_primer changes included here:
ebaa9fd27b..4c22d192a4

- Add strawberry as a `good.txt` project (was previously included in our
fork)
- Print Red Knot compilation errors to stderr (thanks @MichaReiser)
2025-04-23 10:57:11 +02:00
David Peter
b1b8ca3bcd [red-knot] GenericAlias instances as a base class (#17575)
## Summary

We currently emit a diagnostic for code like the following:
```py
from typing import Any

# error: Invalid class base with type `GenericAlias` (all bases must be a class, `Any`, `Unknown` or `Todo`)
class C(tuple[Any, ...]): ...
```

The changeset here silences this diagnostic by recognizing instances of
`GenericAlias` in `ClassBase::try_from_type`, and inferring a `@Todo`
type for them. This is a change in preparation for #17557, because `C`
previously had `Unknown` in its MRO …
```py
reveal_type(C.__mro__)  # tuple[Literal[C], Unknown, Literal[object]]
```
… which would cause us to think that `C` is assignable to everything.

The changeset also removes some false positive `invalid-base`
diagnostics across the ecosystem.

## Test Plan

Updated Markdown tests.
2025-04-23 10:39:10 +02:00
Shaygan Hooshyari
3fae176345 Remove redundant type_to_visitor_function entries (#17564) 2025-04-23 09:27:00 +02:00
David Salvisberg
f36262d970 Fixes how the checker visits typing.cast/typing.NewType arguments (#17538) 2025-04-23 09:26:00 +02:00
Matthew Mckee
e45f23b0ec [red-knot] Class literal __new__ function callable subtyping (#17533)
## Summary

From
https://typing.python.org/en/latest/spec/constructors.html#converting-a-constructor-to-callable

this covers step 2 and partially step 3 (always respecting the
`__new__`)

## Test Plan

Update is_subtype_of.md

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-04-22 22:40:33 -07:00
Matthew Mckee
aa46047649 [red-knot] Surround intersections with () in potentially ambiguous contexts (#17568)
## Summary

Add parentheses to multi-element intersections, when displayed in a
context that's otherwise potentially ambiguous.

## Test Plan

Update mdtest files

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-04-23 04:18:20 +00:00
Brent Westbrook
f9da115fdc [minor] Delete outdated TODO comment (#17565)
Summary
--

Delete a TODO I left that was handled in the last minor release
(#16125).

Test Plan
--

N/a
2025-04-22 20:23:08 +00:00
Carl Meyer
3872d57463 [red-knot] add regression test for fixed cycle panic (#17535)
Add a regression test for the cycle documented in
https://github.com/astral-sh/ruff/issues/14767, which no longer panics
(or even causes a cycle at all.)

Fixes https://github.com/astral-sh/ruff/issues/14767
2025-04-22 09:20:53 -07:00
Carl Meyer
27ada26ddb [red-knot] fix unions of literals, again (#17534)
## Summary

#17451 was incomplete. `AlwaysFalsy` and `AlwaysTruthy` are not the only
two types that are super-types of some literals (of a given kind) and
not others. That set also includes intersections containing
`AlwaysTruthy` or `AlwaysFalsy`, and intersections containing literal
types of the same kind. Cover these cases as well.

Fixes #17478.

## Test Plan

Added mdtests.

`QUICKCHECK_TESTS=1000000 cargo test -p red_knot_python_semantic --
--ignored types::property_tests::stable` failed on both
`all_fully_static_type_pairs_are_subtypes_of_their_union` and
`all_type_pairs_are_assignable_to_their_union` prior to this PR, passes
after it.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-04-22 16:12:52 +00:00
Andrew Gallant
810478f68b red_knot_python_semantic: remove last vestige of old diagnostics! 2025-04-22 12:08:03 -04:00
Andrew Gallant
17f799424a red_knot_python_semantic: migrate types to new diagnostics 2025-04-22 12:08:03 -04:00
Andrew Gallant
c12640fea8 red_knot_python_semantic: migrate types/diagnostic to new diagnostics 2025-04-22 12:08:03 -04:00
Andrew Gallant
3796b13ea2 red_knot_python_semantic: migrate types/call/bind to new diagnostics 2025-04-22 12:08:03 -04:00
Andrew Gallant
ad5a659f29 red_knot_python_semantic: migrate types/string_annotation to new diagnostics 2025-04-22 12:08:03 -04:00
Andrew Gallant
27a377f077 red_knot_python_semantic: migrate types/infer to new diagnostic model
I gave up trying to do this one lint at a time and just (mostly)
mechanically translated this entire file in one go.

Generally the messages stay the same (with most moving from an
annotation message to the diagnostic's main message). I added a couple
of `info` sub-diagnostics where it seemed to be the obvious intent.
2025-04-22 12:08:03 -04:00
Andrew Gallant
b8b624d890 red_knot_python_semantic: migrate INVALID_ASSIGNMENT for inference
This finishes the migration for the `INVALID_ASSIGNMENT` lint.

Notice how I'm steadily losing steam in terms of actually improving the
diagnostics. This change is more mechanical, because taking the time to
revamp every diagnostic is a ton of effort. Probably future migrations
will be similar unless there are easy pickings.
2025-04-22 12:08:03 -04:00
Andrew Gallant
6dc2d29966 red_knot_python_semantic: migrate INVALID_ASSIGNMENT for shadowing
We mostly keep things the same here, but the message has been moved from
the annotation to the diagnostic's top-line message. I think this is
perhaps a little worse, but some bigger improvements could be made here.
Indeed, we could perhaps even add a "fix" here.
2025-04-22 12:08:03 -04:00
Andrew Gallant
890ba725d9 red_knot_python_semantic: migrate INVALID_ASSIGNMENT for unpacking
This moves all INVALID_ASSIGNMENT lints related to unpacking over to the new
diagnostic model.

While we're here, we improve the diagnostic a bit by adding a secondary
annotation covering where the value is. We also split apart the original
singular message into one message for the diagnostic and the "expected
versus got" into annotation messages.
2025-04-22 12:08:03 -04:00
Andrew Gallant
298f43f34e red_knot_python_semantic: add invalid assignment diagnostic snapshot
This tests the diagnostic rendering of a case that wasn't previously
covered by snapshots: when unpacking fails because there are too few
values, but where the left hand side can tolerate "N or more." In the
code, this is a distinct diagnostic, so we capture it here.

(Sorry about the diff here, but it made sense to rename the other
sections and that changes the name of the snapshot file.)
2025-04-22 12:08:03 -04:00
Andrew Gallant
3b300559ab red_knot_python_semantic: remove #[must_use] on diagnostic guard constructor
I believe this was an artifact of an older iteration of the diagnostic
reporting API. But this is strictly not necessary now, and indeed, might
even be annoying. It is okay, but perhaps looks a little odd, to do
`builder.into_diagnostic("...")` if you don't want to add anything else
to the diagnostic.
2025-04-22 12:08:03 -04:00
Andrew Gallant
14f71ceb83 red_knot_python_semantic: add helper method for creating a secondary annotation
I suspect this will be used pretty frequently (I wanted it
immediately). And more practically, this avoids needing to
import `Annotation` to create it.
2025-04-22 12:08:03 -04:00
David Peter
4775719abf [red-knot] mypy_primer: larger depot runner (#17547)
## Summary

A switch from 16 to 32 cores reduces the `mypy_primer` CI time from
3.5-4 min to 2.5-3 min. There's also a 64-core runner, but the 4 min ->
3 min change when doubling the cores once does suggest that it doesn't
parallelize *this* well.
2025-04-22 17:36:13 +02:00
Alex Waygood
6bdffc3cbf [red-knot] Consider two instance types disjoint if the underlying classes have disjoint metaclasses (#17545) 2025-04-22 15:14:10 +01:00
Aria Desires
775815ef22 Update cargo-dist and apply config improvements (#17453) 2025-04-22 10:05:15 -04:00
Carl Meyer
0299a52fb1 [red-knot] Add list of failing/slow ecosystem projects (#17474)
## Summary

I ran red-knot on every project in mypy-primer. I moved every project
where red-knot ran to completion (fast enough, and mypy-primer could
handle its output) into `good.txt`, so it will run in our CI.

The remaining projects I left listed in `bad.txt`, with a comment
summarizing the failure mode (a few don't fail, they are just slow -- on
a debug build, at least -- or output too many diagnostics for
mypy-primer to handle.)

We will now run CI on 109 projects; 34 are left in `bad.txt`.

## Test Plan

CI on this PR!

---------

Co-authored-by: David Peter <mail@david-peter.de>
2025-04-22 14:15:36 +02:00
David Peter
83d5ad8983 [red-knot] mypy_primer: extend ecosystem checks (#17544)
## Summary

Takes the `good.txt` changes from #17474, and removes the following
projects:
- arrow (not part of mypy_primer upstream)
- freqtrade, hydpy, ibis, pandera, xarray (saw panics locally, all
related to try_metaclass cycles)

Increases the mypy_primer CI run time to ~4 min.

## Test Plan

Three successful CI runs.
2025-04-22 13:39:42 +02:00
Alex Waygood
ae6fde152c [red-knot] Move InstanceType to its own submodule (#17525) 2025-04-22 11:34:46 +00:00
David Peter
d2b20f7367 [red-knot] mypy_primer: capture backtraces (#17543)
## Summary

`mypy_primer` is not deterministic (we pin `mypy_primer` itself, but
projects change over time and we just pull in the latest version). We've
also seen occasional panics being caught in `mypy_primer` runs, so this
is trying to make these CI failures more helpful.
2025-04-22 12:05:57 +02:00
David Peter
38a3b056e3 [red-knot] mypy_primer: Use upstream repo (#17500)
## Summary

Switch to the official version of
[`mypy_primer`](https://github.com/hauntsaninja/mypy_primer), now that
Red Knot support has been upstreamed (see
https://github.com/hauntsaninja/mypy_primer/pull/138,
https://github.com/hauntsaninja/mypy_primer/pull/135,
https://github.com/hauntsaninja/mypy_primer/pull/151,
https://github.com/hauntsaninja/mypy_primer/pull/155).

## Test Plan

Locally and in CI
2025-04-22 11:55:16 +02:00
David Peter
37a0836bd2 [red-knot] typing.dataclass_transform (#17445)
## Summary

* Add initial support for `typing.dataclass_transform`
* Support decorating a function decorator with `@dataclass_transform(…)`
(used by `attrs`, `strawberry`)
* Support decorating a metaclass with `@dataclass_transform(…)` (used by
`pydantic`, but doesn't work yet, because we don't seem to model
`__new__` calls correctly?)
* *No* support yet for decorating base classes with
`@dataclass_transform(…)`. I haven't figured out how this even supposed
to work. And haven't seen it being used.
* Add `strawberry` as an ecosystem project, as it makes heavy use of
`@dataclass_transform`

## Test Plan

New Markdown tests
2025-04-22 10:33:02 +02:00
renovate[bot]
f83295fe51 Update dependency react-resizable-panels to v2.1.8 (#17513)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 09:30:07 +02:00
renovate[bot]
c4581788b2 Update dependency smol-toml to v1.3.3 (#17505)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 09:19:55 +02:00
renovate[bot]
2894aaa943 Update dependency uuid to v11.1.0 (#17517)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 09:18:54 +02:00
renovate[bot]
ed4866a00b Update actions/setup-node action to v4.4.0 (#17514)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-04-22 09:18:13 +02:00
Matthew Mckee
9b5fe51b32 [red-knot] Fix variable name (#17532) 2025-04-21 17:20:04 -07:00
Matthew Mckee
53ffe7143f [red-knot] Add basic subtyping between class literal and callable (#17469)
## Summary

This covers step 1 from
https://typing.python.org/en/latest/spec/constructors.html#converting-a-constructor-to-callable

Part of #17343

## Test Plan

Update is_subtype_of.md and is_assignable_to.md

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
2025-04-21 22:29:36 +00:00
Hans
21561000b1 [pyupgrade] Add fix safety section to docs (UP030) (#17443)
## Summary

add fix safety section to format_literals, for #15584
2025-04-21 14:14:58 -04:00
w0nder1ng
9c0772d8f0 [perflint] Allow list function calls to be replaced with a comprehension (PERF401) (#17519)
This is an implementation of the discussion from #16719. 

This change will allow list function calls to be replaced with
comprehensions:

```python
result = list()
for i in range(3):
    result.append(i + 1)
# becomes
result = [i + 1 for i in range(3)]
```

I added a new test to `PERF401.py` to verify that this fix will now work
for `list()`.
2025-04-21 13:29:24 -04:00
2025 changed files with 34230 additions and 46362 deletions

6
.gitattributes vendored
View File

@@ -12,6 +12,12 @@ crates/ruff_python_parser/resources/invalid/re_lexing/line_continuation_windows_
crates/ruff_python_parser/resources/invalid/re_lex_logical_token_windows_eol.py text eol=crlf
crates/ruff_python_parser/resources/invalid/re_lex_logical_token_mac_eol.py text eol=cr
crates/ruff_linter/resources/test/fixtures/ruff/RUF046_CR.py text eol=cr
crates/ruff_linter/resources/test/fixtures/ruff/RUF046_LF.py text eol=lf
crates/ruff_linter/resources/test/fixtures/pyupgrade/UP018_CR.py text eol=cr
crates/ruff_linter/resources/test/fixtures/pyupgrade/UP018_LF.py text eol=lf
crates/ruff_python_parser/resources/inline linguist-generated=true
ruff.schema.json -diff linguist-generated=true text=auto eol=lf

10
.github/CODEOWNERS vendored
View File

@@ -14,11 +14,11 @@
# flake8-pyi
/crates/ruff_linter/src/rules/flake8_pyi/ @AlexWaygood
# Script for fuzzing the parser/red-knot etc.
# Script for fuzzing the parser/ty etc.
/python/py-fuzzer/ @AlexWaygood
# red-knot
/crates/red_knot* @carljm @MichaReiser @AlexWaygood @sharkdp @dcreager
# ty
/crates/ty* @carljm @MichaReiser @AlexWaygood @sharkdp @dcreager
/crates/ruff_db/ @carljm @MichaReiser @AlexWaygood @sharkdp @dcreager
/scripts/knot_benchmark/ @carljm @MichaReiser @AlexWaygood @sharkdp @dcreager
/crates/red_knot_python_semantic @carljm @AlexWaygood @sharkdp @dcreager
/scripts/ty_benchmark/ @carljm @MichaReiser @AlexWaygood @sharkdp @dcreager
/crates/ty_python_semantic @carljm @AlexWaygood @sharkdp @dcreager

View File

@@ -1,5 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Report an issue with ty
url: https://github.com/astral-sh/ty/issues/new/choose
about: Please report issues for our type checker ty in the ty repository.
- name: Documentation
url: https://docs.astral.sh/ruff
about: Please consult the documentation before creating an issue.

View File

@@ -6,5 +6,6 @@ self-hosted-runner:
labels:
- depot-ubuntu-latest-8
- depot-ubuntu-22.04-16
- depot-ubuntu-22.04-32
- github-windows-2025-x86_64-8
- github-windows-2025-x86_64-16

View File

@@ -43,7 +43,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
@@ -72,7 +72,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
@@ -114,7 +114,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: arm64
@@ -170,7 +170,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: ${{ matrix.platform.arch }}
@@ -223,7 +223,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
@@ -298,7 +298,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
@@ -363,7 +363,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
@@ -429,7 +429,7 @@ jobs:
with:
submodules: recursive
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"

View File

@@ -79,7 +79,7 @@ jobs:
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/
- name: Build and push by digest
id: build
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6
with:
context: .
platforms: ${{ matrix.platform }}
@@ -113,7 +113,7 @@ jobs:
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
steps:
- name: Download digests
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: /tmp/digests
pattern: digests-*
@@ -231,7 +231,7 @@ jobs:
${{ env.TAG_PATTERNS }}
- name: Build and push
uses: docker/build-push-action@471d1dc4e07e5cdedd4c2171150001c434f0b7a4 # v6
uses: docker/build-push-action@14487ce63c7a62a4a324b0bfb37086795e31c6c1 # v6
with:
context: .
platforms: linux/amd64,linux/arm64
@@ -256,7 +256,7 @@ jobs:
if: ${{ inputs.plan != '' && !fromJson(inputs.plan).announcement_tag_is_implicit }}
steps:
- name: Download digests
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
path: /tmp/digests
pattern: digests-*

View File

@@ -36,8 +36,8 @@ jobs:
code: ${{ steps.check_code.outputs.changed }}
# Flag that is raised when any code that affects the fuzzer is changed
fuzz: ${{ steps.check_fuzzer.outputs.changed }}
# Flag that is set to "true" when code related to red-knot changes.
red_knot: ${{ steps.check_red_knot.outputs.changed }}
# Flag that is set to "true" when code related to ty changes.
ty: ${{ steps.check_ty.outputs.changed }}
# Flag that is set to "true" when code related to the playground changes.
playground: ${{ steps.check_playground.outputs.changed }}
@@ -84,7 +84,7 @@ jobs:
if git diff --quiet "${MERGE_BASE}...HEAD" -- ':Cargo.toml' \
':Cargo.lock' \
':crates/**' \
':!crates/red_knot*/**' \
':!crates/ty*/**' \
':!crates/ruff_python_formatter/**' \
':!crates/ruff_formatter/**' \
':!crates/ruff_dev/**' \
@@ -145,7 +145,7 @@ jobs:
run: |
if git diff --quiet "${MERGE_BASE}...HEAD" -- ':**' \
':!**/*.md' \
':crates/red_knot_python_semantic/resources/mdtest/**/*.md' \
':crates/ty_python_semantic/resources/mdtest/**/*.md' \
':!docs/**' \
':!assets/**' \
':.github/workflows/ci.yaml' \
@@ -168,15 +168,15 @@ jobs:
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Check if the red-knot code changed
id: check_red_knot
- name: Check if the ty code changed
id: check_ty
env:
MERGE_BASE: ${{ steps.merge_base.outputs.sha }}
run: |
if git diff --quiet "${MERGE_BASE}...HEAD" -- \
':Cargo.toml' \
':Cargo.lock' \
':crates/red_knot*/**' \
':crates/ty*/**' \
':crates/ruff_db/**' \
':crates/ruff_annotate_snippets/**' \
':crates/ruff_python_ast/**' \
@@ -221,7 +221,7 @@ jobs:
- name: "Clippy"
run: cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
- name: "Clippy (wasm)"
run: cargo clippy -p ruff_wasm -p red_knot_wasm --target wasm32-unknown-unknown --all-features --locked -- -D warnings
run: cargo clippy -p ruff_wasm -p ty_wasm --target wasm32-unknown-unknown --all-features --locked -- -D warnings
cargo-test-linux:
name: "cargo test (linux)"
@@ -239,21 +239,21 @@ jobs:
- name: "Install mold"
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: "Install cargo nextest"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-nextest
- name: "Install cargo insta"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-insta
- name: Red-knot mdtests (GitHub annotations)
if: ${{ needs.determine_changes.outputs.red_knot == 'true' }}
- name: ty mdtests (GitHub annotations)
if: ${{ needs.determine_changes.outputs.ty == 'true' }}
env:
NO_COLOR: 1
MDTEST_GITHUB_ANNOTATIONS_FORMAT: 1
# Ignore errors if this step fails; we want to continue to later steps in the workflow anyway.
# This step is just to get nice GitHub annotations on the PR diff in the files-changed tab.
run: cargo test -p red_knot_python_semantic --test mdtest || true
run: cargo test -p ty_python_semantic --test mdtest || true
- name: "Run tests"
shell: bash
env:
@@ -268,7 +268,7 @@ jobs:
# sync, not just public items. Eventually we should do this for all
# crates; for now add crates here as they are warning-clean to prevent
# regression.
- run: cargo doc --no-deps -p red_knot_python_semantic -p red_knot -p red_knot_test -p ruff_db --document-private-items
- run: cargo doc --no-deps -p ty_python_semantic -p ty -p ty_test -p ruff_db --document-private-items
env:
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
RUSTDOCFLAGS: "-D warnings"
@@ -276,6 +276,10 @@ jobs:
with:
name: ruff
path: target/debug/ruff
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: ty
path: target/debug/ty
cargo-test-linux-release:
name: "cargo test (linux, release)"
@@ -293,11 +297,11 @@ jobs:
- name: "Install mold"
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: "Install cargo nextest"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-nextest
- name: "Install cargo insta"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-insta
- name: "Run tests"
@@ -320,7 +324,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup show
- name: "Install cargo nextest"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-nextest
- name: "Run tests"
@@ -346,7 +350,7 @@ jobs:
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: "Install Rust toolchain"
run: rustup target add wasm32-unknown-unknown
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 20
cache: "npm"
@@ -358,9 +362,9 @@ jobs:
run: |
cd crates/ruff_wasm
wasm-pack test --node
- name: "Test red_knot_wasm"
- name: "Test ty_wasm"
run: |
cd crates/red_knot_wasm
cd crates/ty_wasm
wasm-pack test --node
cargo-build-release:
@@ -403,11 +407,11 @@ jobs:
- name: "Install mold"
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- name: "Install cargo nextest"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-nextest
- name: "Install cargo insta"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-insta
- name: "Run tests"
@@ -456,7 +460,7 @@ jobs:
with:
persist-credentials: false
- uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
name: Download Ruff binary to test
id: download-cached-binary
with:
@@ -521,11 +525,11 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
name: Download comparison Ruff binary
id: ruff-target
with:
@@ -632,6 +636,53 @@ jobs:
name: ecosystem-result
path: ecosystem-result
fuzz-ty:
name: "Fuzz for new ty panics"
runs-on: depot-ubuntu-22.04-16
needs:
- cargo-test-linux
- determine_changes
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-test') && github.event_name == 'pull_request' && needs.determine_changes.outputs.ty == 'true' }}
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
name: Download new ty binary
id: ty-new
with:
name: ty
path: target/debug
- uses: dawidd6/action-download-artifact@20319c5641d495c8a52e688b7dc5fada6c3a9fbc # v8
name: Download baseline ty binary
with:
name: ty
branch: ${{ github.event.pull_request.base.ref }}
workflow: "ci.yaml"
check_artifacts: true
- uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- name: Fuzz
env:
FORCE_COLOR: 1
NEW_TY: ${{ steps.ty-new.outputs.download-path }}
run: |
# Make executable, since artifact download doesn't preserve this
chmod +x "${PWD}/ty" "${NEW_TY}/ty"
(
uvx \
--python="${PYTHON_VERSION}" \
--from=./python/py-fuzzer \
fuzz \
--test-executable="${NEW_TY}/ty" \
--baseline-executable="${PWD}/ty" \
--only-new-bugs \
--bin=ty \
0-500
)
cargo-shear:
name: "cargo shear"
runs-on: ubuntu-latest
@@ -654,7 +705,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
@@ -708,7 +759,7 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.13"
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
@@ -779,12 +830,12 @@ jobs:
persist-credentials: false
repository: "astral-sh/ruff-lsp"
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
# installation fails on 3.13 and newer
python-version: "3.12"
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
name: Download development ruff binary
id: ruff-target
with:
@@ -821,7 +872,7 @@ jobs:
- name: "Install Rust toolchain"
run: rustup target add wasm32-unknown-unknown
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: "npm"
@@ -857,7 +908,7 @@ jobs:
run: rustup show
- name: "Install codspeed"
uses: taiki-e/install-action@09dc018eee06ae1c9e0409786563f534210ceb83 # v2
uses: taiki-e/install-action@86c23eed46c17b80677df6d8151545ce3e236c61 # v2
with:
tool: cargo-codspeed

View File

@@ -38,17 +38,17 @@ jobs:
- name: "Install mold"
uses: rui314/setup-mold@e16410e7f8d9e167b74ad5697a9089a35126eb50 # v1
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
- name: Build Red Knot
- name: Build ty
# A release build takes longer (2 min vs 1 min), but the property tests run much faster in release
# mode (1.5 min vs 14 min), so the overall time is shorter with a release build.
run: cargo build --locked --release --package red_knot_python_semantic --tests
run: cargo build --locked --release --package ty_python_semantic --tests
- name: Run property tests
shell: bash
run: |
export QUICKCHECK_TESTS=100000
for _ in {1..5}; do
cargo test --locked --release --package red_knot_python_semantic -- --ignored list::property_tests
cargo test --locked --release --package red_knot_python_semantic -- --ignored types::property_tests::stable
cargo test --locked --release --package ty_python_semantic -- --ignored list::property_tests
cargo test --locked --release --package ty_python_semantic -- --ignored types::property_tests::stable
done
create-issue-on-failure:
@@ -68,5 +68,5 @@ jobs:
repo: "ruff",
title: `Daily property test run failed on ${new Date().toDateString()}`,
body: "Run listed here: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
labels: ["bug", "red-knot", "testing"],
labels: ["bug", "ty", "testing"],
})

View File

@@ -5,7 +5,7 @@ permissions: {}
on:
pull_request:
paths:
- "crates/red_knot*/**"
- "crates/ty*/**"
- "crates/ruff_db"
- "crates/ruff_python_ast"
- "crates/ruff_python_parser"
@@ -21,11 +21,12 @@ env:
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
RUST_BACKTRACE: 1
jobs:
mypy_primer:
name: Run mypy_primer
runs-on: depot-ubuntu-22.04-16
runs-on: depot-ubuntu-22.04-32
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -40,19 +41,16 @@ jobs:
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
with:
workspaces: "ruff"
- name: Install Rust toolchain
run: rustup show
- name: Install mypy_primer
run: |
uv tool install "git+https://github.com/astral-sh/mypy_primer.git@add-red-knot-support-v5"
- name: Run mypy_primer
shell: bash
run: |
cd ruff
PRIMER_SELECTOR="$(paste -s -d'|' crates/red_knot_python_semantic/resources/primer/good.txt)"
PRIMER_SELECTOR="$(paste -s -d'|' crates/ty_python_semantic/resources/primer/good.txt)"
echo "new commit"
git rev-list --format=%s --max-count=1 "$GITHUB_SHA"
@@ -66,9 +64,11 @@ jobs:
echo "Project selector: $PRIMER_SELECTOR"
# Allow the exit code to be 0 or 1, only fail for actual mypy_primer crashes/bugs
uvx mypy_primer \
uvx \
--from="git+https://github.com/hauntsaninja/mypy_primer@4b15cf3b07db69db67bbfaebfffb2a8a28040933" \
mypy_primer \
--repo ruff \
--type-checker knot \
--type-checker ty \
--old base_commit \
--new "$GITHUB_SHA" \
--project-selector "/($PRIMER_SELECTOR)\$" \

View File

@@ -28,7 +28,7 @@ jobs:
ref: ${{ inputs.ref }}
persist-credentials: true
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: 3.12

View File

@@ -29,7 +29,7 @@ jobs:
persist-credentials: false
- name: "Install Rust toolchain"
run: rustup target add wasm32-unknown-unknown
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
cache: "npm"

View File

@@ -23,7 +23,7 @@ jobs:
steps:
- name: "Install uv"
uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
pattern: wheels-*
path: wheels

View File

@@ -1,5 +1,5 @@
# Publish the Red Knot playground.
name: "[Knot Playground] Release"
# Publish the ty playground.
name: "[ty Playground] Release"
permissions: {}
@@ -7,12 +7,12 @@ on:
push:
branches: [main]
paths:
- "crates/red_knot*/**"
- "crates/ty*/**"
- "crates/ruff_db/**"
- "crates/ruff_python_ast/**"
- "crates/ruff_python_parser/**"
- "playground/**"
- ".github/workflows/publish-knot-playground.yml"
- ".github/workflows/publish-ty-playground.yml"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
@@ -35,7 +35,7 @@ jobs:
persist-credentials: false
- name: "Install Rust toolchain"
run: rustup target add wasm32-unknown-unknown
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 22
- uses: jetli/wasm-bindgen-action@20b33e20595891ab1a0ed73145d8a21fc96e7c29 # v0.2.0
@@ -45,8 +45,8 @@ jobs:
- name: "Run TypeScript checks"
run: npm run check
working-directory: playground
- name: "Build Knot playground"
run: npm run build --workspace knot-playground
- name: "Build ty playground"
run: npm run build --workspace ty-playground
working-directory: playground
- name: "Deploy to Cloudflare Pages"
if: ${{ env.CF_API_TOKEN_EXISTS == 'true' }}
@@ -55,4 +55,4 @@ jobs:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
# `github.head_ref` is only set during pull requests and for manual runs or tags we use `main` to deploy to production
command: pages deploy playground/knot/dist --project-name=knot-playground --branch ${{ github.head_ref || 'main' }} --commit-hash ${GITHUB_SHA}
command: pages deploy playground/ty/dist --project-name=ty-playground --branch ${{ github.head_ref || 'main' }} --commit-hash ${GITHUB_SHA}

View File

@@ -45,7 +45,7 @@ jobs:
jq '.name="@astral-sh/ruff-wasm-${{ matrix.target }}"' crates/ruff_wasm/pkg/package.json > /tmp/package.json
mv /tmp/package.json crates/ruff_wasm/pkg
- run: cp LICENSE crates/ruff_wasm/pkg # wasm-pack does not put the LICENSE file in the pkg
- uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e # v4.3.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: 20
registry-url: "https://registry.npmjs.org"

View File

@@ -40,6 +40,7 @@ permissions:
# If there's a prerelease-style suffix to the version, then the release(s)
# will be marked as a prerelease.
on:
pull_request:
workflow_dispatch:
inputs:
tag:
@@ -60,7 +61,7 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2
with:
persist-credentials: false
submodules: recursive
@@ -68,9 +69,9 @@ jobs:
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/cargo-dist/releases/download/v0.28.4-prerelease.1/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/astral-sh/cargo-dist/releases/download/v0.28.5-prerelease.1/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47
with:
name: cargo-dist-cache
path: ~/.cargo/bin/dist
@@ -86,7 +87,7 @@ jobs:
cat plan-dist-manifest.json
echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47
with:
name: artifacts-plan-dist-manifest
path: plan-dist-manifest.json
@@ -123,19 +124,19 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Get all the local artifacts for the global tasks to use (for e.g. checksums)
- name: Fetch local artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: target/distrib/
@@ -153,7 +154,7 @@ jobs:
cp dist-manifest.json "$BUILD_MANIFEST_NAME"
- name: "Upload artifacts"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47
with:
name: artifacts-build-global
path: |
@@ -174,19 +175,19 @@ jobs:
outputs:
val: ${{ steps.host.outputs.manifest }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2
with:
persist-credentials: false
submodules: recursive
- name: Install cached dist
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
name: cargo-dist-cache
path: ~/.cargo/bin/
- run: chmod +x ~/.cargo/bin/dist
# Fetch artifacts from scratch-storage
- name: Fetch artifacts
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: target/distrib/
@@ -200,7 +201,7 @@ jobs:
cat dist-manifest.json
echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT"
- name: "Upload dist-manifest.json"
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47
with:
# Overwrite the previous copy
name: artifacts-dist-manifest
@@ -250,13 +251,13 @@ jobs:
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2
with:
persist-credentials: false
submodules: recursive
# Create a GitHub Release while uploading all files to it
- name: "Download GitHub Artifacts"
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
with:
pattern: artifacts-*
path: artifacts

View File

@@ -39,13 +39,13 @@ jobs:
- name: Sync typeshed
id: sync
run: |
rm -rf ruff/crates/red_knot_vendored/vendor/typeshed
mkdir ruff/crates/red_knot_vendored/vendor/typeshed
cp typeshed/README.md ruff/crates/red_knot_vendored/vendor/typeshed
cp typeshed/LICENSE ruff/crates/red_knot_vendored/vendor/typeshed
cp -r typeshed/stdlib ruff/crates/red_knot_vendored/vendor/typeshed/stdlib
rm -rf ruff/crates/red_knot_vendored/vendor/typeshed/stdlib/@tests
git -C typeshed rev-parse HEAD > ruff/crates/red_knot_vendored/vendor/typeshed/source_commit.txt
rm -rf ruff/crates/ty_vendored/vendor/typeshed
mkdir ruff/crates/ty_vendored/vendor/typeshed
cp typeshed/README.md ruff/crates/ty_vendored/vendor/typeshed
cp typeshed/LICENSE ruff/crates/ty_vendored/vendor/typeshed
cp -r typeshed/stdlib ruff/crates/ty_vendored/vendor/typeshed/stdlib
rm -rf ruff/crates/ty_vendored/vendor/typeshed/stdlib/@tests
git -C typeshed rev-parse HEAD > ruff/crates/ty_vendored/vendor/typeshed/source_commit.txt
- name: Commit the changes
id: commit
if: ${{ steps.sync.outcome == 'success' }}
@@ -79,5 +79,5 @@ jobs:
repo: "ruff",
title: `Automated typeshed sync failed on ${new Date().toDateString()}`,
body: "Run listed here: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
labels: ["bug", "red-knot"],
labels: ["bug", "ty"],
})

View File

@@ -3,8 +3,8 @@ fail_fast: false
exclude: |
(?x)^(
.github/workflows/release.yml|
crates/red_knot_vendored/vendor/.*|
crates/red_knot_project/resources/.*|
crates/ty_vendored/vendor/.*|
crates/ty_project/resources/.*|
crates/ruff_benchmark/resources/.*|
crates/ruff_linter/resources/.*|
crates/ruff_linter/src/rules/.*/snapshots/.*|
@@ -65,7 +65,7 @@ repos:
- black==25.1.0
- repo: https://github.com/crate-ci/typos
rev: v1.31.1
rev: v1.32.0
hooks:
- id: typos
@@ -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.6
rev: v0.11.8
hooks:
- id: ruff-format
- id: ruff

View File

@@ -1,5 +1,66 @@
# Changelog
## 0.11.8
### Preview features
- \[`airflow`\] Apply auto fixes to cases where the names have changed in Airflow 3 (`AIR302`, `AIR311`) ([#17553](https://github.com/astral-sh/ruff/pull/17553), [#17570](https://github.com/astral-sh/ruff/pull/17570), [#17571](https://github.com/astral-sh/ruff/pull/17571))
- \[`airflow`\] Extend `AIR301` rule ([#17598](https://github.com/astral-sh/ruff/pull/17598))
- \[`airflow`\] Update existing `AIR302` rules with better suggestions ([#17542](https://github.com/astral-sh/ruff/pull/17542))
- \[`refurb`\] Mark fix as safe for `readlines-in-for` (`FURB129`) ([#17644](https://github.com/astral-sh/ruff/pull/17644))
- [syntax-errors] `nonlocal` declaration at module level ([#17559](https://github.com/astral-sh/ruff/pull/17559))
- [syntax-errors] Detect single starred expression assignment `x = *y` ([#17624](https://github.com/astral-sh/ruff/pull/17624))
### Bug fixes
- \[`flake8-pyi`\] Ensure `Literal[None,] | Literal[None,]` is not autofixed to `None | None` (`PYI061`) ([#17659](https://github.com/astral-sh/ruff/pull/17659))
- \[`flake8-use-pathlib`\] Avoid suggesting `Path.iterdir()` for `os.listdir` with file descriptor (`PTH208`) ([#17715](https://github.com/astral-sh/ruff/pull/17715))
- \[`flake8-use-pathlib`\] Fix `PTH104` false positive when `rename` is passed a file descriptor ([#17712](https://github.com/astral-sh/ruff/pull/17712))
- \[`flake8-use-pathlib`\] Fix `PTH116` false positive when `stat` is passed a file descriptor ([#17709](https://github.com/astral-sh/ruff/pull/17709))
- \[`flake8-use-pathlib`\] Fix `PTH123` false positive when `open` is passed a file descriptor from a function call ([#17705](https://github.com/astral-sh/ruff/pull/17705))
- \[`pycodestyle`\] Fix duplicated diagnostic in `E712` ([#17651](https://github.com/astral-sh/ruff/pull/17651))
- \[`pylint`\] Detect `global` declarations in module scope (`PLE0118`) ([#17411](https://github.com/astral-sh/ruff/pull/17411))
- [syntax-errors] Make `async-comprehension-in-sync-comprehension` more specific ([#17460](https://github.com/astral-sh/ruff/pull/17460))
### Configuration
- Add option to disable `typing_extensions` imports ([#17611](https://github.com/astral-sh/ruff/pull/17611))
### Documentation
- Fix example syntax for the `lint.pydocstyle.ignore-var-parameters` option ([#17740](https://github.com/astral-sh/ruff/pull/17740))
- Add fix safety sections (`ASYNC116`, `FLY002`, `D200`, `RUF005`, `RUF017`, `RUF027`, `RUF028`, `RUF057`) ([#17497](https://github.com/astral-sh/ruff/pull/17497), [#17496](https://github.com/astral-sh/ruff/pull/17496), [#17502](https://github.com/astral-sh/ruff/pull/17502), [#17484](https://github.com/astral-sh/ruff/pull/17484), [#17480](https://github.com/astral-sh/ruff/pull/17480), [#17485](https://github.com/astral-sh/ruff/pull/17485), [#17722](https://github.com/astral-sh/ruff/pull/17722), [#17483](https://github.com/astral-sh/ruff/pull/17483))
### Other changes
- Add Python 3.14 to configuration options ([#17647](https://github.com/astral-sh/ruff/pull/17647))
- Make syntax error for unparenthesized except tuples version specific to before 3.14 ([#17660](https://github.com/astral-sh/ruff/pull/17660))
## 0.11.7
### Preview features
- \[`airflow`\] Apply auto fixes to cases where the names have changed in Airflow 3 (`AIR301`) ([#17355](https://github.com/astral-sh/ruff/pull/17355))
- \[`perflint`\] Implement fix for `manual-dict-comprehension` (`PERF403`) ([#16719](https://github.com/astral-sh/ruff/pull/16719))
- [syntax-errors] Make duplicate parameter names a semantic error ([#17131](https://github.com/astral-sh/ruff/pull/17131))
### Bug fixes
- \[`airflow`\] Fix typos in provider package names (`AIR302`, `AIR312`) ([#17574](https://github.com/astral-sh/ruff/pull/17574))
- \[`flake8-type-checking`\] Visit keyword arguments in checks involving `typing.cast`/`typing.NewType` arguments ([#17538](https://github.com/astral-sh/ruff/pull/17538))
- \[`pyupgrade`\] Preserve parenthesis when fixing native literals containing newlines (`UP018`) ([#17220](https://github.com/astral-sh/ruff/pull/17220))
- \[`refurb`\] Mark the `FURB161` fix unsafe except for integers and booleans ([#17240](https://github.com/astral-sh/ruff/pull/17240))
### Rule changes
- \[`perflint`\] Allow list function calls to be replaced with a comprehension (`PERF401`) ([#17519](https://github.com/astral-sh/ruff/pull/17519))
- \[`pycodestyle`\] Auto-fix redundant boolean comparison (`E712`) ([#17090](https://github.com/astral-sh/ruff/pull/17090))
- \[`pylint`\] make fix unsafe if delete comments (`PLR1730`) ([#17459](https://github.com/astral-sh/ruff/pull/17459))
### Documentation
- Add fix safety sections to docs for several rules ([#17410](https://github.com/astral-sh/ruff/pull/17410),[#17440](https://github.com/astral-sh/ruff/pull/17440),[#17441](https://github.com/astral-sh/ruff/pull/17441),[#17443](https://github.com/astral-sh/ruff/pull/17443),[#17444](https://github.com/astral-sh/ruff/pull/17444))
## 0.11.6
### Preview features

View File

@@ -71,8 +71,7 @@ representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
<charlie.r.marsh@gmail.com>.
reported to the community leaders responsible for enforcement at <hey@astral.sh>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the

View File

@@ -366,6 +366,15 @@ uvx --from ./python/ruff-ecosystem ruff-ecosystem format ruff "./target/debug/ru
See the [ruff-ecosystem package](https://github.com/astral-sh/ruff/tree/main/python/ruff-ecosystem) for more details.
## Upgrading Rust
1. Change the `channel` in `./rust-toolchain.toml` to the new Rust version (`<latest>`)
1. Change the `rust-version` in the `./Cargo.toml` to `<latest> - 2` (e.g. 1.84 if the latest is 1.86)
1. Run `cargo clippy --fix --allow-dirty --allow-staged` to fix new clippy warnings
1. Create and merge the PR
1. Bump the Rust version in Ruff's conda forge recipe. See [this PR](https://github.com/conda-forge/ruff-feedstock/pull/266) for an example.
1. Enjoy the new Rust version!
## Benchmarking and Profiling
We have several ways of benchmarking and profiling Ruff:

600
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -35,14 +35,14 @@ ruff_python_trivia = { path = "crates/ruff_python_trivia" }
ruff_server = { path = "crates/ruff_server" }
ruff_source_file = { path = "crates/ruff_source_file" }
ruff_text_size = { path = "crates/ruff_text_size" }
red_knot_vendored = { path = "crates/red_knot_vendored" }
ruff_workspace = { path = "crates/ruff_workspace" }
red_knot_ide = { path = "crates/red_knot_ide" }
red_knot_project = { path = "crates/red_knot_project", default-features = false }
red_knot_python_semantic = { path = "crates/red_knot_python_semantic" }
red_knot_server = { path = "crates/red_knot_server" }
red_knot_test = { path = "crates/red_knot_test" }
ty_ide = { path = "crates/ty_ide" }
ty_project = { path = "crates/ty_project", default-features = false }
ty_python_semantic = { path = "crates/ty_python_semantic" }
ty_server = { path = "crates/ty_server" }
ty_test = { path = "crates/ty_test" }
ty_vendored = { path = "crates/ty_vendored" }
aho-corasick = { version = "1.1.3" }
anstream = { version = "0.6.18" }
@@ -124,7 +124,7 @@ rayon = { version = "1.10.0" }
regex = { version = "1.10.2" }
rustc-hash = { version = "2.0.0" }
# When updating salsa, make sure to also update the revision in `fuzz/Cargo.toml`
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "87bf6b6c2d5f6479741271da73bd9d30c2580c26" }
salsa = { git = "https://github.com/salsa-rs/salsa.git", rev = "2c869364a9592d06fdf45c422e1e4a7265a8fe8a" }
schemars = { version = "0.8.16" }
seahash = { version = "4.1.0" }
serde = { version = "1.0.197", features = ["derive"] }
@@ -185,6 +185,9 @@ zip = { version = "0.6.6", default-features = false }
ignored = ["getrandom"]
[patch."https://github.com/salsa-rs/salsa.git"]
salsa = { path = "../salsa" }
[workspace.lints.rust]
unsafe_code = "warn"
unreachable_pub = "warn"
@@ -268,73 +271,3 @@ debug = 1
# The profile that 'cargo dist' will build with.
[profile.dist]
inherits = "release"
# Config for 'dist'
[workspace.metadata.dist]
# The preferred dist version to use in CI (Cargo.toml SemVer syntax)
cargo-dist-version = "0.28.4-prerelease.1"
# CI backends to support
ci = "github"
# The installers to generate for each app
installers = ["shell", "powershell"]
# The archive format to use for windows builds (defaults .zip)
windows-archive = ".zip"
# The archive format to use for non-windows builds (defaults .tar.xz)
unix-archive = ".tar.gz"
# Target platforms to build apps for (Rust target-triple syntax)
targets = [
"aarch64-apple-darwin",
"aarch64-pc-windows-msvc",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"arm-unknown-linux-musleabihf",
"armv7-unknown-linux-gnueabihf",
"armv7-unknown-linux-musleabihf",
"i686-pc-windows-msvc",
"i686-unknown-linux-gnu",
"i686-unknown-linux-musl",
"powerpc64-unknown-linux-gnu",
"powerpc64le-unknown-linux-gnu",
"s390x-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
"x86_64-unknown-linux-gnu",
"x86_64-unknown-linux-musl",
]
# Whether to auto-include files like READMEs, LICENSEs, and CHANGELOGs (default true)
auto-includes = false
# Whether dist should create a Github Release or use an existing draft
create-release = true
# Which actions to run on pull requests
pr-run-mode = "skip"
# Whether CI should trigger releases with dispatches instead of tag pushes
dispatch-releases = true
# Which phase dist should use to create the GitHub release
github-release = "announce"
# Whether CI should include auto-generated code to build local artifacts
build-local-artifacts = false
# Local artifacts jobs to run in CI
local-artifacts-jobs = ["./build-binaries", "./build-docker"]
# Publish jobs to run in CI
publish-jobs = ["./publish-pypi", "./publish-wasm"]
# Post-announce jobs to run in CI
post-announce-jobs = [
"./notify-dependents",
"./publish-docs",
"./publish-playground",
]
# Custom permissions for GitHub Jobs
github-custom-job-permissions = { "build-docker" = { packages = "write", contents = "read" }, "publish-wasm" = { contents = "read", id-token = "write", packages = "write" } }
# Whether to install an updater program
install-updater = false
# Path that installers should place binaries in
install-path = ["$XDG_BIN_HOME/", "$XDG_DATA_HOME/../bin", "~/.local/bin"]
[workspace.metadata.dist.github-custom-runners]
global = "depot-ubuntu-latest-4"
[workspace.metadata.dist.github-action-commits]
"actions/checkout" = "11bd71901bbe5b1630ceea73d27597364c9af683" # v4
"actions/upload-artifact" = "ea165f8d65b6e75b540449e92b4886f43607fa02" # v4.6.2
"actions/download-artifact" = "95815c38cf2ff2164869cbab79da8d1f422bc89e" # v4.2.1
"actions/attest-build-provenance" = "c074443f1aee8d4aeeae555aebba3282517141b2" #v2.2.3

View File

@@ -149,8 +149,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
# For a specific version.
curl -LsSf https://astral.sh/ruff/0.11.6/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.11.6/install.ps1 | iex"
curl -LsSf https://astral.sh/ruff/0.11.8/install.sh | sh
powershell -c "irm https://astral.sh/ruff/0.11.8/install.ps1 | iex"
```
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
@@ -183,7 +183,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
```yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.11.6
rev: v0.11.8
hooks:
# Run the linter.
- id: ruff

View File

@@ -1,7 +1,7 @@
[files]
# https://github.com/crate-ci/typos/issues/868
extend-exclude = [
"crates/red_knot_vendored/vendor/**/*",
"crates/ty_vendored/vendor/**/*",
"**/resources/**/*",
"**/snapshots/**/*",
]

View File

@@ -1,25 +0,0 @@
# Red Knot
Red Knot is an extremely fast type checker.
Currently, it is a work-in-progress and not ready for user testing.
Red Knot is designed to prioritize good type inference, even in unannotated code,
and aims to avoid false positives.
While Red Knot will produce similar results to mypy and pyright on many codebases,
100% compatibility with these tools is a non-goal.
On some codebases, Red Knot's design decisions lead to different outcomes
than you would get from running one of these more established tools.
## Contributing
Core type checking tests are written as Markdown code blocks.
They can be found in [`red_knot_python_semantic/resources/mdtest`][resources-mdtest].
See [`red_knot_test/README.md`][mdtest-readme] for more information
on the test framework itself.
The list of open issues can be found [here][open-issues].
[mdtest-readme]: ../red_knot_test/README.md
[open-issues]: https://github.com/astral-sh/ruff/issues?q=sort%3Aupdated-desc%20is%3Aissue%20is%3Aopen%20label%3Ared-knot
[resources-mdtest]: ../red_knot_python_semantic/resources/mdtest

View File

@@ -1,83 +0,0 @@
# Any
## Annotation
`typing.Any` is a way to name the Any type.
```py
from typing import Any
x: Any = 1
x = "foo"
def f():
reveal_type(x) # revealed: Any
```
## Aliased to a different name
If you alias `typing.Any` to another name, we still recognize that as a spelling of the Any type.
```py
from typing import Any as RenamedAny
x: RenamedAny = 1
x = "foo"
def f():
reveal_type(x) # revealed: Any
```
## Shadowed class
If you define your own class named `Any`, using that in a type expression refers to your class, and
isn't a spelling of the Any type.
```py
class Any: ...
x: Any
def f():
reveal_type(x) # revealed: Any
# This verifies that we're not accidentally seeing typing.Any, since str is assignable
# to that but not to our locally defined class.
y: Any = "not an Any" # error: [invalid-assignment]
```
## Subclass
The spec allows you to define subclasses of `Any`.
TODO: Handle assignments correctly. `Subclass` has an unknown superclass, which might be `int`. The
assignment to `x` should not be allowed, even when the unknown superclass is `int`. The assignment
to `y` should be allowed, since `Subclass` might have `int` as a superclass, and is therefore
assignable to `int`.
```py
from typing import Any
class Subclass(Any): ...
reveal_type(Subclass.__mro__) # revealed: tuple[Literal[Subclass], Any, Literal[object]]
x: Subclass = 1 # error: [invalid-assignment]
# TODO: no diagnostic
y: int = Subclass() # error: [invalid-assignment]
def _(s: Subclass):
reveal_type(s) # revealed: Subclass
```
## Invalid
`Any` cannot be parameterized:
```py
from typing import Any
# error: [invalid-type-form] "Type `typing.Any` expected no type parameter"
def f(x: Any[int]):
reveal_type(x) # revealed: Unknown
```

View File

@@ -1,129 +0,0 @@
# Typing-module aliases to other stdlib classes
The `typing` module has various aliases to other stdlib classes. These are a legacy feature, but
still need to be supported by a type checker.
## Correspondence
All of the following symbols can be mapped one-to-one with the actual type:
```py
import typing
def f(
list_bare: typing.List,
list_parametrized: typing.List[int],
dict_bare: typing.Dict,
dict_parametrized: typing.Dict[int, str],
set_bare: typing.Set,
set_parametrized: typing.Set[int],
frozen_set_bare: typing.FrozenSet,
frozen_set_parametrized: typing.FrozenSet[str],
chain_map_bare: typing.ChainMap,
chain_map_parametrized: typing.ChainMap[int],
counter_bare: typing.Counter,
counter_parametrized: typing.Counter[int],
default_dict_bare: typing.DefaultDict,
default_dict_parametrized: typing.DefaultDict[str, int],
deque_bare: typing.Deque,
deque_parametrized: typing.Deque[str],
ordered_dict_bare: typing.OrderedDict,
ordered_dict_parametrized: typing.OrderedDict[int, str],
):
reveal_type(list_bare) # revealed: list
reveal_type(list_parametrized) # revealed: list
reveal_type(dict_bare) # revealed: dict
reveal_type(dict_parametrized) # revealed: dict
reveal_type(set_bare) # revealed: set
reveal_type(set_parametrized) # revealed: set
reveal_type(frozen_set_bare) # revealed: frozenset
reveal_type(frozen_set_parametrized) # revealed: frozenset
reveal_type(chain_map_bare) # revealed: ChainMap
reveal_type(chain_map_parametrized) # revealed: ChainMap
reveal_type(counter_bare) # revealed: Counter
reveal_type(counter_parametrized) # revealed: Counter
reveal_type(default_dict_bare) # revealed: defaultdict
reveal_type(default_dict_parametrized) # revealed: defaultdict
reveal_type(deque_bare) # revealed: deque
reveal_type(deque_parametrized) # revealed: deque
reveal_type(ordered_dict_bare) # revealed: OrderedDict
reveal_type(ordered_dict_parametrized) # revealed: OrderedDict
```
## Inheritance
The aliases can be inherited from. Some of these are still partially or wholly TODOs.
```py
import typing
####################
### Built-ins
####################
class ListSubclass(typing.List): ...
# TODO: generic protocols
# revealed: tuple[Literal[ListSubclass], Literal[list], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(ListSubclass.__mro__)
class DictSubclass(typing.Dict): ...
# TODO: generic protocols
# revealed: tuple[Literal[DictSubclass], Literal[dict], Literal[MutableMapping], Literal[Mapping], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(DictSubclass.__mro__)
class SetSubclass(typing.Set): ...
# TODO: generic protocols
# revealed: tuple[Literal[SetSubclass], Literal[set], Literal[MutableSet], Literal[AbstractSet], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(SetSubclass.__mro__)
class FrozenSetSubclass(typing.FrozenSet): ...
# TODO: should have `Generic`, should not have `Unknown`
# revealed: tuple[Literal[FrozenSetSubclass], Literal[frozenset], Unknown, Literal[object]]
reveal_type(FrozenSetSubclass.__mro__)
####################
### `collections`
####################
class ChainMapSubclass(typing.ChainMap): ...
# TODO: generic protocols
# revealed: tuple[Literal[ChainMapSubclass], Literal[ChainMap], Literal[MutableMapping], Literal[Mapping], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(ChainMapSubclass.__mro__)
class CounterSubclass(typing.Counter): ...
# TODO: Should be (CounterSubclass, Counter, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
# revealed: tuple[Literal[CounterSubclass], Literal[Counter], Unknown, Literal[object]]
reveal_type(CounterSubclass.__mro__)
class DefaultDictSubclass(typing.DefaultDict): ...
# TODO: Should be (DefaultDictSubclass, defaultdict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
# revealed: tuple[Literal[DefaultDictSubclass], Literal[defaultdict], Unknown, Literal[object]]
reveal_type(DefaultDictSubclass.__mro__)
class DequeSubclass(typing.Deque): ...
# TODO: generic protocols
# revealed: tuple[Literal[DequeSubclass], Literal[deque], Literal[MutableSequence], Literal[Sequence], Literal[Reversible], Literal[Collection], Literal[Iterable], Literal[Container], @Todo(`Protocol[]` subscript), @Todo(`Generic[]` subscript), Literal[object]]
reveal_type(DequeSubclass.__mro__)
class OrderedDictSubclass(typing.OrderedDict): ...
# TODO: Should be (OrderedDictSubclass, OrderedDict, dict, MutableMapping, Mapping, Collection, Sized, Iterable, Container, Generic, object)
# revealed: tuple[Literal[OrderedDictSubclass], Literal[OrderedDict], Unknown, Literal[object]]
reveal_type(OrderedDictSubclass.__mro__)
```

View File

@@ -1,72 +0,0 @@
# Legacy type variables
The tests in this file focus on how type variables are defined using the legacy notation. Most
_uses_ of type variables are tested in other files in this directory; we do not duplicate every test
for both type variable syntaxes.
Unless otherwise specified, all quotations come from the [Generics] section of the typing spec.
## Type variables
### Defining legacy type variables
> Generics can be parameterized by using a factory available in `typing` called `TypeVar`.
This was the only way to create type variables prior to PEP 695/Python 3.12. It is still available
in newer Python releases.
```py
from typing import TypeVar
T = TypeVar("T")
```
### Directly assigned to a variable
> A `TypeVar()` expression must always directly be assigned to a variable (it should not be used as
> part of a larger expression).
```py
from typing import TypeVar
# TODO: error
TestList = list[TypeVar("W")]
```
### `TypeVar` parameter must match variable name
> The argument to `TypeVar()` must be a string equal to the variable name to which it is assigned.
```py
from typing import TypeVar
# TODO: error
T = TypeVar("Q")
```
### No redefinition
> Type variables must not be redefined.
```py
from typing import TypeVar
T = TypeVar("T")
# TODO: error
T = TypeVar("T")
```
### Cannot have only one constraint
> `TypeVar` supports constraining parametric types to a fixed set of possible types...There should
> be at least two constraints, if any; specifying a single constraint is disallowed.
```py
from typing import TypeVar
# TODO: error: [invalid-type-variable-constraints]
T = TypeVar("T", int)
```
[generics]: https://typing.python.org/en/latest/spec/generics.html

View File

@@ -1,7 +0,0 @@
# Dictionaries
## Empty dictionary
```py
reveal_type({}) # revealed: dict
```

View File

@@ -1,408 +0,0 @@
# Method Resolution Order tests
Tests that assert that we can infer the correct type for a class's `__mro__` attribute.
This attribute is rarely accessed directly at runtime. However, it's extremely important for *us* to
know the precise possible values of a class's Method Resolution Order, or we won't be able to infer
the correct type of attributes accessed from instances.
For documentation on method resolution orders, see:
- <https://docs.python.org/3/glossary.html#term-method-resolution-order>
- <https://docs.python.org/3/howto/mro.html#python-2-3-mro>
## No bases
```py
class C: ...
reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[object]]
```
## The special case: `object` itself
```py
reveal_type(object.__mro__) # revealed: tuple[Literal[object]]
```
## Explicit inheritance from `object`
```py
class C(object): ...
reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[object]]
```
## Explicit inheritance from non-`object` single base
```py
class A: ...
class B(A): ...
reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[A], Literal[object]]
```
## Linearization of multiple bases
```py
class A: ...
class B: ...
class C(A, B): ...
reveal_type(C.__mro__) # revealed: tuple[Literal[C], Literal[A], Literal[B], Literal[object]]
```
## Complex diamond inheritance (1)
This is "ex_2" from <https://docs.python.org/3/howto/mro.html#the-end>
```py
class O: ...
class X(O): ...
class Y(O): ...
class A(X, Y): ...
class B(Y, X): ...
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]]
reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]]
```
## Complex diamond inheritance (2)
This is "ex_5" from <https://docs.python.org/3/howto/mro.html#the-end>
```py
class O: ...
class F(O): ...
class E(O): ...
class D(O): ...
class C(D, F): ...
class B(D, E): ...
class A(B, C): ...
# revealed: tuple[Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
reveal_type(C.__mro__)
# revealed: tuple[Literal[B], Literal[D], Literal[E], Literal[O], Literal[object]]
reveal_type(B.__mro__)
# revealed: tuple[Literal[A], Literal[B], Literal[C], Literal[D], Literal[E], Literal[F], Literal[O], Literal[object]]
reveal_type(A.__mro__)
```
## Complex diamond inheritance (3)
This is "ex_6" from <https://docs.python.org/3/howto/mro.html#the-end>
```py
class O: ...
class F(O): ...
class E(O): ...
class D(O): ...
class C(D, F): ...
class B(E, D): ...
class A(B, C): ...
# revealed: tuple[Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
reveal_type(C.__mro__)
# revealed: tuple[Literal[B], Literal[E], Literal[D], Literal[O], Literal[object]]
reveal_type(B.__mro__)
# revealed: tuple[Literal[A], Literal[B], Literal[E], Literal[C], Literal[D], Literal[F], Literal[O], Literal[object]]
reveal_type(A.__mro__)
```
## Complex diamond inheritance (4)
This is "ex_9" from <https://docs.python.org/3/howto/mro.html#the-end>
```py
class O: ...
class A(O): ...
class B(O): ...
class C(O): ...
class D(O): ...
class E(O): ...
class K1(A, B, C): ...
class K2(D, B, E): ...
class K3(D, A): ...
class Z(K1, K2, K3): ...
# revealed: tuple[Literal[K1], Literal[A], Literal[B], Literal[C], Literal[O], Literal[object]]
reveal_type(K1.__mro__)
# revealed: tuple[Literal[K2], Literal[D], Literal[B], Literal[E], Literal[O], Literal[object]]
reveal_type(K2.__mro__)
# revealed: tuple[Literal[K3], Literal[D], Literal[A], Literal[O], Literal[object]]
reveal_type(K3.__mro__)
# revealed: tuple[Literal[Z], Literal[K1], Literal[K2], Literal[K3], Literal[D], Literal[A], Literal[B], Literal[C], Literal[E], Literal[O], Literal[object]]
reveal_type(Z.__mro__)
```
## Inheritance from `Unknown`
```py
from does_not_exist import DoesNotExist # error: [unresolved-import]
class A(DoesNotExist): ...
class B: ...
class C: ...
class D(A, B, C): ...
class E(B, C): ...
class F(E, A): ...
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Unknown, Literal[object]]
reveal_type(D.__mro__) # revealed: tuple[Literal[D], Literal[A], Unknown, Literal[B], Literal[C], Literal[object]]
reveal_type(E.__mro__) # revealed: tuple[Literal[E], Literal[B], Literal[C], Literal[object]]
reveal_type(F.__mro__) # revealed: tuple[Literal[F], Literal[E], Literal[B], Literal[C], Literal[A], Unknown, Literal[object]]
```
## `__bases__` lists that cause errors at runtime
If the class's `__bases__` cause an exception to be raised at runtime and therefore the class
creation to fail, we infer the class's `__mro__` as being `[<class>, Unknown, object]`:
```py
# error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Foo` with bases list `[<class 'object'>, <class 'int'>]`"
class Foo(object, int): ...
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
class Bar(Foo): ...
reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Literal[Foo], Unknown, Literal[object]]
# This is the `TypeError` at the bottom of "ex_2"
# in the examples at <https://docs.python.org/3/howto/mro.html#the-end>
class O: ...
class X(O): ...
class Y(O): ...
class A(X, Y): ...
class B(Y, X): ...
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]]
reveal_type(B.__mro__) # revealed: tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]]
# error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Z` with bases list `[<class 'A'>, <class 'B'>]`"
class Z(A, B): ...
reveal_type(Z.__mro__) # revealed: tuple[Literal[Z], Unknown, Literal[object]]
class AA(Z): ...
reveal_type(AA.__mro__) # revealed: tuple[Literal[AA], Literal[Z], Unknown, Literal[object]]
```
## `__bases__` includes a `Union`
We don't support union types in a class's bases; a base must resolve to a single `ClassLiteralType`.
If we find a union type in a class's bases, we infer the class's `__mro__` as being
`[<class>, Unknown, object]`, the same as for MROs that cause errors at runtime.
```py
def returns_bool() -> bool:
return True
class A: ...
class B: ...
if returns_bool():
x = A
else:
x = B
reveal_type(x) # revealed: Literal[A, B]
# error: 11 [invalid-base] "Invalid class base with type `Literal[A, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
class Foo(x): ...
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
```
## `__bases__` includes multiple `Union`s
```py
def returns_bool() -> bool:
return True
class A: ...
class B: ...
class C: ...
class D: ...
if returns_bool():
x = A
else:
x = B
if returns_bool():
y = C
else:
y = D
reveal_type(x) # revealed: Literal[A, B]
reveal_type(y) # revealed: Literal[C, D]
# error: 11 [invalid-base] "Invalid class base with type `Literal[A, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
# error: 14 [invalid-base] "Invalid class base with type `Literal[C, D]` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
class Foo(x, y): ...
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
```
## `__bases__` lists that cause errors... now with `Union`s
```py
def returns_bool() -> bool:
return True
class O: ...
class X(O): ...
class Y(O): ...
if returns_bool():
foo = Y
else:
foo = object
# error: 21 [invalid-base] "Invalid class base with type `Literal[Y, object]` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
class PossibleError(foo, X): ...
reveal_type(PossibleError.__mro__) # revealed: tuple[Literal[PossibleError], Unknown, Literal[object]]
class A(X, Y): ...
reveal_type(A.__mro__) # revealed: tuple[Literal[A], Literal[X], Literal[Y], Literal[O], Literal[object]]
if returns_bool():
class B(X, Y): ...
else:
class B(Y, X): ...
# revealed: tuple[Literal[B], Literal[X], Literal[Y], Literal[O], Literal[object]] | tuple[Literal[B], Literal[Y], Literal[X], Literal[O], Literal[object]]
reveal_type(B.__mro__)
# error: 12 [invalid-base] "Invalid class base with type `Literal[B, B]` (all bases must be a class, `Any`, `Unknown` or `Todo`)"
class Z(A, B): ...
reveal_type(Z.__mro__) # revealed: tuple[Literal[Z], Unknown, Literal[object]]
```
## `__bases__` lists with duplicate bases
```py
class Foo(str, str): ... # error: 16 [duplicate-base] "Duplicate base class `str`"
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
class Spam: ...
class Eggs: ...
class Ham(
Spam,
Eggs,
Spam, # error: [duplicate-base] "Duplicate base class `Spam`"
Eggs, # error: [duplicate-base] "Duplicate base class `Eggs`"
): ...
reveal_type(Ham.__mro__) # revealed: tuple[Literal[Ham], Unknown, Literal[object]]
class Mushrooms: ...
class Omelette(Spam, Eggs, Mushrooms, Mushrooms): ... # error: [duplicate-base]
reveal_type(Omelette.__mro__) # revealed: tuple[Literal[Omelette], Unknown, Literal[object]]
```
## `__bases__` lists with duplicate `Unknown` bases
```py
# error: [unresolved-import]
# error: [unresolved-import]
from does_not_exist import unknown_object_1, unknown_object_2
reveal_type(unknown_object_1) # revealed: Unknown
reveal_type(unknown_object_2) # revealed: Unknown
# We *should* emit an error here to warn the user that we have no idea
# what the MRO of this class should really be.
# However, we don't complain about "duplicate base classes" here,
# even though two classes are both inferred as being `Unknown`.
#
# (TODO: should we revisit this? Does it violate the gradual guarantee?
# Should we just silently infer `[Foo, Unknown, object]` as the MRO here
# without emitting any error at all? Not sure...)
#
# error: [inconsistent-mro] "Cannot create a consistent method resolution order (MRO) for class `Foo` with bases list `[Unknown, Unknown]`"
class Foo(unknown_object_1, unknown_object_2): ...
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
```
## Unrelated objects inferred as `Any`/`Unknown` do not have special `__mro__` attributes
```py
from does_not_exist import unknown_object # error: [unresolved-import]
reveal_type(unknown_object) # revealed: Unknown
reveal_type(unknown_object.__mro__) # revealed: Unknown
```
## Classes that inherit from themselves
These are invalid, but we need to be able to handle them gracefully without panicking.
```pyi
class Foo(Foo): ... # error: [cyclic-class-definition]
reveal_type(Foo) # revealed: Literal[Foo]
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
class Bar: ...
class Baz: ...
class Boz(Bar, Baz, Boz): ... # error: [cyclic-class-definition]
reveal_type(Boz) # revealed: Literal[Boz]
reveal_type(Boz.__mro__) # revealed: tuple[Literal[Boz], Unknown, Literal[object]]
```
## Classes with indirect cycles in their MROs
These are similarly unlikely, but we still shouldn't crash:
```pyi
class Foo(Bar): ... # error: [cyclic-class-definition]
class Bar(Baz): ... # error: [cyclic-class-definition]
class Baz(Foo): ... # error: [cyclic-class-definition]
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Unknown, Literal[object]]
reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]]
```
## Classes with cycles in their MROs, and multiple inheritance
```pyi
class Spam: ...
class Foo(Bar): ... # error: [cyclic-class-definition]
class Bar(Baz): ... # error: [cyclic-class-definition]
class Baz(Foo, Spam): ... # error: [cyclic-class-definition]
reveal_type(Foo.__mro__) # revealed: tuple[Literal[Foo], Unknown, Literal[object]]
reveal_type(Bar.__mro__) # revealed: tuple[Literal[Bar], Unknown, Literal[object]]
reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]]
```
## Classes with cycles in their MRO, and a sub-graph
```pyi
class FooCycle(BarCycle): ... # error: [cyclic-class-definition]
class Foo: ...
class BarCycle(FooCycle): ... # error: [cyclic-class-definition]
class Bar(Foo): ...
# Avoid emitting the errors for these. The classes have cyclic superclasses,
# but are not themselves cyclic...
class Baz(Bar, BarCycle): ...
class Spam(Baz): ...
reveal_type(FooCycle.__mro__) # revealed: tuple[Literal[FooCycle], Unknown, Literal[object]]
reveal_type(BarCycle.__mro__) # revealed: tuple[Literal[BarCycle], Unknown, Literal[object]]
reveal_type(Baz.__mro__) # revealed: tuple[Literal[Baz], Unknown, Literal[object]]
reveal_type(Spam.__mro__) # revealed: tuple[Literal[Spam], Unknown, Literal[object]]
```

View File

@@ -1,53 +0,0 @@
# Narrowing with assert statements
## `assert` a value `is None` or `is not None`
```py
def _(x: str | None, y: str | None):
assert x is not None
reveal_type(x) # revealed: str
assert y is None
reveal_type(y) # revealed: None
```
## `assert` a value is truthy or falsy
```py
def _(x: bool, y: bool):
assert x
reveal_type(x) # revealed: Literal[True]
assert not y
reveal_type(y) # revealed: Literal[False]
```
## `assert` with `is` and `==` for literals
```py
from typing import Literal
def _(x: Literal[1, 2, 3], y: Literal[1, 2, 3]):
assert x is 2
reveal_type(x) # revealed: Literal[2]
assert y == 2
reveal_type(y) # revealed: Literal[1, 2, 3]
```
## `assert` with `isinstance`
```py
def _(x: int | str):
assert isinstance(x, int)
reveal_type(x) # revealed: int
```
## `assert` a value `in` a tuple
```py
from typing import Literal
def _(x: Literal[1, 2, 3], y: Literal[1, 2, 3]):
assert x in (1, 2)
reveal_type(x) # revealed: Literal[1, 2]
assert y not in (1, 2)
reveal_type(y) # revealed: Literal[3]
```

View File

@@ -1,47 +0,0 @@
# Narrowing for nested conditionals
## Multiple negative contributions
```py
def _(x: int):
if x != 1:
if x != 2:
if x != 3:
reveal_type(x) # revealed: int & ~Literal[1] & ~Literal[2] & ~Literal[3]
```
## Multiple negative contributions with simplification
```py
def _(flag1: bool, flag2: bool):
x = 1 if flag1 else 2 if flag2 else 3
if x != 1:
reveal_type(x) # revealed: Literal[2, 3]
if x != 2:
reveal_type(x) # revealed: Literal[3]
```
## elif-else blocks
```py
def _(flag1: bool, flag2: bool):
x = 1 if flag1 else 2 if flag2 else 3
if x != 1:
reveal_type(x) # revealed: Literal[2, 3]
if x == 2:
# TODO should be `Literal[2]`
reveal_type(x) # revealed: Literal[2, 3]
elif x == 3:
reveal_type(x) # revealed: Literal[3]
else:
reveal_type(x) # revealed: Never
elif x != 2:
# TODO should be Literal[1]
reveal_type(x) # revealed: Literal[1, 3]
else:
# TODO should be Never
reveal_type(x) # revealed: Literal[1, 2, 3]
```

View File

@@ -1,28 +0,0 @@
---
source: crates/red_knot_test/src/lib.rs
expression: snapshot
---
---
mdtest name: basic.md - Structures - Unresolvable module import
mdtest path: crates/red_knot_python_semantic/resources/mdtest/import/basic.md
---
# Python source files
## mdtest_snippet.py
```
1 | import zqzqzqzqzqzqzq # error: [unresolved-import] "Cannot resolve import `zqzqzqzqzqzqzq`"
```
# Diagnostics
```
error: lint:unresolved-import
--> /src/mdtest_snippet.py:1:8
|
1 | import zqzqzqzqzqzqzq # error: [unresolved-import] "Cannot resolve import `zqzqzqzqzqzqzq`"
| ^^^^^^^^^^^^^^ Cannot resolve import `zqzqzqzqzqzqzq`
|
```

View File

@@ -1,32 +0,0 @@
---
source: crates/red_knot_test/src/lib.rs
expression: snapshot
---
---
mdtest name: for.md - For loops - Invalid iterable
mdtest path: crates/red_knot_python_semantic/resources/mdtest/loops/for.md
---
# Python source files
## mdtest_snippet.py
```
1 | nonsense = 123
2 | for x in nonsense: # error: [not-iterable]
3 | pass
```
# Diagnostics
```
error: lint:not-iterable
--> /src/mdtest_snippet.py:2:10
|
1 | nonsense = 123
2 | for x in nonsense: # error: [not-iterable]
| ^^^^^^^^ Object of type `Literal[123]` is not iterable because it doesn't have an `__iter__` method or a `__getitem__` method
3 | pass
|
```

View File

@@ -1,28 +0,0 @@
---
source: crates/red_knot_test/src/lib.rs
expression: snapshot
---
---
mdtest name: unpacking.md - Unpacking - Right hand side not iterable
mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/unpacking.md
---
# Python source files
## mdtest_snippet.py
```
1 | a, b = 1 # error: [not-iterable]
```
# Diagnostics
```
error: lint:not-iterable
--> /src/mdtest_snippet.py:1:8
|
1 | a, b = 1 # error: [not-iterable]
| ^ Object of type `Literal[1]` is not iterable because it doesn't have an `__iter__` method or a `__getitem__` method
|
```

View File

@@ -1,28 +0,0 @@
---
source: crates/red_knot_test/src/lib.rs
expression: snapshot
---
---
mdtest name: unpacking.md - Unpacking - Too few values to unpack
mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/unpacking.md
---
# Python source files
## mdtest_snippet.py
```
1 | a, b = (1,) # error: [invalid-assignment]
```
# Diagnostics
```
error: lint:invalid-assignment
--> /src/mdtest_snippet.py:1:1
|
1 | a, b = (1,) # error: [invalid-assignment]
| ^^^^ Not enough values to unpack (expected 2, got 1)
|
```

View File

@@ -1,28 +0,0 @@
---
source: crates/red_knot_test/src/lib.rs
expression: snapshot
---
---
mdtest name: unpacking.md - Unpacking - Too many values to unpack
mdtest path: crates/red_knot_python_semantic/resources/mdtest/diagnostics/unpacking.md
---
# Python source files
## mdtest_snippet.py
```
1 | a, b = (1, 2, 3) # error: [invalid-assignment]
```
# Diagnostics
```
error: lint:invalid-assignment
--> /src/mdtest_snippet.py:1:1
|
1 | a, b = (1, 2, 3) # error: [invalid-assignment]
| ^^^^ Too many values to unpack (expected 2, got 3)
|
```

View File

@@ -1,191 +0,0 @@
# Suppressing errors with `knot: ignore`
Type check errors can be suppressed by a `knot: ignore` comment on the same line as the violation.
## Simple `knot: ignore`
```py
a = 4 + test # knot: ignore
```
## Suppressing a specific code
```py
a = 4 + test # knot: ignore[unresolved-reference]
```
## Unused suppression
```py
test = 10
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'possibly-unresolved-reference'"
a = test + 3 # knot: ignore[possibly-unresolved-reference]
```
## Unused suppression if the error codes don't match
```py
# error: [unresolved-reference]
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'possibly-unresolved-reference'"
a = test + 3 # knot: ignore[possibly-unresolved-reference]
```
## Suppressed unused comment
```py
# error: [unused-ignore-comment]
a = 10 / 2 # knot: ignore[division-by-zero]
a = 10 / 2 # knot: ignore[division-by-zero, unused-ignore-comment]
a = 10 / 2 # knot: ignore[unused-ignore-comment, division-by-zero]
a = 10 / 2 # knot: ignore[unused-ignore-comment] # type: ignore
a = 10 / 2 # type: ignore # knot: ignore[unused-ignore-comment]
```
## Unused ignore comment
```py
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'unused-ignore-comment'"
a = 10 / 0 # knot: ignore[division-by-zero, unused-ignore-comment]
```
## Multiple unused comments
Today, Red Knot emits a diagnostic for every unused code. We might want to group the codes by
comment at some point in the future.
```py
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'division-by-zero'"
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'unresolved-reference'"
a = 10 / 2 # knot: ignore[division-by-zero, unresolved-reference]
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'invalid-assignment'"
# error: [unused-ignore-comment] "Unused `knot: ignore` directive: 'unresolved-reference'"
a = 10 / 0 # knot: ignore[invalid-assignment, division-by-zero, unresolved-reference]
```
## Multiple suppressions
```py
# fmt: off
def test(a: f"f-string type annotation", b: b"byte-string-type-annotation"): ... # knot: ignore[fstring-type-annotation, byte-string-type-annotation]
```
## Can't suppress syntax errors
<!-- blacken-docs:off -->
```py
# error: [invalid-syntax]
# error: [unused-ignore-comment]
def test($): # knot: ignore
pass
```
<!-- blacken-docs:on -->
## Can't suppress `revealed-type` diagnostics
```py
a = 10
# revealed: Literal[10]
# error: [unknown-rule] "Unknown rule `revealed-type`"
reveal_type(a) # knot: ignore[revealed-type]
```
## Extra whitespace in type ignore comments is allowed
```py
a = 10 / 0 # knot : ignore
a = 10 / 0 # knot: ignore [ division-by-zero ]
```
## Whitespace is optional
```py
# fmt: off
a = 10 / 0 #knot:ignore[division-by-zero]
```
## Trailing codes comma
Trailing commas in the codes section are allowed:
```py
a = 10 / 0 # knot: ignore[division-by-zero,]
```
## Invalid characters in codes
```py
# error: [division-by-zero]
# error: [invalid-ignore-comment] "Invalid `knot: ignore` comment: expected a alphanumeric character or `-` or `_` as code"
a = 10 / 0 # knot: ignore[*-*]
```
## Trailing whitespace
<!-- blacken-docs:off -->
```py
a = 10 / 0 # knot: ignore[division-by-zero]
# ^^^^^^ trailing whitespace
```
<!-- blacken-docs:on -->
## Missing comma
A missing comma results in an invalid suppression comment. We may want to recover from this in the
future.
```py
# error: [unresolved-reference]
# error: [invalid-ignore-comment] "Invalid `knot: ignore` comment: expected a comma separating the rule codes"
a = x / 0 # knot: ignore[division-by-zero unresolved-reference]
```
## Missing closing bracket
```py
# error: [unresolved-reference] "Name `x` used when not defined"
# error: [invalid-ignore-comment] "Invalid `knot: ignore` comment: expected a comma separating the rule codes"
a = x / 2 # knot: ignore[unresolved-reference
```
## Empty codes
An empty codes array suppresses no-diagnostics and is always useless
```py
# error: [division-by-zero]
# error: [unused-ignore-comment] "Unused `knot: ignore` without a code"
a = 4 / 0 # knot: ignore[]
```
## File-level suppression comments
File level suppression comments are currently intentionally unsupported because we've yet to decide
if they should use a different syntax that also supports enabling rules or changing the rule's
severity: `knot: possibly-undefined-reference=error`
```py
# error: [unused-ignore-comment]
# knot: ignore[division-by-zero]
a = 4 / 0 # error: [division-by-zero]
```
## Unknown rule
```py
# error: [unknown-rule] "Unknown rule `is-equal-14`"
a = 10 + 4 # knot: ignore[is-equal-14]
```
## Code with `lint:` prefix
```py
# error:[unknown-rule] "Unknown rule `lint:division-by-zero`. Did you mean `division-by-zero`?"
# error: [division-by-zero]
a = 10 / 0 # knot: ignore[lint:division-by-zero]
```

View File

@@ -1,23 +0,0 @@
arrow
async-utils
bidict
black
dacite
git-revise
isort
itsdangerous
mypy_primer
packaging
paroxython
porcupine
psycopg
pybind11
pyinstrument
pyp
python-chess
python-htmlgen
rich
scrapy
typeshed-stats
werkzeug
zipp

View File

@@ -1,3 +0,0 @@
The `knot_extensions.pyi` file in this directory will be symlinked into
the `vendor/typeshed/stdlib` directory every time we sync our `typeshed`
stubs (see `.github/workflows/sync_typeshed.yaml`).

View File

@@ -1 +0,0 @@
f65bdc1acde54fda93c802459280da74518d2eef

View File

@@ -1,34 +0,0 @@
# Utility types for typeshed
This package and its submodules contains various common types used by
typeshed. It can also be used by packages outside typeshed, but beware
the API stability guarantees below.
## Usage
The `_typeshed` package and its types do not exist at runtime, but can be
used freely in stubs (`.pyi`) files. To import the types from this package in
implementation (`.py`) files, use the following construct:
```python
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from _typeshed import ...
```
Types can then be used in annotations by either quoting them or
using:
```python
from __future__ import annotations
```
## API Stability
You can use this package and its submodules outside of typeshed, but we
guarantee only limited API stability. Items marked as "stable" will not be
removed or changed in an incompatible way for at least one year.
Before making such a change, the "stable" moniker will be removed
and we will mark the type in question as deprecated. No guarantees
are made about unmarked types.

View File

@@ -1,366 +0,0 @@
# Utility types for typeshed
#
# See the README.md file in this directory for more information.
import sys
from collections.abc import Awaitable, Callable, Iterable, Sequence, Set as AbstractSet, Sized
from dataclasses import Field
from os import PathLike
from types import FrameType, TracebackType
from typing import (
Any,
AnyStr,
ClassVar,
Final,
Generic,
Literal,
Protocol,
SupportsFloat,
SupportsIndex,
SupportsInt,
TypeVar,
final,
overload,
)
from typing_extensions import Buffer, LiteralString, Self as _Self, TypeAlias
_KT = TypeVar("_KT")
_KT_co = TypeVar("_KT_co", covariant=True)
_KT_contra = TypeVar("_KT_contra", contravariant=True)
_VT = TypeVar("_VT")
_VT_co = TypeVar("_VT_co", covariant=True)
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_T_contra = TypeVar("_T_contra", contravariant=True)
# Alternative to `typing_extensions.Self`, exclusively for use with `__new__`
# in metaclasses:
# def __new__(cls: type[Self], ...) -> Self: ...
# In other cases, use `typing_extensions.Self`.
Self = TypeVar("Self") # noqa: Y001
# covariant version of typing.AnyStr, useful for protocols
AnyStr_co = TypeVar("AnyStr_co", str, bytes, covariant=True) # noqa: Y001
# For partially known annotations. Usually, fields where type annotations
# haven't been added are left unannotated, but in some situations this
# isn't possible or a type is already partially known. In cases like these,
# use Incomplete instead of Any as a marker. For example, use
# "Incomplete | None" instead of "Any | None".
Incomplete: TypeAlias = Any # stable
# To describe a function parameter that is unused and will work with anything.
Unused: TypeAlias = object # stable
# Marker for return types that include None, but where forcing the user to
# check for None can be detrimental. Sometimes called "the Any trick". See
# CONTRIBUTING.md for more information.
MaybeNone: TypeAlias = Any # stable
# Used to mark arguments that default to a sentinel value. This prevents
# stubtest from complaining about the default value not matching.
#
# def foo(x: int | None = sentinel) -> None: ...
#
# In cases where the sentinel object is exported and can be used by user code,
# a construct like this is better:
#
# _SentinelType = NewType("_SentinelType", object)
# sentinel: _SentinelType
# def foo(x: int | None | _SentinelType = ...) -> None: ...
sentinel: Any
# stable
class IdentityFunction(Protocol):
def __call__(self, x: _T, /) -> _T: ...
# stable
class SupportsNext(Protocol[_T_co]):
def __next__(self) -> _T_co: ...
# stable
class SupportsAnext(Protocol[_T_co]):
def __anext__(self) -> Awaitable[_T_co]: ...
# Comparison protocols
class SupportsDunderLT(Protocol[_T_contra]):
def __lt__(self, other: _T_contra, /) -> bool: ...
class SupportsDunderGT(Protocol[_T_contra]):
def __gt__(self, other: _T_contra, /) -> bool: ...
class SupportsDunderLE(Protocol[_T_contra]):
def __le__(self, other: _T_contra, /) -> bool: ...
class SupportsDunderGE(Protocol[_T_contra]):
def __ge__(self, other: _T_contra, /) -> bool: ...
class SupportsAllComparisons(
SupportsDunderLT[Any], SupportsDunderGT[Any], SupportsDunderLE[Any], SupportsDunderGE[Any], Protocol
): ...
SupportsRichComparison: TypeAlias = SupportsDunderLT[Any] | SupportsDunderGT[Any]
SupportsRichComparisonT = TypeVar("SupportsRichComparisonT", bound=SupportsRichComparison) # noqa: Y001
# Dunder protocols
class SupportsAdd(Protocol[_T_contra, _T_co]):
def __add__(self, x: _T_contra, /) -> _T_co: ...
class SupportsRAdd(Protocol[_T_contra, _T_co]):
def __radd__(self, x: _T_contra, /) -> _T_co: ...
class SupportsSub(Protocol[_T_contra, _T_co]):
def __sub__(self, x: _T_contra, /) -> _T_co: ...
class SupportsRSub(Protocol[_T_contra, _T_co]):
def __rsub__(self, x: _T_contra, /) -> _T_co: ...
class SupportsMul(Protocol[_T_contra, _T_co]):
def __mul__(self, x: _T_contra, /) -> _T_co: ...
class SupportsRMul(Protocol[_T_contra, _T_co]):
def __rmul__(self, x: _T_contra, /) -> _T_co: ...
class SupportsDivMod(Protocol[_T_contra, _T_co]):
def __divmod__(self, other: _T_contra, /) -> _T_co: ...
class SupportsRDivMod(Protocol[_T_contra, _T_co]):
def __rdivmod__(self, other: _T_contra, /) -> _T_co: ...
# This protocol is generic over the iterator type, while Iterable is
# generic over the type that is iterated over.
class SupportsIter(Protocol[_T_co]):
def __iter__(self) -> _T_co: ...
# This protocol is generic over the iterator type, while AsyncIterable is
# generic over the type that is iterated over.
class SupportsAiter(Protocol[_T_co]):
def __aiter__(self) -> _T_co: ...
class SupportsLenAndGetItem(Protocol[_T_co]):
def __len__(self) -> int: ...
def __getitem__(self, k: int, /) -> _T_co: ...
class SupportsTrunc(Protocol):
def __trunc__(self) -> int: ...
# Mapping-like protocols
# stable
class SupportsItems(Protocol[_KT_co, _VT_co]):
def items(self) -> AbstractSet[tuple[_KT_co, _VT_co]]: ...
# stable
class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]):
def keys(self) -> Iterable[_KT]: ...
def __getitem__(self, key: _KT, /) -> _VT_co: ...
# stable
class SupportsGetItem(Protocol[_KT_contra, _VT_co]):
def __getitem__(self, key: _KT_contra, /) -> _VT_co: ...
# stable
class SupportsContainsAndGetItem(Protocol[_KT_contra, _VT_co]):
def __contains__(self, x: Any, /) -> bool: ...
def __getitem__(self, key: _KT_contra, /) -> _VT_co: ...
# stable
class SupportsItemAccess(Protocol[_KT_contra, _VT]):
def __contains__(self, x: Any, /) -> bool: ...
def __getitem__(self, key: _KT_contra, /) -> _VT: ...
def __setitem__(self, key: _KT_contra, value: _VT, /) -> None: ...
def __delitem__(self, key: _KT_contra, /) -> None: ...
StrPath: TypeAlias = str | PathLike[str] # stable
BytesPath: TypeAlias = bytes | PathLike[bytes] # stable
GenericPath: TypeAlias = AnyStr | PathLike[AnyStr]
StrOrBytesPath: TypeAlias = str | bytes | PathLike[str] | PathLike[bytes] # stable
OpenTextModeUpdating: TypeAlias = Literal[
"r+",
"+r",
"rt+",
"r+t",
"+rt",
"tr+",
"t+r",
"+tr",
"w+",
"+w",
"wt+",
"w+t",
"+wt",
"tw+",
"t+w",
"+tw",
"a+",
"+a",
"at+",
"a+t",
"+at",
"ta+",
"t+a",
"+ta",
"x+",
"+x",
"xt+",
"x+t",
"+xt",
"tx+",
"t+x",
"+tx",
]
OpenTextModeWriting: TypeAlias = Literal["w", "wt", "tw", "a", "at", "ta", "x", "xt", "tx"]
OpenTextModeReading: TypeAlias = Literal["r", "rt", "tr", "U", "rU", "Ur", "rtU", "rUt", "Urt", "trU", "tUr", "Utr"]
OpenTextMode: TypeAlias = OpenTextModeUpdating | OpenTextModeWriting | OpenTextModeReading
OpenBinaryModeUpdating: TypeAlias = Literal[
"rb+",
"r+b",
"+rb",
"br+",
"b+r",
"+br",
"wb+",
"w+b",
"+wb",
"bw+",
"b+w",
"+bw",
"ab+",
"a+b",
"+ab",
"ba+",
"b+a",
"+ba",
"xb+",
"x+b",
"+xb",
"bx+",
"b+x",
"+bx",
]
OpenBinaryModeWriting: TypeAlias = Literal["wb", "bw", "ab", "ba", "xb", "bx"]
OpenBinaryModeReading: TypeAlias = Literal["rb", "br", "rbU", "rUb", "Urb", "brU", "bUr", "Ubr"]
OpenBinaryMode: TypeAlias = OpenBinaryModeUpdating | OpenBinaryModeReading | OpenBinaryModeWriting
# stable
class HasFileno(Protocol):
def fileno(self) -> int: ...
FileDescriptor: TypeAlias = int # stable
FileDescriptorLike: TypeAlias = int | HasFileno # stable
FileDescriptorOrPath: TypeAlias = int | StrOrBytesPath
# stable
class SupportsRead(Protocol[_T_co]):
def read(self, length: int = ..., /) -> _T_co: ...
# stable
class SupportsReadline(Protocol[_T_co]):
def readline(self, length: int = ..., /) -> _T_co: ...
# stable
class SupportsNoArgReadline(Protocol[_T_co]):
def readline(self) -> _T_co: ...
# stable
class SupportsWrite(Protocol[_T_contra]):
def write(self, s: _T_contra, /) -> object: ...
# stable
class SupportsFlush(Protocol):
def flush(self) -> object: ...
# Unfortunately PEP 688 does not allow us to distinguish read-only
# from writable buffers. We use these aliases for readability for now.
# Perhaps a future extension of the buffer protocol will allow us to
# distinguish these cases in the type system.
ReadOnlyBuffer: TypeAlias = Buffer # stable
# Anything that implements the read-write buffer interface.
WriteableBuffer: TypeAlias = Buffer
# Same as WriteableBuffer, but also includes read-only buffer types (like bytes).
ReadableBuffer: TypeAlias = Buffer # stable
class SliceableBuffer(Buffer, Protocol):
def __getitem__(self, slice: slice, /) -> Sequence[int]: ...
class IndexableBuffer(Buffer, Protocol):
def __getitem__(self, i: int, /) -> int: ...
class SupportsGetItemBuffer(SliceableBuffer, IndexableBuffer, Protocol):
def __contains__(self, x: Any, /) -> bool: ...
@overload
def __getitem__(self, slice: slice, /) -> Sequence[int]: ...
@overload
def __getitem__(self, i: int, /) -> int: ...
class SizedBuffer(Sized, Buffer, Protocol): ...
# for compatibility with third-party stubs that may use this
_BufferWithLen: TypeAlias = SizedBuffer # not stable # noqa: Y047
ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType]
OptExcInfo: TypeAlias = ExcInfo | tuple[None, None, None]
# stable
if sys.version_info >= (3, 10):
from types import NoneType as NoneType
else:
# Used by type checkers for checks involving None (does not exist at runtime)
@final
class NoneType:
def __bool__(self) -> Literal[False]: ...
# This is an internal CPython type that is like, but subtly different from, a NamedTuple
# Subclasses of this type are found in multiple modules.
# In typeshed, `structseq` is only ever used as a mixin in combination with a fixed-length `Tuple`
# See discussion at #6546 & #6560
# `structseq` classes are unsubclassable, so are all decorated with `@final`.
class structseq(Generic[_T_co]):
n_fields: Final[int]
n_unnamed_fields: Final[int]
n_sequence_fields: Final[int]
# The first parameter will generally only take an iterable of a specific length.
# E.g. `os.uname_result` takes any iterable of length exactly 5.
#
# The second parameter will accept a dict of any kind without raising an exception,
# but only has any meaning if you supply it a dict where the keys are strings.
# https://github.com/python/typeshed/pull/6560#discussion_r767149830
def __new__(cls, sequence: Iterable[_T_co], dict: dict[str, Any] = ...) -> _Self: ...
if sys.version_info >= (3, 13):
def __replace__(self, **kwargs: Any) -> _Self: ...
# Superset of typing.AnyStr that also includes LiteralString
AnyOrLiteralStr = TypeVar("AnyOrLiteralStr", str, bytes, LiteralString) # noqa: Y001
# Represents when str or LiteralStr is acceptable. Useful for string processing
# APIs where literalness of return value depends on literalness of inputs
StrOrLiteralStr = TypeVar("StrOrLiteralStr", LiteralString, str) # noqa: Y001
# Objects suitable to be passed to sys.setprofile, threading.setprofile, and similar
ProfileFunction: TypeAlias = Callable[[FrameType, str, Any], object]
# Objects suitable to be passed to sys.settrace, threading.settrace, and similar
TraceFunction: TypeAlias = Callable[[FrameType, str, Any], TraceFunction | None]
# experimental
# Might not work as expected for pyright, see
# https://github.com/python/typeshed/pull/9362
# https://github.com/microsoft/pyright/issues/4339
class DataclassInstance(Protocol):
__dataclass_fields__: ClassVar[dict[str, Field[Any]]]
# Anything that can be passed to the int/float constructors
ConvertibleToInt: TypeAlias = str | ReadableBuffer | SupportsInt | SupportsIndex | SupportsTrunc
ConvertibleToFloat: TypeAlias = str | ReadableBuffer | SupportsFloat | SupportsIndex
# A few classes updated from Foo(str, Enum) to Foo(StrEnum). This is a convenience so these
# can be accurate on all python versions without getting too wordy
if sys.version_info >= (3, 11):
from enum import StrEnum as StrEnum
else:
from enum import Enum
class StrEnum(str, Enum): ...

View File

@@ -1,37 +0,0 @@
# PEP 249 Database API 2.0 Types
# https://www.python.org/dev/peps/pep-0249/
from collections.abc import Mapping, Sequence
from typing import Any, Protocol
from typing_extensions import TypeAlias
DBAPITypeCode: TypeAlias = Any | None
# Strictly speaking, this should be a Sequence, but the type system does
# not support fixed-length sequences.
DBAPIColumnDescription: TypeAlias = tuple[str, DBAPITypeCode, int | None, int | None, int | None, int | None, bool | None]
class DBAPIConnection(Protocol):
def close(self) -> object: ...
def commit(self) -> object: ...
# optional:
# def rollback(self) -> Any: ...
def cursor(self) -> DBAPICursor: ...
class DBAPICursor(Protocol):
@property
def description(self) -> Sequence[DBAPIColumnDescription] | None: ...
@property
def rowcount(self) -> int: ...
# optional:
# def callproc(self, procname: str, parameters: Sequence[Any] = ..., /) -> Sequence[Any]: ...
def close(self) -> object: ...
def execute(self, operation: str, parameters: Sequence[Any] | Mapping[str, Any] = ..., /) -> object: ...
def executemany(self, operation: str, seq_of_parameters: Sequence[Sequence[Any]], /) -> object: ...
def fetchone(self) -> Sequence[Any] | None: ...
def fetchmany(self, size: int = ..., /) -> Sequence[Sequence[Any]]: ...
def fetchall(self) -> Sequence[Sequence[Any]]: ...
# optional:
# def nextset(self) -> None | Literal[True]: ...
arraysize: int
def setinputsizes(self, sizes: Sequence[DBAPITypeCode | int | None], /) -> object: ...
def setoutputsize(self, size: int, column: int = ..., /) -> object: ...

View File

@@ -1,18 +0,0 @@
# Implicit protocols used in importlib.
# We intentionally omit deprecated and optional methods.
from collections.abc import Sequence
from importlib.machinery import ModuleSpec
from types import ModuleType
from typing import Protocol
__all__ = ["LoaderProtocol", "MetaPathFinderProtocol", "PathEntryFinderProtocol"]
class LoaderProtocol(Protocol):
def load_module(self, fullname: str, /) -> ModuleType: ...
class MetaPathFinderProtocol(Protocol):
def find_spec(self, fullname: str, path: Sequence[str] | None, target: ModuleType | None = ..., /) -> ModuleSpec | None: ...
class PathEntryFinderProtocol(Protocol):
def find_spec(self, fullname: str, target: ModuleType | None = ..., /) -> ModuleSpec | None: ...

View File

@@ -1,44 +0,0 @@
# Types to support PEP 3333 (WSGI)
#
# Obsolete since Python 3.11: Use wsgiref.types instead.
#
# See the README.md file in this directory for more information.
import sys
from _typeshed import OptExcInfo
from collections.abc import Callable, Iterable, Iterator
from typing import Any, Protocol
from typing_extensions import TypeAlias
class _Readable(Protocol):
def read(self, size: int = ..., /) -> bytes: ...
# Optional: def close(self) -> object: ...
if sys.version_info >= (3, 11):
from wsgiref.types import *
else:
# stable
class StartResponse(Protocol):
def __call__(
self, status: str, headers: list[tuple[str, str]], exc_info: OptExcInfo | None = ..., /
) -> Callable[[bytes], object]: ...
WSGIEnvironment: TypeAlias = dict[str, Any] # stable
WSGIApplication: TypeAlias = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] # stable
# WSGI input streams per PEP 3333, stable
class InputStream(Protocol):
def read(self, size: int = ..., /) -> bytes: ...
def readline(self, size: int = ..., /) -> bytes: ...
def readlines(self, hint: int = ..., /) -> list[bytes]: ...
def __iter__(self) -> Iterator[bytes]: ...
# WSGI error streams per PEP 3333, stable
class ErrorStream(Protocol):
def flush(self) -> object: ...
def write(self, s: str, /) -> object: ...
def writelines(self, seq: list[str], /) -> object: ...
# Optional file wrapper in wsgi.file_wrapper
class FileWrapper(Protocol):
def __call__(self, file: _Readable, block_size: int = ..., /) -> Iterable[bytes]: ...

View File

@@ -1,9 +0,0 @@
# See the README.md file in this directory for more information.
from typing import Any, Protocol
# As defined https://docs.python.org/3/library/xml.dom.html#domimplementation-objects
class DOMImplementation(Protocol):
def hasFeature(self, feature: str, version: str | None, /) -> bool: ...
def createDocument(self, namespaceUri: str, qualifiedName: str, doctype: Any | None, /) -> Any: ...
def createDocumentType(self, qualifiedName: str, publicId: str, systemId: str, /) -> Any: ...

View File

@@ -1,990 +0,0 @@
# ruff: noqa: PLR5501 # This condition is so big, it's clearer to keep to platform condition in two blocks
# Can't NOQA on a specific line: https://github.com/plinss/flake8-noqa/issues/22
import sys
from collections.abc import Awaitable, Coroutine, Generator
from typing import Any, TypeVar
from typing_extensions import TypeAlias
# As at runtime, this depends on all submodules defining __all__ accurately.
from .base_events import *
from .coroutines import *
from .events import *
from .exceptions import *
from .futures import *
from .locks import *
from .protocols import *
from .queues import *
from .runners import *
from .streams import *
from .subprocess import *
from .tasks import *
from .threads import *
from .transports import *
if sys.version_info >= (3, 11):
from .taskgroups import *
from .timeouts import *
if sys.platform == "win32":
from .windows_events import *
else:
from .unix_events import *
if sys.platform == "win32":
if sys.version_info >= (3, 14):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"_set_running_loop", # from events
"get_running_loop", # from events
"_get_running_loop", # from events
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"QueueShutDown", # 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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
"EventLoop", # from windows_events
)
elif sys.version_info >= (3, 13):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"QueueShutDown", # 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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
"EventLoop", # from windows_events
)
elif sys.version_info >= (3, 12):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
)
elif sys.version_info >= (3, 11):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"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
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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:
__all__ = (
"BaseEventLoop", # from base_events
"Server", # 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
"to_thread", # from threads
"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__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"_set_running_loop", # from events
"get_running_loop", # from events
"_get_running_loop", # from events
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"QueueShutDown", # 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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"BaseTransport", # from transports
"ReadTransport", # from transports
"WriteTransport", # from transports
"Transport", # from transports
"DatagramTransport", # from transports
"SubprocessTransport", # from transports
"SelectorEventLoop", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
"EventLoop", # from unix_events
)
elif sys.version_info >= (3, 13):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"run", # from runners
"Queue", # from queues
"PriorityQueue", # from queues
"LifoQueue", # from queues
"QueueFull", # from queues
"QueueEmpty", # from queues
"QueueShutDown", # 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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
"PidfdChildWatcher", # from unix_events
"MultiLoopChildWatcher", # from unix_events
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
"EventLoop", # from unix_events
)
elif sys.version_info >= (3, 12):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"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
"create_eager_task_factory", # from tasks
"eager_task_factory", # from tasks
"_register_task", # from tasks
"_unregister_task", # from tasks
"_enter_task", # from tasks
"_leave_task", # from tasks
"TaskGroup", # from taskgroups
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
"PidfdChildWatcher", # from unix_events
"MultiLoopChildWatcher", # from unix_events
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
elif sys.version_info >= (3, 11):
__all__ = (
"BaseEventLoop", # from base_events
"Server", # from base_events
"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
"BrokenBarrierError", # from exceptions
"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
"Barrier", # from locks
"BaseProtocol", # from protocols
"Protocol", # from protocols
"DatagramProtocol", # from protocols
"SubprocessProtocol", # from protocols
"BufferedProtocol", # from protocols
"Runner", # from runners
"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
"to_thread", # from threads
"Timeout", # from timeouts
"timeout", # from timeouts
"timeout_at", # from timeouts
"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
"PidfdChildWatcher", # from unix_events
"MultiLoopChildWatcher", # from unix_events
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
else:
__all__ = (
"BaseEventLoop", # from base_events
"Server", # 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
"to_thread", # from threads
"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
"PidfdChildWatcher", # from unix_events
"MultiLoopChildWatcher", # from unix_events
"ThreadedChildWatcher", # from unix_events
"DefaultEventLoopPolicy", # from unix_events
)
_T_co = TypeVar("_T_co", covariant=True)
# Aliases imported by multiple submodules in typeshed
if sys.version_info >= (3, 12):
_AwaitableLike: TypeAlias = Awaitable[_T_co] # noqa: Y047
_CoroutineLike: TypeAlias = Coroutine[Any, Any, _T_co] # noqa: Y047
else:
_AwaitableLike: TypeAlias = Generator[Any, None, _T_co] | Awaitable[_T_co]
_CoroutineLike: TypeAlias = Generator[Any, None, _T_co] | Coroutine[Any, Any, _T_co]

View File

@@ -1,488 +0,0 @@
import ssl
import sys
from _typeshed import FileDescriptorLike, ReadableBuffer, WriteableBuffer
from asyncio import _AwaitableLike, _CoroutineLike
from asyncio.events import AbstractEventLoop, AbstractServer, Handle, TimerHandle, _TaskFactory
from asyncio.futures import Future
from asyncio.protocols import BaseProtocol
from asyncio.tasks import Task
from asyncio.transports import BaseTransport, DatagramTransport, ReadTransport, SubprocessTransport, Transport, WriteTransport
from collections.abc import Callable, Iterable, Sequence
from concurrent.futures import Executor, ThreadPoolExecutor
from contextvars import Context
from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket
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
__all__ = ("BaseEventLoop", "Server")
_T = TypeVar("_T")
_Ts = TypeVarTuple("_Ts")
_ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol)
_Context: TypeAlias = dict[str, Any]
_ExceptionHandler: TypeAlias = Callable[[AbstractEventLoop, _Context], object]
_ProtocolFactory: TypeAlias = Callable[[], BaseProtocol]
_SSLContext: TypeAlias = bool | None | ssl.SSLContext
class Server(AbstractServer):
if sys.version_info >= (3, 11):
def __init__(
self,
loop: AbstractEventLoop,
sockets: Iterable[socket],
protocol_factory: _ProtocolFactory,
ssl_context: _SSLContext,
backlog: int,
ssl_handshake_timeout: float | None,
ssl_shutdown_timeout: float | None = None,
) -> None: ...
else:
def __init__(
self,
loop: AbstractEventLoop,
sockets: Iterable[socket],
protocol_factory: _ProtocolFactory,
ssl_context: _SSLContext,
backlog: int,
ssl_handshake_timeout: float | None,
) -> None: ...
if sys.version_info >= (3, 13):
def close_clients(self) -> None: ...
def abort_clients(self) -> None: ...
def get_loop(self) -> AbstractEventLoop: ...
def is_serving(self) -> bool: ...
async def start_serving(self) -> None: ...
async def serve_forever(self) -> None: ...
@property
def sockets(self) -> tuple[socket, ...]: ...
def close(self) -> None: ...
async def wait_closed(self) -> None: ...
class BaseEventLoop(AbstractEventLoop):
def run_forever(self) -> None: ...
def run_until_complete(self, future: _AwaitableLike[_T]) -> _T: ...
def stop(self) -> None: ...
def is_running(self) -> bool: ...
def is_closed(self) -> bool: ...
def close(self) -> None: ...
async def shutdown_asyncgens(self) -> None: ...
# Methods scheduling callbacks. All these return Handles.
def call_soon(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
def call_later(
self, delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
def call_at(
self, when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> TimerHandle: ...
def time(self) -> float: ...
# Future methods
def create_future(self) -> Future[Any]: ...
# Tasks methods
if sys.version_info >= (3, 11):
def create_task(self, coro: _CoroutineLike[_T], *, name: object = None, context: Context | None = None) -> Task[_T]: ...
else:
def create_task(self, coro: _CoroutineLike[_T], *, name: object = None) -> Task[_T]: ...
def set_task_factory(self, factory: _TaskFactory | None) -> None: ...
def get_task_factory(self) -> _TaskFactory | None: ...
# Methods for interacting with threads
def call_soon_threadsafe(
self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], context: Context | None = None
) -> Handle: ...
def run_in_executor(self, executor: Executor | None, func: Callable[[Unpack[_Ts]], _T], *args: Unpack[_Ts]) -> Future[_T]: ...
def set_default_executor(self, executor: ThreadPoolExecutor) -> None: ... # type: ignore[override]
# Network I/O methods returning Futures.
async def getaddrinfo(
self,
host: bytes | str | None,
port: bytes | str | int | None,
*,
family: int = 0,
type: int = 0,
proto: int = 0,
flags: int = 0,
) -> list[tuple[AddressFamily, SocketKind, int, str, tuple[str, int] | tuple[str, int, int, int]]]: ...
async def getnameinfo(self, sockaddr: tuple[str, int] | tuple[str, int, int, int], flags: int = 0) -> tuple[str, str]: ...
if sys.version_info >= (3, 12):
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: str = ...,
port: int = ...,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: None = None,
local_addr: tuple[str, int] | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
all_errors: bool = False,
) -> tuple[Transport, _ProtocolT]: ...
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: None = None,
port: None = None,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: socket,
local_addr: None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
all_errors: bool = False,
) -> tuple[Transport, _ProtocolT]: ...
elif sys.version_info >= (3, 11):
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: str = ...,
port: int = ...,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: None = None,
local_addr: tuple[str, int] | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: None = None,
port: None = None,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: socket,
local_addr: None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
else:
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: str = ...,
port: int = ...,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: None = None,
local_addr: tuple[str, int] | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
@overload
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: None = None,
port: None = None,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: socket,
local_addr: None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
if sys.version_info >= (3, 13):
# 3.13 added `keep_alive`.
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
keep_alive: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
keep_alive: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
elif sys.version_info >= (3, 11):
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
else:
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
if sys.version_info >= (3, 11):
async def start_tls(
self,
transport: BaseTransport,
protocol: BaseProtocol,
sslcontext: ssl.SSLContext,
*,
server_side: bool = False,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> Transport | None: ...
async def connect_accepted_socket(
self,
protocol_factory: Callable[[], _ProtocolT],
sock: socket,
*,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
else:
async def start_tls(
self,
transport: BaseTransport,
protocol: BaseProtocol,
sslcontext: ssl.SSLContext,
*,
server_side: bool = False,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
) -> Transport | None: ...
async def connect_accepted_socket(
self,
protocol_factory: Callable[[], _ProtocolT],
sock: socket,
*,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
async def sock_sendfile(
self, sock: socket, file: IO[bytes], offset: int = 0, count: int | None = None, *, fallback: bool | None = True
) -> int: ...
async def sendfile(
self, transport: WriteTransport, file: IO[bytes], offset: int = 0, count: int | None = None, *, fallback: bool = True
) -> int: ...
if sys.version_info >= (3, 11):
async def create_datagram_endpoint( # type: ignore[override]
self,
protocol_factory: Callable[[], _ProtocolT],
local_addr: tuple[str, int] | str | None = None,
remote_addr: tuple[str, int] | str | None = None,
*,
family: int = 0,
proto: int = 0,
flags: int = 0,
reuse_port: bool | None = None,
allow_broadcast: bool | None = None,
sock: socket | None = None,
) -> tuple[DatagramTransport, _ProtocolT]: ...
else:
async def create_datagram_endpoint(
self,
protocol_factory: Callable[[], _ProtocolT],
local_addr: tuple[str, int] | str | None = None,
remote_addr: tuple[str, int] | str | None = None,
*,
family: int = 0,
proto: int = 0,
flags: int = 0,
reuse_address: bool | None = ...,
reuse_port: bool | None = None,
allow_broadcast: bool | None = None,
sock: socket | None = None,
) -> tuple[DatagramTransport, _ProtocolT]: ...
# Pipes and subprocesses.
async def connect_read_pipe(
self, protocol_factory: Callable[[], _ProtocolT], pipe: Any
) -> tuple[ReadTransport, _ProtocolT]: ...
async def connect_write_pipe(
self, protocol_factory: Callable[[], _ProtocolT], pipe: Any
) -> tuple[WriteTransport, _ProtocolT]: ...
async def subprocess_shell(
self,
protocol_factory: Callable[[], _ProtocolT],
cmd: bytes | str,
*,
stdin: int | IO[Any] | None = -1,
stdout: int | IO[Any] | None = -1,
stderr: int | IO[Any] | None = -1,
universal_newlines: Literal[False] = False,
shell: Literal[True] = True,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
**kwargs: Any,
) -> tuple[SubprocessTransport, _ProtocolT]: ...
async def subprocess_exec(
self,
protocol_factory: Callable[[], _ProtocolT],
program: Any,
*args: Any,
stdin: int | IO[Any] | None = -1,
stdout: int | IO[Any] | None = -1,
stderr: int | IO[Any] | None = -1,
universal_newlines: Literal[False] = False,
shell: Literal[False] = False,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
**kwargs: Any,
) -> tuple[SubprocessTransport, _ProtocolT]: ...
def add_reader(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ...
def remove_reader(self, fd: FileDescriptorLike) -> bool: ...
def add_writer(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ...
def remove_writer(self, fd: FileDescriptorLike) -> bool: ...
# The sock_* methods (and probably some others) are not actually implemented on
# BaseEventLoop, only on subclasses. We list them here for now for convenience.
async def sock_recv(self, sock: socket, nbytes: int) -> bytes: ...
async def sock_recv_into(self, sock: socket, buf: WriteableBuffer) -> int: ...
async def sock_sendall(self, sock: socket, data: ReadableBuffer) -> None: ...
async def sock_connect(self, sock: socket, address: _Address) -> None: ...
async def sock_accept(self, sock: socket) -> tuple[socket, _RetAddress]: ...
if sys.version_info >= (3, 11):
async def sock_recvfrom(self, sock: socket, bufsize: int) -> tuple[bytes, _RetAddress]: ...
async def sock_recvfrom_into(self, sock: socket, buf: WriteableBuffer, nbytes: int = 0) -> tuple[int, _RetAddress]: ...
async def sock_sendto(self, sock: socket, data: ReadableBuffer, address: _Address) -> int: ...
# Signal handling.
def add_signal_handler(self, sig: int, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ...
def remove_signal_handler(self, sig: int) -> bool: ...
# Error handlers.
def set_exception_handler(self, handler: _ExceptionHandler | None) -> None: ...
def get_exception_handler(self) -> _ExceptionHandler | None: ...
def default_exception_handler(self, context: _Context) -> None: ...
def call_exception_handler(self, context: _Context) -> None: ...
# Debug flag management.
def get_debug(self) -> bool: ...
def set_debug(self, enabled: bool) -> None: ...
if sys.version_info >= (3, 12):
async def shutdown_default_executor(self, timeout: float | None = None) -> None: ...
else:
async def shutdown_default_executor(self) -> None: ...
def __del__(self) -> None: ...

View File

@@ -1,19 +0,0 @@
from collections.abc import Callable, Sequence
from contextvars import Context
from typing import Any, Final
from . import futures
__all__ = ()
# asyncio defines 'isfuture()' in base_futures.py and re-imports it in futures.py
# but it leads to circular import error in pytype tool.
# That's why the import order is reversed.
from .futures import isfuture as isfuture
_PENDING: Final = "PENDING" # undocumented
_CANCELLED: Final = "CANCELLED" # undocumented
_FINISHED: Final = "FINISHED" # undocumented
def _format_callbacks(cb: Sequence[tuple[Callable[[futures.Future[Any]], None], Context]]) -> str: ... # undocumented
def _future_repr_info(future: futures.Future[Any]) -> list[str]: ... # undocumented

View File

@@ -1,63 +0,0 @@
import subprocess
from collections import deque
from collections.abc import Callable, Sequence
from typing import IO, Any
from typing_extensions import TypeAlias
from . import events, futures, protocols, transports
_File: TypeAlias = int | IO[Any] | None
class BaseSubprocessTransport(transports.SubprocessTransport):
_closed: bool # undocumented
_protocol: protocols.SubprocessProtocol # undocumented
_loop: events.AbstractEventLoop # undocumented
_proc: subprocess.Popen[Any] | None # undocumented
_pid: int | None # undocumented
_returncode: int | None # undocumented
_exit_waiters: list[futures.Future[Any]] # undocumented
_pending_calls: deque[tuple[Callable[..., Any], tuple[Any, ...]]] # undocumented
_pipes: dict[int, _File] # undocumented
_finished: bool # undocumented
def __init__(
self,
loop: events.AbstractEventLoop,
protocol: protocols.SubprocessProtocol,
args: str | bytes | Sequence[str | bytes],
shell: bool,
stdin: _File,
stdout: _File,
stderr: _File,
bufsize: int,
waiter: futures.Future[Any] | None = None,
extra: Any | None = None,
**kwargs: Any,
) -> None: ...
def _start(
self,
args: str | bytes | Sequence[str | bytes],
shell: bool,
stdin: _File,
stdout: _File,
stderr: _File,
bufsize: int,
**kwargs: Any,
) -> None: ... # undocumented
def get_pid(self) -> int | None: ... # type: ignore[override]
def get_pipe_transport(self, fd: int) -> _File: ... # type: ignore[override]
def _check_proc(self) -> None: ... # undocumented
def send_signal(self, signal: int) -> None: ...
async def _connect_pipes(self, waiter: futures.Future[Any] | None) -> None: ... # undocumented
def _call(self, cb: Callable[..., object], *data: Any) -> None: ... # undocumented
def _pipe_connection_lost(self, fd: int, exc: BaseException | None) -> None: ... # undocumented
def _pipe_data_received(self, fd: int, data: bytes) -> None: ... # undocumented
def _process_exited(self, returncode: int) -> None: ... # undocumented
async def _wait(self) -> int: ... # undocumented
def _try_finish(self) -> None: ... # undocumented
def _call_connection_lost(self, exc: BaseException | None) -> None: ... # undocumented
def __del__(self) -> None: ...
class WriteSubprocessPipeProto(protocols.BaseProtocol): # undocumented
def __init__(self, proc: BaseSubprocessTransport, fd: int) -> None: ...
class ReadSubprocessPipeProto(WriteSubprocessPipeProto, protocols.Protocol): ... # undocumented

View File

@@ -1,9 +0,0 @@
from _typeshed import StrOrBytesPath
from types import FrameType
from typing import Any
from . import tasks
def _task_repr_info(task: tasks.Task[Any]) -> list[str]: ... # undocumented
def _task_get_stack(task: tasks.Task[Any], limit: int | None) -> list[FrameType]: ... # undocumented
def _task_print_stack(task: tasks.Task[Any], limit: int | None, file: StrOrBytesPath) -> None: ... # undocumented

View File

@@ -1,20 +0,0 @@
import enum
import sys
from typing import Final
LOG_THRESHOLD_FOR_CONNLOST_WRITES: Final = 5
ACCEPT_RETRY_DELAY: Final = 1
DEBUG_STACK_DEPTH: Final = 10
SSL_HANDSHAKE_TIMEOUT: float
SENDFILE_FALLBACK_READBUFFER_SIZE: Final = 262144
if sys.version_info >= (3, 11):
SSL_SHUTDOWN_TIMEOUT: float
FLOW_CONTROL_HIGH_WATER_SSL_READ: Final = 256
FLOW_CONTROL_HIGH_WATER_SSL_WRITE: Final = 512
if sys.version_info >= (3, 12):
THREAD_JOIN_TIMEOUT: Final = 300
class _SendfileMode(enum.Enum):
UNSUPPORTED = 1
TRY_NATIVE = 2
FALLBACK = 3

View File

@@ -1,27 +0,0 @@
import sys
from collections.abc import Awaitable, Callable, Coroutine
from typing import Any, TypeVar, overload
from typing_extensions import ParamSpec, TypeGuard, TypeIs
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 11):
__all__ = ("iscoroutinefunction", "iscoroutine")
else:
__all__ = ("coroutine", "iscoroutinefunction", "iscoroutine")
_T = TypeVar("_T")
_FunctionT = TypeVar("_FunctionT", bound=Callable[..., Any])
_P = ParamSpec("_P")
if sys.version_info < (3, 11):
def coroutine(func: _FunctionT) -> _FunctionT: ...
@overload
def iscoroutinefunction(func: Callable[..., Coroutine[Any, Any, Any]]) -> bool: ...
@overload
def iscoroutinefunction(func: Callable[_P, Awaitable[_T]]) -> TypeGuard[Callable[_P, Coroutine[Any, Any, _T]]]: ...
@overload
def iscoroutinefunction(func: Callable[_P, object]) -> TypeGuard[Callable[_P, Coroutine[Any, Any, Any]]]: ...
@overload
def iscoroutinefunction(func: object) -> TypeGuard[Callable[..., Coroutine[Any, Any, Any]]]: ...
def iscoroutine(obj: object) -> TypeIs[Coroutine[Any, Any, Any]]: ...

View File

@@ -1,642 +0,0 @@
import ssl
import sys
from _asyncio import (
_get_running_loop as _get_running_loop,
_set_running_loop as _set_running_loop,
get_event_loop as get_event_loop,
get_running_loop as get_running_loop,
)
from _typeshed import FileDescriptorLike, ReadableBuffer, StrPath, Unused, WriteableBuffer
from abc import ABCMeta, abstractmethod
from collections.abc import Callable, Sequence
from concurrent.futures import Executor
from contextvars import Context
from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket
from typing import IO, Any, Literal, Protocol, TypeVar, overload
from typing_extensions import Self, TypeAlias, TypeVarTuple, Unpack, deprecated
from . import _AwaitableLike, _CoroutineLike
from .base_events import Server
from .futures import Future
from .protocols import BaseProtocol
from .tasks import Task
from .transports import BaseTransport, DatagramTransport, ReadTransport, SubprocessTransport, Transport, WriteTransport
from .unix_events import AbstractChildWatcher
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 14):
__all__ = (
"AbstractEventLoopPolicy",
"AbstractEventLoop",
"AbstractServer",
"Handle",
"TimerHandle",
"get_event_loop_policy",
"set_event_loop_policy",
"get_event_loop",
"set_event_loop",
"new_event_loop",
"_set_running_loop",
"get_running_loop",
"_get_running_loop",
)
else:
__all__ = (
"AbstractEventLoopPolicy",
"AbstractEventLoop",
"AbstractServer",
"Handle",
"TimerHandle",
"get_event_loop_policy",
"set_event_loop_policy",
"get_event_loop",
"set_event_loop",
"new_event_loop",
"get_child_watcher",
"set_child_watcher",
"_set_running_loop",
"get_running_loop",
"_get_running_loop",
)
_T = TypeVar("_T")
_Ts = TypeVarTuple("_Ts")
_ProtocolT = TypeVar("_ProtocolT", bound=BaseProtocol)
_Context: TypeAlias = dict[str, Any]
_ExceptionHandler: TypeAlias = Callable[[AbstractEventLoop, _Context], object]
_ProtocolFactory: TypeAlias = Callable[[], BaseProtocol]
_SSLContext: TypeAlias = bool | None | ssl.SSLContext
class _TaskFactory(Protocol):
def __call__(self, loop: AbstractEventLoop, factory: _CoroutineLike[_T], /) -> Future[_T]: ...
class Handle:
_cancelled: bool
_args: Sequence[Any]
def __init__(
self, callback: Callable[..., object], args: Sequence[Any], loop: AbstractEventLoop, context: Context | None = None
) -> None: ...
def cancel(self) -> None: ...
def _run(self) -> None: ...
def cancelled(self) -> bool: ...
if sys.version_info >= (3, 12):
def get_context(self) -> Context: ...
class TimerHandle(Handle):
def __init__(
self,
when: float,
callback: Callable[..., object],
args: Sequence[Any],
loop: AbstractEventLoop,
context: Context | None = None,
) -> None: ...
def __hash__(self) -> int: ...
def when(self) -> float: ...
def __lt__(self, other: TimerHandle) -> bool: ...
def __le__(self, other: TimerHandle) -> bool: ...
def __gt__(self, other: TimerHandle) -> bool: ...
def __ge__(self, other: TimerHandle) -> bool: ...
def __eq__(self, other: object) -> bool: ...
class AbstractServer:
@abstractmethod
def close(self) -> None: ...
if sys.version_info >= (3, 13):
@abstractmethod
def close_clients(self) -> None: ...
@abstractmethod
def abort_clients(self) -> None: ...
async def __aenter__(self) -> Self: ...
async def __aexit__(self, *exc: Unused) -> None: ...
@abstractmethod
def get_loop(self) -> AbstractEventLoop: ...
@abstractmethod
def is_serving(self) -> bool: ...
@abstractmethod
async def start_serving(self) -> None: ...
@abstractmethod
async def serve_forever(self) -> None: ...
@abstractmethod
async def wait_closed(self) -> None: ...
class AbstractEventLoop:
slow_callback_duration: float
@abstractmethod
def run_forever(self) -> None: ...
@abstractmethod
def run_until_complete(self, future: _AwaitableLike[_T]) -> _T: ...
@abstractmethod
def stop(self) -> None: ...
@abstractmethod
def is_running(self) -> bool: ...
@abstractmethod
def is_closed(self) -> bool: ...
@abstractmethod
def close(self) -> None: ...
@abstractmethod
async def shutdown_asyncgens(self) -> None: ...
# Methods scheduling callbacks. All these return Handles.
# "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
@abstractmethod
def create_future(self) -> Future[Any]: ...
# Tasks methods
if sys.version_info >= (3, 11):
@abstractmethod
def create_task(
self, coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None
) -> Task[_T]: ...
else:
@abstractmethod
def create_task(self, coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ...
@abstractmethod
def set_task_factory(self, factory: _TaskFactory | None) -> None: ...
@abstractmethod
def get_task_factory(self) -> _TaskFactory | None: ...
# Methods for interacting with threads
# "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
def set_default_executor(self, executor: Executor) -> None: ...
# Network I/O methods returning Futures.
@abstractmethod
async def getaddrinfo(
self,
host: bytes | str | None,
port: bytes | str | int | None,
*,
family: int = 0,
type: int = 0,
proto: int = 0,
flags: int = 0,
) -> list[tuple[AddressFamily, SocketKind, int, str, tuple[str, int] | tuple[str, int, int, int]]]: ...
@abstractmethod
async def getnameinfo(self, sockaddr: tuple[str, int] | tuple[str, int, int, int], flags: int = 0) -> tuple[str, str]: ...
if sys.version_info >= (3, 11):
@overload
@abstractmethod
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: str = ...,
port: int = ...,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: None = None,
local_addr: tuple[str, int] | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
@overload
@abstractmethod
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: None = None,
port: None = None,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: socket,
local_addr: None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
else:
@overload
@abstractmethod
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: str = ...,
port: int = ...,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: None = None,
local_addr: tuple[str, int] | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
@overload
@abstractmethod
async def create_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
host: None = None,
port: None = None,
*,
ssl: _SSLContext = None,
family: int = 0,
proto: int = 0,
flags: int = 0,
sock: socket,
local_addr: None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
happy_eyeballs_delay: float | None = None,
interleave: int | None = None,
) -> tuple[Transport, _ProtocolT]: ...
if sys.version_info >= (3, 13):
# 3.13 added `keep_alive`.
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
keep_alive: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
keep_alive: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
elif sys.version_info >= (3, 11):
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
else:
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: str | Sequence[str] | None = None,
port: int = ...,
*,
family: int = ...,
flags: int = ...,
sock: None = None,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
@overload
@abstractmethod
async def create_server(
self,
protocol_factory: _ProtocolFactory,
host: None = None,
port: None = None,
*,
family: int = ...,
flags: int = ...,
sock: socket = ...,
backlog: int = 100,
ssl: _SSLContext = None,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
ssl_handshake_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
if sys.version_info >= (3, 11):
@abstractmethod
async def start_tls(
self,
transport: WriteTransport,
protocol: BaseProtocol,
sslcontext: ssl.SSLContext,
*,
server_side: bool = False,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> Transport | None: ...
async def create_unix_server(
self,
protocol_factory: _ProtocolFactory,
path: StrPath | None = None,
*,
sock: socket | None = None,
backlog: int = 100,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
else:
@abstractmethod
async def start_tls(
self,
transport: BaseTransport,
protocol: BaseProtocol,
sslcontext: ssl.SSLContext,
*,
server_side: bool = False,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
) -> Transport | None: ...
async def create_unix_server(
self,
protocol_factory: _ProtocolFactory,
path: StrPath | None = None,
*,
sock: socket | None = None,
backlog: int = 100,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
start_serving: bool = True,
) -> Server: ...
if sys.version_info >= (3, 11):
async def connect_accepted_socket(
self,
protocol_factory: Callable[[], _ProtocolT],
sock: socket,
*,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
elif sys.version_info >= (3, 10):
async def connect_accepted_socket(
self,
protocol_factory: Callable[[], _ProtocolT],
sock: socket,
*,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
if sys.version_info >= (3, 11):
async def create_unix_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
path: str | None = None,
*,
ssl: _SSLContext = None,
sock: socket | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
else:
async def create_unix_connection(
self,
protocol_factory: Callable[[], _ProtocolT],
path: str | None = None,
*,
ssl: _SSLContext = None,
sock: socket | None = None,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
) -> tuple[Transport, _ProtocolT]: ...
@abstractmethod
async def sock_sendfile(
self, sock: socket, file: IO[bytes], offset: int = 0, count: int | None = None, *, fallback: bool | None = None
) -> int: ...
@abstractmethod
async def sendfile(
self, transport: WriteTransport, file: IO[bytes], offset: int = 0, count: int | None = None, *, fallback: bool = True
) -> int: ...
@abstractmethod
async def create_datagram_endpoint(
self,
protocol_factory: Callable[[], _ProtocolT],
local_addr: tuple[str, int] | str | None = None,
remote_addr: tuple[str, int] | str | None = None,
*,
family: int = 0,
proto: int = 0,
flags: int = 0,
reuse_address: bool | None = None,
reuse_port: bool | None = None,
allow_broadcast: bool | None = None,
sock: socket | None = None,
) -> tuple[DatagramTransport, _ProtocolT]: ...
# Pipes and subprocesses.
@abstractmethod
async def connect_read_pipe(
self, protocol_factory: Callable[[], _ProtocolT], pipe: Any
) -> tuple[ReadTransport, _ProtocolT]: ...
@abstractmethod
async def connect_write_pipe(
self, protocol_factory: Callable[[], _ProtocolT], pipe: Any
) -> tuple[WriteTransport, _ProtocolT]: ...
@abstractmethod
async def subprocess_shell(
self,
protocol_factory: Callable[[], _ProtocolT],
cmd: bytes | str,
*,
stdin: int | IO[Any] | None = -1,
stdout: int | IO[Any] | None = -1,
stderr: int | IO[Any] | None = -1,
universal_newlines: Literal[False] = False,
shell: Literal[True] = True,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = ...,
**kwargs: Any,
) -> tuple[SubprocessTransport, _ProtocolT]: ...
@abstractmethod
async def subprocess_exec(
self,
protocol_factory: Callable[[], _ProtocolT],
program: Any,
*args: Any,
stdin: int | IO[Any] | None = -1,
stdout: int | IO[Any] | None = -1,
stderr: int | IO[Any] | None = -1,
universal_newlines: Literal[False] = False,
shell: Literal[False] = False,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
**kwargs: Any,
) -> tuple[SubprocessTransport, _ProtocolT]: ...
@abstractmethod
def add_reader(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ...
@abstractmethod
def remove_reader(self, fd: FileDescriptorLike) -> bool: ...
@abstractmethod
def add_writer(self, fd: FileDescriptorLike, callback: Callable[[Unpack[_Ts]], Any], *args: Unpack[_Ts]) -> None: ...
@abstractmethod
def remove_writer(self, fd: FileDescriptorLike) -> bool: ...
@abstractmethod
async def sock_recv(self, sock: socket, nbytes: int) -> bytes: ...
@abstractmethod
async def sock_recv_into(self, sock: socket, buf: WriteableBuffer) -> int: ...
@abstractmethod
async def sock_sendall(self, sock: socket, data: ReadableBuffer) -> None: ...
@abstractmethod
async def sock_connect(self, sock: socket, address: _Address) -> None: ...
@abstractmethod
async def sock_accept(self, sock: socket) -> tuple[socket, _RetAddress]: ...
if sys.version_info >= (3, 11):
@abstractmethod
async def sock_recvfrom(self, sock: socket, bufsize: int) -> tuple[bytes, _RetAddress]: ...
@abstractmethod
async def sock_recvfrom_into(self, sock: socket, buf: WriteableBuffer, nbytes: int = 0) -> tuple[int, _RetAddress]: ...
@abstractmethod
async def sock_sendto(self, sock: socket, data: ReadableBuffer, address: _Address) -> int: ...
# Signal handling.
@abstractmethod
def add_signal_handler(self, sig: int, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts]) -> None: ...
@abstractmethod
def remove_signal_handler(self, sig: int) -> bool: ...
# Error handlers.
@abstractmethod
def set_exception_handler(self, handler: _ExceptionHandler | None) -> None: ...
@abstractmethod
def get_exception_handler(self) -> _ExceptionHandler | None: ...
@abstractmethod
def default_exception_handler(self, context: _Context) -> None: ...
@abstractmethod
def call_exception_handler(self, context: _Context) -> None: ...
# Debug flag management.
@abstractmethod
def get_debug(self) -> bool: ...
@abstractmethod
def set_debug(self, enabled: bool) -> None: ...
@abstractmethod
async def shutdown_default_executor(self) -> None: ...
class AbstractEventLoopPolicy:
@abstractmethod
def get_event_loop(self) -> AbstractEventLoop: ...
@abstractmethod
def set_event_loop(self, loop: AbstractEventLoop | None) -> None: ...
@abstractmethod
def new_event_loop(self) -> AbstractEventLoop: ...
# Child processes handling (Unix only).
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
@abstractmethod
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def get_child_watcher(self) -> AbstractChildWatcher: ...
@abstractmethod
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ...
else:
@abstractmethod
def get_child_watcher(self) -> AbstractChildWatcher: ...
@abstractmethod
def set_child_watcher(self, watcher: AbstractChildWatcher) -> None: ...
class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy, metaclass=ABCMeta):
def get_event_loop(self) -> AbstractEventLoop: ...
def set_event_loop(self, loop: AbstractEventLoop | None) -> None: ...
def new_event_loop(self) -> AbstractEventLoop: ...
def get_event_loop_policy() -> AbstractEventLoopPolicy: ...
def set_event_loop_policy(policy: AbstractEventLoopPolicy | None) -> None: ...
def set_event_loop(loop: AbstractEventLoop | None) -> None: ...
def new_event_loop() -> AbstractEventLoop: ...
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def get_child_watcher() -> AbstractChildWatcher: ...
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def set_child_watcher(watcher: AbstractChildWatcher) -> None: ...
else:
def get_child_watcher() -> AbstractChildWatcher: ...
def set_child_watcher(watcher: AbstractChildWatcher) -> None: ...

View File

@@ -1,44 +0,0 @@
import sys
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 11):
__all__ = (
"BrokenBarrierError",
"CancelledError",
"InvalidStateError",
"TimeoutError",
"IncompleteReadError",
"LimitOverrunError",
"SendfileNotAvailableError",
)
else:
__all__ = (
"CancelledError",
"InvalidStateError",
"TimeoutError",
"IncompleteReadError",
"LimitOverrunError",
"SendfileNotAvailableError",
)
class CancelledError(BaseException): ...
if sys.version_info >= (3, 11):
from builtins import TimeoutError as TimeoutError
else:
class TimeoutError(Exception): ...
class InvalidStateError(Exception): ...
class SendfileNotAvailableError(RuntimeError): ...
class IncompleteReadError(EOFError):
expected: int | None
partial: bytes
def __init__(self, partial: bytes, expected: int | None) -> None: ...
class LimitOverrunError(Exception):
consumed: int
def __init__(self, message: str, consumed: int) -> None: ...
if sys.version_info >= (3, 11):
class BrokenBarrierError(RuntimeError): ...

View File

@@ -1,31 +0,0 @@
import functools
import sys
import traceback
from collections.abc import Iterable
from types import FrameType, FunctionType
from typing import Any, overload
from typing_extensions import TypeAlias
class _HasWrapper:
__wrapper__: _HasWrapper | FunctionType
_FuncType: TypeAlias = FunctionType | _HasWrapper | functools.partial[Any] | functools.partialmethod[Any]
@overload
def _get_function_source(func: _FuncType) -> tuple[str, int]: ...
@overload
def _get_function_source(func: object) -> tuple[str, int] | None: ...
if sys.version_info >= (3, 13):
def _format_callback_source(func: object, args: Iterable[Any], *, debug: bool = False) -> str: ...
def _format_args_and_kwargs(args: Iterable[Any], kwargs: dict[str, Any], *, debug: bool = False) -> str: ...
def _format_callback(
func: object, args: Iterable[Any], kwargs: dict[str, Any], *, debug: bool = False, suffix: str = ""
) -> str: ...
else:
def _format_callback_source(func: object, args: Iterable[Any]) -> str: ...
def _format_args_and_kwargs(args: Iterable[Any], kwargs: dict[str, Any]) -> str: ...
def _format_callback(func: object, args: Iterable[Any], kwargs: dict[str, Any], suffix: str = "") -> str: ...
def extract_stack(f: FrameType | None = None, limit: int | None = None) -> traceback.StackSummary: ...

View File

@@ -1,17 +0,0 @@
from _asyncio import Future as Future
from concurrent.futures._base import Future as _ConcurrentFuture
from typing import Any, TypeVar
from typing_extensions import TypeIs
from .events import AbstractEventLoop
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("Future", "wrap_future", "isfuture")
_T = TypeVar("_T")
# asyncio defines 'isfuture()' in base_futures.py and re-imports it in futures.py
# but it leads to circular import error in pytype tool.
# That's why the import order is reversed.
def isfuture(obj: object) -> TypeIs[Future[Any]]: ...
def wrap_future(future: _ConcurrentFuture[_T] | Future[_T], *, loop: AbstractEventLoop | None = None) -> Future[_T]: ...

View File

@@ -1,104 +0,0 @@
import enum
import sys
from _typeshed import Unused
from collections import deque
from collections.abc import Callable
from types import TracebackType
from typing import Any, Literal, TypeVar
from typing_extensions import Self
from .events import AbstractEventLoop
from .futures import Future
if sys.version_info >= (3, 10):
from .mixins import _LoopBoundMixin
else:
_LoopBoundMixin = object
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 11):
__all__ = ("Lock", "Event", "Condition", "Semaphore", "BoundedSemaphore", "Barrier")
else:
__all__ = ("Lock", "Event", "Condition", "Semaphore", "BoundedSemaphore")
_T = TypeVar("_T")
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
if sys.version_info >= (3, 10):
def __init__(self) -> None: ...
else:
def __init__(self, *, loop: AbstractEventLoop | None = None) -> None: ...
def locked(self) -> bool: ...
async def acquire(self) -> Literal[True]: ...
def release(self) -> None: ...
class Event(_LoopBoundMixin):
_waiters: deque[Future[Any]]
if sys.version_info >= (3, 10):
def __init__(self) -> None: ...
else:
def __init__(self, *, loop: AbstractEventLoop | None = None) -> None: ...
def is_set(self) -> bool: ...
def set(self) -> None: ...
def clear(self) -> None: ...
async def wait(self) -> Literal[True]: ...
class Condition(_ContextManagerMixin, _LoopBoundMixin):
_waiters: deque[Future[Any]]
if sys.version_info >= (3, 10):
def __init__(self, lock: Lock | None = None) -> None: ...
else:
def __init__(self, lock: Lock | None = None, *, loop: AbstractEventLoop | None = None) -> None: ...
def locked(self) -> bool: ...
async def acquire(self) -> Literal[True]: ...
def release(self) -> None: ...
async def wait(self) -> Literal[True]: ...
async def wait_for(self, predicate: Callable[[], _T]) -> _T: ...
def notify(self, n: int = 1) -> None: ...
def notify_all(self) -> None: ...
class Semaphore(_ContextManagerMixin, _LoopBoundMixin):
_value: int
_waiters: deque[Future[Any]] | None
if sys.version_info >= (3, 10):
def __init__(self, value: int = 1) -> None: ...
else:
def __init__(self, value: int = 1, *, loop: AbstractEventLoop | None = None) -> None: ...
def locked(self) -> bool: ...
async def acquire(self) -> Literal[True]: ...
def release(self) -> None: ...
def _wake_up_next(self) -> None: ...
class BoundedSemaphore(Semaphore): ...
if sys.version_info >= (3, 11):
class _BarrierState(enum.Enum): # undocumented
FILLING = "filling"
DRAINING = "draining"
RESETTING = "resetting"
BROKEN = "broken"
class Barrier(_LoopBoundMixin):
def __init__(self, parties: int) -> None: ...
async def __aenter__(self) -> Self: ...
async def __aexit__(self, *args: Unused) -> None: ...
async def wait(self) -> int: ...
async def abort(self) -> None: ...
async def reset(self) -> None: ...
@property
def parties(self) -> int: ...
@property
def n_waiting(self) -> int: ...
@property
def broken(self) -> bool: ...

View File

@@ -1,3 +0,0 @@
import logging
logger: logging.Logger

View File

@@ -1,9 +0,0 @@
import sys
import threading
from typing_extensions import Never
_global_lock: threading.Lock
class _LoopBoundMixin:
if sys.version_info < (3, 11):
def __init__(self, *, loop: Never = ...) -> None: ...

View File

@@ -1,65 +0,0 @@
import sys
from collections.abc import Mapping
from socket import socket
from typing import Any, ClassVar, Literal
from . import base_events, constants, events, futures, streams, transports
__all__ = ("BaseProactorEventLoop",)
class _ProactorBasePipeTransport(transports._FlowControlMixin, transports.BaseTransport):
def __init__(
self,
loop: events.AbstractEventLoop,
sock: socket,
protocol: streams.StreamReaderProtocol,
waiter: futures.Future[Any] | None = None,
extra: Mapping[Any, Any] | None = None,
server: events.AbstractServer | None = None,
) -> None: ...
def __del__(self) -> None: ...
class _ProactorReadPipeTransport(_ProactorBasePipeTransport, transports.ReadTransport):
if sys.version_info >= (3, 10):
def __init__(
self,
loop: events.AbstractEventLoop,
sock: socket,
protocol: streams.StreamReaderProtocol,
waiter: futures.Future[Any] | None = None,
extra: Mapping[Any, Any] | None = None,
server: events.AbstractServer | None = None,
buffer_size: int = 65536,
) -> None: ...
else:
def __init__(
self,
loop: events.AbstractEventLoop,
sock: socket,
protocol: streams.StreamReaderProtocol,
waiter: futures.Future[Any] | None = None,
extra: Mapping[Any, Any] | None = None,
server: events.AbstractServer | None = None,
) -> None: ...
class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport, transports.WriteTransport): ...
class _ProactorWritePipeTransport(_ProactorBaseWritePipeTransport): ...
class _ProactorDuplexPipeTransport(_ProactorReadPipeTransport, _ProactorBaseWritePipeTransport, transports.Transport): ...
class _ProactorSocketTransport(_ProactorReadPipeTransport, _ProactorBaseWritePipeTransport, transports.Transport):
_sendfile_compatible: ClassVar[constants._SendfileMode]
def __init__(
self,
loop: events.AbstractEventLoop,
sock: socket,
protocol: streams.StreamReaderProtocol,
waiter: futures.Future[Any] | None = None,
extra: Mapping[Any, Any] | None = None,
server: events.AbstractServer | None = None,
) -> None: ...
def _set_extra(self, sock: socket) -> None: ...
def can_write_eof(self) -> Literal[True]: ...
class BaseProactorEventLoop(base_events.BaseEventLoop):
def __init__(self, proactor: Any) -> None: ...
async def sock_recv(self, sock: socket, n: int) -> bytes: ...

View File

@@ -1,35 +0,0 @@
from _typeshed import ReadableBuffer
from asyncio import transports
from typing import Any
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("BaseProtocol", "Protocol", "DatagramProtocol", "SubprocessProtocol", "BufferedProtocol")
class BaseProtocol:
def connection_made(self, transport: transports.BaseTransport) -> None: ...
def connection_lost(self, exc: Exception | None) -> None: ...
def pause_writing(self) -> None: ...
def resume_writing(self) -> None: ...
class Protocol(BaseProtocol):
def data_received(self, data: bytes) -> None: ...
def eof_received(self) -> bool | None: ...
class BufferedProtocol(BaseProtocol):
def get_buffer(self, sizehint: int) -> ReadableBuffer: ...
def buffer_updated(self, nbytes: int) -> None: ...
def eof_received(self) -> bool | None: ...
class DatagramProtocol(BaseProtocol):
def connection_made(self, transport: transports.DatagramTransport) -> None: ... # type: ignore[override]
# addr can be a tuple[int, int] for some unusual protocols like socket.AF_NETLINK.
# Use tuple[str | Any, int] to not cause typechecking issues on most usual cases.
# This could be improved by using tuple[AnyOf[str, int], int] if the AnyOf feature is accepted.
# See https://github.com/python/typing/issues/566
def datagram_received(self, data: bytes, addr: tuple[str | Any, int]) -> None: ...
def error_received(self, exc: Exception) -> None: ...
class SubprocessProtocol(BaseProtocol):
def pipe_data_received(self, fd: int, data: bytes) -> None: ...
def pipe_connection_lost(self, fd: int, exc: Exception | None) -> None: ...
def process_exited(self) -> None: ...

View File

@@ -1,54 +0,0 @@
import sys
from asyncio.events import AbstractEventLoop
from types import GenericAlias
from typing import Any, Generic, TypeVar
if sys.version_info >= (3, 10):
from .mixins import _LoopBoundMixin
else:
_LoopBoundMixin = object
class QueueEmpty(Exception): ...
class QueueFull(Exception): ...
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 13):
__all__ = ("Queue", "PriorityQueue", "LifoQueue", "QueueFull", "QueueEmpty", "QueueShutDown")
else:
__all__ = ("Queue", "PriorityQueue", "LifoQueue", "QueueFull", "QueueEmpty")
_T = TypeVar("_T")
if sys.version_info >= (3, 13):
class QueueShutDown(Exception): ...
# If Generic[_T] is last and _LoopBoundMixin is object, pyright is unhappy.
# We can remove the noqa pragma when dropping 3.9 support.
class Queue(Generic[_T], _LoopBoundMixin): # noqa: Y059
if sys.version_info >= (3, 10):
def __init__(self, maxsize: int = 0) -> None: ...
else:
def __init__(self, maxsize: int = 0, *, loop: AbstractEventLoop | None = None) -> None: ...
def _init(self, maxsize: int) -> None: ...
def _get(self) -> _T: ...
def _put(self, item: _T) -> None: ...
def _format(self) -> str: ...
def qsize(self) -> int: ...
@property
def maxsize(self) -> int: ...
def empty(self) -> bool: ...
def full(self) -> bool: ...
async def put(self, item: _T) -> None: ...
def put_nowait(self, item: _T) -> None: ...
async def get(self) -> _T: ...
def get_nowait(self) -> _T: ...
async def join(self) -> None: ...
def task_done(self) -> None: ...
def __class_getitem__(cls, type: Any, /) -> GenericAlias: ...
if sys.version_info >= (3, 13):
def shutdown(self, immediate: bool = False) -> None: ...
class PriorityQueue(Queue[_T]): ...
class LifoQueue(Queue[_T]): ...

View File

@@ -1,33 +0,0 @@
import sys
from _typeshed import Unused
from collections.abc import Callable, Coroutine
from contextvars import Context
from typing import Any, TypeVar, final
from typing_extensions import Self
from .events import AbstractEventLoop
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 11):
__all__ = ("Runner", "run")
else:
__all__ = ("run",)
_T = TypeVar("_T")
if sys.version_info >= (3, 11):
@final
class Runner:
def __init__(self, *, debug: bool | None = None, loop_factory: Callable[[], AbstractEventLoop] | None = None) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(self, exc_type: Unused, exc_val: Unused, exc_tb: Unused) -> None: ...
def close(self) -> None: ...
def get_loop(self) -> AbstractEventLoop: ...
def run(self, coro: Coroutine[Any, Any, _T], *, context: Context | None = None) -> _T: ...
if sys.version_info >= (3, 12):
def run(
main: Coroutine[Any, Any, _T], *, debug: bool | None = ..., loop_factory: Callable[[], AbstractEventLoop] | None = ...
) -> _T: ...
else:
def run(main: Coroutine[Any, Any, _T], *, debug: bool | None = None) -> _T: ...

View File

@@ -1,10 +0,0 @@
import selectors
from socket import socket
from . import base_events
__all__ = ("BaseSelectorEventLoop",)
class BaseSelectorEventLoop(base_events.BaseEventLoop):
def __init__(self, selector: selectors.BaseSelector | None = None) -> None: ...
async def sock_recv(self, sock: socket, n: int) -> bytes: ...

View File

@@ -1,165 +0,0 @@
import ssl
import sys
from collections import deque
from collections.abc import Callable
from enum import Enum
from typing import Any, ClassVar, Final, Literal
from typing_extensions import TypeAlias
from . import constants, events, futures, protocols, transports
def _create_transport_context(server_side: bool, server_hostname: str | None) -> ssl.SSLContext: ...
if sys.version_info >= (3, 11):
SSLAgainErrors: tuple[type[ssl.SSLWantReadError], type[ssl.SSLSyscallError]]
class SSLProtocolState(Enum):
UNWRAPPED = "UNWRAPPED"
DO_HANDSHAKE = "DO_HANDSHAKE"
WRAPPED = "WRAPPED"
FLUSHING = "FLUSHING"
SHUTDOWN = "SHUTDOWN"
class AppProtocolState(Enum):
STATE_INIT = "STATE_INIT"
STATE_CON_MADE = "STATE_CON_MADE"
STATE_EOF = "STATE_EOF"
STATE_CON_LOST = "STATE_CON_LOST"
def add_flowcontrol_defaults(high: int | None, low: int | None, kb: int) -> tuple[int, int]: ...
else:
_UNWRAPPED: Final = "UNWRAPPED"
_DO_HANDSHAKE: Final = "DO_HANDSHAKE"
_WRAPPED: Final = "WRAPPED"
_SHUTDOWN: Final = "SHUTDOWN"
if sys.version_info < (3, 11):
class _SSLPipe:
max_size: ClassVar[int]
_context: ssl.SSLContext
_server_side: bool
_server_hostname: str | None
_state: str
_incoming: ssl.MemoryBIO
_outgoing: ssl.MemoryBIO
_sslobj: ssl.SSLObject | None
_need_ssldata: bool
_handshake_cb: Callable[[BaseException | None], None] | None
_shutdown_cb: Callable[[], None] | None
def __init__(self, context: ssl.SSLContext, server_side: bool, server_hostname: str | None = None) -> None: ...
@property
def context(self) -> ssl.SSLContext: ...
@property
def ssl_object(self) -> ssl.SSLObject | None: ...
@property
def need_ssldata(self) -> bool: ...
@property
def wrapped(self) -> bool: ...
def do_handshake(self, callback: Callable[[BaseException | None], object] | None = None) -> list[bytes]: ...
def shutdown(self, callback: Callable[[], object] | None = None) -> list[bytes]: ...
def feed_eof(self) -> None: ...
def feed_ssldata(self, data: bytes, only_handshake: bool = False) -> tuple[list[bytes], list[bytes]]: ...
def feed_appdata(self, data: bytes, offset: int = 0) -> tuple[list[bytes], int]: ...
class _SSLProtocolTransport(transports._FlowControlMixin, transports.Transport):
_sendfile_compatible: ClassVar[constants._SendfileMode]
_loop: events.AbstractEventLoop
if sys.version_info >= (3, 11):
_ssl_protocol: SSLProtocol | None
else:
_ssl_protocol: SSLProtocol
_closed: bool
def __init__(self, loop: events.AbstractEventLoop, ssl_protocol: SSLProtocol) -> None: ...
def get_extra_info(self, name: str, default: Any | None = None) -> dict[str, Any]: ...
@property
def _protocol_paused(self) -> bool: ...
def write(self, data: bytes | bytearray | memoryview[Any]) -> None: ... # any memoryview format or shape
def can_write_eof(self) -> Literal[False]: ...
if sys.version_info >= (3, 11):
def get_write_buffer_limits(self) -> tuple[int, int]: ...
def get_read_buffer_limits(self) -> tuple[int, int]: ...
def set_read_buffer_limits(self, high: int | None = None, low: int | None = None) -> None: ...
def get_read_buffer_size(self) -> int: ...
def __del__(self) -> None: ...
if sys.version_info >= (3, 11):
_SSLProtocolBase: TypeAlias = protocols.BufferedProtocol
else:
_SSLProtocolBase: TypeAlias = protocols.Protocol
class SSLProtocol(_SSLProtocolBase):
_server_side: bool
_server_hostname: str | None
_sslcontext: ssl.SSLContext
_extra: dict[str, Any]
_write_backlog: deque[tuple[bytes, int]]
_write_buffer_size: int
_waiter: futures.Future[Any]
_loop: events.AbstractEventLoop
_app_transport: _SSLProtocolTransport
_transport: transports.BaseTransport | None
_ssl_handshake_timeout: int | None
_app_protocol: protocols.BaseProtocol
_app_protocol_is_buffer: bool
if sys.version_info >= (3, 11):
max_size: ClassVar[int]
else:
_sslpipe: _SSLPipe | None
_session_established: bool
_call_connection_made: bool
_in_handshake: bool
_in_shutdown: bool
if sys.version_info >= (3, 11):
def __init__(
self,
loop: events.AbstractEventLoop,
app_protocol: protocols.BaseProtocol,
sslcontext: ssl.SSLContext,
waiter: futures.Future[Any],
server_side: bool = False,
server_hostname: str | None = None,
call_connection_made: bool = True,
ssl_handshake_timeout: int | None = None,
ssl_shutdown_timeout: float | None = None,
) -> None: ...
else:
def __init__(
self,
loop: events.AbstractEventLoop,
app_protocol: protocols.BaseProtocol,
sslcontext: ssl.SSLContext,
waiter: futures.Future[Any],
server_side: bool = False,
server_hostname: str | None = None,
call_connection_made: bool = True,
ssl_handshake_timeout: int | None = None,
) -> None: ...
def _set_app_protocol(self, app_protocol: protocols.BaseProtocol) -> None: ...
def _wakeup_waiter(self, exc: BaseException | None = None) -> None: ...
def connection_lost(self, exc: BaseException | None) -> None: ...
def eof_received(self) -> None: ...
def _get_extra_info(self, name: str, default: Any | None = None) -> Any: ...
def _start_shutdown(self) -> None: ...
if sys.version_info >= (3, 11):
def _write_appdata(self, list_of_data: list[bytes]) -> None: ...
else:
def _write_appdata(self, data: bytes) -> None: ...
def _start_handshake(self) -> None: ...
def _check_handshake_timeout(self) -> None: ...
def _on_handshake_complete(self, handshake_exc: BaseException | None) -> None: ...
def _fatal_error(self, exc: BaseException, message: str = "Fatal error on transport") -> None: ...
if sys.version_info >= (3, 11):
def _abort(self, exc: BaseException | None) -> None: ...
def get_buffer(self, n: int) -> memoryview: ...
else:
def _abort(self) -> None: ...
def _finalize(self) -> None: ...
def _process_write_backlog(self) -> None: ...

View File

@@ -1,10 +0,0 @@
from collections.abc import Awaitable, Callable, Iterable
from typing import Any
from . import events
__all__ = ("staggered_race",)
async def staggered_race(
coro_fns: Iterable[Callable[[], Awaitable[Any]]], delay: float | None, *, loop: events.AbstractEventLoop | None = None
) -> tuple[Any, int | None, list[Exception | None]]: ...

View File

@@ -1,158 +0,0 @@
import ssl
import sys
from _typeshed import ReadableBuffer, StrPath
from collections.abc import Awaitable, Callable, Iterable, Sequence, Sized
from types import ModuleType
from typing import Any, Protocol, SupportsIndex
from typing_extensions import Self, TypeAlias
from . import events, protocols, transports
from .base_events import Server
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.platform == "win32":
__all__ = ("StreamReader", "StreamWriter", "StreamReaderProtocol", "open_connection", "start_server")
else:
__all__ = (
"StreamReader",
"StreamWriter",
"StreamReaderProtocol",
"open_connection",
"start_server",
"open_unix_connection",
"start_unix_server",
)
_ClientConnectedCallback: TypeAlias = Callable[[StreamReader, StreamWriter], Awaitable[None] | None]
class _ReaduntilBuffer(ReadableBuffer, Sized, Protocol): ...
if sys.version_info >= (3, 10):
async def open_connection(
host: str | None = None,
port: int | str | None = None,
*,
limit: int = 65536,
ssl_handshake_timeout: float | None = ...,
**kwds: Any,
) -> tuple[StreamReader, StreamWriter]: ...
async def start_server(
client_connected_cb: _ClientConnectedCallback,
host: str | Sequence[str] | None = None,
port: int | str | None = None,
*,
limit: int = 65536,
ssl_handshake_timeout: float | None = ...,
**kwds: Any,
) -> Server: ...
else:
async def open_connection(
host: str | None = None,
port: int | str | None = None,
*,
loop: events.AbstractEventLoop | None = None,
limit: int = 65536,
ssl_handshake_timeout: float | None = ...,
**kwds: Any,
) -> tuple[StreamReader, StreamWriter]: ...
async def start_server(
client_connected_cb: _ClientConnectedCallback,
host: str | None = None,
port: int | str | None = None,
*,
loop: events.AbstractEventLoop | None = None,
limit: int = 65536,
ssl_handshake_timeout: float | None = ...,
**kwds: Any,
) -> Server: ...
if sys.platform != "win32":
if sys.version_info >= (3, 10):
async def open_unix_connection(
path: StrPath | None = None, *, limit: int = 65536, **kwds: Any
) -> tuple[StreamReader, StreamWriter]: ...
async def start_unix_server(
client_connected_cb: _ClientConnectedCallback, path: StrPath | None = None, *, limit: int = 65536, **kwds: Any
) -> Server: ...
else:
async def open_unix_connection(
path: StrPath | None = None, *, loop: events.AbstractEventLoop | None = None, limit: int = 65536, **kwds: Any
) -> tuple[StreamReader, StreamWriter]: ...
async def start_unix_server(
client_connected_cb: _ClientConnectedCallback,
path: StrPath | None = None,
*,
loop: events.AbstractEventLoop | None = None,
limit: int = 65536,
**kwds: Any,
) -> Server: ...
class FlowControlMixin(protocols.Protocol):
def __init__(self, loop: events.AbstractEventLoop | None = None) -> None: ...
class StreamReaderProtocol(FlowControlMixin, protocols.Protocol):
def __init__(
self,
stream_reader: StreamReader,
client_connected_cb: _ClientConnectedCallback | None = None,
loop: events.AbstractEventLoop | None = None,
) -> None: ...
def __del__(self) -> None: ...
class StreamWriter:
def __init__(
self,
transport: transports.WriteTransport,
protocol: protocols.BaseProtocol,
reader: StreamReader | None,
loop: events.AbstractEventLoop,
) -> None: ...
@property
def transport(self) -> transports.WriteTransport: ...
def write(self, data: bytes | bytearray | memoryview) -> None: ...
def writelines(self, data: Iterable[bytes | bytearray | memoryview]) -> None: ...
def write_eof(self) -> None: ...
def can_write_eof(self) -> bool: ...
def close(self) -> None: ...
def is_closing(self) -> bool: ...
async def wait_closed(self) -> None: ...
def get_extra_info(self, name: str, default: Any = None) -> Any: ...
async def drain(self) -> None: ...
if sys.version_info >= (3, 12):
async def start_tls(
self,
sslcontext: ssl.SSLContext,
*,
server_hostname: str | None = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
) -> None: ...
elif sys.version_info >= (3, 11):
async def start_tls(
self, sslcontext: ssl.SSLContext, *, server_hostname: str | None = None, ssl_handshake_timeout: float | None = None
) -> None: ...
if sys.version_info >= (3, 13):
def __del__(self, warnings: ModuleType = ...) -> None: ...
elif sys.version_info >= (3, 11):
def __del__(self) -> None: ...
class StreamReader:
def __init__(self, limit: int = 65536, loop: events.AbstractEventLoop | None = None) -> None: ...
def exception(self) -> Exception: ...
def set_exception(self, exc: Exception) -> None: ...
def set_transport(self, transport: transports.BaseTransport) -> None: ...
def feed_eof(self) -> None: ...
def at_eof(self) -> bool: ...
def feed_data(self, data: Iterable[SupportsIndex]) -> None: ...
async def readline(self) -> bytes: ...
if sys.version_info >= (3, 13):
async def readuntil(self, separator: _ReaduntilBuffer | tuple[_ReaduntilBuffer, ...] = b"\n") -> bytes: ...
else:
async def readuntil(self, separator: _ReaduntilBuffer = b"\n") -> bytes: ...
async def read(self, n: int = -1) -> bytes: ...
async def readexactly(self, n: int) -> bytes: ...
def __aiter__(self) -> Self: ...
async def __anext__(self) -> bytes: ...

View File

@@ -1,230 +0,0 @@
import subprocess
import sys
from _typeshed import StrOrBytesPath
from asyncio import events, protocols, streams, transports
from collections.abc import Callable, Collection
from typing import IO, Any, Literal
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("create_subprocess_exec", "create_subprocess_shell")
PIPE: int
STDOUT: int
DEVNULL: int
class SubprocessStreamProtocol(streams.FlowControlMixin, protocols.SubprocessProtocol):
stdin: streams.StreamWriter | None
stdout: streams.StreamReader | None
stderr: streams.StreamReader | None
def __init__(self, limit: int, loop: events.AbstractEventLoop) -> None: ...
def pipe_data_received(self, fd: int, data: bytes | str) -> None: ...
class Process:
stdin: streams.StreamWriter | None
stdout: streams.StreamReader | None
stderr: streams.StreamReader | None
pid: int
def __init__(
self, transport: transports.BaseTransport, protocol: protocols.BaseProtocol, loop: events.AbstractEventLoop
) -> None: ...
@property
def returncode(self) -> int | None: ...
async def wait(self) -> int: ...
def send_signal(self, signal: int) -> None: ...
def terminate(self) -> None: ...
def kill(self) -> None: ...
async def communicate(self, input: bytes | bytearray | memoryview | None = None) -> tuple[bytes, bytes]: ...
if sys.version_info >= (3, 11):
async def create_subprocess_shell(
cmd: str | bytes,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
limit: int = 65536,
*,
# These parameters are forced to these values by BaseEventLoop.subprocess_shell
universal_newlines: Literal[False] = False,
shell: Literal[True] = True,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
process_group: int | None = None,
pipesize: int = -1,
) -> Process: ...
async def create_subprocess_exec(
program: StrOrBytesPath,
*args: StrOrBytesPath,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
limit: int = 65536,
# These parameters are forced to these values by BaseEventLoop.subprocess_exec
universal_newlines: Literal[False] = False,
shell: Literal[False] = False,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
process_group: int | None = None,
pipesize: int = -1,
) -> Process: ...
elif sys.version_info >= (3, 10):
async def create_subprocess_shell(
cmd: str | bytes,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
limit: int = 65536,
*,
# These parameters are forced to these values by BaseEventLoop.subprocess_shell
universal_newlines: Literal[False] = False,
shell: Literal[True] = True,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
pipesize: int = -1,
) -> Process: ...
async def create_subprocess_exec(
program: StrOrBytesPath,
*args: StrOrBytesPath,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
limit: int = 65536,
# These parameters are forced to these values by BaseEventLoop.subprocess_exec
universal_newlines: Literal[False] = False,
shell: Literal[False] = False,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
pipesize: int = -1,
) -> Process: ...
else: # >= 3.9
async def create_subprocess_shell(
cmd: str | bytes,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
loop: events.AbstractEventLoop | None = None,
limit: int = 65536,
*,
# These parameters are forced to these values by BaseEventLoop.subprocess_shell
universal_newlines: Literal[False] = False,
shell: Literal[True] = True,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
) -> Process: ...
async def create_subprocess_exec(
program: StrOrBytesPath,
*args: StrOrBytesPath,
stdin: int | IO[Any] | None = None,
stdout: int | IO[Any] | None = None,
stderr: int | IO[Any] | None = None,
loop: events.AbstractEventLoop | None = None,
limit: int = 65536,
# These parameters are forced to these values by BaseEventLoop.subprocess_exec
universal_newlines: Literal[False] = False,
shell: Literal[False] = False,
bufsize: Literal[0] = 0,
encoding: None = None,
errors: None = None,
text: Literal[False] | None = None,
# These parameters are taken by subprocess.Popen, which this ultimately delegates to
executable: StrOrBytesPath | None = None,
preexec_fn: Callable[[], Any] | None = None,
close_fds: bool = True,
cwd: StrOrBytesPath | None = None,
env: subprocess._ENV | None = None,
startupinfo: Any | None = None,
creationflags: int = 0,
restore_signals: bool = True,
start_new_session: bool = False,
pass_fds: Collection[int] = ...,
group: None | str | int = None,
extra_groups: None | Collection[str | int] = None,
user: None | str | int = None,
umask: int = -1,
) -> Process: ...

View File

@@ -1,26 +0,0 @@
import sys
from contextvars import Context
from types import TracebackType
from typing import Any, TypeVar
from typing_extensions import Self
from . import _CoroutineLike
from .events import AbstractEventLoop
from .tasks import Task
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 12):
__all__ = ("TaskGroup",)
else:
__all__ = ["TaskGroup"]
_T = TypeVar("_T")
class TaskGroup:
_loop: AbstractEventLoop | None
_tasks: set[Task[Any]]
async def __aenter__(self) -> Self: ...
async def __aexit__(self, et: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None: ...
def create_task(self, coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None) -> Task[_T]: ...
def _on_task_done(self, task: Task[object]) -> None: ...

View File

@@ -1,460 +0,0 @@
import concurrent.futures
import sys
from _asyncio import (
Task as Task,
_enter_task as _enter_task,
_leave_task as _leave_task,
_register_task as _register_task,
_unregister_task as _unregister_task,
)
from collections.abc import AsyncIterator, Awaitable, Coroutine, Generator, Iterable, Iterator
from typing import Any, Literal, Protocol, TypeVar, overload
from typing_extensions import TypeAlias
from . import _CoroutineLike
from .events import AbstractEventLoop
from .futures import Future
if sys.version_info >= (3, 11):
from contextvars import Context
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.version_info >= (3, 12):
__all__ = (
"Task",
"create_task",
"FIRST_COMPLETED",
"FIRST_EXCEPTION",
"ALL_COMPLETED",
"wait",
"wait_for",
"as_completed",
"sleep",
"gather",
"shield",
"ensure_future",
"run_coroutine_threadsafe",
"current_task",
"all_tasks",
"create_eager_task_factory",
"eager_task_factory",
"_register_task",
"_unregister_task",
"_enter_task",
"_leave_task",
)
else:
__all__ = (
"Task",
"create_task",
"FIRST_COMPLETED",
"FIRST_EXCEPTION",
"ALL_COMPLETED",
"wait",
"wait_for",
"as_completed",
"sleep",
"gather",
"shield",
"ensure_future",
"run_coroutine_threadsafe",
"current_task",
"all_tasks",
"_register_task",
"_unregister_task",
"_enter_task",
"_leave_task",
)
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_T1 = TypeVar("_T1")
_T2 = TypeVar("_T2")
_T3 = TypeVar("_T3")
_T4 = TypeVar("_T4")
_T5 = TypeVar("_T5")
_T6 = TypeVar("_T6")
_FT = TypeVar("_FT", bound=Future[Any])
if sys.version_info >= (3, 12):
_FutureLike: TypeAlias = Future[_T] | Awaitable[_T]
else:
_FutureLike: TypeAlias = Future[_T] | Generator[Any, None, _T] | Awaitable[_T]
_TaskYieldType: TypeAlias = Future[object] | None
FIRST_COMPLETED = concurrent.futures.FIRST_COMPLETED
FIRST_EXCEPTION = concurrent.futures.FIRST_EXCEPTION
ALL_COMPLETED = concurrent.futures.ALL_COMPLETED
if sys.version_info >= (3, 13):
class _SyncAndAsyncIterator(Iterator[_T_co], AsyncIterator[_T_co], Protocol[_T_co]): ...
def as_completed(fs: Iterable[_FutureLike[_T]], *, timeout: float | None = None) -> _SyncAndAsyncIterator[Future[_T]]: ...
elif sys.version_info >= (3, 10):
def as_completed(fs: Iterable[_FutureLike[_T]], *, timeout: float | None = None) -> Iterator[Future[_T]]: ...
else:
def as_completed(
fs: Iterable[_FutureLike[_T]], *, loop: AbstractEventLoop | None = None, timeout: float | None = None
) -> Iterator[Future[_T]]: ...
@overload
def ensure_future(coro_or_future: _FT, *, loop: AbstractEventLoop | None = None) -> _FT: ... # type: ignore[overload-overlap]
@overload
def ensure_future(coro_or_future: Awaitable[_T], *, loop: AbstractEventLoop | None = None) -> Task[_T]: ...
# `gather()` actually returns a list with length equal to the number
# of tasks passed; however, Tuple is used similar to the annotation for
# zip() because typing does not support variadic type variables. See
# typing PR #1550 for discussion.
#
# N.B. Having overlapping overloads is the only way to get acceptable type inference in all edge cases.
if sys.version_info >= (3, 10):
@overload
def gather(coro_or_future1: _FutureLike[_T1], /, *, return_exceptions: Literal[False] = False) -> Future[tuple[_T1]]: ... # type: ignore[overload-overlap]
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1], coro_or_future2: _FutureLike[_T2], /, *, return_exceptions: Literal[False] = False
) -> Future[tuple[_T1, _T2]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
/,
*,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
/,
*,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
/,
*,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
coro_or_future6: _FutureLike[_T6],
/,
*,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ...
@overload
def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: Literal[False] = False) -> Future[list[_T]]: ... # type: ignore[overload-overlap]
@overload
def gather(coro_or_future1: _FutureLike[_T1], /, *, return_exceptions: bool) -> Future[tuple[_T1 | BaseException]]: ...
@overload
def gather(
coro_or_future1: _FutureLike[_T1], coro_or_future2: _FutureLike[_T2], /, *, return_exceptions: bool
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ...
@overload
def gather(
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
/,
*,
return_exceptions: bool,
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ...
@overload
def gather(
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
/,
*,
return_exceptions: bool,
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ...
@overload
def gather(
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
/,
*,
return_exceptions: bool,
) -> Future[
tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException, _T5 | BaseException]
]: ...
@overload
def gather(
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
coro_or_future6: _FutureLike[_T6],
/,
*,
return_exceptions: bool,
) -> Future[
tuple[
_T1 | BaseException,
_T2 | BaseException,
_T3 | BaseException,
_T4 | BaseException,
_T5 | BaseException,
_T6 | BaseException,
]
]: ...
@overload
def gather(*coros_or_futures: _FutureLike[_T], return_exceptions: bool) -> Future[list[_T | BaseException]]: ...
else:
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1], /, *, loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False
) -> Future[tuple[_T1]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4, _T5]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
coro_or_future6: _FutureLike[_T6],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: Literal[False] = False,
) -> Future[tuple[_T1, _T2, _T3, _T4, _T5, _T6]]: ...
@overload
def gather( # type: ignore[overload-overlap]
*coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: Literal[False] = False
) -> Future[list[_T]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1], /, *, loop: AbstractEventLoop | None = None, return_exceptions: bool
) -> Future[tuple[_T1 | BaseException]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: bool,
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: bool,
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: bool,
) -> Future[tuple[_T1 | BaseException, _T2 | BaseException, _T3 | BaseException, _T4 | BaseException]]: ...
@overload
def gather( # type: ignore[overload-overlap]
coro_or_future1: _FutureLike[_T1],
coro_or_future2: _FutureLike[_T2],
coro_or_future3: _FutureLike[_T3],
coro_or_future4: _FutureLike[_T4],
coro_or_future5: _FutureLike[_T5],
coro_or_future6: _FutureLike[_T6],
/,
*,
loop: AbstractEventLoop | None = None,
return_exceptions: bool,
) -> Future[
tuple[
_T1 | BaseException,
_T2 | BaseException,
_T3 | BaseException,
_T4 | BaseException,
_T5 | BaseException,
_T6 | BaseException,
]
]: ...
@overload
def gather(
*coros_or_futures: _FutureLike[_T], loop: AbstractEventLoop | None = None, return_exceptions: bool
) -> Future[list[_T | BaseException]]: ...
# unlike some asyncio apis, This does strict runtime checking of actually being a coroutine, not of any future-like.
def run_coroutine_threadsafe(coro: Coroutine[Any, Any, _T], loop: AbstractEventLoop) -> concurrent.futures.Future[_T]: ...
if sys.version_info >= (3, 10):
def shield(arg: _FutureLike[_T]) -> Future[_T]: ...
@overload
async def sleep(delay: float) -> None: ...
@overload
async def sleep(delay: float, result: _T) -> _T: ...
async def wait_for(fut: _FutureLike[_T], timeout: float | None) -> _T: ...
else:
def shield(arg: _FutureLike[_T], *, loop: AbstractEventLoop | None = None) -> Future[_T]: ...
@overload
async def sleep(delay: float, *, loop: AbstractEventLoop | None = None) -> None: ...
@overload
async def sleep(delay: float, result: _T, *, loop: AbstractEventLoop | None = None) -> _T: ...
async def wait_for(fut: _FutureLike[_T], timeout: float | None, *, loop: AbstractEventLoop | None = None) -> _T: ...
if sys.version_info >= (3, 11):
@overload
async def wait(
fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> tuple[set[_FT], set[_FT]]: ...
@overload
async def wait(
fs: Iterable[Task[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> tuple[set[Task[_T]], set[Task[_T]]]: ...
elif sys.version_info >= (3, 10):
@overload
async def wait( # type: ignore[overload-overlap]
fs: Iterable[_FT], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> tuple[set[_FT], set[_FT]]: ...
@overload
async def wait(
fs: Iterable[Awaitable[_T]], *, timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> tuple[set[Task[_T]], set[Task[_T]]]: ...
else:
@overload
async def wait( # type: ignore[overload-overlap]
fs: Iterable[_FT],
*,
loop: AbstractEventLoop | None = None,
timeout: float | None = None,
return_when: str = "ALL_COMPLETED",
) -> tuple[set[_FT], set[_FT]]: ...
@overload
async def wait(
fs: Iterable[Awaitable[_T]],
*,
loop: AbstractEventLoop | None = None,
timeout: float | None = None,
return_when: str = "ALL_COMPLETED",
) -> tuple[set[Task[_T]], set[Task[_T]]]: ...
if sys.version_info >= (3, 12):
_TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co]
else:
_TaskCompatibleCoro: TypeAlias = Generator[_TaskYieldType, None, _T_co] | Coroutine[Any, Any, _T_co]
def all_tasks(loop: AbstractEventLoop | None = None) -> set[Task[Any]]: ...
if sys.version_info >= (3, 11):
def create_task(coro: _CoroutineLike[_T], *, name: str | None = None, context: Context | None = None) -> Task[_T]: ...
else:
def create_task(coro: _CoroutineLike[_T], *, name: str | None = None) -> Task[_T]: ...
if sys.version_info >= (3, 12):
from _asyncio import current_task as current_task
else:
def current_task(loop: AbstractEventLoop | None = None) -> Task[Any] | None: ...
if sys.version_info >= (3, 12):
_TaskT_co = TypeVar("_TaskT_co", bound=Task[Any], covariant=True)
class _CustomTaskConstructor(Protocol[_TaskT_co]):
def __call__(
self,
coro: _TaskCompatibleCoro[Any],
/,
*,
loop: AbstractEventLoop,
name: str | None,
context: Context | None,
eager_start: bool,
) -> _TaskT_co: ...
class _EagerTaskFactoryType(Protocol[_TaskT_co]):
def __call__(
self,
loop: AbstractEventLoop,
coro: _TaskCompatibleCoro[Any],
*,
name: str | None = None,
context: Context | None = None,
) -> _TaskT_co: ...
def create_eager_task_factory(
custom_task_constructor: _CustomTaskConstructor[_TaskT_co],
) -> _EagerTaskFactoryType[_TaskT_co]: ...
def eager_task_factory(
loop: AbstractEventLoop | None,
coro: _TaskCompatibleCoro[_T_co],
*,
name: str | None = None,
context: Context | None = None,
) -> Task[_T_co]: ...

View File

@@ -1,10 +0,0 @@
from collections.abc import Callable
from typing import TypeVar
from typing_extensions import ParamSpec
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("to_thread",)
_P = ParamSpec("_P")
_R = TypeVar("_R")
async def to_thread(func: Callable[_P, _R], /, *args: _P.args, **kwargs: _P.kwargs) -> _R: ...

View File

@@ -1,20 +0,0 @@
from types import TracebackType
from typing import final
from typing_extensions import Self
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("Timeout", "timeout", "timeout_at")
@final
class Timeout:
def __init__(self, when: float | None) -> None: ...
def when(self) -> float | None: ...
def reschedule(self, when: float | None) -> None: ...
def expired(self) -> bool: ...
async def __aenter__(self) -> Self: ...
async def __aexit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
) -> None: ...
def timeout(delay: float | None) -> Timeout: ...
def timeout_at(when: float | None) -> Timeout: ...

View File

@@ -1,50 +0,0 @@
from asyncio.events import AbstractEventLoop
from asyncio.protocols import BaseProtocol
from collections.abc import Iterable, Mapping
from socket import _Address
from typing import Any
# Keep asyncio.__all__ updated with any changes to __all__ here
__all__ = ("BaseTransport", "ReadTransport", "WriteTransport", "Transport", "DatagramTransport", "SubprocessTransport")
class BaseTransport:
def __init__(self, extra: Mapping[str, Any] | None = None) -> None: ...
def get_extra_info(self, name: str, default: Any = None) -> Any: ...
def is_closing(self) -> bool: ...
def close(self) -> None: ...
def set_protocol(self, protocol: BaseProtocol) -> None: ...
def get_protocol(self) -> BaseProtocol: ...
class ReadTransport(BaseTransport):
def is_reading(self) -> bool: ...
def pause_reading(self) -> None: ...
def resume_reading(self) -> None: ...
class WriteTransport(BaseTransport):
def set_write_buffer_limits(self, high: int | None = None, low: int | None = None) -> None: ...
def get_write_buffer_size(self) -> int: ...
def get_write_buffer_limits(self) -> tuple[int, int]: ...
def write(self, data: bytes | bytearray | memoryview[Any]) -> None: ... # any memoryview format or shape
def writelines(
self, list_of_data: Iterable[bytes | bytearray | memoryview[Any]]
) -> None: ... # any memoryview format or shape
def write_eof(self) -> None: ...
def can_write_eof(self) -> bool: ...
def abort(self) -> None: ...
class Transport(ReadTransport, WriteTransport): ...
class DatagramTransport(BaseTransport):
def sendto(self, data: bytes | bytearray | memoryview, addr: _Address | None = None) -> None: ...
def abort(self) -> None: ...
class SubprocessTransport(BaseTransport):
def get_pid(self) -> int: ...
def get_returncode(self) -> int | None: ...
def get_pipe_transport(self, fd: int) -> BaseTransport | None: ...
def send_signal(self, signal: int) -> None: ...
def terminate(self) -> None: ...
def kill(self) -> None: ...
class _FlowControlMixin(Transport):
def __init__(self, extra: Mapping[str, Any] | None = None, loop: AbstractEventLoop | None = None) -> None: ...

View File

@@ -1,94 +0,0 @@
import socket
import sys
from _typeshed import ReadableBuffer
from builtins import type as Type # alias to avoid name clashes with property named "type"
from collections.abc import Iterable
from types import TracebackType
from typing import Any, BinaryIO, NoReturn, overload
from typing_extensions import TypeAlias
# These are based in socket, maybe move them out into _typeshed.pyi or such
_Address: TypeAlias = socket._Address
_RetAddress: TypeAlias = Any
_WriteBuffer: TypeAlias = bytearray | memoryview
_CMSG: TypeAlias = tuple[int, int, bytes]
class TransportSocket:
def __init__(self, sock: socket.socket) -> None: ...
@property
def family(self) -> int: ...
@property
def type(self) -> int: ...
@property
def proto(self) -> int: ...
def __getstate__(self) -> NoReturn: ...
def fileno(self) -> int: ...
def dup(self) -> socket.socket: ...
def get_inheritable(self) -> bool: ...
def shutdown(self, how: int) -> None: ...
@overload
def getsockopt(self, level: int, optname: int) -> int: ...
@overload
def getsockopt(self, level: int, optname: int, buflen: int) -> bytes: ...
@overload
def setsockopt(self, level: int, optname: int, value: int | ReadableBuffer) -> None: ...
@overload
def setsockopt(self, level: int, optname: int, value: None, optlen: int) -> None: ...
def getpeername(self) -> _RetAddress: ...
def getsockname(self) -> _RetAddress: ...
def getsockbyname(self) -> NoReturn: ... # This method doesn't exist on socket, yet is passed through?
def settimeout(self, value: float | None) -> None: ...
def gettimeout(self) -> float | None: ...
def setblocking(self, flag: bool) -> None: ...
if sys.version_info < (3, 11):
def _na(self, what: str) -> None: ...
def accept(self) -> tuple[socket.socket, _RetAddress]: ...
def connect(self, address: _Address) -> None: ...
def connect_ex(self, address: _Address) -> int: ...
def bind(self, address: _Address) -> None: ...
if sys.platform == "win32":
def ioctl(self, control: int, option: int | tuple[int, int, int] | bool) -> None: ...
else:
def ioctl(self, control: int, option: int | tuple[int, int, int] | bool) -> NoReturn: ...
def listen(self, backlog: int = ..., /) -> None: ...
def makefile(self) -> BinaryIO: ...
def sendfile(self, file: BinaryIO, offset: int = ..., count: int | None = ...) -> int: ...
def close(self) -> None: ...
def detach(self) -> int: ...
if sys.platform == "linux":
def sendmsg_afalg(
self, msg: Iterable[ReadableBuffer] = ..., *, op: int, iv: Any = ..., assoclen: int = ..., flags: int = ...
) -> int: ...
else:
def sendmsg_afalg(
self, msg: Iterable[ReadableBuffer] = ..., *, op: int, iv: Any = ..., assoclen: int = ..., flags: int = ...
) -> NoReturn: ...
def sendmsg(
self, buffers: Iterable[ReadableBuffer], ancdata: Iterable[_CMSG] = ..., flags: int = ..., address: _Address = ..., /
) -> int: ...
@overload
def sendto(self, data: ReadableBuffer, address: _Address) -> int: ...
@overload
def sendto(self, data: ReadableBuffer, flags: int, address: _Address) -> int: ...
def send(self, data: ReadableBuffer, flags: int = ...) -> int: ...
def sendall(self, data: ReadableBuffer, flags: int = ...) -> None: ...
def set_inheritable(self, inheritable: bool) -> None: ...
if sys.platform == "win32":
def share(self, process_id: int) -> bytes: ...
else:
def share(self, process_id: int) -> NoReturn: ...
def recv_into(self, buffer: _WriteBuffer, nbytes: int = ..., flags: int = ...) -> int: ...
def recvfrom_into(self, buffer: _WriteBuffer, nbytes: int = ..., flags: int = ...) -> tuple[int, _RetAddress]: ...
def recvmsg_into(
self, buffers: Iterable[_WriteBuffer], ancbufsize: int = ..., flags: int = ..., /
) -> tuple[int, list[_CMSG], int, Any]: ...
def recvmsg(self, bufsize: int, ancbufsize: int = ..., flags: int = ..., /) -> tuple[bytes, list[_CMSG], int, Any]: ...
def recvfrom(self, bufsize: int, flags: int = ...) -> tuple[bytes, _RetAddress]: ...
def recv(self, bufsize: int, flags: int = ...) -> bytes: ...
def __enter__(self) -> socket.socket: ...
def __exit__(
self, exc_type: Type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
) -> None: ...

View File

@@ -1,243 +0,0 @@
import sys
import types
from _typeshed import StrPath
from abc import ABCMeta, abstractmethod
from collections.abc import Callable
from socket import socket
from typing import Literal
from typing_extensions import Self, TypeVarTuple, Unpack, deprecated
from .base_events import Server, _ProtocolFactory, _SSLContext
from .events import AbstractEventLoop, BaseDefaultEventLoopPolicy
from .selector_events import BaseSelectorEventLoop
_Ts = TypeVarTuple("_Ts")
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.platform != "win32":
if sys.version_info >= (3, 14):
__all__ = ("SelectorEventLoop", "DefaultEventLoopPolicy", "EventLoop")
elif sys.version_info >= (3, 13):
# Adds EventLoop
__all__ = (
"SelectorEventLoop",
"AbstractChildWatcher",
"SafeChildWatcher",
"FastChildWatcher",
"PidfdChildWatcher",
"MultiLoopChildWatcher",
"ThreadedChildWatcher",
"DefaultEventLoopPolicy",
"EventLoop",
)
else:
# adds PidfdChildWatcher
__all__ = (
"SelectorEventLoop",
"AbstractChildWatcher",
"SafeChildWatcher",
"FastChildWatcher",
"PidfdChildWatcher",
"MultiLoopChildWatcher",
"ThreadedChildWatcher",
"DefaultEventLoopPolicy",
)
# This is also technically not available on Win,
# but other parts of typeshed need this definition.
# So, it is special cased.
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
class AbstractChildWatcher:
@abstractmethod
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
@abstractmethod
def remove_child_handler(self, pid: int) -> bool: ...
@abstractmethod
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
@abstractmethod
def close(self) -> None: ...
@abstractmethod
def __enter__(self) -> Self: ...
@abstractmethod
def __exit__(
self, typ: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None
) -> None: ...
@abstractmethod
def is_active(self) -> bool: ...
else:
class AbstractChildWatcher:
@abstractmethod
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
@abstractmethod
def remove_child_handler(self, pid: int) -> bool: ...
@abstractmethod
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
@abstractmethod
def close(self) -> None: ...
@abstractmethod
def __enter__(self) -> Self: ...
@abstractmethod
def __exit__(
self, typ: type[BaseException] | None, exc: BaseException | None, tb: types.TracebackType | None
) -> None: ...
@abstractmethod
def is_active(self) -> bool: ...
if sys.platform != "win32":
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
# Doesn't actually have ABCMeta metaclass at runtime, but mypy complains if we don't have it in the stub.
# See discussion in #7412
class BaseChildWatcher(AbstractChildWatcher, metaclass=ABCMeta):
def close(self) -> None: ...
def is_active(self) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
class SafeChildWatcher(BaseChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
class FastChildWatcher(BaseChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
else:
# Doesn't actually have ABCMeta metaclass at runtime, but mypy complains if we don't have it in the stub.
# See discussion in #7412
class BaseChildWatcher(AbstractChildWatcher, metaclass=ABCMeta):
def close(self) -> None: ...
def is_active(self) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
class SafeChildWatcher(BaseChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
class FastChildWatcher(BaseChildWatcher):
def __enter__(self) -> Self: ...
def __exit__(
self, a: type[BaseException] | None, b: BaseException | None, c: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
class _UnixSelectorEventLoop(BaseSelectorEventLoop):
if sys.version_info >= (3, 13):
async def create_unix_server(
self,
protocol_factory: _ProtocolFactory,
path: StrPath | None = None,
*,
sock: socket | None = None,
backlog: int = 100,
ssl: _SSLContext = None,
ssl_handshake_timeout: float | None = None,
ssl_shutdown_timeout: float | None = None,
start_serving: bool = True,
cleanup_socket: bool = True,
) -> Server: ...
class _UnixDefaultEventLoopPolicy(BaseDefaultEventLoopPolicy):
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def get_child_watcher(self) -> AbstractChildWatcher: ...
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ...
else:
def get_child_watcher(self) -> AbstractChildWatcher: ...
def set_child_watcher(self, watcher: AbstractChildWatcher | None) -> None: ...
SelectorEventLoop = _UnixSelectorEventLoop
DefaultEventLoopPolicy = _UnixDefaultEventLoopPolicy
if sys.version_info >= (3, 13):
EventLoop = SelectorEventLoop
if sys.version_info < (3, 14):
if sys.version_info >= (3, 12):
@deprecated("Deprecated as of Python 3.12; will be removed in Python 3.14")
class MultiLoopChildWatcher(AbstractChildWatcher):
def is_active(self) -> bool: ...
def close(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
else:
class MultiLoopChildWatcher(AbstractChildWatcher):
def is_active(self) -> bool: ...
def close(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
if sys.version_info < (3, 14):
class ThreadedChildWatcher(AbstractChildWatcher):
def is_active(self) -> Literal[True]: ...
def close(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: types.TracebackType | None
) -> None: ...
def __del__(self) -> None: ...
def add_child_handler(
self, pid: int, callback: Callable[[int, int, Unpack[_Ts]], object], *args: Unpack[_Ts]
) -> None: ...
def remove_child_handler(self, pid: int) -> bool: ...
def attach_loop(self, loop: AbstractEventLoop | None) -> None: ...
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

@@ -1,101 +0,0 @@
import socket
import sys
from _typeshed import Incomplete, ReadableBuffer, WriteableBuffer
from collections.abc import Callable
from typing import IO, Any, ClassVar, Final, NoReturn
from . import events, futures, proactor_events, selector_events, streams, windows_utils
# Keep asyncio.__all__ updated with any changes to __all__ here
if sys.platform == "win32":
if sys.version_info >= (3, 13):
# 3.13 added `EventLoop`.
__all__ = (
"SelectorEventLoop",
"ProactorEventLoop",
"IocpProactor",
"DefaultEventLoopPolicy",
"WindowsSelectorEventLoopPolicy",
"WindowsProactorEventLoopPolicy",
"EventLoop",
)
else:
__all__ = (
"SelectorEventLoop",
"ProactorEventLoop",
"IocpProactor",
"DefaultEventLoopPolicy",
"WindowsSelectorEventLoopPolicy",
"WindowsProactorEventLoopPolicy",
)
NULL: Final = 0
INFINITE: Final = 0xFFFFFFFF
ERROR_CONNECTION_REFUSED: Final = 1225
ERROR_CONNECTION_ABORTED: Final = 1236
CONNECT_PIPE_INIT_DELAY: float
CONNECT_PIPE_MAX_DELAY: float
class PipeServer:
def __init__(self, address: str) -> None: ...
def __del__(self) -> None: ...
def closed(self) -> bool: ...
def close(self) -> None: ...
class _WindowsSelectorEventLoop(selector_events.BaseSelectorEventLoop): ...
class ProactorEventLoop(proactor_events.BaseProactorEventLoop):
def __init__(self, proactor: IocpProactor | None = None) -> None: ...
async def create_pipe_connection(
self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str
) -> tuple[proactor_events._ProactorDuplexPipeTransport, streams.StreamReaderProtocol]: ...
async def start_serving_pipe(
self, protocol_factory: Callable[[], streams.StreamReaderProtocol], address: str
) -> list[PipeServer]: ...
class IocpProactor:
def __init__(self, concurrency: int = 0xFFFFFFFF) -> None: ...
def __del__(self) -> None: ...
def set_loop(self, loop: events.AbstractEventLoop) -> None: ...
def select(self, timeout: int | None = None) -> list[futures.Future[Any]]: ...
def recv(self, conn: socket.socket, nbytes: int, flags: int = 0) -> futures.Future[bytes]: ...
def recv_into(self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0) -> futures.Future[Any]: ...
def recvfrom(
self, conn: socket.socket, nbytes: int, flags: int = 0
) -> futures.Future[tuple[bytes, socket._RetAddress]]: ...
def sendto(
self, conn: socket.socket, buf: ReadableBuffer, flags: int = 0, addr: socket._Address | None = None
) -> futures.Future[int]: ...
def send(self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0) -> futures.Future[Any]: ...
def accept(self, listener: socket.socket) -> futures.Future[Any]: ...
def connect(
self,
conn: socket.socket,
address: tuple[Incomplete, Incomplete] | tuple[Incomplete, Incomplete, Incomplete, Incomplete],
) -> futures.Future[Any]: ...
def sendfile(self, sock: socket.socket, file: IO[bytes], offset: int, count: int) -> futures.Future[Any]: ...
def accept_pipe(self, pipe: socket.socket) -> futures.Future[Any]: ...
async def connect_pipe(self, address: str) -> windows_utils.PipeHandle: ...
def wait_for_handle(self, handle: windows_utils.PipeHandle, timeout: int | None = None) -> bool: ...
def close(self) -> None: ...
if sys.version_info >= (3, 11):
def recvfrom_into(
self, conn: socket.socket, buf: WriteableBuffer, flags: int = 0
) -> futures.Future[tuple[int, socket._RetAddress]]: ...
SelectorEventLoop = _WindowsSelectorEventLoop
class WindowsSelectorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
_loop_factory: ClassVar[type[SelectorEventLoop]]
if sys.version_info < (3, 14):
def get_child_watcher(self) -> NoReturn: ...
def set_child_watcher(self, watcher: Any) -> NoReturn: ...
class WindowsProactorEventLoopPolicy(events.BaseDefaultEventLoopPolicy):
_loop_factory: ClassVar[type[ProactorEventLoop]]
def get_child_watcher(self) -> NoReturn: ...
def set_child_watcher(self, watcher: Any) -> NoReturn: ...
DefaultEventLoopPolicy = WindowsSelectorEventLoopPolicy
if sys.version_info >= (3, 13):
EventLoop = ProactorEventLoop

View File

@@ -1,49 +0,0 @@
import subprocess
import sys
from collections.abc import Callable
from types import TracebackType
from typing import Any, AnyStr, Final
from typing_extensions import Self
if sys.platform == "win32":
__all__ = ("pipe", "Popen", "PIPE", "PipeHandle")
BUFSIZE: Final = 8192
PIPE = subprocess.PIPE
STDOUT = subprocess.STDOUT
def pipe(*, duplex: bool = False, overlapped: tuple[bool, bool] = (True, True), bufsize: int = 8192) -> tuple[int, int]: ...
class PipeHandle:
def __init__(self, handle: int) -> None: ...
def __del__(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(self, t: type[BaseException] | None, v: BaseException | None, tb: TracebackType | None) -> None: ...
@property
def handle(self) -> int: ...
def fileno(self) -> int: ...
def close(self, *, CloseHandle: Callable[[int], object] = ...) -> None: ...
class Popen(subprocess.Popen[AnyStr]):
stdin: PipeHandle | None # type: ignore[assignment]
stdout: PipeHandle | None # type: ignore[assignment]
stderr: PipeHandle | None # type: ignore[assignment]
# For simplicity we omit the full overloaded __new__ signature of
# subprocess.Popen. The arguments are mostly the same, but
# subprocess.Popen takes other positional-or-keyword arguments before
# stdin.
def __new__(
cls,
args: subprocess._CMD,
stdin: subprocess._FILE | None = ...,
stdout: subprocess._FILE | None = ...,
stderr: subprocess._FILE | None = ...,
**kwds: Any,
) -> Self: ...
def __init__(
self,
args: subprocess._CMD,
stdin: subprocess._FILE | None = None,
stdout: subprocess._FILE | None = None,
stderr: subprocess._FILE | None = None,
**kwds: Any,
) -> None: ...

View File

@@ -1,51 +0,0 @@
import sys
from ._base import (
ALL_COMPLETED as ALL_COMPLETED,
FIRST_COMPLETED as FIRST_COMPLETED,
FIRST_EXCEPTION as FIRST_EXCEPTION,
BrokenExecutor as BrokenExecutor,
CancelledError as CancelledError,
Executor as Executor,
Future as Future,
InvalidStateError as InvalidStateError,
TimeoutError as TimeoutError,
as_completed as as_completed,
wait as wait,
)
from .process import ProcessPoolExecutor as ProcessPoolExecutor
from .thread import ThreadPoolExecutor as ThreadPoolExecutor
if sys.version_info >= (3, 13):
__all__ = (
"FIRST_COMPLETED",
"FIRST_EXCEPTION",
"ALL_COMPLETED",
"CancelledError",
"TimeoutError",
"InvalidStateError",
"BrokenExecutor",
"Future",
"Executor",
"wait",
"as_completed",
"ProcessPoolExecutor",
"ThreadPoolExecutor",
)
else:
__all__ = (
"FIRST_COMPLETED",
"FIRST_EXCEPTION",
"ALL_COMPLETED",
"CancelledError",
"TimeoutError",
"BrokenExecutor",
"Future",
"Executor",
"wait",
"as_completed",
"ProcessPoolExecutor",
"ThreadPoolExecutor",
)
def __dir__() -> tuple[str, ...]: ...

View File

@@ -1,108 +0,0 @@
import sys
import threading
from _typeshed import Unused
from collections.abc import Callable, Iterable, Iterator
from logging import Logger
from types import GenericAlias, TracebackType
from typing import Any, Final, Generic, NamedTuple, Protocol, TypeVar
from typing_extensions import ParamSpec, Self
FIRST_COMPLETED: Final = "FIRST_COMPLETED"
FIRST_EXCEPTION: Final = "FIRST_EXCEPTION"
ALL_COMPLETED: Final = "ALL_COMPLETED"
PENDING: Final = "PENDING"
RUNNING: Final = "RUNNING"
CANCELLED: Final = "CANCELLED"
CANCELLED_AND_NOTIFIED: Final = "CANCELLED_AND_NOTIFIED"
FINISHED: Final = "FINISHED"
_FUTURE_STATES: list[str]
_STATE_TO_DESCRIPTION_MAP: dict[str, str]
LOGGER: Logger
class Error(Exception): ...
class CancelledError(Error): ...
if sys.version_info >= (3, 11):
from builtins import TimeoutError as TimeoutError
else:
class TimeoutError(Error): ...
class InvalidStateError(Error): ...
class BrokenExecutor(RuntimeError): ...
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_P = ParamSpec("_P")
class Future(Generic[_T]):
_condition: threading.Condition
_state: str
_result: _T | None
_exception: BaseException | None
_waiters: list[_Waiter]
def cancel(self) -> bool: ...
def cancelled(self) -> bool: ...
def running(self) -> bool: ...
def done(self) -> bool: ...
def add_done_callback(self, fn: Callable[[Future[_T]], object]) -> None: ...
def result(self, timeout: float | None = None) -> _T: ...
def set_running_or_notify_cancel(self) -> bool: ...
def set_result(self, result: _T) -> None: ...
def exception(self, timeout: float | None = None) -> BaseException | None: ...
def set_exception(self, exception: BaseException | None) -> None: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
class Executor:
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]: ...
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
) -> bool | None: ...
class _AsCompletedFuture(Protocol[_T_co]):
# as_completed only mutates non-generic aspects of passed Futures and does not do any nominal
# checks. Therefore, we can use a Protocol here to allow as_completed to act covariantly.
# See the tests for concurrent.futures
_condition: threading.Condition
_state: str
_waiters: list[_Waiter]
# Not used by as_completed, but needed to propagate the generic type
def result(self, timeout: float | None = None) -> _T_co: ...
def as_completed(fs: Iterable[_AsCompletedFuture[_T]], timeout: float | None = None) -> Iterator[Future[_T]]: ...
class DoneAndNotDoneFutures(NamedTuple, Generic[_T]):
done: set[Future[_T]]
not_done: set[Future[_T]]
def wait(
fs: Iterable[Future[_T]], timeout: float | None = None, return_when: str = "ALL_COMPLETED"
) -> DoneAndNotDoneFutures[_T]: ...
class _Waiter:
event: threading.Event
finished_futures: list[Future[Any]]
def add_result(self, future: Future[Any]) -> None: ...
def add_exception(self, future: Future[Any]) -> None: ...
def add_cancelled(self, future: Future[Any]) -> None: ...
class _AsCompletedWaiter(_Waiter):
lock: threading.Lock
class _FirstCompletedWaiter(_Waiter): ...
class _AllCompletedWaiter(_Waiter):
num_pending_calls: int
stop_on_exception: bool
lock: threading.Lock
def __init__(self, num_pending_calls: int, stop_on_exception: bool) -> None: ...
class _AcquireFutures:
futures: Iterable[Future[Any]]
def __init__(self, futures: Iterable[Future[Any]]) -> None: ...
def __enter__(self) -> None: ...
def __exit__(self, *args: Unused) -> None: ...

View File

@@ -1,238 +0,0 @@
import sys
from collections.abc import Callable, Generator, Iterable, Mapping, MutableMapping, MutableSequence
from multiprocessing.connection import Connection
from multiprocessing.context import BaseContext, Process
from multiprocessing.queues import Queue, SimpleQueue
from threading import Lock, Semaphore, Thread
from types import TracebackType
from typing import Any, Generic, TypeVar, overload
from typing_extensions import TypeVarTuple, Unpack
from weakref import ref
from ._base import BrokenExecutor, Executor, Future
_T = TypeVar("_T")
_Ts = TypeVarTuple("_Ts")
_threads_wakeups: MutableMapping[Any, Any]
_global_shutdown: bool
class _ThreadWakeup:
_closed: bool
# Any: Unused send and recv methods
_reader: Connection[Any, Any]
_writer: Connection[Any, Any]
def close(self) -> None: ...
def wakeup(self) -> None: ...
def clear(self) -> None: ...
def _python_exit() -> None: ...
EXTRA_QUEUED_CALLS: int
_MAX_WINDOWS_WORKERS: int
class _RemoteTraceback(Exception):
tb: str
def __init__(self, tb: TracebackType) -> None: ...
class _ExceptionWithTraceback:
exc: BaseException
tb: TracebackType
def __init__(self, exc: BaseException, tb: TracebackType) -> None: ...
def __reduce__(self) -> str | tuple[Any, ...]: ...
def _rebuild_exc(exc: Exception, tb: str) -> Exception: ...
class _WorkItem(Generic[_T]):
future: Future[_T]
fn: Callable[..., _T]
args: Iterable[Any]
kwargs: Mapping[str, Any]
def __init__(self, future: Future[_T], fn: Callable[..., _T], args: Iterable[Any], kwargs: Mapping[str, Any]) -> None: ...
class _ResultItem:
work_id: int
exception: Exception
result: Any
if sys.version_info >= (3, 11):
exit_pid: int | None
def __init__(
self, work_id: int, exception: Exception | None = None, result: Any | None = None, exit_pid: int | None = None
) -> None: ...
else:
def __init__(self, work_id: int, exception: Exception | None = None, result: Any | None = None) -> None: ...
class _CallItem:
work_id: int
fn: Callable[..., Any]
args: Iterable[Any]
kwargs: Mapping[str, Any]
def __init__(self, work_id: int, fn: Callable[..., Any], args: Iterable[Any], kwargs: Mapping[str, Any]) -> None: ...
class _SafeQueue(Queue[Future[Any]]):
pending_work_items: dict[int, _WorkItem[Any]]
if sys.version_info < (3, 12):
shutdown_lock: Lock
thread_wakeup: _ThreadWakeup
if sys.version_info >= (3, 12):
def __init__(
self,
max_size: int | None = 0,
*,
ctx: BaseContext,
pending_work_items: dict[int, _WorkItem[Any]],
thread_wakeup: _ThreadWakeup,
) -> None: ...
else:
def __init__(
self,
max_size: int | None = 0,
*,
ctx: BaseContext,
pending_work_items: dict[int, _WorkItem[Any]],
shutdown_lock: Lock,
thread_wakeup: _ThreadWakeup,
) -> None: ...
def _on_queue_feeder_error(self, e: Exception, obj: _CallItem) -> None: ...
def _get_chunks(*iterables: Any, chunksize: int) -> Generator[tuple[Any, ...], None, None]: ...
def _process_chunk(fn: Callable[..., _T], chunk: Iterable[tuple[Any, ...]]) -> list[_T]: ...
if sys.version_info >= (3, 11):
def _sendback_result(
result_queue: SimpleQueue[_WorkItem[Any]],
work_id: int,
result: Any | None = None,
exception: Exception | None = None,
exit_pid: int | None = None,
) -> None: ...
else:
def _sendback_result(
result_queue: SimpleQueue[_WorkItem[Any]], work_id: int, result: Any | None = None, exception: Exception | None = None
) -> None: ...
if sys.version_info >= (3, 11):
def _process_worker(
call_queue: Queue[_CallItem],
result_queue: SimpleQueue[_ResultItem],
initializer: Callable[[Unpack[_Ts]], object] | None,
initargs: tuple[Unpack[_Ts]],
max_tasks: int | None = None,
) -> None: ...
else:
def _process_worker(
call_queue: Queue[_CallItem],
result_queue: SimpleQueue[_ResultItem],
initializer: Callable[[Unpack[_Ts]], object] | None,
initargs: tuple[Unpack[_Ts]],
) -> None: ...
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
def _check_system_limits() -> None: ...
def _chain_from_iterable_of_lists(iterable: Iterable[MutableSequence[Any]]) -> Any: ...
class BrokenProcessPool(BrokenExecutor): ...
class ProcessPoolExecutor(Executor):
_mp_context: BaseContext | None
_initializer: Callable[..., None] | None
_initargs: tuple[Any, ...]
_executor_manager_thread: _ThreadWakeup
_processes: MutableMapping[int, Process]
_shutdown_thread: bool
_shutdown_lock: Lock
_idle_worker_semaphore: Semaphore
_broken: bool
_queue_count: int
_pending_work_items: dict[int, _WorkItem[Any]]
_cancel_pending_futures: bool
_executor_manager_thread_wakeup: _ThreadWakeup
_result_queue: SimpleQueue[Any]
_work_ids: Queue[Any]
if sys.version_info >= (3, 11):
@overload
def __init__(
self,
max_workers: int | None = None,
mp_context: BaseContext | None = None,
initializer: Callable[[], object] | None = None,
initargs: tuple[()] = (),
*,
max_tasks_per_child: int | None = None,
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None = None,
mp_context: BaseContext | None = None,
*,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
max_tasks_per_child: int | None = None,
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None,
mp_context: BaseContext | None,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
*,
max_tasks_per_child: int | None = None,
) -> None: ...
else:
@overload
def __init__(
self,
max_workers: int | None = None,
mp_context: BaseContext | None = None,
initializer: Callable[[], object] | None = None,
initargs: tuple[()] = (),
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None = None,
mp_context: BaseContext | None = None,
*,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None,
mp_context: BaseContext | None,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
def _start_executor_manager_thread(self) -> None: ...
def _adjust_process_count(self) -> None: ...

View File

@@ -1,76 +0,0 @@
import queue
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
from ._base import BrokenExecutor, Executor, Future
_Ts = TypeVarTuple("_Ts")
_threads_queues: Mapping[Any, Any]
_shutdown: bool
_global_shutdown_lock: Lock
def _python_exit() -> None: ...
_S = TypeVar("_S")
class _WorkItem(Generic[_S]):
future: Future[_S]
fn: Callable[..., _S]
args: Iterable[Any]
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: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
def _worker(
executor_reference: ref[Any],
work_queue: queue.SimpleQueue[Any],
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
class BrokenThreadPool(BrokenExecutor): ...
class ThreadPoolExecutor(Executor):
_max_workers: int
_idle_semaphore: Semaphore
_threads: AbstractSet[Thread]
_broken: bool
_shutdown: bool
_shutdown_lock: Lock
_thread_name_prefix: str | None
_initializer: Callable[..., None] | None
_initargs: tuple[Any, ...]
_work_queue: queue.SimpleQueue[_WorkItem[Any]]
@overload
def __init__(
self,
max_workers: int | None = None,
thread_name_prefix: str = "",
initializer: Callable[[], object] | None = None,
initargs: tuple[()] = (),
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None = None,
thread_name_prefix: str = "",
*,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
@overload
def __init__(
self,
max_workers: int | None,
thread_name_prefix: str,
initializer: Callable[[Unpack[_Ts]], object],
initargs: tuple[Unpack[_Ts]],
) -> None: ...
def _adjust_thread_count(self) -> None: ...
def _initializer_failed(self) -> None: ...

View File

@@ -1,306 +0,0 @@
import sys
from _ctypes import (
POINTER as POINTER,
RTLD_GLOBAL as RTLD_GLOBAL,
RTLD_LOCAL as RTLD_LOCAL,
Array as Array,
CFuncPtr as _CFuncPtr,
Structure as Structure,
Union as Union,
_CanCastTo as _CanCastTo,
_CArgObject as _CArgObject,
_CData as _CData,
_CDataType as _CDataType,
_CField as _CField,
_Pointer as _Pointer,
_PointerLike as _PointerLike,
_SimpleCData as _SimpleCData,
addressof as addressof,
alignment as alignment,
byref as byref,
get_errno as get_errno,
pointer as pointer,
resize as resize,
set_errno as set_errno,
sizeof as sizeof,
)
from _typeshed import StrPath
from ctypes._endian import BigEndianStructure as BigEndianStructure, LittleEndianStructure as LittleEndianStructure
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":
from _ctypes import FormatError as FormatError, get_last_error as get_last_error, set_last_error as set_last_error
if sys.version_info >= (3, 11):
from ctypes._endian import BigEndianUnion as BigEndianUnion, LittleEndianUnion as LittleEndianUnion
_T = TypeVar("_T", default=Any)
_DLLT = TypeVar("_DLLT", bound=CDLL)
_CT = TypeVar("_CT", bound=_CData)
DEFAULT_MODE: int
class ArgumentError(Exception): ...
# defined within CDLL.__init__
# Runtime name is ctypes.CDLL.__init__.<locals>._FuncPtr
@type_check_only
class _CDLLFuncPointer(_CFuncPtr):
_flags_: ClassVar[int]
_restype_: ClassVar[type[_CDataType]]
# Not a real class; _CDLLFuncPointer with a __name__ set on it.
@type_check_only
class _NamedFuncPointer(_CDLLFuncPointer):
__name__: str
if sys.version_info >= (3, 12):
_NameTypes: TypeAlias = StrPath | None
else:
_NameTypes: TypeAlias = str | None
class CDLL:
_func_flags_: ClassVar[int]
_func_restype_: ClassVar[type[_CDataType]]
_name: str
_handle: int
_FuncPtr: type[_CDLLFuncPointer]
def __init__(
self,
name: _NameTypes,
mode: int = ...,
handle: int | None = None,
use_errno: bool = False,
use_last_error: bool = False,
winmode: int | None = None,
) -> None: ...
def __getattr__(self, name: str) -> _NamedFuncPointer: ...
def __getitem__(self, name_or_ordinal: str) -> _NamedFuncPointer: ...
if sys.platform == "win32":
class OleDLL(CDLL): ...
class WinDLL(CDLL): ...
class PyDLL(CDLL): ...
class LibraryLoader(Generic[_DLLT]):
def __init__(self, dlltype: type[_DLLT]) -> None: ...
def __getattr__(self, name: str) -> _DLLT: ...
def __getitem__(self, name: str) -> _DLLT: ...
def LoadLibrary(self, name: str) -> _DLLT: ...
def __class_getitem__(cls, item: Any, /) -> GenericAlias: ...
cdll: LibraryLoader[CDLL]
if sys.platform == "win32":
windll: LibraryLoader[WinDLL]
oledll: LibraryLoader[OleDLL]
pydll: LibraryLoader[PyDLL]
pythonapi: PyDLL
# Class definition within CFUNCTYPE / WINFUNCTYPE / PYFUNCTYPE
# Names at runtime are
# ctypes.CFUNCTYPE.<locals>.CFunctionType
# ctypes.WINFUNCTYPE.<locals>.WinFunctionType
# ctypes.PYFUNCTYPE.<locals>.CFunctionType
@type_check_only
class _CFunctionType(_CFuncPtr):
_argtypes_: ClassVar[list[type[_CData | _CDataType]]]
_restype_: ClassVar[type[_CData | _CDataType] | None]
_flags_: ClassVar[int]
# Alias for either function pointer type
_FuncPointer: TypeAlias = _CDLLFuncPointer | _CFunctionType # noqa: Y047 # not used here
def CFUNCTYPE(
restype: type[_CData | _CDataType] | None,
*argtypes: type[_CData | _CDataType],
use_errno: bool = False,
use_last_error: bool = False,
) -> type[_CFunctionType]: ...
if sys.platform == "win32":
def WINFUNCTYPE(
restype: type[_CData | _CDataType] | None,
*argtypes: type[_CData | _CDataType],
use_errno: bool = False,
use_last_error: bool = False,
) -> type[_CFunctionType]: ...
def PYFUNCTYPE(restype: type[_CData | _CDataType] | None, *argtypes: type[_CData | _CDataType]) -> type[_CFunctionType]: ...
# Any type that can be implicitly converted to c_void_p when passed as a C function argument.
# (bytes is not included here, see below.)
_CVoidPLike: TypeAlias = _PointerLike | Array[Any] | _CArgObject | int
# Same as above, but including types known to be read-only (i. e. bytes).
# This distinction is not strictly necessary (ctypes doesn't differentiate between const
# and non-const pointers), but it catches errors like memmove(b'foo', buf, 4)
# when memmove(buf, b'foo', 4) was intended.
_CVoidConstPLike: TypeAlias = _CVoidPLike | bytes
_CastT = TypeVar("_CastT", bound=_CanCastTo)
def cast(obj: _CData | _CDataType | _CArgObject | int, typ: type[_CastT]) -> _CastT: ...
def create_string_buffer(init: int | bytes, size: int | None = None) -> Array[c_char]: ...
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) -> 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
# Actually just an instance of _NamedFuncPointer (aka _CDLLFuncPointer),
# but we want to set a more specific __call__
@type_check_only
class _GetLastErrorFunctionType(_NamedFuncPointer):
def __call__(self) -> int: ...
GetLastError: _GetLastErrorFunctionType
# Actually just an instance of _CFunctionType, but we want to set a more
# specific __call__.
@type_check_only
class _MemmoveFunctionType(_CFunctionType):
def __call__(self, dst: _CVoidPLike, src: _CVoidConstPLike, count: int) -> int: ...
memmove: _MemmoveFunctionType
# Actually just an instance of _CFunctionType, but we want to set a more
# specific __call__.
@type_check_only
class _MemsetFunctionType(_CFunctionType):
def __call__(self, dst: _CVoidPLike, c: int, count: int) -> int: ...
memset: _MemsetFunctionType
def string_at(ptr: _CVoidConstPLike, size: int = -1) -> bytes: ...
if sys.platform == "win32":
def WinError(code: int | None = None, descr: str | None = None) -> OSError: ...
def wstring_at(ptr: _CVoidConstPLike, size: int = -1) -> str: ...
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_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]):
_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: ...
if sys.platform == "win32":
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_int, c_long, or c_longlong
# This covers all our bases.
c_time_t: type[c_int32 | c_int64 | c_int | c_long | c_longlong]

View File

@@ -1,12 +0,0 @@
import sys
from ctypes import Structure, Union
# At runtime, the native endianness is an alias for Structure,
# while the other is a subclass with a metaclass added in.
class BigEndianStructure(Structure): ...
class LittleEndianStructure(Structure): ...
# Same thing for these: one is an alias of Union at runtime
if sys.version_info >= (3, 11):
class BigEndianUnion(Union): ...
class LittleEndianUnion(Union): ...

View File

@@ -1 +0,0 @@
__version__: str

View File

@@ -1,8 +0,0 @@
from collections.abc import Mapping
from ctypes.macholib.dylib import dylib_info as dylib_info
from ctypes.macholib.framework import framework_info as framework_info
__all__ = ["dyld_find", "framework_find", "framework_info", "dylib_info"]
def dyld_find(name: str, executable_path: str | None = None, env: Mapping[str, str] | None = None) -> str: ...
def framework_find(fn: str, executable_path: str | None = None, env: Mapping[str, str] | None = None) -> str: ...

View File

@@ -1,14 +0,0 @@
from typing import TypedDict, type_check_only
__all__ = ["dylib_info"]
# Actual result is produced by re.match.groupdict()
@type_check_only
class _DylibInfo(TypedDict):
location: str
name: str
shortname: str
version: str | None
suffix: str | None
def dylib_info(filename: str) -> _DylibInfo | None: ...

View File

@@ -1,14 +0,0 @@
from typing import TypedDict, type_check_only
__all__ = ["framework_info"]
# Actual result is produced by re.match.groupdict()
@type_check_only
class _FrameworkInfo(TypedDict):
location: str
name: str
shortname: str
version: str | None
suffix: str | None
def framework_info(filename: str) -> _FrameworkInfo | None: ...

View File

@@ -1,8 +0,0 @@
import sys
def find_library(name: str) -> str | None: ...
if sys.platform == "win32":
def find_msvcrt() -> str | None: ...
def test() -> None: ...

View File

@@ -1,312 +0,0 @@
import sys
from _ctypes import _CArgObject, _CField
from ctypes import (
Array,
Structure,
_Pointer,
_SimpleCData,
c_char,
c_char_p,
c_double,
c_float,
c_int,
c_long,
c_longlong,
c_short,
c_uint,
c_ulong,
c_ulonglong,
c_ushort,
c_void_p,
c_wchar,
c_wchar_p,
)
from typing import Any, TypeVar
from typing_extensions import Self, TypeAlias
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
WCHAR = c_wchar
UINT = c_uint
INT = c_int
DOUBLE = c_double
FLOAT = c_float
BOOLEAN = BYTE
BOOL = c_long
class VARIANT_BOOL(_SimpleCData[bool]): ...
ULONG = c_ulong
LONG = c_long
USHORT = c_ushort
SHORT = c_short
LARGE_INTEGER = c_longlong
_LARGE_INTEGER = c_longlong
ULARGE_INTEGER = c_ulonglong
_ULARGE_INTEGER = c_ulonglong
OLESTR = c_wchar_p
LPOLESTR = c_wchar_p
LPCOLESTR = c_wchar_p
LPWSTR = c_wchar_p
LPCWSTR = c_wchar_p
LPSTR = c_char_p
LPCSTR = c_char_p
LPVOID = c_void_p
LPCVOID = c_void_p
# These two types are pointer-sized unsigned and signed ints, respectively.
# At runtime, they are either c_[u]long or c_[u]longlong, depending on the host's pointer size
# (they are not really separate classes).
class WPARAM(_SimpleCData[int]): ...
class LPARAM(_SimpleCData[int]): ...
ATOM = WORD
LANGID = WORD
COLORREF = DWORD
LGRPID = DWORD
LCTYPE = DWORD
LCID = DWORD
HANDLE = c_void_p
HACCEL = HANDLE
HBITMAP = HANDLE
HBRUSH = HANDLE
HCOLORSPACE = HANDLE
HDC = HANDLE
HDESK = HANDLE
HDWP = HANDLE
HENHMETAFILE = HANDLE
HFONT = HANDLE
HGDIOBJ = HANDLE
HGLOBAL = HANDLE
HHOOK = HANDLE
HICON = HANDLE
HINSTANCE = HANDLE
HKEY = HANDLE
HKL = HANDLE
HLOCAL = HANDLE
HMENU = HANDLE
HMETAFILE = HANDLE
HMODULE = HANDLE
HMONITOR = HANDLE
HPALETTE = HANDLE
HPEN = HANDLE
HRGN = HANDLE
HRSRC = HANDLE
HSTR = HANDLE
HTASK = HANDLE
HWINSTA = HANDLE
HWND = HANDLE
SC_HANDLE = HANDLE
SERVICE_STATUS_HANDLE = HANDLE
_CIntLikeT = TypeVar("_CIntLikeT", bound=_SimpleCData[int])
_CIntLikeField: TypeAlias = _CField[_CIntLikeT, int, _CIntLikeT | int]
class RECT(Structure):
left: _CIntLikeField[LONG]
top: _CIntLikeField[LONG]
right: _CIntLikeField[LONG]
bottom: _CIntLikeField[LONG]
RECTL = RECT
_RECTL = RECT
tagRECT = RECT
class _SMALL_RECT(Structure):
Left: _CIntLikeField[SHORT]
Top: _CIntLikeField[SHORT]
Right: _CIntLikeField[SHORT]
Bottom: _CIntLikeField[SHORT]
SMALL_RECT = _SMALL_RECT
class _COORD(Structure):
X: _CIntLikeField[SHORT]
Y: _CIntLikeField[SHORT]
class POINT(Structure):
x: _CIntLikeField[LONG]
y: _CIntLikeField[LONG]
POINTL = POINT
_POINTL = POINT
tagPOINT = POINT
class SIZE(Structure):
cx: _CIntLikeField[LONG]
cy: _CIntLikeField[LONG]
SIZEL = SIZE
tagSIZE = SIZE
def RGB(red: int, green: int, blue: int) -> int: ...
class FILETIME(Structure):
dwLowDateTime: _CIntLikeField[DWORD]
dwHighDateTime: _CIntLikeField[DWORD]
_FILETIME = FILETIME
class MSG(Structure):
hWnd: _CField[HWND, int | None, HWND | int | None]
message: _CIntLikeField[UINT]
wParam: _CIntLikeField[WPARAM]
lParam: _CIntLikeField[LPARAM]
time: _CIntLikeField[DWORD]
pt: _CField[POINT, POINT, POINT]
tagMSG = MSG
MAX_PATH: int
class WIN32_FIND_DATAA(Structure):
dwFileAttributes: _CIntLikeField[DWORD]
ftCreationTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastAccessTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastWriteTime: _CField[FILETIME, FILETIME, FILETIME]
nFileSizeHigh: _CIntLikeField[DWORD]
nFileSizeLow: _CIntLikeField[DWORD]
dwReserved0: _CIntLikeField[DWORD]
dwReserved1: _CIntLikeField[DWORD]
cFileName: _CField[Array[CHAR], bytes, bytes]
cAlternateFileName: _CField[Array[CHAR], bytes, bytes]
class WIN32_FIND_DATAW(Structure):
dwFileAttributes: _CIntLikeField[DWORD]
ftCreationTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastAccessTime: _CField[FILETIME, FILETIME, FILETIME]
ftLastWriteTime: _CField[FILETIME, FILETIME, FILETIME]
nFileSizeHigh: _CIntLikeField[DWORD]
nFileSizeLow: _CIntLikeField[DWORD]
dwReserved0: _CIntLikeField[DWORD]
dwReserved1: _CIntLikeField[DWORD]
cFileName: _CField[Array[WCHAR], str, str]
cAlternateFileName: _CField[Array[WCHAR], str, str]
# These are all defined with the POINTER() function, which keeps a cache and will
# return a previously created class if it can. The self-reported __name__
# of these classes is f"LP_{typ.__name__}", where typ is the original class
# passed in to the POINTER() function.
# LP_c_short
class PSHORT(_Pointer[SHORT]): ...
# LP_c_ushort
class PUSHORT(_Pointer[USHORT]): ...
PWORD = PUSHORT
LPWORD = PUSHORT
# LP_c_long
class PLONG(_Pointer[LONG]): ...
LPLONG = PLONG
PBOOL = PLONG
LPBOOL = PLONG
# LP_c_ulong
class PULONG(_Pointer[ULONG]): ...
PDWORD = PULONG
LPDWORD = PDWORD
LPCOLORREF = PDWORD
PLCID = PDWORD
# LP_c_int (or LP_c_long if int and long have the same size)
class PINT(_Pointer[INT]): ...
LPINT = PINT
# LP_c_uint (or LP_c_ulong if int and long have the same size)
class PUINT(_Pointer[UINT]): ...
LPUINT = PUINT
# LP_c_float
class PFLOAT(_Pointer[FLOAT]): ...
# LP_c_longlong (or LP_c_long if long and long long have the same size)
class PLARGE_INTEGER(_Pointer[LARGE_INTEGER]): ...
# LP_c_ulonglong (or LP_c_ulong if long and long long have the same size)
class PULARGE_INTEGER(_Pointer[ULARGE_INTEGER]): ...
# LP_c_byte types
class PBYTE(_Pointer[BYTE]): ...
LPBYTE = PBYTE
PBOOLEAN = PBYTE
# LP_c_char
class PCHAR(_Pointer[CHAR]):
# this is inherited from ctypes.c_char_p, kind of.
@classmethod
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
# LP_c_wchar
class PWCHAR(_Pointer[WCHAR]):
# inherited from ctypes.c_wchar_p, kind of
@classmethod
def from_param(cls, value: Any, /) -> Self | _CArgObject: ...
# LP_c_void_p
class PHANDLE(_Pointer[HANDLE]): ...
LPHANDLE = PHANDLE
PHKEY = PHANDLE
LPHKL = PHANDLE
LPSC_HANDLE = PHANDLE
# LP_FILETIME
class PFILETIME(_Pointer[FILETIME]): ...
LPFILETIME = PFILETIME
# LP_MSG
class PMSG(_Pointer[MSG]): ...
LPMSG = PMSG
# LP_POINT
class PPOINT(_Pointer[POINT]): ...
LPPOINT = PPOINT
PPOINTL = PPOINT
# LP_RECT
class PRECT(_Pointer[RECT]): ...
LPRECT = PRECT
PRECTL = PRECT
LPRECTL = PRECT
# LP_SIZE
class PSIZE(_Pointer[SIZE]): ...
LPSIZE = PSIZE
PSIZEL = PSIZE
LPSIZEL = PSIZE
# LP__SMALL_RECT
class PSMALL_RECT(_Pointer[SMALL_RECT]): ...
# LP_WIN32_FIND_DATAA
class PWIN32_FIND_DATAA(_Pointer[WIN32_FIND_DATAA]): ...
LPWIN32_FIND_DATAA = PWIN32_FIND_DATAA
# LP_WIN32_FIND_DATAW
class PWIN32_FIND_DATAW(_Pointer[WIN32_FIND_DATAW]): ...
LPWIN32_FIND_DATAW = PWIN32_FIND_DATAW

View File

@@ -1,45 +0,0 @@
import sys
from _curses import *
from _curses import window as window
from _typeshed import structseq
from collections.abc import Callable
from typing import Final, TypeVar, final, type_check_only
from typing_extensions import Concatenate, ParamSpec
# NOTE: The _curses module is ordinarily only available on Unix, but the
# windows-curses package makes it available on Windows as well with the same
# contents.
_T = TypeVar("_T")
_P = ParamSpec("_P")
# available after calling `curses.initscr()`
LINES: int
COLS: int
# available after calling `curses.start_color()`
COLORS: int
COLOR_PAIRS: int
def wrapper(func: Callable[Concatenate[window, _P], _T], /, *arg: _P.args, **kwds: _P.kwargs) -> _T: ...
# typeshed used the name _CursesWindow for the underlying C class before
# it was mapped to the name 'window' in 3.8.
# Kept here as a legacy alias in case any third-party code is relying on it.
_CursesWindow = window
# At runtime this class is unexposed and calls itself curses.ncurses_version.
# That name would conflict with the actual curses.ncurses_version, which is
# an instance of this class.
@final
@type_check_only
class _ncurses_version(structseq[int], tuple[int, int, int]):
if sys.version_info >= (3, 10):
__match_args__: Final = ("major", "minor", "patch")
@property
def major(self) -> int: ...
@property
def minor(self) -> int: ...
@property
def patch(self) -> int: ...

View File

@@ -1,62 +0,0 @@
from typing import TypeVar
_CharT = TypeVar("_CharT", str, int)
NUL: int
SOH: int
STX: int
ETX: int
EOT: int
ENQ: int
ACK: int
BEL: int
BS: int
TAB: int
HT: int
LF: int
NL: int
VT: int
FF: int
CR: int
SO: int
SI: int
DLE: int
DC1: int
DC2: int
DC3: int
DC4: int
NAK: int
SYN: int
ETB: int
CAN: int
EM: int
SUB: int
ESC: int
FS: int
GS: int
RS: int
US: int
SP: int
DEL: int
controlnames: list[int]
def isalnum(c: str | int) -> bool: ...
def isalpha(c: str | int) -> bool: ...
def isascii(c: str | int) -> bool: ...
def isblank(c: str | int) -> bool: ...
def iscntrl(c: str | int) -> bool: ...
def isdigit(c: str | int) -> bool: ...
def isgraph(c: str | int) -> bool: ...
def islower(c: str | int) -> bool: ...
def isprint(c: str | int) -> bool: ...
def ispunct(c: str | int) -> bool: ...
def isspace(c: str | int) -> bool: ...
def isupper(c: str | int) -> bool: ...
def isxdigit(c: str | int) -> bool: ...
def isctrl(c: str | int) -> bool: ...
def ismeta(c: str | int) -> bool: ...
def ascii(c: _CharT) -> _CharT: ...
def ctrl(c: _CharT) -> _CharT: ...
def alt(c: _CharT) -> _CharT: ...
def unctrl(c: str | int) -> str: ...

View File

@@ -1 +0,0 @@
def has_key(ch: int | str) -> bool: ...

View File

@@ -1 +0,0 @@
from _curses_panel import *

View File

@@ -1,11 +0,0 @@
from _curses import window
from collections.abc import Callable
def rectangle(win: window, uly: int, ulx: int, lry: int, lrx: int) -> None: ...
class Textbox:
stripspaces: bool
def __init__(self, win: window, insert_mode: bool = False) -> None: ...
def edit(self, validate: Callable[[int], int] | None = None) -> str: ...
def do_command(self, ch: str | int) -> None: ...
def gather(self) -> str: ...

View File

@@ -1,104 +0,0 @@
import sys
from _typeshed import StrOrBytesPath
from collections.abc import Iterator, MutableMapping
from types import TracebackType
from typing import Literal, type_check_only
from typing_extensions import Self, TypeAlias
__all__ = ["open", "whichdb", "error"]
_KeyType: TypeAlias = str | bytes
_ValueType: TypeAlias = str | bytes | bytearray
_TFlags: TypeAlias = Literal[
"r",
"w",
"c",
"n",
"rf",
"wf",
"cf",
"nf",
"rs",
"ws",
"cs",
"ns",
"ru",
"wu",
"cu",
"nu",
"rfs",
"wfs",
"cfs",
"nfs",
"rfu",
"wfu",
"cfu",
"nfu",
"rsf",
"wsf",
"csf",
"nsf",
"rsu",
"wsu",
"csu",
"nsu",
"ruf",
"wuf",
"cuf",
"nuf",
"rus",
"wus",
"cus",
"nus",
"rfsu",
"wfsu",
"cfsu",
"nfsu",
"rfus",
"wfus",
"cfus",
"nfus",
"rsfu",
"wsfu",
"csfu",
"nsfu",
"rsuf",
"wsuf",
"csuf",
"nsuf",
"rufs",
"wufs",
"cufs",
"nufs",
"rusf",
"wusf",
"cusf",
"nusf",
]
class _Database(MutableMapping[_KeyType, bytes]):
def close(self) -> None: ...
def __getitem__(self, key: _KeyType) -> bytes: ...
def __setitem__(self, key: _KeyType, value: _ValueType) -> None: ...
def __delitem__(self, key: _KeyType) -> None: ...
def __iter__(self) -> Iterator[bytes]: ...
def __len__(self) -> int: ...
def __del__(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
) -> None: ...
# This class is not exposed. It calls itself dbm.error.
@type_check_only
class _error(Exception): ...
error: tuple[type[_error], type[OSError]]
if sys.version_info >= (3, 11):
def whichdb(filename: StrOrBytesPath) -> str | None: ...
def open(file: StrOrBytesPath, flag: _TFlags = "r", mode: int = 0o666) -> _Database: ...
else:
def whichdb(filename: str) -> str | None: ...
def open(file: str, flag: _TFlags = "r", mode: int = 0o666) -> _Database: ...

View File

@@ -1,37 +0,0 @@
import sys
from _typeshed import StrOrBytesPath
from collections.abc import Iterator, MutableMapping
from types import TracebackType
from typing_extensions import Self, TypeAlias
__all__ = ["error", "open"]
_KeyType: TypeAlias = str | bytes
_ValueType: TypeAlias = str | bytes
error = OSError
# This class doesn't exist at runtime. open() can return an instance of
# any of the three implementations of dbm (dumb, gnu, ndbm), and this
# class is intended to represent the common interface supported by all three.
class _Database(MutableMapping[_KeyType, bytes]):
def __init__(self, filebasename: str, mode: str, flag: str = "c") -> None: ...
def sync(self) -> None: ...
def iterkeys(self) -> Iterator[bytes]: ... # undocumented
def close(self) -> None: ...
def __getitem__(self, key: _KeyType) -> bytes: ...
def __setitem__(self, key: _KeyType, val: _ValueType) -> None: ...
def __delitem__(self, key: _KeyType) -> None: ...
def __iter__(self) -> Iterator[bytes]: ...
def __len__(self) -> int: ...
def __del__(self) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(
self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None
) -> None: ...
if sys.version_info >= (3, 11):
def open(file: StrOrBytesPath, flag: str = "c", mode: int = 0o666) -> _Database: ...
else:
def open(file: str, flag: str = "c", mode: int = 0o666) -> _Database: ...

View File

@@ -1 +0,0 @@
from _gdbm import *

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