Skip to content

Commit

Permalink
Per review
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed Jan 10, 2025
1 parent b5d8b8f commit 5d6ab96
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ python-version = "3.10"
from typing_extensions import assert_type

def _(a: str | int):
# TODO: Infer the second argument as a type expression
# Should be fine
assert_type(a, str | int) # fine

# TODO: Order-independent union handling in type equivalence
assert_type(a, int | str) # error: [type-assertion-failure]
```

Expand All @@ -137,7 +138,8 @@ def _(a: A):
if isinstance(a, B) and not isinstance(a, C) and not isinstance(a, D):
reveal_type(a) # revealed: A & B & ~C & ~D

# TODO: Infer the second argument as a type expression
# Should be fine
assert_type(a, Intersection[A, B, Not[C], Not[D]]) # fine

# TODO: Order-independent intersection handling in type equivalence
assert_type(a, Intersection[B, A, Not[D], Not[C]]) # error: [type-assertion-failure]
```
30 changes: 23 additions & 7 deletions crates/red_knot_python_semantic/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,10 @@ impl<'db> Type<'db> {
match (self, other) {
(_, _) if self == other => true,

(Type::Any | Type::Unknown, Type::Any | Type::Unknown) => true,
(
Type::Todo(_) | Type::Any | Type::Unknown,
Type::Todo(_) | Type::Any | Type::Unknown,
) => true,

(Type::Instance(instance), Type::SubclassOf(subclass))
| (Type::SubclassOf(subclass), Type::Instance(instance)) => {
Expand All @@ -1126,9 +1129,10 @@ impl<'db> Type<'db> {
(Type::SubclassOf(first), Type::SubclassOf(second)) => {
match (first.subclass_of(), second.subclass_of()) {
(first, second) if first == second => true,
(ClassBase::Any | ClassBase::Unknown, ClassBase::Any | ClassBase::Unknown) => {
true
}
(
ClassBase::Todo(_) | ClassBase::Any | ClassBase::Unknown,
ClassBase::Todo(_) | ClassBase::Any | ClassBase::Unknown,
) => true,
_ => false,
}
}
Expand All @@ -1138,6 +1142,7 @@ impl<'db> Type<'db> {
&& iter::zip(first.elements(db), second.elements(db)).all(equivalent)
}

// TODO: Handle equivalent unions with items in different order
(Type::Union(first), Type::Union(second)) => {
let first_elements = first.elements(db);
let second_elements = second.elements(db);
Expand All @@ -1149,6 +1154,7 @@ impl<'db> Type<'db> {
iter::zip(first_elements, second_elements).all(equivalent)
}

// TODO: Handle equivalent intersections with items in different order
(Type::Intersection(first), Type::Intersection(second)) => {
let first_positive = first.positive(db);
let first_negative = first.negative(db);
Expand Down Expand Up @@ -3406,9 +3412,17 @@ impl KnownFunction {
}
}

/// Whether or not a particular function takes type expression as arguments, i.e. should
/// the argument of a call like `f(int)` be interpreted as the type int (true) or as the
/// type of the expression `int`, i.e. `Literal[int]` (false).
/// Returns a `u32` bitmask specifying whether or not
/// arguments given to a particular function
/// should be interpreted as type expressions or value expressions.
///
/// The argument is treated as a type expression
/// when the corresponding bit is `1`.
/// The least-significant (right-most) bit corresponds to
/// the argument at the index 0 and so on.
///
/// For example, `assert_type()` has the bitmask value of `0b10`.
/// This means the second argument is a type expression and the first a value expression.
const fn takes_type_expression_arguments(self) -> u32 {
const ALL_VALUES: u32 = 0b0;
const SINGLE_TYPE: u32 = 0b1;
Expand Down Expand Up @@ -4718,6 +4732,8 @@ pub(crate) mod tests {
#[test_case(Ty::Any, Ty::Any)]
#[test_case(Ty::Unknown, Ty::Unknown)]
#[test_case(Ty::Any, Ty::Unknown)]
#[test_case(Ty::Todo, Ty::Unknown)]
#[test_case(Ty::Todo, Ty::Any)]
#[test_case(Ty::Never, Ty::Never)]
#[test_case(Ty::AlwaysTruthy, Ty::AlwaysTruthy)]
#[test_case(Ty::AlwaysFalsy, Ty::AlwaysFalsy)]
Expand Down
1 change: 0 additions & 1 deletion crates/red_knot_python_semantic/src/types/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2545,7 +2545,6 @@ impl<'db> TypeInferenceBuilder<'db> {
.arguments_source_order()
.enumerate()
.map(|(index, arg_or_keyword)| {
// TODO: Remove this once we have proper overload matching
let infer_argument_type = if index < u32::BITS as usize
&& infer_as_type_expressions & (1 << index) != 0
{
Expand Down

0 comments on commit 5d6ab96

Please sign in to comment.