[ty] Implement Duboc's TDD optimization for narrowing constraints#25787
[ty] Implement Duboc's TDD optimization for narrowing constraints#25787charliermarsh wants to merge 12 commits into
Conversation
Typing conformance resultsNo changes detected ✅Current numbersThe percentage of diagnostics emitted that were expected errors held steady at 92.23%. The percentage of expected errors that received a diagnostic held steady at 87.42%. The number of fully passing files held steady at 92/134. |
Memory usage reportSummary
Significant changesClick to expand detailed breakdownprefect
sphinx
trio
flake8
|
|
| Lint rule | Added | Removed | Changed |
|---|---|---|---|
unresolved-attribute |
0 | 0 | 22 |
invalid-return-type |
0 | 0 | 2 |
invalid-argument-type |
0 | 0 | 1 |
invalid-assignment |
0 | 0 | 1 |
| Total | 0 | 0 | 26 |
Large timing changes:
| Project | Old Time | New Time | Change |
|---|---|---|---|
isort |
0.18s | 0.31s | +74% |
Raw diff (26 changes)
meson (https://github.com/mesonbuild/meson)
- run_project_tests.py:1314:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `msg` on type `Unknown | TestResult | None`
+ run_project_tests.py:1314:13 error[invalid-assignment] Object of type `str` is not assignable to attribute `msg` on type `TestResult | None`
- run_project_tests.py:1317:41 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1317:41 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1318:64 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1318:64 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1321:14 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1321:14 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1323:41 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1323:41 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1324:41 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1324:41 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1338:46 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1338:46 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1338:76 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1338:76 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1339:16 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1339:16 error[unresolved-attribute] Attribute `step` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1339:55 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1339:55 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1343:37 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1343:37 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1348:37 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1348:37 error[unresolved-attribute] Attribute `mlog` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1349:37 error[unresolved-attribute] Attribute `stdo` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1349:37 error[unresolved-attribute] Attribute `stdo` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1351:37 error[unresolved-attribute] Attribute `stdo` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1351:37 error[unresolved-attribute] Attribute `stdo` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1352:28 error[unresolved-attribute] Attribute `cicmds` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1352:28 error[unresolved-attribute] Attribute `cicmds` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1354:33 error[unresolved-attribute] Attribute `stde` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1354:33 error[unresolved-attribute] Attribute `stde` is not defined on `None` in union `TestResult | None`
- run_project_tests.py:1360:64 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `Unknown | TestResult | None`
+ run_project_tests.py:1360:64 error[unresolved-attribute] Attribute `msg` is not defined on `None` in union `TestResult | None`
pandas (https://github.com/pandas-dev/pandas)
- pandas/core/groupby/grouper.py:643:26 error[unresolved-attribute] Attribute `categories` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:643:26 error[unresolved-attribute] Attribute `categories` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/core/groupby/grouper.py:646:46 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:646:46 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/core/groupby/grouper.py:655:27 error[unresolved-attribute] Attribute `isna` is not defined on `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:655:27 error[unresolved-attribute] Attribute `isna` is not defined on `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/core/groupby/grouper.py:665:59 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:665:59 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/core/groupby/grouper.py:669:62 error[unresolved-attribute] Attribute `ordered` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:669:62 error[unresolved-attribute] Attribute `ordered` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/core/groupby/grouper.py:671:21 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/core/groupby/grouper.py:671:21 error[unresolved-attribute] Attribute `codes` is not defined on `Index`, `ndarray[tuple[Any, ...], dtype[Any]]` in union `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
- pandas/io/excel/_base.py:1406:16 error[invalid-return-type] Return type does not match returned value: expected `tuple[int | float | str | date, str | None]`, found `tuple[(Unknown & date) | int | float | Decimal | str, None | str]`
+ pandas/io/excel/_base.py:1406:16 error[invalid-return-type] Return type does not match returned value: expected `tuple[int | float | str | date, str | None]`, found `tuple[(Unknown & date & ~datetime) | (Unknown & datetime) | int | ... omitted 3 union elements, None | str]`
- pandas/tests/extension/base/groupby.py:32:41 error[invalid-argument-type] Argument to function `assert_extension_array_equal` is incorrect: Expected `ExtensionArray`, found `(Unknown & Series) | Index | (Unknown & ExtensionArray) | ... omitted 4 union elements`
+ pandas/tests/extension/base/groupby.py:32:41 error[invalid-argument-type] Argument to function `assert_extension_array_equal` is incorrect: Expected `ExtensionArray`, found `(Unknown & ndarray[tuple[object, ...], dtype[object]]) | (Unknown & Series) | Index | ... omitted 4 union elements`
pydantic (https://github.com/pydantic/pydantic)
- pydantic/v1/utils.py:613:16 error[invalid-return-type] Return type does not match returned value: expected `Mapping[int | str, Any]`, found `(AbstractSet[int | str] & Top[Mapping[Unknown, object]]) | (Mapping[int | str, Any] & AbstractSet[object]) | (Mapping[int | str, Any] & ~AbstractSet[object]) | dict[int | str, EllipsisType]`
+ pydantic/v1/utils.py:613:16 error[invalid-return-type] Return type does not match returned value: expected `Mapping[int | str, Any]`, found `(AbstractSet[int | str] & Top[Mapping[Unknown, object]]) | Mapping[int | str, Any] | dict[int | str, EllipsisType]`
Merging this PR will improve performance by 39.92%
Performance Changes
Tip Curious why this is faster? Use the CodSpeed MCP and ask your agent. Comparing |
89c4940 to
e41f7c9
Compare
c1e3e6f to
c106298
Compare
|
I think we may just want to eat the isort slowdown for now. I couldn't find any low-hanging fruit, and we already know that isort suffers from pathological performance around narrowing that we need to resolve (it's the motivation for our existing caps). We could probably avoid the slowdown by further adjusting our caps, but I'd rather just proceed with this and investigate that separately. |
|
Separately, I've confirmed that this solves the PyTorch performance problems to the same degree as the prior PR (e.g., 70% faster or more vs. |
Summary
This implements the alternative Doug outlined in his review of #25729: apply Duboc's TDD optimization directly to narrowing constraints.
For an
if/elifchain like:Each later branch is reached only after the earlier checks fail, so we record the paths as
A,not A and B, andnot A and not B and C. Once the successful branches meet, those earlier failed checks are redundant, but retaining them makes the formula grow quickly and makes every later load ofvalueexpensive.Narrowing constraints previously reused the reachability TDD. Reachability uses its third branch for an ambiguous result in Kleene three-valued logic, while narrowing formulas are boolean and do not use that branch. This gives narrowing constraints their own graph and uses the third edge as a "don't care" edge, following the Duboc optimization already used for specialization constraints in #23881. For example,
A or Bcan storeAonce onB's "don't care" edge instead of copying it into both outcomes ofB. Projected narrowing now uses the same representation.When merging an
if/elifcontinuation, we remove preceding branch predicates from each later branch and use the smaller formula only when the resulting merge is equivalent to the original. This simplifies the example toA or B or C, while preserving exclusions when an earlier branch returns and does not reach the merge. Other control-flow merges retain the existing canonical representation to avoid unrelated revealed-type changes.