mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[red-knot] add test cases result in false positive errors (#16856)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / test ruff-lsp (push) Blocked by required conditions
CI / check playground (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
[Knot Playground] Release / publish (push) Waiting to run
## Summary From #16641 The previous PR attempted to fix the errors presented in this PR, but as discussed in the conversation, it was concluded that the approach was undesirable and that further work would be needed to fix the errors with a correct general solution. In this PR, I instead add the test cases from the previous PR as TODOs, as a starting point for future work. ## Test Plan --------- Co-authored-by: Carl Meyer <carl@oddbird.net>
This commit is contained in:
parent
c1971fdde2
commit
23382f5f8c
5 changed files with 90 additions and 7 deletions
|
@ -663,6 +663,7 @@ to the fact that `bool` is a `@final` class at runtime that cannot be subclassed
|
|||
|
||||
```py
|
||||
from knot_extensions import Intersection, Not, AlwaysTruthy, AlwaysFalsy
|
||||
from typing_extensions import Literal
|
||||
|
||||
class P: ...
|
||||
|
||||
|
@ -686,6 +687,19 @@ def f(
|
|||
reveal_type(f) # revealed: Never
|
||||
reveal_type(g) # revealed: Never
|
||||
reveal_type(h) # revealed: Never
|
||||
|
||||
def never(
|
||||
a: Intersection[Intersection[AlwaysFalsy, Not[Literal[False]]], bool],
|
||||
b: Intersection[Intersection[AlwaysTruthy, Not[Literal[True]]], bool],
|
||||
c: Intersection[Intersection[Literal[True], Not[AlwaysTruthy]], bool],
|
||||
d: Intersection[Intersection[Literal[False], Not[AlwaysFalsy]], bool],
|
||||
):
|
||||
# TODO: This should be `Never`
|
||||
reveal_type(a) # revealed: Literal[True]
|
||||
# TODO: This should be `Never`
|
||||
reveal_type(b) # revealed: Literal[False]
|
||||
reveal_type(c) # revealed: Never
|
||||
reveal_type(d) # revealed: Never
|
||||
```
|
||||
|
||||
## Simplification of `LiteralString`, `AlwaysTruthy` and `AlwaysFalsy`
|
||||
|
|
|
@ -206,8 +206,8 @@ static_assert(not is_assignable_to(tuple[Any, Literal[2]], tuple[int, str]))
|
|||
## Union types
|
||||
|
||||
```py
|
||||
from knot_extensions import static_assert, is_assignable_to, Unknown
|
||||
from typing import Literal, Any
|
||||
from knot_extensions import AlwaysTruthy, AlwaysFalsy, static_assert, is_assignable_to, Unknown
|
||||
from typing_extensions import Literal, Any, LiteralString
|
||||
|
||||
static_assert(is_assignable_to(int, int | str))
|
||||
static_assert(is_assignable_to(str, int | str))
|
||||
|
@ -227,13 +227,22 @@ static_assert(not is_assignable_to(int | None, str | None))
|
|||
static_assert(not is_assignable_to(Literal[1] | None, int))
|
||||
static_assert(not is_assignable_to(Literal[1] | None, str | None))
|
||||
static_assert(not is_assignable_to(Any | int | str, int))
|
||||
|
||||
# TODO: No errors
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(bool, Literal[False] | AlwaysTruthy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(bool, Literal[True] | AlwaysFalsy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(LiteralString, Literal[""] | AlwaysTruthy))
|
||||
static_assert(not is_assignable_to(Literal[True] | AlwaysFalsy, Literal[False] | AlwaysTruthy))
|
||||
```
|
||||
|
||||
## Intersection types
|
||||
|
||||
```py
|
||||
from knot_extensions import static_assert, is_assignable_to, Intersection, Not
|
||||
from typing_extensions import Any, Literal
|
||||
from knot_extensions import static_assert, is_assignable_to, Intersection, Not, AlwaysTruthy, AlwaysFalsy
|
||||
from typing_extensions import Any, Literal, final, LiteralString
|
||||
|
||||
class Parent: ...
|
||||
class Child1(Parent): ...
|
||||
|
@ -296,6 +305,19 @@ static_assert(is_assignable_to(Intersection[Any, Unrelated], Intersection[Any, P
|
|||
static_assert(is_assignable_to(Intersection[Any, Parent, Unrelated], Intersection[Any, Parent, Unrelated]))
|
||||
static_assert(is_assignable_to(Intersection[Unrelated, Any], Intersection[Unrelated, Not[Any]]))
|
||||
static_assert(is_assignable_to(Intersection[Literal[1], Any], Intersection[Unrelated, Not[Any]]))
|
||||
|
||||
# TODO: No errors
|
||||
# The condition `is_assignable_to(T & U, U)` should still be satisfied after the following transformations:
|
||||
# `LiteralString & AlwaysTruthy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(Intersection[LiteralString, Not[Literal[""]]], AlwaysTruthy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(Intersection[LiteralString, Not[Literal["", "a"]]], AlwaysTruthy))
|
||||
# `LiteralString & ~AlwaysFalsy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(Intersection[LiteralString, Not[Literal[""]]], Not[AlwaysFalsy]))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_assignable_to(Intersection[LiteralString, Not[Literal["", "a"]]], Not[AlwaysFalsy]))
|
||||
```
|
||||
|
||||
## General properties
|
||||
|
|
|
@ -196,7 +196,7 @@ static_assert(is_disjoint_from(None, Intersection[int, Not[str]]))
|
|||
|
||||
```py
|
||||
from typing_extensions import Literal, LiteralString
|
||||
from knot_extensions import TypeOf, is_disjoint_from, static_assert
|
||||
from knot_extensions import Intersection, Not, TypeOf, is_disjoint_from, static_assert, AlwaysFalsy, AlwaysTruthy
|
||||
|
||||
static_assert(is_disjoint_from(Literal[True], Literal[False]))
|
||||
static_assert(is_disjoint_from(Literal[True], Literal[1]))
|
||||
|
@ -223,6 +223,25 @@ static_assert(not is_disjoint_from(Literal[1], Literal[1]))
|
|||
static_assert(not is_disjoint_from(Literal["a"], Literal["a"]))
|
||||
static_assert(not is_disjoint_from(Literal["a"], LiteralString))
|
||||
static_assert(not is_disjoint_from(Literal["a"], str))
|
||||
|
||||
# TODO: No errors
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(AlwaysFalsy, Intersection[LiteralString, Not[Literal[""]]]))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(Intersection[Not[Literal[True]], Not[Literal[False]]], bool))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(Intersection[AlwaysFalsy, Not[Literal[False]]], bool))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(Intersection[AlwaysTruthy, Not[Literal[True]]], bool))
|
||||
|
||||
# TODO: No errors
|
||||
# The condition `is_disjoint(T, Not[T])` must still be satisfied after the following transformations:
|
||||
# `LiteralString & AlwaysTruthy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(Intersection[LiteralString, AlwaysTruthy], Not[LiteralString] | AlwaysFalsy))
|
||||
# `LiteralString & ~AlwaysFalsy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_disjoint_from(Intersection[LiteralString, Not[AlwaysFalsy]], Not[LiteralString] | AlwaysFalsy))
|
||||
```
|
||||
|
||||
### Class, module and function literals
|
||||
|
|
|
@ -46,6 +46,12 @@ static_assert(is_gradual_equivalent_to(Intersection[str | int, Not[type[Any]]],
|
|||
|
||||
static_assert(not is_gradual_equivalent_to(str | int, int | str | bytes))
|
||||
static_assert(not is_gradual_equivalent_to(str | int | bytes, int | str | dict))
|
||||
|
||||
# TODO: No errors
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_gradual_equivalent_to(Unknown, Unknown | Any))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_gradual_equivalent_to(Unknown, Intersection[Unknown, Any]))
|
||||
```
|
||||
|
||||
## Tuples
|
||||
|
|
|
@ -276,8 +276,8 @@ static_assert(is_subtype_of(Never, AlwaysFalsy))
|
|||
### `AlwaysTruthy` and `AlwaysFalsy`
|
||||
|
||||
```py
|
||||
from knot_extensions import AlwaysTruthy, AlwaysFalsy, is_subtype_of, static_assert
|
||||
from typing import Literal
|
||||
from knot_extensions import AlwaysTruthy, AlwaysFalsy, Intersection, Not, is_subtype_of, static_assert
|
||||
from typing_extensions import Literal, LiteralString
|
||||
|
||||
static_assert(is_subtype_of(Literal[1], AlwaysTruthy))
|
||||
static_assert(is_subtype_of(Literal[0], AlwaysFalsy))
|
||||
|
@ -290,6 +290,28 @@ static_assert(not is_subtype_of(Literal[0], AlwaysTruthy))
|
|||
|
||||
static_assert(not is_subtype_of(str, AlwaysTruthy))
|
||||
static_assert(not is_subtype_of(str, AlwaysFalsy))
|
||||
|
||||
# TODO: No errors
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(bool, Literal[False] | AlwaysTruthy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(bool, Literal[True] | AlwaysFalsy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(LiteralString, Literal[""] | AlwaysTruthy))
|
||||
static_assert(not is_subtype_of(Literal[True] | AlwaysFalsy, Literal[False] | AlwaysTruthy))
|
||||
|
||||
# TODO: No errors
|
||||
# The condition `is_subtype_of(T & U, U)` must still be satisfied after the following transformations:
|
||||
# `LiteralString & AlwaysTruthy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(Intersection[LiteralString, Not[Literal[""]]], AlwaysTruthy))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(Intersection[LiteralString, Not[Literal["", "a"]]], AlwaysTruthy))
|
||||
# `LiteralString & ~AlwaysFalsy` -> `LiteralString & ~Literal[""]`
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(Intersection[LiteralString, Not[Literal[""]]], Not[AlwaysFalsy]))
|
||||
# error: [static-assert-error]
|
||||
static_assert(is_subtype_of(Intersection[LiteralString, Not[Literal["", "a"]]], Not[AlwaysFalsy]))
|
||||
```
|
||||
|
||||
### Module literals
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue