diff --git a/docs/changelog.md b/docs/changelog.md index 62126062..6209b0ee 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,8 @@ ## Unreleased +- `tuple[T, ...]` is no longer considered compatible with + fixed-length tuple types (#711) - More PEP 695 support: generic classes and functions. Scoping rules are not yet fully implemented. (#703) - Fix type inference when constructing user-defined generic classes diff --git a/pyanalyze/test_value.py b/pyanalyze/test_value.py index 5f132318..98bb20ab 100644 --- a/pyanalyze/test_value.py +++ b/pyanalyze/test_value.py @@ -224,8 +224,8 @@ def test_sequence_value() -> None: val = value.SequenceValue( tuple, [(False, TypedValue(int)), (False, TypedValue(str))] ) - assert_can_assign(val, TypedValue(tuple)) - assert_can_assign(val, GenericValue(tuple, [TypedValue(int) | TypedValue(str)])) + assert_cannot_assign(val, TypedValue(tuple)) + assert_cannot_assign(val, GenericValue(tuple, [TypedValue(int) | TypedValue(str)])) assert_cannot_assign(val, GenericValue(tuple, [TypedValue(int) | TypedValue(list)])) assert_can_assign(val, val) diff --git a/pyanalyze/value.py b/pyanalyze/value.py index 433e1a8c..0e70a27d 100644 --- a/pyanalyze/value.py +++ b/pyanalyze/value.py @@ -729,6 +729,8 @@ def get_type_object( return self._type_object def can_assign(self, other: Value, ctx: CanAssignContext) -> CanAssign: + if isinstance(self, SequenceValue): + return super().can_assign(other, ctx) self_tobj = self.get_type_object(ctx) if self_tobj.is_thrift_enum: # Special case: Thrift enums. These are conceptually like @@ -904,7 +906,11 @@ def can_assign(self, other: Value, ctx: CanAssignContext) -> CanAssign: other = replace_known_sequence_value(other) if isinstance(other, KnownValue): other = TypedValue(type(other.val)) - if isinstance(other, TypedValue) and not isinstance(other.typ, super): + if ( + isinstance(other, TypedValue) + and not isinstance(other.typ, super) + and not isinstance(self, SequenceValue) + ): generic_args = other.get_generic_args_for_type(self.typ, ctx) # If we don't think it's a generic base, try super; # runtime isinstance() may disagree.