|
| 1 | +# Typeshed PR Ecosystem Analysis for ruff#23963 |
| 2 | + |
| 3 | +## Summary |
| 4 | + |
| 5 | +The typeshed sync in [ruff#23963](https://github.com/astral-sh/ruff/pull/23963) covers commits |
| 6 | +`843c1fd..f8f0794` from [python/typeshed](https://github.com/python/typeshed). Of the 26 commits |
| 7 | +in this range, **two typeshed PRs** are responsible for all new ecosystem hits: |
| 8 | + |
| 9 | +### 1. [python/typeshed#15470](https://github.com/python/typeshed/pull/15470) — Canonicalized set/frozenset signatures |
| 10 | + |
| 11 | +**Commit:** `e8638cd0e` |
| 12 | + |
| 13 | +**What changed:** |
| 14 | +- `set.discard(element: _T)` → `set.discard(element: object)` |
| 15 | +- `set.difference/intersection/isdisjoint/issubset/issuperset(*s: Iterable[Any])` → `Iterable[object]` |
| 16 | +- `set.symmetric_difference(s: Iterable[_T])` → `set.symmetric_difference(s: Iterable[_S]) -> set[_T | _S]` |
| 17 | +- `frozenset.isdisjoint(s: Iterable[_T_co])` → `Iterable[object]` |
| 18 | +- `frozenset.__and__(value: AbstractSet[_T_co])` → `AbstractSet[object]` |
| 19 | +- `frozenset.symmetric_difference(s: Iterable[_T_co])` → `frozenset.symmetric_difference(s: Iterable[_S]) -> frozenset[_T_co | _S]` |
| 20 | + |
| 21 | +**Ecosystem impact:** |
| 22 | +- **Home Assistant (core):** New `invalid-method-override` error at `core_config.py:529` where |
| 23 | + `_ComponentSet.discard(value: str)` overrides `set.discard(element: object)` — the parameter type |
| 24 | + is narrower than the base class, which is now `object` instead of `_T` (i.e., `str`). |
| 25 | +- **Home Assistant (core):** New `unused-type-ignore-comment` — a `# type: ignore` comment that |
| 26 | + suppressed the old `discard` signature mismatch is now unnecessary since the base method accepts |
| 27 | + `object`. |
| 28 | +- **SymPy:** Error message text change — `set.intersection` parameter shown as `Iterable[object]` |
| 29 | + instead of `Iterable[Any]` in diagnostic output. |
| 30 | + |
| 31 | +**Reproduction:** |
| 32 | +```python |
| 33 | +class MySet(set[str]): |
| 34 | + def discard(self, value: str) -> None: # error[invalid-method-override] with new stubs |
| 35 | + pass |
| 36 | +``` |
| 37 | + |
| 38 | +### 2. [python/typeshed#14284](https://github.com/python/typeshed/pull/14284) — Remove `dict.__or__` overloads |
| 39 | + |
| 40 | +**Commit:** `bfb7342f8` |
| 41 | + |
| 42 | +**What changed:** |
| 43 | +- Removed the identity overloads for `dict.__or__` and `dict.__ror__` that preserved the exact |
| 44 | + type when merging dicts of the same type. Only the union-expanding overload |
| 45 | + `def __or__(self, value: dict[_T1, _T2]) -> dict[_KT | _T1, _VT | _T2]` remains. |
| 46 | + |
| 47 | +**Ecosystem impact:** |
| 48 | +- **Pydantic:** `dict[str, Any] | dict[str, <specific>]` now infers `dict[str, Any | <specific>]` |
| 49 | + instead of `dict[str, Any]`. This causes `CoreMetadata` TypedDict operations to produce |
| 50 | + `dict[str, Divergent]` in some cyclic type resolution paths, triggering `invalid-parameter-default` |
| 51 | + and `invalid-assignment` errors. |
| 52 | +- **Rotki:** `dict[str, Any] | dict[str, <typed-values>]` (used in `common_arguments` at |
| 53 | + `schemas.py:690`) now infers `dict[str, Any | IncludeExcludeFilterData | list[Any] | None]` |
| 54 | + instead of `dict[str, Any]`, causing `invalid-argument-type` errors when dict values are passed |
| 55 | + to functions expecting specific types. |
| 56 | +- **OpenLibrary:** Similar dict merge patterns produce wider union types, causing |
| 57 | + `invalid-argument-type` errors in `lists.py`. |
| 58 | + |
| 59 | +**Reproduction:** |
| 60 | +```python |
| 61 | +from typing import Any |
| 62 | + |
| 63 | +def get_base() -> dict[str, Any]: |
| 64 | + return {} |
| 65 | + |
| 66 | +# Old: dict[str, Any] (identity overload matched same key type) |
| 67 | +# New: dict[str, Any | int] (only union overload remains) |
| 68 | +merged = get_base() | {"x": 1} |
| 69 | +``` |
| 70 | + |
| 71 | +## Affected projects summary |
| 72 | + |
| 73 | +| Project | New diagnostics | Responsible typeshed PR | |
| 74 | +|---------|----------------|----------------------| |
| 75 | +| Rotki | ~137 `invalid-argument-type` | #14284 (dict.__or__) | |
| 76 | +| Pydantic | ~9 `invalid-parameter-default` / `invalid-assignment` | #14284 (dict.__or__) | |
| 77 | +| OpenLibrary | 4 `invalid-argument-type` | #14284 (dict.__or__) | |
| 78 | +| SymPy | 1 message text change | #15470 (set/frozenset) | |
| 79 | +| Home Assistant | 1 `invalid-method-override` + 1 `unused-type-ignore-comment` | #15470 (set/frozenset) | |
| 80 | + |
| 81 | +## Notes |
| 82 | + |
| 83 | +- The exact ecosystem hits could not be fully reproduced locally because the ecosystem analyzer |
| 84 | + tests against unpinned project HEADs, which may have changed between the CI run (March 15, 2026) |
| 85 | + and local testing. |
| 86 | +- Pydantic consistently causes stack overflows in non-release ty builds, making it difficult to |
| 87 | + test locally. |
| 88 | +- The `dict.__or__` overload removal is the higher-impact change (affecting ~150 diagnostics across |
| 89 | + 3 projects), while the set/frozenset canonicalization has a smaller but still notable impact |
| 90 | + (3 diagnostics across 2 projects). |
0 commit comments