| from __future__ import annotations |
| |
| from mypy.constraints import SUBTYPE_OF, SUPERTYPE_OF, Constraint, infer_constraints |
| from mypy.test.helpers import Suite |
| from mypy.test.typefixture import TypeFixture |
| from mypy.types import Instance, TupleType, UnpackType |
| |
| |
| class ConstraintsSuite(Suite): |
| def setUp(self) -> None: |
| self.fx = TypeFixture() |
| |
| def test_no_type_variables(self) -> None: |
| assert not infer_constraints(self.fx.o, self.fx.o, SUBTYPE_OF) |
| |
| def test_basic_type_variable(self) -> None: |
| fx = self.fx |
| for direction in [SUBTYPE_OF, SUPERTYPE_OF]: |
| assert infer_constraints(fx.gt, fx.ga, direction) == [ |
| Constraint(type_var=fx.t, op=direction, target=fx.a) |
| ] |
| |
| def test_basic_type_var_tuple_subtype(self) -> None: |
| fx = self.fx |
| assert infer_constraints( |
| Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUBTYPE_OF |
| ) == [ |
| Constraint(type_var=fx.ts, op=SUBTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple)) |
| ] |
| |
| def test_basic_type_var_tuple(self) -> None: |
| fx = self.fx |
| assert infer_constraints( |
| Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUPERTYPE_OF |
| ) == [ |
| Constraint( |
| type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple) |
| ) |
| ] |
| |
| def test_type_var_tuple_with_prefix_and_suffix(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance(fx.gv2i, [fx.t, UnpackType(fx.ts), fx.s]), |
| Instance(fx.gv2i, [fx.a, fx.b, fx.c, fx.d]), |
| SUPERTYPE_OF, |
| ) |
| ) == { |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), |
| Constraint( |
| type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.b, fx.c], fx.std_tuple) |
| ), |
| Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.d), |
| } |
| |
| def test_unpack_homogenous_tuple(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance(fx.gvi, [UnpackType(Instance(fx.std_tuplei, [fx.t]))]), |
| Instance(fx.gvi, [fx.a, fx.b]), |
| SUPERTYPE_OF, |
| ) |
| ) == { |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.b), |
| } |
| |
| def test_unpack_homogenous_tuple_with_prefix_and_suffix(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance(fx.gv2i, [fx.t, UnpackType(Instance(fx.std_tuplei, [fx.s])), fx.u]), |
| Instance(fx.gv2i, [fx.a, fx.b, fx.c, fx.d]), |
| SUPERTYPE_OF, |
| ) |
| ) == { |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), |
| Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.b), |
| Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.c), |
| Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.d), |
| } |
| |
| def test_unpack_tuple(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance( |
| fx.gvi, |
| [ |
| UnpackType( |
| TupleType([fx.t, fx.s], fallback=Instance(fx.std_tuplei, [fx.o])) |
| ) |
| ], |
| ), |
| Instance(fx.gvi, [fx.a, fx.b]), |
| SUPERTYPE_OF, |
| ) |
| ) == { |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a), |
| Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.b), |
| } |
| |
| def test_unpack_with_prefix_and_suffix(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance( |
| fx.gv2i, |
| [ |
| fx.u, |
| UnpackType( |
| TupleType([fx.t, fx.s], fallback=Instance(fx.std_tuplei, [fx.o])) |
| ), |
| fx.u, |
| ], |
| ), |
| Instance(fx.gv2i, [fx.a, fx.b, fx.c, fx.d]), |
| SUPERTYPE_OF, |
| ) |
| ) == { |
| Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.a), |
| Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.b), |
| Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.c), |
| Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.d), |
| } |
| |
| def test_unpack_tuple_length_non_match(self) -> None: |
| fx = self.fx |
| assert set( |
| infer_constraints( |
| Instance( |
| fx.gv2i, |
| [ |
| fx.u, |
| UnpackType( |
| TupleType([fx.t, fx.s], fallback=Instance(fx.std_tuplei, [fx.o])) |
| ), |
| fx.u, |
| ], |
| ), |
| Instance(fx.gv2i, [fx.a, fx.b, fx.d]), |
| SUPERTYPE_OF, |
| ) |
| # We still get constraints on the prefix/suffix in this case. |
| ) == { |
| Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.a), |
| Constraint(type_var=fx.u, op=SUPERTYPE_OF, target=fx.d), |
| } |
| |
| def test_var_length_tuple_with_fixed_length_tuple(self) -> None: |
| fx = self.fx |
| assert not infer_constraints( |
| TupleType([fx.t, fx.s], fallback=Instance(fx.std_tuplei, [fx.o])), |
| Instance(fx.std_tuplei, [fx.a]), |
| SUPERTYPE_OF, |
| ) |