[ty] Add mdtests that exercise constraint sets#20319
Conversation
1779737 to
9192e06
Compare
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
9192e06 to
a8e2919
Compare
* main: Bump LibCST to 1.8.4 (#20321)
a8e2919 to
65f13e5
Compare
crates/ty_python_semantic/resources/mdtest/type_properties/constraints.md
Outdated
Show resolved
Hide resolved
crates/ty_python_semantic/resources/mdtest/type_properties/constraints.md
Outdated
Show resolved
Hide resolved
|
|
||
| ```py | ||
| def _[T]() -> None: | ||
| # revealed: ty_extensions.ConstraintSet[(SubSub ≤ T@_ ≤ Base) ∨ (Sub ≤ T@_ ≤ Super)] |
There was a problem hiding this comment.
Why doesn't this union simplify to SubSub <= T <= Super?
There was a problem hiding this comment.
There can be types that satisfy SubSub ≤ T ≤ Super but which aren't comparable to Sub or Base, and which therefore shouldn't be included in the union.
So with just set theory, if the possible values are 0, 1, and 2, you get a type lattice of
012
01 02 12
0 1 2
∅
Then we might have
SubSub = ∅
Sub = 1
Base = 12
Super = 012
SubSub ≤ T ≤ Base = {∅, 1, 2, 12}
Sub ≤ T ≤ Super = {1, 01, 12, 012}
The union should be
(SubSub ≤ T ≤ Base) ∪ (Sub ≤ T ≤ Super) = {∅, 1, 2, 01, 12, 012}
but the simplification you suggest would be
SubSub ≤ T ≤ Super = {∅, 0, 1, 2, 01, 02, 12, 012}
0 and 02 are included in the simplification but not in the actual union.
Translating that into Python, an example problem type would be Super \ Sub*, where Sub* indicates instances of just Sub, but not any of its subclasses. (So in English, the problem type is "instances of Super, or any subclass of Super other than Sub". That type is not in SubSub ≤ T ≤ Base, since it includes Super, which is outside the range. It's also not in Sub ≤ T ≤ Super, because it does not include Sub. But it is in SubSub ≤ T ≤ Super.
There was a problem hiding this comment.
Makes sense, thank you! Might be worth recording a short version of this as a comment?
crates/ty_python_semantic/resources/mdtest/type_properties/constraints.md
Show resolved
Hide resolved
* main: (26 commits) Ignore deprecated rules unless selected by exact code (#20167) Stabilize adding future import via config option (#20277) [`flake8-errmsg`] Stabilize extending `raw-string-in-exception` (`EM101`) to support byte strings (#20273) Stabilize the remaining Airflow rules (#20250) [`flake8-bugbear`] Stabilize support for non-context-manager calls in `assert-raises-exception` (`B017`) (#20274) [`flake8-commas`] Stabilize support for trailing comma checks in type parameter lists (`COM812`, `COM819`) (#20275) [`pygrep_hooks`] Stabilize using`AsyncMock` methods in `invalid-mock-access` (`PGH005`) (#20272) Stabilize new strategy for classifying imports as first party (#20268) [`pylint`] Stabilize ignoring `__init__.py` for `useless-import-alias` (`PLC0414`) (#20271) [`pylint`] Stabilize adding U+061C to `bidirectional-unicode` (`PLE2502`) (#20276) [`flake8-simplify`] Stabilize fix safety of `multiple-with-statements` (`SIM117`) (#20270) Stabilize `pytest-raises-ambiguous-pattern` (`RUF043`) (#20253) Stabilize `f-string-number-format` (`FURB116`) (#20247) [`pyupgrade`] Remove `non-pep604-isinstance` (`UP038`) (#19156) [`pandas-vet`] Remove `pandas-df-variable-name` (`PD901`) (#19223) Remove deprecated macOS config file discovery (#19210) Stabilize `redundant-none-literal` (`PYI061`) (#20236) Stabilize `generic-not-last-base-class` (`PYI059`) (#20246) Stabilize `useless-class-metaclass-type` (`UP050`) (#20230) Stabilize `os-symlink` (`PTH211`) (#20229) ...
This PR adds a new
ty_extensions.ConstraintSetclass, which is used to expose constraint sets to our mdtest framework. This lets us write a large collection of unit tests that exercise the invariants and rewrite rules of our constraint set implementation.As part of this,
is_assignable_toand friends are updated to return aConstraintSetinstead of abool, and we implementConstraintSet.__bool__to return when a constraint set is always satisfied. That lets us still usestatic_assert(is_assignable_to(...)), since the assertion will coerce the constraint set to a bool, and also lets usreveal_type(is_assignable_to(...))to see more detail about whether/when the two types are assignable. That lets us get rid ofreveal_when_assignable_toand friends, since they are now redundant with the expanded capabilities ofis_assignable_to.