Skip to content

Merge upstream - #145

Merged
KotlinIsland merged 391 commits into
mainfrom
merge-upstream
Aug 14, 2026
Merged

Merge upstream#145
KotlinIsland merged 391 commits into
mainfrom
merge-upstream

Conversation

@KotlinIsland

Copy link
Copy Markdown
Owner

No description provided.

carljm and others added 30 commits July 29, 2026 08:05
## Summary

Rebases and continues #26245 on the latest `main`, keeping constraint
source ordering in a sidecar instead of TDD nodes and integrating it
with current abstraction, type-mapping, and path-traversal code.
Normalizes owned source-order sidecars into a dense, canonical
representation, preventing irrelevant construction history from
affecting Salsa equality or cycle convergence.

Brings over the behavior-focused regressions from #27141
(astral-sh/ty#4073), covering union-order-independent callable inference
and constraint absorption without adding the shape-cache implementation
that the sidecar representation makes unnecessary.

Fixes astral-sh/ty#4073

## Test plan

- Adds legacy-TypeVar and PEP 695 mdtests covering callable-return
inference across actual/formal union orders, nested tuples, covariant
generic members, and gradual `Container[Any]` constraints.
- Adds constraint-set regressions covering absorption, compound and
partitioned constraints, preserved binding order, distinct solutions,
type mapping, and source-ordered sequent initialization across
constraint traversals.
- Adds owned-constraint-set regression coverage for canonical
source-order identity across different construction histories and
source-order reuse in compacted overlays.
- Adds a Steam corpus reproducer covering the previously observed
constraint-cycle panic.
- Updates revealed-type ordering expectations for quantification and
high-fanout constraints.


### Ecosystem

- Reproduces all the same favorable ecosystem changes as #27141, plus a
bunch of ordering changes in diagnostics.
- There is one regression relative to main, in `static-frame`. This
shows up because of a subtle difference in the way constraints are
ordered in this PR compared to main -- the sidecar's reconstructed
ordering is not always identical to main's effective ordering. That
exposes this bug, but the real bug is protocol inference collecting
constraints from all overloads without accounting for
overlapping-overload precedence. This should be a separate fix. (Or
alternately, the real bug is that the constraint solver is not
commutative -- this is also out of scope :) ).

---------

Co-authored-by: Douglas Creager <dcreager@dcreager.net>
…ly (#27178)

## Summary

Fixes astral-sh/ty#4089, where `ty check` took O(n²) time in the size of
a literal union such as `mypy_boto3_ec2`'s `InstanceTypeType` (~1200
string literals).

Checking iteration over `Sequence[Literal[...]]` builds a constraint set
that is a single conjunction with one lower-bound constraint per union
element. Deciding its satisfiability walks the BDD with
`PathAssignments`, whose `discover_constraint` computes sequents for
every pair of constraints — quadratic in the number of constraints. For
lower-bound-only pairs, each pair computation also eagerly builds a
`Literal[a] | Literal[b]` union in `ConstraintId::intersect`, only for
the result to be discarded as `CannotSimplify`, so the entire quadratic
pass produces empty sequent maps.

This PR adds a linear fast path to `is_never_satisfied` for BDDs that
are a single all-positive conjunction with typevar-free bounds: per
typevar occurrence, check that the union of the lower bounds is
assignable to each upper-bound clause. Assignability distributes over
the union on the left and the intersection clauses on the right, so this
finds exactly the contradictions that the walk's pairwise disjointness
sequents detect. Bounds are grouped by occurrence identity so
differently materialized instances of the same typevar are handled
together. Type aliases and protocols can hide typevars in lazy
attributes, so bounds containing either conservatively fall back to the
general walk; this also avoids expanding recursively specialized aliases
in the fast path.

The existing `compute_simple_bound_conjunction` fast path used for
solution extraction is updated to use the same identity and lazy-bound
handling. For typevars with only upper-bound evidence, it skips
quadratic per-clause redundancy pruning and lets the final intersection
determine the solution.

Timings for the issue's reproducer (debug build): 4.6s → 0.03s against
an installed `mypy_boto3_ec2`, 2.3s → 0.03s for a synthetic 1200-literal
union, and the runtime is now flat in the union size (5000 literals also
check in ~0.03s).

## Test plan

- Added benchmarks covering `Sequence[Literal[...]]` access and many
contravariant callback arguments that produce upper-bound-only
constraints.
- Added unit tests covering satisfiable and contradictory simple
conjunctions without sequent-cache growth, equivalence with the general
path walk, differently materialized instances of the same typevar,
hidden typevars in lazy aliases, and large upper-bound-only
conjunctions.
- The `ty_python_semantic` test suite passes.
- Stable type property tests pass with 2000 generated cases.
- Manually verified the issue's reproducer and upper-bound-only scaling.

---------

Co-authored-by: Carl Meyer <carl@astral.sh>
Co-authored-by: Douglas Creager <dcreager@dcreager.net>
## Summary

Reintroducing `demisto/content` back to `ruff-ecosystem`, it's a huge
repo with 4.5K py file and 2.5M loc, so may have catch some cases for
ecosystem report. It was previously commented out in
astral-sh/ruff#12129 due to the use of removed
`E999`

Issue with the use of removed rules upstream is resolved, though
apparently `E999` was dropped from selection a while ago and new issue
with the use of removed `UP038` occurred, but it's resolved now too -
demisto/content#45227

Syntax error in still present in
https://github.com/demisto/content/blob/master/Packs/ThreatQ/Integrations/ThreatQ/ThreatQ.py,
so keeping `exclude`. Though apparently it doesn't break
`ruff-ecosystem` anymore, but keeping it safe for now. I've submitted a
fix upstream demisto/content#45275, so `exclude`
can be removed later too.


## Test Plan

Tested running `ruff-ecosystem` locally, no issues found.
## Summary

Fixes astral-sh/ty#4111.

Collection inference promotes exact runtime `float` and `complex`
elements to their numeric-tower unions, which can introduce types that
violate a covariant `Sequence` or `Iterable` context. Preserve the
original inferred element when it satisfies that context but the
promoted type does not.

This fixes the original `Sequence[str | Just[float]]` false positive
without changing `Just` protocol matching, invariant collection
inference, or ordinary mutable-list numeric widening.

## Test plan

Added focused bidirectional mdtests covering exact-float `Sequence` and
`Iterable` contexts, exact-complex sequence contexts, the original
`Just[float]` union, tuples, invariant and explicitly annotated lists,
rejection of actual integer and float mismatches, and preserved widening
for mutable float lists.

The full `ty_python_semantic` test suite and all applicable file-scoped
repository hooks pass.
## Summary
Changes the diagnostic fix applicability for rule `PT022` (missing yield
types / old-style yield fixtures) from a safe edit to an `unsafe_edit`.

Converting a `yield` to a `return` fundamentally alters execution flow,
scope lifetimes, and teardown behavior. In certain contexts (e.g., when
interacting with bindings like GDAL), this transformation can cause
critical runtime failures such as segmentation faults. Forcing this to
be an unsafe fix ensures that it will not be executed blindly during a
standard `--fix` pass without explicit opt-in via
`--allow-unsafe-fixes`.

Fixes #26332

## Test Plan
Updated the companion snapshot test (`PT022.snap`) using `insta` to
verify that the generated diagnostic now correctly appends the trailing
note: `note: This is an unsafe fix and may change runtime behavior`. All
relevant linter tests now pass cleanly.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
…y` clause (`RET504`) (#25441)

<!--
Thank you for contributing to Ruff/ty! 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? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
- Does this PR follow our AI policy
(https://github.com/astral-sh/.github/blob/main/AI_POLICY.md)?
-->

## Summary

Fixes #17292
                                                            
RET504 flagged assignments as unnecessary even when the variable was
read in `finally`/`except`, breaking runtime behavior on fix.
Checks that the binding has only one reference (the return itself)
before flagging

## Test Plan
- Fixture cases for finally, except, nested try, and the still-fires
case.
-  ran ecosystem checks locally and verified expected results

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
## Summary

Fixes astral-sh/ty#4114.

Enum classes were incorrectly rejected as `Container[T]` even though
`EnumMeta.__contains__` accepts `object`. The underlying issue was that
concrete class objects and generic aliases were considered assignable to
`type[Any]` during eager relation checks, but not while lazily solving
explicitly annotated metaclass-receiver constraints. This produced an
unsatisfiable hidden constraint on an otherwise correctly bound
`__contains__` method.

Make class literals and generic aliases consistently assignable to
gradual `type[...]` targets in both eager and lazy assignability checks,
while preserving stricter subtyping and incompatible protocol
signatures.

## Test plan

- Added enum mdtests covering `Enum`, `IntEnum`, and `StrEnum`,
including unparameterized containers, `Container[Any]`,
`Container[object]`, enum-member and unrelated-element container types,
and iterable, reversible, and collection protocols.
- Added protocol mdtests covering explicitly typed metaclass receivers,
conflicting class-level special methods, structural membership
protocols, and rejection of incompatible membership parameters and
return types.
- Verified the original issue reproducer on Python 3.11 through 3.14.
## Summary

Emit `not-subscriptable` when a non-generic class is specialized in a
type expression, and recover as `Unknown` instead of an internal `@Todo`
type.

This highlighted some scenarios in the ecosystem result where
`not-subscriptable` is being emitted but it might not be ideal, refer to
my inline comments. I've added mdtest cases for these looking at the
ecosystem result.

Closes astral-sh/ty#2439.

## Test plan

Update the mdtest
## Summary

Respect declared upper bounds and constraints when materializing generic
type arguments across covariance, contravariance, and invariance.
Preserve constrained top and bottom materializations during
type-relation checks, filter valid alternatives safely, and avoid
recursively forcing lazy bounds. Narrow runtime class checks using
unknown specializations instead of type-parameter defaults, fixing
incorrect `Never`-default narrowing.

Closes astral-sh/ty#1109.

## Test plan

- Add mdtests for PEP 695 and legacy bounded and constrained generics
across all variance directions, subtype and assignability relations,
overlapping and gradual constraints, and partial unions and
intersections.
- Cover invariant attributes, getter and setter polarity, unrelated
`Any`, mixed constrained and invariant type arguments, and recursive
bounds.
- Cover positive and negative bounded and constrained `isinstance`
narrowing, tuple class information, `issubclass`, class-pattern
fallthrough, and `Never`-default regressions.
- Cover equivalence for gradual bounded shape aliases, invariant and
covariant specializations, and defaulted nested generics.

## Ecosystem

Ecosystem changes are all positive and in line with the intended
semantics of this PR.
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[astral-sh/ruff-pre-commit](https://redirect.github.com/astral-sh/ruff-pre-commit)
| repository | minor | `v0.15.22` → `v0.16.0` |
|
[astral-sh/uv-pre-commit](https://redirect.github.com/astral-sh/uv-pre-commit)
| repository | minor | `0.11.32` → `0.12.0` |
|
[rbubley/mirrors-prettier](https://redirect.github.com/rbubley/mirrors-prettier)
| repository | patch | `v3.9.5` → `v3.9.6` |
|
[zizmorcore/zizmor-pre-commit](https://redirect.github.com/zizmorcore/zizmor-pre-commit)
| repository | minor | `v1.27.0` → `v1.28.0` |

Note: The `pre-commit` manager in Renovate is not supported by the
`pre-commit` maintainers or community. Please do not report any problems
there, instead [create a Discussion in the Renovate
repository](https://redirect.github.com/renovatebot/renovate/discussions/new)
if you have any questions.

---

### Release Notes

<details>
<summary>astral-sh/ruff-pre-commit (astral-sh/ruff-pre-commit)</summary>

###
[`v0.16.0`](https://redirect.github.com/astral-sh/ruff-pre-commit/releases/tag/v0.16.0)

[Compare
Source](https://redirect.github.com/astral-sh/ruff-pre-commit/compare/v0.15.22...v0.16.0)

See: <https://github.com/astral-sh/ruff/releases/tag/0.16.0>

</details>

<details>
<summary>astral-sh/uv-pre-commit (astral-sh/uv-pre-commit)</summary>

###
[`v0.12.0`](https://redirect.github.com/astral-sh/uv-pre-commit/releases/tag/0.12.0)

[Compare
Source](https://redirect.github.com/astral-sh/uv-pre-commit/compare/0.11.33...0.12.0)

See: <https://github.com/astral-sh/uv/releases/tag/0.12.0>

###
[`v0.11.33`](https://redirect.github.com/astral-sh/uv-pre-commit/compare/0.11.32...0.11.33)

[Compare
Source](https://redirect.github.com/astral-sh/uv-pre-commit/compare/0.11.32...0.11.33)

</details>

<details>
<summary>rbubley/mirrors-prettier (rbubley/mirrors-prettier)</summary>

###
[`v3.9.6`](https://redirect.github.com/rbubley/mirrors-prettier/compare/v3.9.5...v3.9.6)

[Compare
Source](https://redirect.github.com/rbubley/mirrors-prettier/compare/v3.9.5...v3.9.6)

</details>

<details>
<summary>zizmorcore/zizmor-pre-commit
(zizmorcore/zizmor-pre-commit)</summary>

###
[`v1.28.0`](https://redirect.github.com/zizmorcore/zizmor-pre-commit/releases/tag/v1.28.0)

[Compare
Source](https://redirect.github.com/zizmorcore/zizmor-pre-commit/compare/v1.27.0...v1.28.0)

See: <https://github.com/zizmorcore/zizmor/releases/tag/v1.28.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "before 4am on Wednesday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/astral-sh/ruff).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4MC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJpbnRlcm5hbCJdfQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
Summary
--

This PR adds TOML linting and fixing support to the LSP following
astral-sh/ruff#26772. It's organized as 3
initial refactoring commits followed by the two commits actually adding
TOML support.

After this lands, we'll also need to add TOML support in the VS Code
extension, like we did for Markdown files in
astral-sh/ruff-vscode#950.

Test Plan
--

New e2e tests
## Summary

A callback using `Unpack[Config]` or `Unpack[tuple[...]]` can accept
several arguments through a single `**kwargs` or `*args` declaration.
Forwarded `ParamSpec` diagnostics currently fall back to the forwarding
function because they cannot reliably map those arguments to the
callback's source parameter:

```py
import asyncio
from typing import TypedDict, Unpack

class Config(TypedDict):
    alpha: int
    beta: int

def callback(**options: Unpack[Config]) -> None: ...

async def run() -> None:
    await asyncio.to_thread(callback, alpha=1, beta="incorrect")
```

We now preserve parameter definitions while expanding tuple annotations,
select the correct overload after `Concatenate` filtering, and map
expanded arguments back to the original `*args` or `**kwargs`
declaration.
This is a mechanical change that updates the _internal_ constraint set
APIs to take in `ConstraintSetStorage`, instead of the
`RefCell`-carrying `ConstraintSetBuilder`. That means we only have to
`borrow` or `borrow_mut` at the public API boundary, instead of multiple
times throughout the internals.

I'm not sure if this will have a huge performance impact, but that's not
the goal — rather it's to simplify the internal APIs.
The _support_ of a constraint is the set of typevars that it mentions
(i.e. the subject of the constraint, and the (free) typevars mentioned
in its lower and upper bounds). The support of a BDD node is union of
the supports of every constraint in that subtree.

In #27173, we'll need the support to implement a custom path walker for
finding solutions of a constraint set. So I've pulled out the
calculation of the support into this separate PR, mostly to verify that
it has no ecosystem or performance impact. It doesn't, largely because
we can piggy-back on a type walk that we're already doing while
interning things in the `ConstraintSetBuilder.`

But also, it turns out that there's one existing method, `exists`, which
is determining which constraints to quantify away by doing a deep type
walk of each constraints. We can start using the new support for that
instead!
## Summary

We currently top-materialize `TypeIs` types to work around the fact that
typeshed annotates some standard library functions like `isawaitable`
with a gradual `TypeIs[Awaitable[Any]]` return type. This is problematic
when taken verbatim, since that instructs us to intersect with a gradual
`Awaitable[Any]` type instead of truly selecting *all* awaitables
(`Awaitable[object]`). For example, narrowing `Item | Awaitable[Item]`
with a final `Item` class using `isawaitable` would result in
`Awaitable[Item] & Awaitable[Any] = Awaitable[Item & Any]`, instead of
just `Awaitable[Item]`.

However, the current behavior is problematic for user-defined `TypeIs`
functions, since we don't respect their declared return type.

Here, we fix this by patching typeshed while dropping the
top-materialization. This leads to an unchanged behavior for
standard-library functions like `isawaitable`, `iscallable`, etc, but
respects users annotations for custom `TypeIs` functions:

```py
def is_list(arg: object) -> TypeIs[list[Any]]:
    return isinstance(arg, list)

def _(x: object):
    if is_list(x):
        reveal_type(x)  # list[Any], previously: Top[list[Any]]
```

relates to astral-sh/ty#3375

## Ecosystem report

Looks mostly good: Removed false positives, new unused ignore comment
diagnostics

Some expected problems, e.g. with this user-defined function in
beartype, leading to unfortunate types like `((...) -> Unknown) &
~((...) -> Unknown)`, which are technically correct (and could maybe be
simplified), but certainly unintended:
```py
def is_callable_like(value: Any) -> TypeIs[Callable]:
    return callable(value)
```

## Conformance results

- One false positive removed, which is expected.
- One new false positive, which looks like it's due to a generic solver
gap.

## Test Plan

Adapted tests
## Summary

Migrate legacy TypeVar diagnostics to inline snapshots.
## Summary

Reuse static-class accessor for tuple checks.
## Summary

Remove unused frozen-collection APIs.
## Summary

Remove unused generic-context display settings.
## Summary

Share symmetric narrowing-constraint branches.
## Summary

Remove unused string-literal display settings.
## Summary

Remove unused file-scoped place identifiers.
## Summary

Simplify static class specialization dispatch.
## Summary

Unify symmetric bounded TypeVar comparisons.
## Summary

Consolidate functional enum mixin conversion.
## Summary

Derive the corpus workspace root without spawning Cargo.
## Summary

Unify break and continue flow handling.
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

ecosystem check

Linter (stable)

ℹ️ ecosystem check detected linter changes. (+40384 -299 violations, +0 -0 fixes in 33 projects; 1 project error; 25 projects unchanged)

DisnakeDev/disnake (+248 -0 violations, +0 -0 fixes)

+ disnake/__main__.py:1:1: CPY001 Missing copyright notice at top of file
+ disnake/_version.pyi:1:1: CPY001 Missing copyright notice at top of file
+ disnake/abc.py:1:1: CPY001 Missing copyright notice at top of file
+ disnake/activity.py:1:1: CPY001 Missing copyright notice at top of file
+ disnake/app_commands.py:1:1: CPY001 Missing copyright notice at top of file
+ disnake/appinfo.py:1:1: CPY001 Missing copyright notice at top of file
... 236 additional changes omitted for rule CPY001
+ disnake/gateway.py:335:37: RUF036 [*] `None` not at the end of the type union.
+ disnake/i18n.py:102:15: RUF036 [*] `None` not at the end of the type union.
+ disnake/i18n.py:29:37: RUF036 `None` not at the end of the type union.
+ disnake/i18n.py:92:15: RUF036 [*] `None` not at the end of the type union.
... 238 additional changes omitted for project

RasaHQ/rasa (+3 -0 violations, +0 -0 fixes)

+ rasa/shared/core/events.py:597:42: RUF036 `None` not at the end of the type union.
+ rasa/shared/core/events.py:624:25: RUF036 [*] `None` not at the end of the type union.
+ rasa/utils/tensorflow/models.py:247:29: RUF036 [*] `None` not at the end of the type union.

PlasmaPy/PlasmaPy (+0 -63 violations, +0 -0 fixes)

- src/plasmapy/analysis/nullpoint.py:143:21: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/analysis/nullpoint.py:1475:23: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/analysis/nullpoint.py:1560:31: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/analysis/nullpoint.py:570:54: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/analysis/time_series/conditional_averaging.py:308:35: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/diagnostics/charged_particle_radiography/detector_stacks.py:59:20: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/diagnostics/charged_particle_radiography/synthetic_radiography.py:210:20: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/diagnostics/charged_particle_radiography/synthetic_radiography.py:396:25: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/diagnostics/charged_particle_radiography/synthetic_radiography.py:527:28: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
- src/plasmapy/diagnostics/charged_particle_radiography/synthetic_radiography.py:655:28: RUF100 [*] Unused `noqa` directive (non-enabled: `PLR0917`)
... 53 additional changes omitted for project

apache/airflow (+9663 -90 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --no-preview --select ALL

+ airflow-core/docs/conf.py:1:1: CPY001 Missing copyright notice at top of file
+ airflow-core/docs/empty_plugin/empty_plugin.py:1:1: CPY001 Missing copyright notice at top of file
+ airflow-core/docs/img/diagram_auth_manager_airflow_architecture.py:1:1: CPY001 Missing copyright notice at top of file
+ airflow-core/docs/img/diagram_basic_airflow_architecture.py:1:1: CPY001 Missing copyright notice at top of file
+ airflow-core/docs/img/diagram_dag_processor_airflow_architecture.py:1:1: CPY001 Missing copyright notice at top of file
+ airflow-core/docs/img/diagram_distributed_airflow_architecture.py:1:1: CPY001 Missing copyright notice at top of file
... 7719 additional changes omitted for rule CPY001
+ airflow-core/src/airflow/api/client/local_client.py:38:9: PLR0917 Too many positional arguments (6 > 5)
+ airflow-core/src/airflow/api/common/trigger_dag.py:154:11: RUF036 [*] `None` not at the end of the type union.
+ airflow-core/src/airflow/api/common/trigger_dag.py:60:11: RUF036 [*] `None` not at the end of the type union.
- airflow-core/src/airflow/api_fastapi/app.py:89:12: BLE001 Do not catch blind exception: `Exception`
- airflow-core/src/airflow/api_fastapi/auth/tokens.py:360:40: BLE001 Do not catch blind exception: `Exception`
... 9742 additional changes omitted for project

apache/superset (+2889 -38 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --no-preview --select ALL

+ RELEASING/changelog.py:1:1: CPY001 Missing copyright notice at top of file
+ RELEASING/generate_email.py:1:1: CPY001 Missing copyright notice at top of file
+ RELEASING/verify_release.py:1:1: CPY001 Missing copyright notice at top of file
+ docker/pythonpath_dev/superset_config.py:1:1: CPY001 Missing copyright notice at top of file
+ docker/pythonpath_dev/superset_config_docker_light.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/scripts/extract_custom_errors.py:1:1: CPY001 Missing copyright notice at top of file
... 2546 additional changes omitted for rule CPY001
+ scripts/check-env.py:30:9: PLR0917 Too many positional arguments (6 > 5)
+ scripts/cypress_run.py:39:5: PLR0917 Too many positional arguments (6 > 5)
+ scripts/translations/backfill_po.py:310:9: ISC004 Unparenthesized implicit string concatenation in collection
+ scripts/translations/backfill_po.py:312:9: ISC004 Unparenthesized implicit string concatenation in collection
... 2917 additional changes omitted for project

aws/aws-sam-cli (+376 -0 violations, +0 -0 fixes)

+ samcli/cli/cli_config_file.py:177:5: PLR0917 Too many positional arguments (7 > 5)
+ samcli/commands/_utils/options.py:210:5: PLR0917 Too many positional arguments (6 > 5)
+ samcli/commands/_utils/table_print.py:117:5: PLR0917 Too many positional arguments (7 > 5)
+ samcli/commands/_utils/table_print.py:18:5: PLR0917 Too many positional arguments (6 > 5)
+ samcli/commands/build/build_context.py:605:9: PLR0917 Too many positional arguments (9 > 5)
+ samcli/commands/build/build_context.py:815:9: PLR0917 Too many positional arguments (9 > 5)
+ samcli/commands/build/build_context.py:84:9: PLR0917 Too many positional arguments (30 > 5)
+ samcli/commands/build/build_context.py:895:9: PLR0917 Too many positional arguments (9 > 5)
+ samcli/commands/build/build_context.py:950:9: PLR0917 Too many positional arguments (10 > 5)
+ samcli/commands/build/command.py:142:5: PLR0917 Too many positional arguments (29 > 5)
... 366 additional changes omitted for project

bokeh/bokeh (+1430 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --no-preview --select ALL

+ docs/bokeh/api_reference/__init__.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/bokeh/api_reference/__main__.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/bokeh/docserver.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/bokeh/source/conf.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/bokeh/source/docs/first_steps/examples/first_steps_1_multiple_lines.py:1:1: CPY001 Missing copyright notice at top of file
+ docs/bokeh/source/docs/first_steps/examples/first_steps_1_simple_line.py:1:1: CPY001 Missing copyright notice at top of file
... 1366 additional changes omitted for rule CPY001
+ examples/basic/annotations/colorbar_log.py:15:5: PLR0917 Too many positional arguments (6 > 5)
+ examples/models/gauges.py:48:5: PLR0917 Too many positional arguments (7 > 5)
+ examples/output/webgl/fractal_sierpinski.py:12:5: PLR0917 Too many positional arguments (11 > 5)
+ examples/plotting/histogram.py:17:5: PLR0917 Too many positional arguments (6 > 5)
... 1420 additional changes omitted for project

docker/docker-py (+210 -0 violations, +0 -0 fixes)

+ docker/api/build.py:128:9: SIM102 Use a single `if` statement instead of nested `if` statements
+ docker/api/build.py:133:13: SIM118 Use `key in dict` instead of `key in dict.keys()`
+ docker/api/client.py:259:17: TRY004 Prefer `TypeError` exception for invalid type
+ docker/api/client.py:512:23: TRY201 Use `raise` without specifying exception name
+ docker/api/container.py:867:13: SIM114 [*] Combine `if` branches using logical `or` operator
+ docker/api/container.py:884:13: SIM114 [*] Combine `if` branches using logical `or` operator
+ docker/api/image.py:401:19: RUF059 Unpacked variable `repo_name` is never used
+ docker/api/image.py:476:19: RUF059 Unpacked variable `repo_name` is never used
+ docker/api/plugin.py:132:19: RUF059 Unpacked variable `repo_name` is never used
+ docker/api/plugin.py:173:19: RUF059 Unpacked variable `repo_name` is never used
... 200 additional changes omitted for project

facebookresearch/chameleon (+293 -0 violations, +0 -0 fixes)

+ chameleon/inference/alignment.py:13:38: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
+ chameleon/inference/alignment.py:13:43: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
+ chameleon/inference/alignment.py:17:41: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
+ chameleon/inference/alignment.py:17:46: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
+ chameleon/inference/alignment.py:31:38: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
+ chameleon/inference/alignment.py:31:43: FA102 Missing `from __future__ import annotations`, but uses PEP 585 collection
... 261 additional changes omitted for rule FA102
+ chameleon/inference/chameleon.py:433:12: FA100 Add `from __future__ import annotations` to simplify `typing.Union`
+ chameleon/inference/chameleon.py:434:12: FA100 Add `from __future__ import annotations` to simplify `typing.Union`
+ chameleon/inference/chameleon.py:435:17: FA100 Add `from __future__ import annotations` to simplify `typing.Union`
+ chameleon/inference/chameleon.py:436:22: FA100 Add `from __future__ import annotations` to simplify `typing.Union`
... 283 additional changes omitted for project

... Truncated remaining completed project reports due to GitHub comment length restrictions

indico/indico (error)

ruff failed
  Cause: Failed to load configuration `/home/runner/work/basedpython/basedpython/checkouts/indico:indico/ruff.toml`
  Cause: Failed to parse /home/runner/work/basedpython/basedpython/checkouts/indico:indico/ruff.toml
  Cause: TOML parse error at line 1, column 1
  |
1 | target-version = "py312"
  | ^
unknown field `output-prefer-rule-codes`

Changes by rule (174 rules affected)

code total + violation - violation + fix - fix
CPY001 15785 15785 0 0 0
UP045 5961 5961 0 0 0
PLR0917 2955 2955 0 0 0
FA102 2937 2937 0 0 0
UP006 2227 2227 0 0 0
C408 1369 1369 0 0 0
UP037 1214 1214 0 0 0
UP007 917 917 0 0 0
RUF100 823 707 116 0 0
UP035 806 806 0 0 0
FA100 552 552 0 0 0
BLE001 459 321 138 0 0
B008 432 432 0 0 0
ISC004 384 384 0 0 0
RUF036 383 383 0 0 0
SIM117 373 373 0 0 0
ASYNC230 244 244 0 0 0
RUF059 179 179 0 0 0
SIM102 166 166 0 0 0
RUF012 144 144 0 0 0
I001 97 97 0 0 0
TRY002 95 95 0 0 0
PLR0402 80 80 0 0 0
DTZ001 74 74 0 0 0
PYI036 74 74 0 0 0
C419 73 73 0 0 0
TRY004 69 69 0 0 0
TRY201 62 62 0 0 0
SIM118 61 61 0 0 0
RUF015 57 57 0 0 0
PIE790 54 54 0 0 0
FLY002 51 51 0 0 0
PYI063 51 51 0 0 0
B006 48 48 0 0 0
B018 46 46 0 0 0
S110 44 44 0 0 0
SIM115 43 43 0 0 0
RUF010 41 41 0 0 0
RUF022 36 36 0 0 0
G201 36 36 0 0 0
RUF013 33 33 0 0 0
B009 32 32 0 0 0
B010 32 32 0 0 0
RET501 30 30 0 0 0
SIM103 29 29 0 0 0
SIM114 28 28 0 0 0
DTZ005 27 27 0 0 0
PLR1704 27 27 0 0 0
PERF402 26 26 0 0 0
PIE804 26 26 0 0 0
PLW1510 25 25 0 0 0
C401 24 24 0 0 0
PLC0414 24 24 0 0 0
PYI041 24 24 0 0 0
C402 24 24 0 0 0
UP012 23 23 0 0 0
PYI032 22 22 0 0 0
UP032 21 21 0 0 0
B015 19 19 0 0 0
UP030 19 19 0 0 0
PT031 18 18 0 0 0
C403 18 18 0 0 0
LOG004 17 17 0 0 0
PLR1711 17 17 0 0 0
PT014 16 16 0 0 0
PLW1508 16 16 0 0 0
PYI034 16 16 0 0 0
ASYNC115 16 16 0 0 0
PIE807 15 15 0 0 0
PYI055 15 15 0 0 0
C413 14 14 0 0 0
E402 14 0 14 0 0
F403 14 0 14 0 0
B023 13 13 0 0 0
PLW0602 13 13 0 0 0
PYI016 13 13 0 0 0
UP004 13 13 0 0 0
PIE808 12 12 0 0 0
ASYNC251 12 12 0 0 0
LOG015 12 12 0 0 0
PIE810 11 11 0 0 0
B017 11 11 0 0 0
ASYNC220 11 11 0 0 0
PERF102 11 11 0 0 0
TRY203 10 10 0 0 0
UP009 10 10 0 0 0
S102 10 10 0 0 0
FURB192 9 9 0 0 0
PLR1722 9 9 0 0 0
PLC0208 9 9 0 0 0
TRY401 9 9 0 0 0
S310 9 0 9 0 0
SIM201 8 8 0 0 0
SIM101 8 8 0 0 0
C414 8 8 0 0 0
D419 8 8 0 0 0
E712 8 0 8 0 0
UP034 7 7 0 0 0
UP024 7 7 0 0 0
FURB177 7 7 0 0 0
LOG014 7 7 0 0 0
PLC0206 6 6 0 0 0
PIE800 6 6 0 0 0
RUF018 6 6 0 0 0
RUF068 5 5 0 0 0
PLW0127 5 5 0 0 0
DTZ007 5 5 0 0 0
C405 5 5 0 0 0
C400 5 5 0 0 0
PLR1733 5 5 0 0 0
B026 5 5 0 0 0
G202 5 5 0 0 0
PLR0124 5 5 0 0 0
C417 5 5 0 0 0
PYI019 5 5 0 0 0
EXE001 4 4 0 0 0
UP036 4 4 0 0 0
FURB136 4 4 0 0 0
PLR0133 4 4 0 0 0
PLR2044 3 3 0 0 0
PLW0120 3 3 0 0 0
TC005 3 3 0 0 0
FURB188 3 3 0 0 0
UP031 3 3 0 0 0
B020 3 3 0 0 0
PYI030 3 3 0 0 0
B033 3 3 0 0 0
ASYNC210 3 3 0 0 0
FURB129 2 2 0 0 0
EXE002 2 2 0 0 0
DTZ004 2 2 0 0 0
SIM113 2 2 0 0 0
PLE1205 2 2 0 0 0
PLR1730 2 2 0 0 0
SIM210 2 2 0 0 0
PLE0704 2 2 0 0 0
LOG009 2 2 0 0 0
PLW0128 2 2 0 0 0
PIE794 2 2 0 0 0
YTT103 2 2 0 0 0
UP010 2 2 0 0 0
FURB167 2 2 0 0 0
B039 2 2 0 0 0
UP028 2 2 0 0 0
PLC0105 2 2 0 0 0
SIM223 2 2 0 0 0
PYI061 2 2 0 0 0
TC004 2 2 0 0 0
DTZ011 2 2 0 0 0
UP018 2 2 0 0 0
FURB105 2 2 0 0 0
PLW1509 1 1 0 0 0
PLW0133 1 1 0 0 0
PLW0211 1 1 0 0 0
UP014 1 1 0 0 0
RUF007 1 1 0 0 0
S112 1 1 0 0 0
PLW0642 1 1 0 0 0
B013 1 1 0 0 0
YTT301 1 1 0 0 0
DTZ006 1 1 0 0 0
SIM211 1 1 0 0 0
PYI059 1 1 0 0 0
UP011 1 1 0 0 0
PLC0205 1 1 0 0 0
PYI025 1 1 0 0 0
FURB163 1 1 0 0 0
UP033 1 1 0 0 0
PLW0129 1 1 0 0 0
SIM202 1 1 0 0 0
RUF019 1 1 0 0 0
PLR1736 1 1 0 0 0
DTZ003 1 1 0 0 0
PYI044 1 1 0 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+8025 -7954 violations, +0 -0 fixes in 31 projects; 1 project error; 27 projects unchanged)

DisnakeDev/disnake (+65 -65 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ disnake/app_commands.py:511:33: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- disnake/app_commands.py:511:33: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ disnake/asset.py:108:40: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- disnake/asset.py:108:40: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ disnake/components.py:131:97: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- disnake/components.py:131:97: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ disnake/components.py:169:102: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- disnake/components.py:169:102: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ disnake/entitlement.py:157:63: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- disnake/entitlement.py:157:63: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
... 120 additional changes omitted for project

RasaHQ/rasa (+73 -73 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ .github/tests/test_download_pretrained.py:102:19: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- .github/tests/test_download_pretrained.py:102:19: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ .github/tests/test_download_pretrained.py:26:19: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- .github/tests/test_download_pretrained.py:26:19: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ .github/tests/test_download_pretrained.py:46:19: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- .github/tests/test_download_pretrained.py:46:19: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ .github/tests/test_download_pretrained.py:63:19: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- .github/tests/test_download_pretrained.py:63:19: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ .github/tests/test_download_pretrained.py:83:19: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- .github/tests/test_download_pretrained.py:83:19: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
... 136 additional changes omitted for project

apache/airflow (+780 -780 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

+ airflow-core/src/airflow/api_fastapi/execution_api/deps.py:19:1: noqa-comments [*] `ruff: noqa` comment used instead of `ruff: file-ignore`
- airflow-core/src/airflow/api_fastapi/execution_api/deps.py:19:1: noqa-comments [*] `ruff: noqa` comment used instead of `ruff:file-ignore`
+ airflow-core/src/airflow/api_fastapi/execution_api/security.py:68:1: noqa-comments [*] `ruff: noqa` comment used instead of `ruff: file-ignore`
- airflow-core/src/airflow/api_fastapi/execution_api/security.py:68:1: noqa-comments [*] `ruff: noqa` comment used instead of `ruff:file-ignore`
+ airflow-core/src/airflow/callbacks/callback_requests.py:29:88: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- airflow-core/src/airflow/callbacks/callback_requests.py:29:88: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ airflow-core/src/airflow/cli/commands/api_server_command.py:152:30: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- airflow-core/src/airflow/cli/commands/api_server_command.py:152:30: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ airflow-core/src/airflow/dag_processing/bundles/manager.py:33:64: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- airflow-core/src/airflow/dag_processing/bundles/manager.py:33:64: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
... 1550 additional changes omitted for project

apache/superset (+3069 -3069 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

+ RELEASING/changelog.py:274:59: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/changelog.py:274:59: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/changelog.py:281:53: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/changelog.py:281:53: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/changelog.py:292:82: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/changelog.py:292:82: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/generate_email.py:34:111: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/generate_email.py:34:111: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:144:35: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/verify_release.py:144:35: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:26:131: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/verify_release.py:26:131: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:31:89: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/verify_release.py:31:89: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:46:93: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/verify_release.py:46:93: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:56:162: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- RELEASING/verify_release.py:56:162: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ RELEASING/verify_release.py:78:31: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
... 6119 additional changes omitted for project

bokeh/bokeh (+44 -44 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select ALL

+ examples/basic/data/color_mappers.py:9:5: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- examples/basic/data/color_mappers.py:9:5: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ examples/interaction/js_callbacks/color_sliders.py:9:5: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- examples/interaction/js_callbacks/color_sliders.py:9:5: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
+ examples/models/buttons.py:15:5: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
- examples/models/buttons.py:15:5: noqa-comments [*] `noqa` comment used instead of `ruff:ignore`
... 37 additional changes omitted for rule noqa-comments
- tests/unit/bokeh/application/handlers/test_server_lifecycle.py:209:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/application/handlers/test_server_lifecycle.py:209:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- tests/unit/bokeh/application/handlers/test_server_request_handler.py:98:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ tests/unit/bokeh/application/handlers/test_server_request_handler.py:98:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
... 78 additional changes omitted for project

demisto/content (+4 -4 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

- Packs/Base/Scripts/WordTokenizerV2/WordTokenizerV2_test.py:56:9: pytest-composite-assertion Assertion should be broken down into multiple parts
+ Packs/Base/Scripts/WordTokenizerV2/WordTokenizerV2_test.py:56:9: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- Packs/CommonScripts/Scripts/ParseEmailFiles/ParseEmailFiles_test.py:81:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ Packs/CommonScripts/Scripts/ParseEmailFiles/ParseEmailFiles_test.py:81:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- Packs/IntSight/Integrations/IntSight/IntSight_test.py:72:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ Packs/IntSight/Integrations/IntSight/IntSight_test.py:72:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts
- Packs/Jira/Integrations/JiraV2/JiraV2_test.py:1254:5: pytest-composite-assertion Assertion should be broken down into multiple parts
+ Packs/Jira/Integrations/JiraV2/JiraV2_test.py:1254:5: pytest-composite-assertion [*] Assertion should be broken down into multiple parts

docker/docker-py (+13 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ tests/integration/api_build_test.py:105:17: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/integration/api_build_test.py:265:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/integration/api_build_test.py:63:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/integration/api_build_test.py:78:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/integration/api_container_test.py:843:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/integration/api_container_test.py:845:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/ssh/api_build_test.py:256:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/ssh/api_build_test.py:63:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/ssh/api_build_test.py:78:13: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
+ tests/unit/api_build_test.py:23:21: implicit-string-concatenation-in-collection-literal Unparenthesized implicit string concatenation in collection
... 3 additional changes omitted for project

... Truncated remaining completed project reports due to GitHub comment length restrictions

indico/indico (error)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

ruff failed
  Cause: Failed to load configuration `/home/runner/work/basedpython/basedpython/checkouts/indico:indico/ruff.toml`
  Cause: Failed to parse /home/runner/work/basedpython/basedpython/checkouts/indico:indico/ruff.toml
  Cause: TOML parse error at line 1, column 1
  |
1 | target-version = "py312"
  | ^
unknown field `output-prefer-rule-codes`

Changes by rule (6 rules affected)

code total + violation - violation + fix - fix
noqa-comments 15790 7895 7895 0 0
pytest-composite-assertion 118 59 59 0 0
implicit-string-concatenation-in-collection-literal 65 65 0 0 0
sorted-min-max 4 4 0 0 0
unused-noqa 1 1 0 0 0
non-augmented-assignment 1 1 0 0 0

Formatter (stable)

ℹ️ ecosystem check detected format changes. (+5034 -4635 lines in 560 files in 30 projects; 2 project errors; 27 projects unchanged)

DisnakeDev/disnake (+6 -0 lines across 1 file)

README.md~L61

 
 bot = commands.InteractionBot(test_guilds=[12345])
 
+
 @bot.slash_command()
 async def ping(inter):
     await inter.response.send_message("Pong!")
 
+
 bot.run("BOT_TOKEN")
<a href='https://github.com/DisnakeDev/disnake/blob/6a8247cf2020284b61023b56ae92c5ca090a2ffb/README.md#L76'>README.md~L76</a>
```diff
 
 bot = commands.InteractionBot(test_guilds=[12345])
 
+
 @bot.user_command()
 async def avatar(inter, user):
     embed = disnake.Embed(title=str(user))
     embed.set_image(url=user.display_avatar.url)
     await inter.response.send_message(embed=embed)
 
+
 bot.run("BOT_TOKEN")
<a href='https://github.com/DisnakeDev/disnake/blob/6a8247cf2020284b61023b56ae92c5ca090a2ffb/README.md#L93'>README.md~L93</a>
```diff
 
 bot = commands.Bot(command_prefix=commands.when_mentioned)
 
+
 @bot.command()
 async def ping(ctx):
     await ctx.send("Pong!")
 
+
 bot.run("BOT_TOKEN")

</p>
</details>
<details><summary><a href="/Snowflake-Labs/snowcli">Snowflake-Labs/snowcli</a> (+36 -20 lines across 3 files)</summary>
<p>

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L37'>docs/contributing/conventions.md~L37</a>
```diff
 
 # ALSO WRONG — f-string still composes before FQN sees the parts
 from snowflake.cli.api.identifiers import FQN
+
 fqn = FQN.from_string(f"{database}.{schema}.{table_name}")
 cursor.execute(f"CREATE TABLE {fqn.sql_identifier} ...")
 
 # CORRECT — pass each component individually
 from snowflake.cli.api.identifiers import FQN
+
 fqn = FQN(database=database, schema=schema, name=table_name)
 cursor.execute(f"CREATE TABLE {fqn.sql_identifier} ...")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L61'>docs/contributing/conventions.md~L61</a>
```diff
 
 # CORRECT
 from snowflake.cli.api.project.util import to_string_literal
+
 cursor.execute(f"SHOW DATABASES LIKE {to_string_literal(database)}")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L71'>docs/contributing/conventions.md~L71</a>
```diff
 
 ```python
 from snowflake.cli.api.project.util import identifier_to_show_like_pattern
+
 cursor.execute(f"SHOW DATABASES LIKE {identifier_to_show_like_pattern(name)}")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L96'>docs/contributing/conventions.md~L96</a>
```diff
 
 ```python
 from snowflake.cli.api.commands.flags import SecretTypeParser
-from snowflake.cli.api.secret import SecretType  # annotation only — SecretTypeParser wraps the value at parse time
+from snowflake.cli.api.secret import (
+    SecretType,
+)  # annotation only — SecretTypeParser wraps the value at parse time
+
 
 @app.command()
 def my_command(
     password: Optional[SecretType] = typer.Option(
-        None, click_type=SecretTypeParser(), hide_input=True,
+        None,
+        click_type=SecretTypeParser(),
+        hide_input=True,
     ),
 ):
     if password:
-        do_something(password.value)            # access the real value explicitly
+        do_something(password.value)  # access the real value explicitly
     log.debug("Called with password=%s", password)  # logs "***"
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L120'>docs/contributing/conventions.md~L120</a>
```diff
 ```python
 # WRONG
 from pathlib import Path
+
 content = Path("config.yml").read_text()
 
 # CORRECT
 from snowflake.cli.api.secure_path import SecurePath
+
 content = SecurePath("config.yml").read_text(file_size_limit_mb=1)
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L141'>docs/contributing/conventions.md~L141</a>
```diff
 
 # CORRECT
 from snowflake.cli.api.sanitizers import sanitize_for_terminal
+
 cc.step(f"Object name: {sanitize_for_terminal(server_response['name'])}")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L155'>docs/contributing/conventions.md~L155</a>
```diff
 ```python
 # WRONG
 from click import ClickException
+
 raise ClickException("Something went wrong")
 
 # CORRECT
 from snowflake.cli.api.exceptions import CliError  # or a more specific subclass
+
 raise CliError("Something went wrong")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L186'>docs/contributing/conventions.md~L186</a>
```diff
 # PREFERRED
 from snowflake.cli.api.identifiers import FQN
 
-def my_command():
-    ...
+
+def my_command(): ...
+
 
 # ACCEPTABLE only when a top-level import causes issues
 def my_command():
     from snowflake.cli.api.identifiers import FQN
+
     ...
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L205'>docs/contributing/conventions.md~L205</a>
```diff
 
 log = logging.getLogger(__name__)
 
+
 def my_function():
     log.debug("Starting operation with params: %s", params)
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/conventions.md#L235'>docs/contributing/conventions.md~L235</a>
```diff
 ```python
 from snowflake.cli.api.console import cli_console as cc
 
-cc.step("Doing something...")          # regular progress line
-cc.warning("Something looks off")      # warning line
+cc.step("Doing something...")  # regular progress line
+cc.warning("Something looks off")  # warning line
 
-with cc.phase("Building...", "Done."): # grouped output block
+with cc.phase("Building...", "Done."):  # grouped output block
     cc.step("Step A")
     cc.step("Step B")
<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/lifecycle.md#L99'>docs/contributing/lifecycle.md~L99</a>
```diff
 callable):
 ```python
 @app.command(hidden=not FeatureFlag.ENABLE_MY_FEATURE.is_enabled())
-def my_command():
-    ...
+def my_command(): ...

Hide a single option or argument:

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/lifecycle.md#L111'>docs/contributing/lifecycle.md~L111</a>
```diff
         None,
         hidden=not FeatureFlag.ENABLE_MY_FEATURE.is_enabled(),
     ),
-):
-    ...
+): ...

Gate a feature so it cannot be invoked at all (use sparingly — only when
running without the flag would be unsafe or meaningless):

@app.command(is_enabled=FeatureFlag.ENABLE_MY_FEATURE.is_enabled)
-def my_command():
-    ...
+def my_command(): ...

Independent lifecycle example

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/lifecycle.md#L132'>docs/contributing/lifecycle.md~L132</a>
```diff
 # Command group is GA — no feature flag
 app = SnowTyperFactory(name="my-group")
 
+
 # This command is PuPr — hidden unless flag is enabled
 @app.command(hidden=not FeatureFlag.ENABLE_MY_COMMAND.is_enabled())
 def my_command(

docs/contributing/lifecycle.md~L140

         None,
         hidden=not FeatureFlag.ENABLE_MY_EXPERIMENTAL_OPTION.is_enabled(),
     ),
-):
-    ...
+): ...

Transitioning between stages

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/lifecycle.md#L171'>docs/contributing/lifecycle.md~L171</a>
```diff
 from tests_common.feature_flag_utils import with_feature_flags
 from snowflake.cli.api.feature_flags import FeatureFlag
 
+
 @with_feature_flags({FeatureFlag.ENABLE_MY_FEATURE: True})
 def test_my_command(runner):
     result = runner.invoke(["my-group", "my-command"])

docs/contributing/lifecycle.md~L215

 
 ```python
 @app.command(deprecated=True)
-def my_old_command():
-    ...
+def my_old_command(): ...

Add a release note entry under ## Deprecations.

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/lifecycle.md#L229'>docs/contributing/lifecycle.md~L229</a>
```diff
 ```python
 from snowflake.cli.api.commands.flags import deprecated_flag_callback
 
+
 @app.command()
 def my_command(
     old_option: Optional[str] = typer.Option(
         None,
         callback=deprecated_flag_callback("Use --new-option instead."),
     ),
-):
-    ...
+): ...

Add a release note entry under ## Deprecations.

<a href='https://github.com/Snowflake-Labs/snowcli/blob/3bfc4f057afcd53add4498d60b072a9ff02d9f28/docs/contributing/testing.md#L72'>docs/contributing/testing.md~L72</a>
```diff
 from tests_common.feature_flag_utils import with_feature_flags
 from snowflake.cli.api.feature_flags import FeatureFlag
 
+
 # As a decorator
 @with_feature_flags({FeatureFlag.ENABLE_MY_FEATURE: True})
 def test_my_command(runner):
     result = runner.invoke(["my-group", "my-command"])
     assert result.exit_code == 0
 
+
 # As a context manager (useful in parametrized tests)
 def test_my_command_parametrized(runner):
     with with_feature_flags({FeatureFlag.ENABLE_MY_FEATURE: True}):

apache/airflow (+11 -11 lines across 4 files)

airflow-core/adr/lang-sdk/0004-dag-parsing.md~L286

 # Module: airflow.sdk.coordinators.java.coordinator
 class JavaCoordinator(BaseCoordinator):
     def __init__(self, *, name, java_executable="java", jvm_args=None, jdk_home=None):
-        self.name = name
+        self.name            = name
         self.java_executable = java_executable
-        self.jvm_args = list(jvm_args or [])
-        self.jdk_home = jdk_home
+        self.jvm_args        = list(jvm_args or [])
+        self.jdk_home        = jdk_home
 
     def can_handle_dag_file(self, bundle_name, path) -> bool:
         # Returns True when path is a JAR with a Main-Class manifest entry

airflow-core/tests/unit/dags/README.md~L25

 
 ```python
 dagbag = DagBag()
-dag = dagbag.get_dag(dag_id)
+dag    = dagbag.get_dag(dag_id)
<a href='https://github.com/apache/airflow/blob/2aef6b1c80c8c57b83972731090d1e578e613459/airflow-core/tests/unit/dags_corrupted/README.md#L28'>airflow-core/tests/unit/dags_corrupted/README.md~L28</a>
```diff
 TEST_DAG_FOLDER = os.path.join(os.path.dirname(os.path.realpath(__file__)), "dags_corrupted")
 
 dagbag = DagBag(dag_folder=TEST_DAG_FOLDER)
-dag = dagbag.get_dag(dag_id)
+dag    = dagbag.get_dag(dag_id)
<a href='https://github.com/apache/airflow/blob/2aef6b1c80c8c57b83972731090d1e578e613459/clients/python/README.md#L121'>clients/python/README.md~L121</a>
```diff
 ```python
 import requests
 
-resource = requests.get("/resource/my-id").json()
+resource             = requests.get("/resource/my-id").json()
 resource["my_field"] = "new-value"
 requests.patch("/resource/my-id?update_mask=my_field", data=json.dumps(resource))
<a href='https://github.com/apache/airflow/blob/2aef6b1c80c8c57b83972731090d1e578e613459/clients/python/README.md#L299'>clients/python/README.md~L299</a>
```diff
     username: str,
     password: str,
 ) -> str:
-    url = f"{host}/auth/token"
-    payload = {
+    url      = f"{host}/auth/token"
+    payload  = {
         "username": username,
         "password": password,
     }
-    headers = {"Content-Type": "application/json"}
+    headers  = {"Content-Type": "application/json"}
     response = requests.post(url, json=payload, headers=headers)
     if response.status_code != 201:
         raise R

_report truncated to fit GitHub's comment size limit; see the `ecosystem-result` artifact of the run for the full text._

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

by ecosystem round-trip

base: 0e6632d9edf5ca2b5b8cdf2046270c1794f8e5e7 (merge base) → head: 145/merge

regressions: 5, changed: 794, improvements: 1, error changes: 10 (across 20980 files in 148 projects)

⚠️ 18 project(s) fail to round-trip on both base and head, so this check says nothing about them.

❌ regressions (built on base, now fails)

apprise —
build: killed: exceeded 11.7365GB memory budget
meson —
build: killed: exceeded 11.7365GB memory budget
more-itertools —
reverse: killed: exceeded 11.7358GB memory budget
parso —
reverse: killed: exceeded 11.7358GB memory budget
setuptools —
reverse: killed: exceeded 11.7358GB memory budget

ℹ️ changed round-trip output

Expression — README.py
--- base/README.py
+++ head/README.py
@@ -734,5 +734,5 @@
 async def fn_option() -> AsyncGenerator[int, int]:
     x: int = yield 42  # Regular value
-    y: int = yield await _soundness_check(Optional(43), Option)  # Awaitable Some value
+    y: int = yield await _soundness_parametric(Optional(43), Option[int], (1,))  # Awaitable Some value
 
     # Short-circuit if condition is met
Expression — tests/test_async_option_builder.py
--- base/tests/test_async_option_builder.py
+++ head/tests/test_async_option_builder.py
@@ -257,5 +257,5 @@
     @effect.async_option[int]()
     async def fn() -> AsyncGenerator[int, int]:
-        x: int = yield await _soundness_check(Optional(42), Option)
+        x: int = yield await _soundness_parametric(Optional(42), Option[int], (1,))
         yield x
 
@@ -289,5 +289,5 @@
     async def fn() -> AsyncGenerator[int, int]:
         # Use await with Some to leverage the awaitable functionality
-        x: int = yield await _soundness_check(Optional(42), Option)
+        x: int = yield await _soundness_parametric(Optional(42), Option[int], (1,))
         yield x + 1
 
@@ -321,5 +321,5 @@
     async def fn() -> AsyncGenerator[int, int]:
         x: int = yield 42
-        y: int = yield await _soundness_check(Optional(43), Option)
+        y: int = yield await _soundness_parametric(Optional(43), Option[int], (1,))
         z: int = yield 44
         yield x + y + z
@@ -394,5 +394,5 @@
     @effect.async_option[int]()
     async def fn() -> AsyncGenerator[int, int]:
... 963 characters elided ...
         await asyncio.sleep(0.01)  # Small delay to simulate async work
-        return _soundness_check(await _soundness_check(Optional(x * 2), Option), int)
+        return await _soundness_parametric(Optional(x * 2), Option[int], (1,))
 
     async def async_nothing_function() -> int:
Expression — tests/test_async_result_builder.py
--- base/tests/test_async_result_builder.py
+++ head/tests/test_async_result_builder.py
@@ -373,5 +373,5 @@
     async def async_ok_function(x: int) -> int:
         await asyncio.sleep(0.01)  # Small delay to simulate async work
-        return _soundness_check(await _soundness_check(Ok(x * 2), Result), int)
+        return await _soundness_check(Ok(x * 2), Result)
 
     async def async_error_function(msg: str) -> int:
PyGithub — github/Branch.py
--- base/github/Branch.py
+++ head/github/Branch.py
@@ -289,5 +289,5 @@
                     for check in _soundness_iter(checks, (str, tuple))
                 ]
-            elif _soundness_check(_soundness_check(is_defined(contexts), bool), bool):
+            elif _soundness_check(is_defined(contexts), bool):
                 checks_parameters = [{"context": context} for context in _soundness_iter(contexts, str)]
 
@@ -457,5 +457,5 @@
                 for check in _soundness_iter(checks, (str, tuple))
             ]
-        elif _soundness_check(_soundness_check(is_defined(contexts), bool), bool):
+        elif _soundness_check(is_defined(contexts), bool):
             checks_parameters = [{"context": context} for context in _soundness_iter(contexts, str)]
Tanjun — tanjun/dependencies/reloaders.py
--- base/tanjun/dependencies/reloaders.py
+++ head/tanjun/dependencies/reloaders.py
@@ -632,5 +632,5 @@
                     self.waiting_for[path] = value.last_modified_at
 
-            elif not (path_info := _soundness_check(_soundness_check(self.paths.get(path), (_PyPathInfo, type(None))), (_PyPathInfo, type(None)))) or path_info.last_modified_at != value.last_modified_at:
+            elif not (path_info := _soundness_check(self.paths.get(path), (_PyPathInfo, type(None)))) or path_info.last_modified_at != value.last_modified_at:
                 self.waiting_for[path] = value.last_modified_at
Tanjun — tanjun/parsing.py
--- base/tanjun/parsing.py
+++ head/tanjun/parsing.py
@@ -640,5 +640,5 @@
                 kwargs[argument.key] = await argument.convert(self.__ctx, value)
 
-            elif argument.is_multi and (values := list[str][str](self.iter_raw_arguments())):
+            elif argument.is_multi and (values := list[str](self.iter_raw_arguments())):
                 kwargs[argument.key] = await asyncio.gather(*(lambda argument: (argument.convert(self.__ctx, value) for value in values))(argument))
aioredis — aioredis/connection.py
--- base/aioredis/connection.py
+++ head/aioredis/connection.py
@@ -939,5 +939,5 @@
         if isinstance(_soundness_check(args[0], (bytes, memoryview, str, int)), str):
             args = tuple(_soundness_check(args[0], str).encode().split()) + _soundness_check(args[1:], tuple)
-        elif b" " in _soundness_check(_soundness_check(args[0], (bytes, memoryview, int)), (bytes, memoryview, int)):
+        elif b" " in _soundness_check(args[0], (bytes, memoryview, int)):
             args = tuple(_soundness_check(args[0], (bytes, memoryview, int)).split()) + _soundness_check(args[1:], tuple)
aiortc — aiortc/codecs/h264.py
--- base/aiortc/codecs/h264.py
+++ head/aiortc/codecs/h264.py
@@ -324,4 +324,4 @@
 
 def h264_depayload(payload: bytes) -> bytes:
-    descriptor, data = H264PayloadDescriptor.parse(payload)
+    descriptor, data = _soundness_check(H264PayloadDescriptor.parse(payload), tuple)
     return data
aiortc — aiortc/codecs/vpx.py
--- base/aiortc/codecs/vpx.py
+++ head/aiortc/codecs/vpx.py
@@ -291,4 +291,4 @@
 
 def vp8_depayload(payload: bytes) -> bytes:
-    descriptor, data = VpxPayloadDescriptor.parse(payload)
+    descriptor, data = _soundness_check(VpxPayloadDescriptor.parse(payload), tuple)
     return data
aiortc — aiortc/rtcpeerconnection.py
--- base/aiortc/rtcpeerconnection.py
+++ head/aiortc/rtcpeerconnection.py
@@ -1290,7 +1290,7 @@
         elif "failed" in iceStates or "failed" in dtlsStates:
             state = "failed"
-        elif not _soundness_check(_soundness_check(iceStates.difference(["new", "closed"]), set), set) and not _soundness_check(_soundness_check(dtlsStates.difference(
+        elif not _soundness_check(iceStates.difference(["new", "closed"]), set) and not _soundness_check(dtlsStates.difference(
             ["new", "closed"]
-        ), set), set):
+        ), set):
             state = "new"
         elif "checking" in iceStates or "connecting" in dtlsStates:
@@ -1325,5 +1325,5 @@
         elif "failed" in states:
             state = "failed"
-        elif states == set[str][str](["completed"]):
+        elif states == set[str](["completed"]):
             state = "completed"
         elif "checking" in states:
aiortc — aiortc/sdp.py
--- base/aiortc/sdp.py
+++ head/aiortc/sdp.py
@@ -127,7 +127,7 @@
         if _soundness_check(bits[i], str) == "raddr":
             candidate.relatedAddress = _soundness_check(bits[i + 1], str)
-        elif _soundness_check(_soundness_check(bits[i], str), str) == "rport":
+        elif _soundness_check(bits[i], str) == "rport":
             candidate.relatedPort = int(_soundness_check(bits[i + 1], str))
-        elif _soundness_check(_soundness_check(bits[i], str), str) == "tcptype":
+        elif _soundness_check(bits[i], str) == "tcptype":
             candidate.tcpType = _soundness_check(bits[i + 1], str)
aiortc — examples/janus/janus.py
--- base/examples/janus/janus.py
+++ head/examples/janus/janus.py
@@ -22,5 +22,5 @@
 
 def transaction_id():
-    return "".join(_soundness_check(random.choice(string.ascii_letters), str) for x in range(12))
+    return "".join(random.choice(string.ascii_letters) for x in range(12))
 
 
@@ -39,5 +39,5 @@
 
         response = await self._queue.get()
-        assert response["transaction"] == _soundness_check(message["transaction"], str)
+        assert response["transaction"] == message["transaction"]
         return response
aiortc — tests/test_h264.py
--- base/tests/test_h264.py
+++ head/tests/test_h264.py
@@ -28,10 +28,10 @@
     def test_parse_empty(self) -> None:
         with self.assertRaises(ValueError) as cm:
-            H264PayloadDescriptor.parse(b"")
+            _soundness_check(H264PayloadDescriptor.parse(b""), tuple)
         self.assertEqual(str(cm.exception), "NAL unit is too short")
 
     def test_parse_stap_a(self) -> None:
         payload = load("h264_0000.bin")
-        descr, rest = H264PayloadDescriptor.parse(payload)
+        descr, rest = _soundness_check(H264PayloadDescriptor.parse(payload), tuple)
         self.assertEqual(descr.first_fragment, True)
         self.assertEqual(repr(descr), "H264PayloadDescriptor(FF=True)")
@@ -43,23 +43,23 @@
 
         with self.assertRaises(ValueError) as cm:
-            H264PayloadDescriptor.parse(payload[0:1])
+            _soundness_check(H264PayloadDescriptor.parse(payload[0:1]), tuple)
         self.assertEqual(str(cm.exception), "NAL unit is too short")
 
         with self.assertRaises(ValueError) as cm:
-            H264PayloadDescriptor.parse(payload[0:2])
... 1823 characters elided ...
         payload = load("h264_0003.bin")
-        descr, rest = H264PayloadDescriptor.parse(payload)
+        descr, rest = _soundness_check(H264PayloadDescriptor.parse(payload), tuple)
         self.assertEqual(descr.first_fragment, True)
         self.assertEqual(repr(descr), "H264PayloadDescriptor(FF=True)")
alectryon — alectryon/lsp.py
--- base/alectryon/lsp.py
+++ head/alectryon/lsp.py
@@ -87,5 +87,5 @@
         data = json.loads(resp)
 
-        return LSPServerMessage.from_json(_soundness_check(data, dict))
+        return LSPServerMessage.from_json(data)
 
 @dataclass
antidote — antidote/lib/interface_ext/_provider.py
--- base/antidote/lib/interface_ext/_provider.py
+++ head/antidote/lib/interface_ext/_provider.py
@@ -320,8 +320,8 @@
             dataclasses.replace(
                 self,
-                weight=_soundness_check(sum(
+                weight=sum(
                     (weight_type.of_neutral_predicate(p) for p in self.predicates),
                     weight_type.neutral(),
-                ), int),
+                ),
             ),
         ), CandidateImplementation)
anyio — anyio/from_thread.py
--- base/anyio/from_thread.py
+++ head/anyio/from_thread.py
@@ -565,5 +565,5 @@
                 if _soundness_check(future.cancelled(), bool):
                     _soundness_check(task_status_future.cancel(), bool)
-                elif _soundness_check(_soundness_check(future.exception(), (BaseException, type(None))), (BaseException, type(None))):
+                elif _soundness_check(future.exception(), (BaseException, type(None))):
                     task_status_future.set_exception(_soundness_check(future.exception(), (BaseException, type(None))))
                 else:
archinstall — archinstall/lib/disk/disk_menu.py
--- base/archinstall/lib/disk/disk_menu.py
+++ head/archinstall/lib/disk/disk_menu.py
@@ -471,5 +471,5 @@
 						device_modifications=modifications,
 					)
-			elif _soundness_check(_soundness_check(result.get_value(), str), str) == manual_mode:
+			elif _soundness_check(result.get_value(), str) == manual_mode:
 				preset_mods = preset.device_modifications if preset else []
 				partitions = await _manual_partitioning(preset_mods, devices)
archinstall — archinstall/lib/disk/subvolume_menu.py
--- base/archinstall/lib/disk/subvolume_menu.py
+++ head/archinstall/lib/disk/subvolume_menu.py
@@ -110,5 +110,5 @@
 					data = [d for d in _soundness_iter(data, SubvolumeModification) if d.name != entry.name and d.name != new_subvolume.name]
 					data += [new_subvolume]
-			elif action == _soundness_check(_soundness_check(self._actions[2], str), str):
+			elif action == _soundness_check(self._actions[2], str):
 				data = [d for d in _soundness_iter(data, SubvolumeModification) if d != entry]
archinstall — archinstall/lib/mirror/mirror_menu.py
--- base/archinstall/lib/mirror/mirror_menu.py
+++ head/archinstall/lib/mirror/mirror_menu.py
@@ -68,10 +68,10 @@
 				data = [d for d in _soundness_iter(data, CustomRepository) if d.name != new_repo.name]
 				data += [new_repo]
-		elif action == _soundness_check(_soundness_check(self._actions[1], str), str) and entry:  # modify repo
+		elif action == _soundness_check(self._actions[1], str) and entry:  # modify repo
 			new_repo = await self._add_custom_repository(entry)
 			if new_repo is not None:
 				data = [d for d in _soundness_iter(data, CustomRepository) if d.name != entry.name]
 				data += [new_repo]
-		elif action == _soundness_check(_soundness_check(self._actions[2], str), str) and entry:  # delete
+		elif action == _soundness_check(self._actions[2], str) and entry:  # delete
 			data = [d for d in _soundness_iter(data, CustomRepository) if d != entry]
 
@@ -189,10 +189,10 @@
 				data = [d for d in _soundness_iter(data, CustomServer) if d.url != new_server.url]
 				data += [new_server]
-		elif action == _soundness_check(_soundness_check(self._actions[1], str), str) and entry:  # modify repo
... 253 characters elided ...
 				data += [new_server]
-		elif action == _soundness_check(_soundness_check(self._actions[2], str), str) and entry:  # delete
+		elif action == _soundness_check(self._actions[2], str) and entry:  # delete
 			data = [d for d in _soundness_iter(data, CustomServer) if d != entry]
archinstall — archinstall/lib/models/bootloader.py
--- base/archinstall/lib/models/bootloader.py
+++ head/archinstall/lib/models/bootloader.py
@@ -44,5 +44,5 @@
 
 	def json(self) -> str:
-		return _soundness_check(self.value, str)
+		return self.value
 
 	@staticmethod
archinstall — archinstall/lib/network/network_menu.py
--- base/archinstall/lib/network/network_menu.py
+++ head/archinstall/lib/network/network_menu.py
@@ -59,5 +59,5 @@
 				nic = await self._edit_iface(entry)
 				data.append(nic)
-			elif action == _soundness_check(_soundness_check(self._actions[2], str), str):  # delete
+			elif action == _soundness_check(self._actions[2], str):  # delete
 				data = [d for d in _soundness_iter(data, Nic) if d != entry]
archinstall — archinstall/lib/user/user_menu.py
--- base/archinstall/lib/user/user_menu.py
+++ head/archinstall/lib/user/user_menu.py
@@ -57,5 +57,5 @@
 				data = [d for d in _soundness_iter(data, User) if d.username != new_user.username]
 				data += [new_user]
-		elif action == _soundness_check(_soundness_check(self._actions[1], str), str) and entry:  # change password
+		elif action == _soundness_check(self._actions[1], str) and entry:  # change password
 			header = f'{tr("User")}: {entry.username}\n'
 			header += tr('Enter new password')
@@ -65,8 +65,8 @@
 				user = next(filter(lambda x: x == entry, data))
 				user.password = new_password
-		elif action == _soundness_check(_soundness_check(self._actions[2], str), str) and entry:  # promote/demote
+		elif action == _soundness_check(self._actions[2], str) and entry:  # promote/demote
 			user = next(filter(lambda x: x == entry, data))
 			user.sudo = False if user.sudo else True
-		elif action == _soundness_check(_soundness_check(self._actions[3], str), str) and entry:  # delete
+		elif action == _soundness_check(self._actions[3], str) and entry:  # delete
 			data = [d for d in _soundness_iter(data, User) if d != entry]
archinstall — archinstall/lib/utils/util.py
--- base/archinstall/lib/utils/util.py
+++ head/archinstall/lib/utils/util.py
@@ -31,3 +31,3 @@
 def generate_password(length: int = 64) -> str:
 	haystack = string.printable  # digits, ascii_letters, punctuation (!"#$[] etc) and whitespace
-	return ''.join(_soundness_check(secrets.choice(haystack), str) for _ in range(length))
+	return ''.join(secrets.choice(haystack) for _ in range(length))
artigraph — arti/artifacts/__init__.py
--- base/arti/artifacts/__init__.py
+++ head/arti/artifacts/__init__.py
@@ -76,7 +76,7 @@
     def _validate_storage(cls, storage: Storage, info: ValidationInfo) -> Storage:
         if (type_ := info.data.get("type")) is not None:
-            storage = storage._visit_type(type_)
+            storage = _soundness_check(storage._visit_type(type_), Storage)
         if (format_ := info.data.get("format")) is not None:
-            storage = storage._visit_format(format_)
+            storage = _soundness_check(storage._visit_format(format_), Storage)
         return storage
artigraph — tests/arti/types/test_pydantic_adapters.py
--- base/tests/arti/types/test_pydantic_adapters.py
+++ head/tests/arti/types/test_pydantic_adapters.py
@@ -84,5 +84,5 @@
                         assert expected_spec_type is not None
                         assert isinstance(sub_spec, expected_spec_type)
-            elif _soundness_check(_soundness_check(lenient_issubclass(expected_origin, (list, tuple)), bool), bool):
+            elif _soundness_check(lenient_issubclass(expected_origin, (list, tuple)), bool):
                 # We currently only support sequence-like tuples
                 if _soundness_check(lenient_issubclass(expected_origin, tuple), bool):
@@ -103,7 +103,7 @@
             else:
                 raise NotImplementedError(f"Don't know how to check {expected_type}")
-        elif _soundness_check(_soundness_check(lenient_issubclass(expected_type, BaseModel), bool), bool):
+        elif _soundness_check(lenient_issubclass(expected_type, BaseModel), bool):
             compare_model_to_type(expected_type, spec)
... 1006 characters elided ...
-        elif _soundness_check(_soundness_check(lenient_issubclass(expected_type, BaseModel), bool), bool):
+        elif _soundness_check(lenient_issubclass(expected_type, BaseModel), bool):
             compare_model_to_generated(expected_type, got_type)
         elif expected_type is got_type:
async-utils — async_utils/_merge_gens.py
--- base/async_utils/_merge_gens.py
+++ head/async_utils/_merge_gens.py
@@ -65,5 +65,5 @@
                         for p in pending:
                             _soundness_check(p.cancel(), bool)
-                elif exc := _soundness_check(_soundness_check(f.exception(), (BaseException, type(None))), (BaseException, type(None))):
+                elif exc := _soundness_check(f.exception(), (BaseException, type(None))):
                     exceptions.append(exc)
                     idx = _soundness_check(futs.index(f), int)
@@ -109,5 +109,5 @@
                         for p in pending:
                             _soundness_check(p.cancel(), bool)
-                elif _soundness_check(_soundness_check(f.exception(), (BaseException, type(None))), (BaseException, type(None))):
+                elif _soundness_check(f.exception(), (BaseException, type(None))):
                     idx = _soundness_check(futs.index(f), int)
                     futs[idx] = None
@@ -150,5 +150,5 @@
                         for p in pending:
                             _soundness_check(p.cancel(), bool)
... 1332 characters elided ...
-                elif exc := _soundness_check(_soundness_check(f.exception(), (BaseException, type(None))), (BaseException, type(None))):
+                elif exc := _soundness_check(f.exception(), (BaseException, type(None))):
                     exceptions.append(exc)
                 else:
async-utils — async_utils/corofunc_cache.py
--- base/async_utils/corofunc_cache.py
+++ head/async_utils/corofunc_cache.py
@@ -72,5 +72,5 @@
     if _soundness_check(a_fut.cancelled(), bool):
         _soundness_check(c_fut.cancel(), bool)
-    elif exc := _soundness_check(_soundness_check(a_fut.exception(), (BaseException, type(None))), (BaseException, type(None))):
+    elif exc := _soundness_check(a_fut.exception(), (BaseException, type(None))):
         c_fut.set_exception(exc)
     else:
async-utils — async_utils/lockout.py
--- base/async_utils/lockout.py
+++ head/async_utils/lockout.py
@@ -49,5 +49,5 @@
     if _soundness_check(a_fut.cancelled(), bool):
         _soundness_check(c_fut.cancel(), bool)
-    elif exc := _soundness_check(_soundness_check(a_fut.exception(), (BaseException, type(None))), (BaseException, type(None))):
+    elif exc := _soundness_check(a_fut.exception(), (BaseException, type(None))):
         c_fut.set_exception(exc)
     else:
async-utils — async_utils/task_cache.py
--- base/async_utils/task_cache.py
+++ head/async_utils/task_cache.py
@@ -77,5 +77,5 @@
     if _soundness_check(a_fut.cancelled(), bool):
         _soundness_check(c_fut.cancel(), bool)
-    elif exc := _soundness_check(_soundness_check(a_fut.exception(), (BaseException, type(None))), (BaseException, type(None))):
+    elif exc := _soundness_check(a_fut.exception(), (BaseException, type(None))):
         c_fut.set_exception(exc)
     else:
async-utils — async_utils/waterfall.py
--- base/async_utils/waterfall.py
+++ head/async_utils/waterfall.py
@@ -134,5 +134,5 @@
         if _soundness_check(future.cancelled(), bool):
             _log.warning("Callback cancelled due to timeout")
-        elif exc := _soundness_check(_soundness_check(future.exception(), (BaseException, type(None))), (BaseException, type(None))):
+        elif exc := _soundness_check(future.exception(), (BaseException, type(None))):
             _log.error("Exception in user callback", exc_info=exc)
beartype — beartype/_util/func/utilfuncscope.py
--- base/beartype/_util/func/utilfuncscope.py
+++ head/beartype/_util/func/utilfuncscope.py
@@ -543,5 +543,5 @@
     # maliciously renamed one but *NOT* both of "__qualname__" and "__name__".
     # In this case, raise an exception. Again, Python permits this. *sigh*
-    elif _soundness_check(_soundness_check(func_scope_names[-1], str), str) != func_name_unqualified:
+    elif _soundness_check(func_scope_names[-1], str) != func_name_unqualified:
         raise exception_cls(
             f'Callable {func_name_unqualified}() fully-qualified basename '
beartype — beartype_test/a00_unit/a20_util/func/test_utilfuncwrap.py
--- base/beartype_test/a00_unit/a20_util/func/test_utilfuncwrap.py
+++ head/beartype_test/a00_unit/a20_util/func/test_utilfuncwrap.py
@@ -220,5 +220,5 @@
 '''
 
-        of_insects_beasts_and_birds: classmethod[Element, Parameters, R] = classmethod(never_to_be_reclaimed)
+        of_insects_beasts_and_birds = classmethod(never_to_be_reclaimed)
 
 
@@ -294,5 +294,5 @@
 '''
 
-        of_insects_beasts_and_birds: classmethod[Element, Parameters, R] = classmethod(never_to_be_reclaimed)
+        of_insects_beasts_and_birds = classmethod(never_to_be_reclaimed)
 
     # ....................{ PASS                           }....................
beartype — beartype_test/a00_unit/a60_decor/a60_pep/pep484/forward/test_pep484refdecor.py
--- base/beartype_test/a00_unit/a60_decor/a60_pep/pep484/forward/test_pep484refdecor.py
+++ head/beartype_test/a00_unit/a60_decor/a60_pep/pep484/forward/test_pep484refdecor.py
@@ -101,5 +101,5 @@
     assert crept_gradual[0] is rugged_and_dark
     assert next(iter(crept_gradual)) is rugged_and_dark
-    assert tuple(reversed(crept_gradual)) == (rugged_and_dark,)
+    assert tuple[()](reversed(crept_gradual)) == (rugged_and_dark,)
 
     # ..................{ PASS ~ closure                     }..................
bidict — tests/test_bidict.py
--- base/tests/test_bidict.py
+++ head/tests/test_bidict.py
@@ -319,10 +319,10 @@
     @invariant()
     def assert_reversed_works(self) -> None:
-        assert list[int](reversed(self.bi)) == list[int](self.bi)[::-1]
+        assert list[int](reversed[int](self.bi)) == list[int](self.bi)[::-1]
         items = self.bi.items()
         assert isinstance(items, Reversible)
-        assert list(reversed(items)) == list[object](items)[::-1]
+        assert list[object](reversed(items)) == list[object](items)[::-1]
         if self.is_ordered():
-            assert zip_equal(reversed(self.bi), reversed(self.oracle.data))
+            assert zip_equal(reversed[int](self.bi), reversed(self.oracle.data))
             assert zip_equal(reversed(items), reversed(self.oracle.data.items()))
             values = self.bi.values()
black — black/concurrency.py
--- base/black/concurrency.py
+++ head/black/concurrency.py
@@ -226,5 +226,5 @@
                 if _soundness_check(task.cancelled(), bool):
                     cancelled.append(task)
-                elif exc := _soundness_check(_soundness_check(task.exception(), (BaseException, type(None))), (BaseException, type(None))):
+                elif exc := _soundness_check(task.exception(), (BaseException, type(None))):
                     if report.verbose:
                         traceback.print_exception(type(exc), exc, exc.__traceback__)
black — black/handle_ipynb_magics.py
--- base/black/handle_ipynb_magics.py
+++ head/black/handle_ipynb_magics.py
@@ -208,5 +208,5 @@
     if n_chars < 4:
         return "_" + "".join(
-            _soundness_check(secrets.choice(string.ascii_letters + string.digits + "_"), str)
+            secrets.choice(string.ascii_letters + string.digits + "_")
             for _ in range(n_chars - 1)
         )
@@ -513,5 +513,5 @@
                 if _soundness_check(args[0], str) == "pinfo":
                     src = f"?{_soundness_check(args[1], str)}"
-                elif _soundness_check(_soundness_check(args[0], str), str) == "pinfo2":
+                elif _soundness_check(args[0], str) == "pinfo2":
                     src = f"??{_soundness_check(args[1], str)}"
                 else:
black — black/linegen.py
--- base/black/linegen.py
+++ head/black/linegen.py
@@ -1940,5 +1940,5 @@
                 remove_with_parens(child, node, mode=mode, features=features)
     elif node.type == syms.asexpr_test and not any(
-        leaf.type == token.COLONEQUAL for leaf in _soundness_iter(_soundness_iter(node.leaves(), str), str)
+        leaf.type == token.COLONEQUAL for leaf in _soundness_iter(node.leaves(), str)
     ):
         if maybe_make_parens_invisible_in_atom(
black — black/lines.py
--- base/black/lines.py
+++ head/black/lines.py
@@ -1132,7 +1132,7 @@
                     not depth
                     and previous_def.depth
-                    and _soundness_check(_soundness_check(current_line.leaves[-1], Leaf), Leaf).type == token.COLON
+                    and _soundness_check(current_line.leaves[-1], Leaf).type == token.COLON
                     and (
-                        _soundness_check(_soundness_check(current_line.leaves[0], Leaf), Leaf).value
+                        _soundness_check(current_line.leaves[0], Leaf).value
                         not in ("with", "try", "for", "while", "if", "match")
                     )
black — black/nodes.py
--- base/black/nodes.py
+++ head/black/nodes.py
@@ -789,5 +789,5 @@
             return (
                 node.children[0].type == token.NAME
-                and all(map(is_simple_decorator_trailer, node.children[1:-1]))
+                and all(map[bool](is_simple_decorator_trailer, node.children[1:-1]))
                 and (
                     len(node.children) < 2
black — black/strings.py
--- base/black/strings.py
+++ head/black/strings.py
@@ -506,8 +506,8 @@
             # \u
             return back_slashes + "u" + _soundness_check(groups["u"], str).lower()
-        elif _soundness_check(_soundness_check(groups["U"], (str, type(None))), (str, type(None))):
+        elif _soundness_check(groups["U"], (str, type(None))):
             # \U
             return back_slashes + "U" + _soundness_check(groups["U"], str).lower()
-        elif _soundness_check(_soundness_check(groups["x"], (str, type(None))), (str, type(None))):
+        elif _soundness_check(groups["x"], (str, type(None))):
             # \x
             return back_slashes + "x" + _soundness_check(groups["x"], str).lower()
black — black/trans.py
--- base/black/trans.py
+++ head/black/trans.py
@@ -1668,7 +1668,7 @@
         # Else the first leaf MAY be a string operator symbol or the 'in' keyword...
         elif is_valid_index(idx) and (
-            _soundness_check(_soundness_check(LL[idx], Leaf), Leaf).type in self.STRING_OPERATORS
-            or _soundness_check(_soundness_check(LL[idx], Leaf), Leaf).type == token.NAME
-            and str(_soundness_check(_soundness_check(LL[idx], Leaf), Leaf)) == "in"
+            _soundness_check(LL[idx], Leaf).type in self.STRING_OPERATORS
+            or _soundness_check(LL[idx], Leaf).type == token.NAME
+            and str(_soundness_check(LL[idx], Leaf)) == "in"
         ):
             idx += 1
bokeh — bokeh/client/connection.py
--- base/bokeh/client/connection.py
+++ head/bokeh/client/connection.py
@@ -226,5 +226,5 @@
         if reply is None:
             raise RuntimeError("Connection to server was lost")
-        elif _soundness_check(_soundness_check(reply.header['msgtype'], str), str) == 'ERROR':
+        elif _soundness_check(reply.header['msgtype'], str) == 'ERROR':
             raise RuntimeError("Failed to pull document: " + reply.content['text'])
         else:
@@ -248,5 +248,5 @@
         if reply is None:
             raise RuntimeError("Connection to server was lost")
-        elif _soundness_check(_soundness_check(reply.header['msgtype'], str), str) == 'ERROR':
+        elif _soundness_check(reply.header['msgtype'], str) == 'ERROR':
             raise RuntimeError("Failed to push document: " + reply.content['text'])
         else:
bokeh — bokeh/core/property/struct.py
--- base/bokeh/core/property/struct.py
+++ head/bokeh/core/property/struct.py
@@ -101,5 +101,5 @@
                     if name not in self._optional:
                         break
-                elif not _soundness_check(_soundness_check(type.is_valid(value[name]), bool), bool):
+                elif not _soundness_check(type.is_valid(value[name]), bool):
                     break
             else:
bokeh — bokeh/core/query.py
--- base/bokeh/core/query.py
+++ head/bokeh/core/query.py
@@ -189,5 +189,5 @@
             if key == "type":
                 # type supports IN, check for that first
-                if isinstance(val, dict) and list[object](val.keys()) == [IN]:
+                if isinstance(val, dict) and list(val.keys()) == [IN]:
                     if not any(isinstance(obj, x) for x in val[IN]): return False
                 # otherwise just check the type of the object against val
bokeh — bokeh/embed/standalone.py
--- base/bokeh/embed/standalone.py
+++ head/bokeh/embed/standalone.py
@@ -441,5 +441,5 @@
         result = _soundness_check(results[0], (str, RenderRoot))
     elif model_keys is not None:
-        result = dict_type(zip[tuple[object, str | RenderRoot]](model_keys, results))
+        result = dict_type(zip(model_keys, results))
     else:
         result = tuple(results)
bokeh — bokeh/models/widgets/tables.py
--- base/bokeh/models/widgets/tables.py
+++ head/bokeh/models/widgets/tables.py
@@ -726,10 +726,10 @@
 """)
 
-    formatter: Instance[S] = Instance(CellFormatter, InstanceDefault[StringFormatter](StringFormatter), help="""\
+    formatter: Instance[CellFormatter] = Instance[CellFormatter](CellFormatter, InstanceDefault[StringFormatter](StringFormatter), help="""\
 The cell formatter for this column. By default, a simple string
 formatter is used.\
 """)
 
-    editor: Instance[S] = Instance(CellEditor, InstanceDefault[StringEditor](StringEditor), help="""\
+    editor: Instance[CellEditor] = Instance[CellEditor](CellEditor, InstanceDefault[StringEditor](StringEditor), help="""\
 The cell editor for this column. By default, a simple string editor
 is used.\
@@ -762,9 +762,9 @@
         super().__init__(*args, **kwargs)
 
-    source: Instance[S] = Instance(DataSource, default=InstanceDefault[ColumnDataSource](ColumnDataSource), help="""\
+    source: Instance[DataSource] = Instance[DataSource](DataSource, default=InstanceDefault[ColumnDataSource](ColumnDataSource), help="""\
 The source of data for the widget.\
 """)
 
-    view: Instance[S] = Instance(CDSView, default=InstanceDefault[CDSView](CDSView), help="""\
+    view: Instance[CDSView] = Instance[CDSView](CDSView, default=InstanceDefault[CDSView](CDSView), help="""\
 A view into the data source to use when rendering table rows. A default view
 of the entire data source is created if a view is not passed in during
bokeh — bokeh/plotting/_renderer.py
--- base/bokeh/plotting/_renderer.py
+++ head/bokeh/plotting/_renderer.py
@@ -139,5 +139,5 @@
     muted_glyph = make_glyph(glyphclass, kwargs, muted_visuals)
 
-    glyph_renderer = GlyphRenderer(
+    glyph_renderer = GlyphRenderer[Glyph](
         glyph=glyph,
         nonselection_glyph=nonselection_glyph or "auto",
bokeh — docs/bokeh/source/conf.py
--- base/docs/bokeh/source/conf.py
+++ head/docs/bokeh/source/conf.py
@@ -131,5 +131,5 @@
             "But bokeh_missing_google_api_key_ok set to true in conf.py, so building docs anyway (with broken Google Maps)",
         )
-    elif _soundness_check(_soundness_check(os.environ.get("BOKEH_DOCS_CDN"), (str, type(None))), (str, type(None))) == "local":
+    elif _soundness_check(os.environ.get("BOKEH_DOCS_CDN"), (str, type(None))) == "local":
         bokeh_missing_google_api_key_ok = True
         print("But BOKEH_DOCS_CDN=local, so building docs anyway (with broken Google Maps)")
bokeh — examples/server/app/surface3d/surface3d.py
--- base/examples/server/app/surface3d/surface3d.py
+++ head/examples/server/app/surface3d/surface3d.py
@@ -57,3 +57,3 @@
     # Any of the available vis.js options for Graph3d can be set by changing
     # the contents of this dictionary.
-    options: Dict[K, V] = Dict(String, Any, default=DEFAULTS)
+    options: Dict[str, str | int | float | dict[str, int | float]] = Dict[str, str | int | float | dict[str, int | float]](String, Any, default=DEFAULTS)
bokeh — tests/unit/bokeh/core/property/test_instance.py
--- base/tests/unit/bokeh/core/property/test_instance.py
+++ head/tests/unit/bokeh/core/property/test_instance.py
@@ -194,5 +194,5 @@
         default =_TestModel(x=10)
         class ExplicitDefault(HasProps):
-            m: Instance[S] = bcpi.Instance(_TestModel, default=bcpi.InstanceDefault[_TestModel](_TestModel, x=10))
+            m: Instance[_TestModel] = bcpi.Instance[_TestModel](_TestModel, default=bcpi.InstanceDefault[_TestModel](_TestModel, x=10))
 
         obj = ExplicitDefault()
@@ -204,5 +204,5 @@
         default =_TestModel(x=10)
         class ExplicitDefault(HasProps):
-            m: Instance[S] = bcpi.Instance(_TestModel, default=lambda: _TestModel(x=10))
+            m: Instance[_TestModel] = bcpi.Instance[_TestModel](_TestModel, default=lambda: _TestModel(x=10))
 
         obj = ExplicitDefault()
bokeh — tests/unit/bokeh/core/property/test_numeric.py
--- base/tests/unit/bokeh/core/property/test_numeric.py
+++ head/tests/unit/bokeh/core/property/test_numeric.py
@@ -91,5 +91,5 @@
 
         with pytest.raises(ValueError):
-            bcpn.Interval(Int, 0.0, 1.0)
+            bcpn.Interval[int | float](Int, 0.0, 1.0)
 
     def test_valid_int(self) -> None:
bokeh — tests/unit/bokeh/core/property/test_wrappers__property.py
--- base/tests/unit/bokeh/core/property/test_wrappers__property.py
+++ head/tests/unit/bokeh/core/property/test_wrappers__property.py
@@ -604,5 +604,5 @@
         Bool(), Int(), Float(), Complex(), String(), Enum("Some", "a", "b"), Color(),
         Regex("^$"), Seq(Any), Tuple(Any, Any), Instance[_TestModel](_TestModel), Any(),
-        Interval(Float, 0, 1), Either(Int, String), DashPattern(), Size(), Percent(),
+        Interval[int](Float, 0, 1), Either(Int, String), DashPattern(), Size(), Percent(),
         Angle(), MinMaxBounds(),
     ]
bokeh — tests/unit/bokeh/document/test_events__document.py
--- base/tests/unit/bokeh/document/test_events__document.py
+++ head/tests/unit/bokeh/document/test_events__document.py
@@ -63,6 +63,6 @@
 class SomeModel(Model):
     data: ColumnData = ColumnData(Any, Any, default={})
-    ref1: Instance[S] = Instance(OtherModel, default=lambda: OtherModel())
-    ref2: Instance[S] = Instance(OtherModel, default=lambda: OtherModel())
+    ref1: Instance[OtherModel] = Instance[OtherModel](OtherModel, default=lambda: OtherModel())
+    ref2: Instance[OtherModel] = Instance[OtherModel](OtherModel, default=lambda: OtherModel())
 
 #-----------------------------------------------------------------------------
bokeh — tests/unit/bokeh/server/views/test_ico_handler.py
--- base/tests/unit/bokeh/server/views/test_ico_handler.py
+++ head/tests/unit/bokeh/server/views/test_ico_handler.py
@@ -1,2 +1,10 @@
+def _soundness_check(_v, _t):
+    if not isinstance(_v, _t):
+        raise TypeError(
+            f"type soundness violation: expected {getattr(_t, '__name__', _t)}, "
+            f"got {type(_v).__name__}"
+        )
+    return _v
+
 #-----------------------------------------------------------------------------
 # Copyright (c) Anaconda, Inc., and Bokeh Contributors.
@@ -32,5 +40,5 @@
 
 async def test_get_raises_for_missing_app() -> None:
-    handler = object.__new__(IcoHandler)
+    handler = _soundness_check(object.__new__(IcoHandler), IcoHandler)
     handler.app = None
bokeh — tests/unit/bokeh/server/views/test_static_handler.py
--- base/tests/unit/bokeh/server/views/test_static_handler.py
+++ head/tests/unit/bokeh/server/views/test_static_handler.py
@@ -66,5 +66,5 @@
     path = tmp_path / "asset.txt"
     path.write_bytes(_CONTENT)
-    handler = object.__new__(AsyncStaticFileHandler)
+    handler = _soundness_check(object.__new__(AsyncStaticFileHandler), AsyncStaticFileHandler)
     handler.absolute_path = str(path)
bokeh — tests/unit/bokeh/server/views/test_ws.py
--- base/tests/unit/bokeh/server/views/test_ws.py
+++ head/tests/unit/bokeh/server/views/test_ws.py
@@ -1,3 +1,11 @@
 lazy from typing import Callable
+def _soundness_check(_v, _t):
+    if not isinstance(_v, _t):
+        raise TypeError(
+            f"type soundness violation: expected {getattr(_t, '__name__', _t)}, "
+            f"got {type(_v).__name__}"
+        )
+    return _v
+
 #-----------------------------------------------------------------------------
 # Copyright (c) Anaconda, Inc., and Bokeh Contributors.
@@ -129,5 +137,5 @@
 
 def test_open_rejects_invalid_signed_token_before_payload() -> None:
-    handler = object.__new__(WSHandler)
+    handler = _soundness_check(object.__new__(WSHandler), WSHandler)
     handler._token = generate_jwt_token("bad-session", signed=True, secret_key="bar", extra_payload=dict(foo="bar"))
     handler.application = SimpleNamespace(
bokeh — tests/unit/bokeh/test_objects.py
--- base/tests/unit/bokeh/test_objects.py
+++ head/tests/unit/bokeh/test_objects.py
@@ -1,3 +1,11 @@
 lazy from typing import Tuple
+def _soundness_check(_v, _t):
+    if not isinstance(_v, _t):
+        raise TypeError(
+            f"type soundness violation: expected {getattr(_t, '__name__', _t)}, "
+            f"got {type(_v).__name__}"
+        )
+    return _v
+
 #-----------------------------------------------------------------------------
 # Copyright (c) Anaconda, Inc., and Bokeh Contributors.
@@ -167,5 +175,5 @@
 
     def test_init(self) -> None:
-        obj = SomeModel.__new__(SomeModel, id=ID("test_id"))
+        obj = _soundness_check(SomeModel.__new__(SomeModel, id=ID("test_id")), SomeModel)
         Model.__init__(obj)
         assert obj.id == "test_id"
@@ -174,5 +182,5 @@
         assert testObject2.id is not None
 
-        assert set(obj.properties()) == {
+        assert set[str](obj.properties()) == {
             "name",
             "tags",
@@ -311,5 +319,5 @@
     def test_func_default_with_model(self) -> None:
         class HasFuncDefaultModel(Model):
-            child: Instance[S] = Instance(Model, lambda: SomeModel())
+            child: Instance[Model] = Instance[Model](Model, lambda: SomeModel())
         obj1 = HasFuncDefaultModel()
         obj2 = HasFuncDefaultModel()
check-jsonschema — check_jsonschema/transforms/azure_pipelines.py
--- base/check_jsonschema/transforms/azure_pipelines.py
+++ head/check_jsonschema/transforms/azure_pipelines.py
@@ -64,5 +64,5 @@
         if item_is_expr:
             # unpack the expression item and recurse over the value
-            item_key, item_value = list[tuple[object, object]](item.items())[0]
+            item_key, item_value = list(item.items())[0]
             item_value = traverse_data(item_value)
cibuildwheel — bin/inspect_all_known_projects.py
--- base/bin/inspect_all_known_projects.py
+++ head/bin/inspect_all_known_projects.py
@@ -114,5 +114,5 @@
 
             return _soundness_check(_soundness_check(self.contents[filename], dict)[repo], (str, type(None)))
-        elif repo in _soundness_check(_soundness_check(self.contents[filename], dict), dict):
+        elif repo in _soundness_check(self.contents[filename], dict):
             return _soundness_check(_soundness_check(self.contents[filename], dict)[repo], (str, type(None)))
         else:
cibuildwheel — cibuildwheel/ci.py
--- base/cibuildwheel/ci.py
+++ head/cibuildwheel/ci.py
@@ -49,5 +49,5 @@
     elif "GITLAB_CI" in os.environ:
         return CIProvider.gitlab
-    elif strtobool(_soundness_check(_soundness_check(os.environ.get("CI", "false"), str), str)):
+    elif strtobool(_soundness_check(os.environ.get("CI", "false"), str)):
         return CIProvider.other
     else:
cibuildwheel — cibuildwheel/platforms/android.py
--- base/cibuildwheel/platforms/android.py
+++ head/cibuildwheel/platforms/android.py
@@ -747,5 +747,5 @@
         # will prepend '-m test', which will run Python's own test suite.
         del test_args[0]
-    elif _soundness_check(_soundness_check(test_args[0], str), str) == "pytest":
+    elif _soundness_check(test_args[0], str) == "pytest":
         # We transform some commands into the `python -m` form, but this is deprecated.
         msg = (
cibuildwheel — test/test_before_test.py
--- base/test/test_before_test.py
+++ head/test/test_before_test.py
@@ -61,5 +61,5 @@
             ["pyodide build {project}/dependency", "pip install --find-links dist/ spam"]
         )
-    elif _soundness_check(_soundness_check(build_frontend_env["CIBW_BUILD_FRONTEND"], str), str) in {"pip", "build"}:
+    elif _soundness_check(build_frontend_env["CIBW_BUILD_FRONTEND"], str) in {"pip", "build"}:
         before_test_steps.append("python -m pip install {project}/dependency")
cibuildwheel — unit_test/validate_schema_test.py
--- base/unit_test/validate_schema_test.py
+++ head/unit_test/validate_schema_test.py
@@ -244,5 +244,5 @@
                     blocks.append("\n".join([header, *block]))
                     block = []
-            elif " = " in line and any((lambda line: ((lambda line: (x.startswith(_soundness_check(_soundness_check(line.partition(" = ")[0], str), str)) for x in _soundness_iter(_soundness_iter(block, str), str)))(line)))(line)):
+            elif " = " in line and any((lambda line: (x.startswith(_soundness_check(line.partition(" = ")[0], str)) for x in _soundness_iter(block, str)))(line)):
                 blocks.append("\n".join([header, *block]))
                 block = [line]
colour — colour/io/luts/iridas_cube.py
--- base/colour/io/luts/iridas_cube.py
+++ head/colour/io/luts/iridas_cube.py
@@ -164,12 +164,12 @@
             if _soundness_check(tokens[0], str) == "TITLE":
                 title = " ".join(_soundness_check(tokens[1:], list))[1:-1]
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "DOMAIN_MIN":
+            elif _soundness_check(tokens[0], str) == "DOMAIN_MIN":
                 domain_min = as_float_array(_soundness_check(tokens[1:], list))
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "DOMAIN_MAX":
+            elif _soundness_check(tokens[0], str) == "DOMAIN_MAX":
                 domain_max = as_float_array(_soundness_check(tokens[1:], list))
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_1D_SIZE":
+            elif _soundness_check(tokens[0], str) == "LUT_1D_SIZE":
                 dimensions = 2
                 size = as_int_scalar(_soundness_check(tokens[1], str))
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_3D_SIZE":
+            elif _soundness_check(tokens[0], str) == "LUT_3D_SIZE":
                 dimensions = 3
                 size = as_int_scalar(_soundness_check(tokens[1], str))
colour — colour/io/luts/resolve_cube.py
--- base/colour/io/luts/resolve_cube.py
+++ head/colour/io/luts/resolve_cube.py
@@ -207,12 +207,12 @@
             if _soundness_check(tokens[0], str) == "TITLE":
                 title = " ".join(_soundness_check(tokens[1:], list))[1:-1]
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_1D_INPUT_RANGE":
+            elif _soundness_check(tokens[0], str) == "LUT_1D_INPUT_RANGE":
                 domain_3x1D = tstack([_soundness_check(tokens[1:], list), _soundness_check(tokens[1:], list), _soundness_check(tokens[1:], list)])
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_3D_INPUT_RANGE":
+            elif _soundness_check(tokens[0], str) == "LUT_3D_INPUT_RANGE":
                 domain_3D = tstack([_soundness_check(tokens[1:], list), _soundness_check(tokens[1:], list), _soundness_check(tokens[1:], list)])
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_1D_SIZE":
+            elif _soundness_check(tokens[0], str) == "LUT_1D_SIZE":
                 has_3x1D = True
                 size_3x1D = as_int_scalar(_soundness_check(tokens[1], str))
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "LUT_3D_SIZE":
+            elif _soundness_check(tokens[0], str) == "LUT_3D_SIZE":
                 has_3D = True
                 size_3D = as_int_scalar(_soundness_check(tokens[1], str))
colour — colour/io/luts/sony_spi1d.py
--- base/colour/io/luts/sony_spi1d.py
+++ head/colour/io/luts/sony_spi1d.py
@@ -129,7 +129,7 @@
             if _soundness_check(tokens[0], str) == "From":
                 domain_min, domain_max = as_float_array(_soundness_check(tokens[1:], list))
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "Length":
-                continue
-            elif _soundness_check(_soundness_check(tokens[0], str), str) == "Components":
+            elif _soundness_check(tokens[0], str) == "Length":
+                continue
+            elif _soundness_check(tokens[0], str) == "Components":
                 component = as_int_scalar(_soundness_check(tokens[1], str))
                 attest(
@@ -139,5 +139,5 @@
 
                 dimensions = 1 if component == 1 else 2
-            elif _soundness_check(_soundness_check(tokens[0], str), str) in ("{", "}"):
+            elif _soundness_check(tokens[0], str) in ("{", "}"):
                 continue
             else:
comtypes — comtypes/safearray.py
--- base/comtypes/safearray.py
+++ head/comtypes/safearray.py
@@ -111,8 +111,8 @@
                 extra = GetRecordInfoFromGuids(*guids)
             vartype = VT_RECORD
-        elif issubclass(itemtype, _soundness_check(_soundness_check(POINTER(IDispatch), type), type)):
+        elif issubclass(itemtype, _soundness_check(POINTER(IDispatch), type)):
             vartype = VT_DISPATCH
             extra = pointer(itemtype._iid_)
-        elif issubclass(itemtype, _soundness_check(_soundness_check(POINTER(IUnknown), type), type)):
+        elif issubclass(itemtype, _soundness_check(POINTER(IUnknown), type)):
             vartype = VT_UNKNOWN
             extra = pointer(itemtype._iid_)
@@ -325,5 +325,5 @@
                     # speedup by creating an ndarray here.
                     return [i.value for i in ptr[:num_elements]]
-                elif issubclass(self._itemtype_, _soundness_check(_soundness_check(POINTER(IUnknown), type), type)):
+                elif issubclass(self._itemtype_, _soundness_check(POINTER(IUnknown), type)):
                     iid = _safearray.SafeArrayGetIID(self)
                     itf = com_interface_registry[str(iid)]
cryptography — tests/x509/test_x509_ext.py
--- base/tests/x509/test_x509_ext.py
+++ head/tests/x509/test_x509_ext.py
@@ -3779,6 +3779,6 @@
                 x509.Name(
                     [
-                        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "PyCA"),
-                        x509.NameAttribute(
+                        x509.NameAttribute[str](NameOID.ORGANIZATION_NAME, "PyCA"),
+                        x509.NameAttribute[str](
                             NameOID.COMMON_NAME, "cryptography.io"
                         ),
cwltool — cwltool/builder.py
--- base/cwltool/builder.py
+++ head/cwltool/builder.py
@@ -407,5 +407,5 @@
                     isinstance(t, MutableMapping)
                     and "name" in t
-                    and self.names.has_name(_soundness_check(_soundness_check(cast(str, t["name"]), str), str), None)
+                    and self.names.has_name(_soundness_check(cast(str, t["name"]), str), None)
                 ):
                     avsc = self.names.get_name(_soundness_check(cast(str, t["name"]), str), None)
cwltool — cwltool/checker.py
--- base/cwltool/checker.py
+++ head/cwltool/checker.py
@@ -535,5 +535,5 @@
                 if vertex_in not in adjacency:
                     adjacency[vertex_in] = [vertex_out]
-                elif vertex_out not in _soundness_check(_soundness_check(adjacency[vertex_in], list), list):
+                elif vertex_out not in _soundness_check(adjacency[vertex_in], list):
                     _soundness_check(adjacency[vertex_in], list).append(vertex_out)
             if vertex_out not in adjacency:
cwltool — cwltool/command_line_tool.py
--- base/cwltool/command_line_tool.py
+++ head/cwltool/command_line_tool.py
@@ -1697,5 +1697,5 @@
                                         sfitem["class"] = "File"
                                         primary["secondaryFiles"].append(sfitem)
-                                    elif fs_access.isdir(_soundness_check(_soundness_check(sfitem["location"], str), str)):
+                                    elif fs_access.isdir(_soundness_check(sfitem["location"], str)):
                                         sfitem["class"] = "Directory"
                                         primary["secondaryFiles"].append(sfitem)
cwltool — cwltool/load_tool.py
--- base/cwltool/load_tool.py
+++ head/cwltool/load_tool.py
@@ -106,5 +106,5 @@
     if split.scheme and split.scheme in ["http", "https", "file"]:
         uri = argsworkflow
-    elif os.path.exists(_soundness_check(_soundness_check(os.path.abspath(argsworkflow), str), str)):
+    elif os.path.exists(_soundness_check(os.path.abspath(argsworkflow), str)):
         uri = file_uri(str(_soundness_check(os.path.abspath(argsworkflow), str)))
     elif resolver is not None:
cwltool — cwltool/process.py
--- base/cwltool/process.py
+++ head/cwltool/process.py
@@ -257,5 +257,5 @@
         if entry.target not in targets:
             targets[entry.target] = entry
-        elif _soundness_check(_soundness_check(targets[entry.target], MapperEnt), MapperEnt).resolved != entry.resolved:
+        elif _soundness_check(targets[entry.target], MapperEnt).resolved != entry.resolved:
             if fix_conflicts:
                 # find first key that does not clash with an existing entry in targets
@@ -533,5 +533,5 @@
                 r = var_spool_cwl_detector(mvalue, map_obj, mkey) or r
         case MutableSequence() as seq_obj:
-            for lkey, lvalue in enumerate[object](seq_obj):
+            for lkey, lvalue in enumerate(seq_obj):
                 r = var_spool_cwl_detector(lvalue, seq_obj, lkey) or r
     return r
cwltool — cwltool/utils.py
--- base/cwltool/utils.py
+++ head/cwltool/utils.py
@@ -272,5 +272,5 @@
     if not __random_outdir:
         __random_outdir = "/" + "".join(
-            [_soundness_check(random.choice(string.ascii_letters), str) for _ in range(6)]  # nosec
+            [random.choice(string.ascii_letters) for _ in range(6)]  # nosec
         )
         return __random_outdir
dacite — tests/core/test_forward_reference.py
--- base/tests/core/test_forward_reference.py
+++ head/tests/core/test_forward_reference.py
@@ -212,5 +212,5 @@
     result = _soundness_parametric(from_dict(Team[Employee], data), Team[Employee], (0,))
 
-    assert result == Team(
+    assert result == Team[Employee](
         name="foo", members=[Employee(name="John")], subteams=[Team[Employee](name="bar", members=[Employee(name="Jane")])]
     )
discord.py — discord/app_commands/checks.py
--- base/discord/app_commands/checks.py
+++ head/discord/app_commands/checks.py
@@ -367,5 +367,5 @@
     """
 
-    invalid = set[str](perms) - set(Permissions.VALID_FLAGS)
+    invalid = set[str](perms) - set[str](Permissions.VALID_FLAGS)
     if invalid:
         raise TypeError(f'Invalid permission(s): {", ".join(invalid)}')
discord.py — discord/app_commands/models.py
--- base/discord/app_commands/models.py
+++ head/discord/app_commands/models.py
@@ -406,5 +406,5 @@
             self.allowed_contexts: Optional[AppCommandContext] = None
         else:
-            self.allowed_contexts = AppCommandContext._from_value(allowed_contexts)
+            self.allowed_contexts = _soundness_check(AppCommandContext._from_value(allowed_contexts), AppCommandContext)
 
         allowed_installs = data.get('integration_types')
@@ -412,5 +412,5 @@
             self.allowed_installs: Optional[AppInstallationType] = None
         else:
-            self.allowed_installs = AppInstallationType._from_value(allowed_installs)
+            self.allowed_installs = _soundness_check(AppInstallationType._from_value(allowed_installs), AppInstallationType)
 
         self.nsfw: bool = data.get('nsfw', False)
@@ -844,5 +844,5 @@
         .. versionadded:: 2.6
         """
-        return ChannelFlags._from_value(self._flags)
+        return _soundness_check(ChannelFlags._from_value(self._flags), ChannelFlags)
 
     def is_nsfw(self) -> bool:
@@ -1095,5 +1095,5 @@
         .. versionadded:: 2.6
... 251 characters elided ...
-            _object = guild.get_member(self.id) or self._state.get_user(self.id)
+            _object = guild.get_member(self.id) or _soundness_check(self._state.get_user(self.id), (User, type(None)))
             _type = Member
         elif self.type is AppCommandPermissionType.channel:
discord.py — discord/invite.py
--- base/discord/invite.py
+++ head/discord/invite.py
@@ -541,5 +541,5 @@
         .. versionadded:: 2.6
         """
-        return InviteFlags._from_value(self._flags)
+        return _soundness_check(InviteFlags._from_value(self._flags), InviteFlags)
 
     def set_scheduled_event(self, scheduled_event: Snowflake, /) -> Self:
strawberry — strawberry/relay/fields.py
(only produced on head)

756 finding(s) omitted to fit GitHub's 65536-character comment limit. The full report is the comment.md artifact of this run.

@KotlinIsland
KotlinIsland force-pushed the merge-upstream branch 6 times, most recently from 2e6bafd to cda250e Compare August 14, 2026 01:12
regenerated the .byi typeshed, threaded ProgramEnvironment through the type
system, and reconciled the fork's features with upstream's new ones:

- numeric-tower unions always display expanded (`int | float`), never `float*`
- an inferred-bivariant class parameter keeps its bivariance when a private
  member is what made it bivariant; the spec's covariance fallback still
  applies to a parameter no member mentions
- adopted upstream's bool-conversion check on comprehension guards
- `__new__` keeps its implicit `cls` when explicitly decorated `@staticmethod`

13042 tests pass; the workspace is clippy-clean under -D warnings
@KotlinIsland
KotlinIsland merged commit ad23a94 into main Aug 14, 2026
71 of 79 checks passed
@KotlinIsland
KotlinIsland temporarily deployed to release-playground August 14, 2026 02:51 — with GitHub Actions Inactive
@KotlinIsland
KotlinIsland deleted the merge-upstream branch August 14, 2026 04:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.