Do not infer join from existing unions - #22039
ilevkivskyi wants to merge 3 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
|
So I will take a look. |
This comment has been minimized.
This comment has been minimized.
|
OK, primer now looks good, there is only one new problem in x: list[str]
x2: list[str | bytes]
x3: list[str | bytes | int]
x + x2 # This works
x + x3 # This works
x2 = x + x2 # This fails because mypy overuses outer context (and this is quite bad IMO)
x3 = x + x3 # This however works againwhile with this PR the last line (consistently) fails as well. It used to works because from FWIW I think this PR is ready, and we should consider outer context for BinOps problem separately. @JukkaL please take a look. |
|
Note a full review, but this seems wrong: from typing import Generic, Optional, TypeVar, Union
T = TypeVar("T")
T_co = TypeVar("T_co", covariant=True)
class A(Generic[T_co]): ...
class B(Generic[T_co]): ...
class C(A[Union[int, str]], B[Union[int, str, None]]): ...
def f(x: Union[A[T], B[Optional[T]]]) -> T: ...
reveal_type(f(C())) # Actual "Never"; expected "int | str"Claude suggested this fix: |
|
@JukkaL But that fails on master as well. I can of course take a look, but why exactly is this important? That said, there is indeed something suspicious with the |
|
@JukkaL OK, there was a (stupid) bug, it is fixed now. So that test now works as well. |
|
Diff from mypy_primer, showing the effect of this PR on open source code: colour (https://github.com/colour-science/colour)
- colour/io/luts/operator.py:257: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | str | _NestedSequence[complex | bytes | str]") [assignment]
- colour/io/luts/operator.py:259: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | str | _NestedSequence[complex | bytes | str]") [assignment]
- colour/io/luts/lut.py:159: error: Argument 1 to "linear_table" of "AbstractLUT" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None" [arg-type]
- colour/io/luts/lut.py:159: error: Argument 2 to "linear_table" of "AbstractLUT" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None" [arg-type]
- colour/io/luts/lut.py:161: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | str | _NestedSequence[complex | bytes | str]") [assignment]
- colour/io/luts/lut.py:163: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | str | _NestedSequence[complex | bytes | str]") [assignment]
+ colour/io/luts/lut.py:1433: error: No overload variant of "pad" matches argument types "ndarray[Any, Any]", "tuple[int, Any | signedinteger[_8Bit] | signedinteger[_16Bit] | signedinteger[_32Bit] | signedinteger[_64Bit] | unsignedinteger[_8Bit] | unsignedinteger[_16Bit] | unsignedinteger[_32Bit] | unsignedinteger[_64Bit]]", "str", "float" [call-overload]
+ colour/io/luts/lut.py:1433: note: Possible overload variants:
+ colour/io/luts/lut.py:1433: note: def [ShapeT: tuple[int, ...], DTypeT: dtype[Any]] pad(array: ndarray[ShapeT, DTypeT], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: Literal['constant', 'edge', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'reflect', 'symmetric', 'wrap', 'empty'] = ..., *, stat_length: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | None = ..., constant_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., end_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., reflect_type: Literal['odd', 'even'] = ...) -> ndarray[ShapeT, DTypeT]
+ colour/io/luts/lut.py:1433: note: def [ScalarT: generic[Any]] pad(array: _SupportsArray[dtype[ScalarT]] | _NestedSequence[_SupportsArray[dtype[ScalarT]]], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: Literal['constant', 'edge', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'reflect', 'symmetric', 'wrap', 'empty'] = ..., *, stat_length: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | None = ..., constant_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., end_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., reflect_type: Literal['odd', 'even'] = ...) -> ndarray[tuple[Any, ...], dtype[ScalarT]]
+ colour/io/luts/lut.py:1433: note: def pad(array: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: Literal['constant', 'edge', 'linear_ramp', 'maximum', 'mean', 'median', 'minimum', 'reflect', 'symmetric', 'wrap', 'empty'] = ..., *, stat_length: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | None = ..., constant_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., end_values: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] = ..., reflect_type: Literal['odd', 'even'] = ...) -> ndarray[tuple[Any, ...], dtype[Any]]
+ colour/io/luts/lut.py:1433: note: def [ShapeT: tuple[int, ...], DTypeT: dtype[Any]] pad(array: ndarray[ShapeT, DTypeT], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: _ModeFunc, **kwargs: Any) -> ndarray[ShapeT, DTypeT]
+ colour/io/luts/lut.py:1433: note: def [ScalarT: generic[Any]] pad(array: _SupportsArray[dtype[ScalarT]] | _NestedSequence[_SupportsArray[dtype[ScalarT]]], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: _ModeFunc, **kwargs: Any) -> ndarray[tuple[Any, ...], dtype[ScalarT]]
+ colour/io/luts/lut.py:1433: note: def pad(array: Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str], pad_width: _SupportsArray[dtype[integer[Any]]] | _NestedSequence[_SupportsArray[dtype[integer[Any]]]] | int | _NestedSequence[int] | dict[int, int] | dict[int, tuple[int, int]] | dict[int, int | tuple[int, int]], mode: _ModeFunc, **kwargs: Any) -> ndarray[tuple[Any, ...], dtype[Any]]
- colour/io/luts/lut.py:922: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:923: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1037: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1038: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1045: error: Argument 1 to "as_int_scalar" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1259: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1260: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1413: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1414: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1419: error: Argument 1 to "tile" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "_SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]]" [arg-type]
- colour/io/luts/lut.py:1419: error: Argument 1 to "tile" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "_SupportsArray[dtype[signedinteger[_8Bit] | signedinteger[_16Bit] | signedinteger[_32Bit] | signedinteger[_64Bit] | unsignedinteger[_8Bit] | unsignedinteger[_16Bit] | unsignedinteger[_32Bit] | unsignedinteger[_64Bit] | Any]] | _NestedSequence[_SupportsArray[dtype[signedinteger[_8Bit] | signedinteger[_16Bit] | signedinteger[_32Bit] | signedinteger[_64Bit] | unsignedinteger[_8Bit] | unsignedinteger[_16Bit] | unsignedinteger[_32Bit] | unsignedinteger[_64Bit] | Any]]]" [arg-type]
- colour/io/luts/lut.py:1419: error: Argument 1 to "as_int_array" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1712: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1713: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1935: error: Incompatible types in assignment (expression has type "object", variable has type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None") [assignment]
- colour/io/luts/lut.py:1936: error: Argument 1 to "as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/io/luts/lut.py:1955: error: Argument 1 to "tile" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "_SupportsArray[dtype[signedinteger[_8Bit] | signedinteger[_16Bit] | signedinteger[_32Bit] | signedinteger[_64Bit] | unsignedinteger[_8Bit] | unsignedinteger[_16Bit] | unsignedinteger[_32Bit] | unsignedinteger[_64Bit]]] | _NestedSequence[_SupportsArray[dtype[signedinteger[_8Bit] | signedinteger[_16Bit] | signedinteger[_32Bit] | signedinteger[_64Bit] | unsignedinteger[_8Bit] | unsignedinteger[_16Bit] | unsignedinteger[_32Bit] | unsignedinteger[_64Bit]]]]" [arg-type]
- colour/io/luts/lut.py:1955: error: Argument 1 to "as_int_array" has incompatible type "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/colorimetry/luminance.py:536: error: Argument 1 to "xp_as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/colorimetry/lightness.py:523: error: Argument 1 to "xp_as_float_array" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/adaptation/fairchild2020.py:345: error: Argument 1 to "to_domain_1" has incompatible type "object"; expected "Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str]" [arg-type]
- colour/colorimetry/tristimulus_values.py:520: error: No overload variant of "__mul__" of "ndarray" matches argument type "object" [operator]
- colour/colorimetry/tristimulus_values.py:520: note: Possible overload variants:
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, int | numpy.bool[builtins.bool], /) -> ndarray[tuple[Any, ...], dtype[floating[Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[numpy.bool[builtins.bool]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool]]]] | builtins.bool | _NestedSequence[builtins.bool], /) -> ndarray[tuple[Any, ...], dtype[floating[Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[floating[_64Bit]]] | _NestedSequence[_SupportsArray[dtype[floating[_64Bit]]]], /) -> ndarray[tuple[Any, ...], dtype[float64]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[complexfloating[_64Bit, _64Bit]]] | _NestedSequence[_SupportsArray[dtype[complexfloating[_64Bit, _64Bit]]]], /) -> ndarray[tuple[Any, ...], dtype[complex128]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[numpy.bool[builtins.bool] | integer[Any] | floating[Any]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool] | integer[Any] | floating[Any]]]] | float | _NestedSequence[float], /) -> ndarray[tuple[Any, ...], dtype[floating[Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]] | complex | _NestedSequence[complex], /) -> ndarray[tuple[Any, ...], dtype[complexfloating[Any, Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]] | _NestedSequence[_SupportsArray[dtype[numpy.bool[builtins.bool] | number[Any, Any]]]] | complex | _NestedSequence[complex], /) -> ndarray[tuple[Any, ...], dtype[number[Any, Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[timedelta64[Any]]] | _NestedSequence[_SupportsArray[dtype[timedelta64[Any]]]], /) -> ndarray[tuple[Any, ...], dtype[timedelta64[Any]]]
- colour/colorimetry/tristimulus_values.py:520: note: def __mul__(self, _SupportsArray[dtype[object_]] | _NestedSequence[_SupportsArray[dtype[object_]]], /) -> Any
... (truncated 16 lines) ...
core (https://github.com/home-assistant/core)
- Warning: disabling incremental mode may severely reduce performance
- If this is intentional, delete '.mypy_cache' to suppress this warning
CPython (cases_generator) (https://github.com/python/cpython)
+ Tools/cases_generator/parsing.py:419: error: Redundant cast to "StackEffect | CacheEffect" [redundant-cast]
+ Tools/cases_generator/parsing.py:524: error: Redundant cast to "OpName | CacheEffect" [redundant-cast]
+ Tools/cases_generator/parsing.py:528: error: Redundant cast to "OpName | CacheEffect" [redundant-cast]
+ Tools/cases_generator/parser.py:70: error: Unused "type: ignore" comment [unused-ignore]
discord.py (https://github.com/Rapptz/discord.py)
- discord/automod.py:435: error: Argument 1 to "_unique" has incompatible type "filter[Hashable]"; expected "Iterable[GuildChannel | Thread]" [arg-type]
- discord/onboarding.py:182: error: Argument 1 to "_unique" has incompatible type "filter[Hashable]"; expected "Iterable[GuildChannel | Thread]" [arg-type]
- discord/onboarding.py:365: error: Argument 1 to "_unique" has incompatible type "filter[Hashable]"; expected "Iterable[GuildChannel | Thread]" [arg-type]
- discord/message.py:2553: error: Argument 1 to "_unique" has incompatible type "filter[Hashable]"; expected "Iterable[GuildChannel | Thread]" [arg-type]
pydantic (https://github.com/pydantic/pydantic)
- pydantic/_internal/_mock_val_ser.py:137: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator | SchemaSerializer]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
+ pydantic/_internal/_mock_val_ser.py:137: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
- pydantic/_internal/_mock_val_ser.py:178: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator | SchemaSerializer]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
+ pydantic/_internal/_mock_val_ser.py:178: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
- pydantic/_internal/_mock_val_ser.py:221: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator | SchemaSerializer]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
+ pydantic/_internal/_mock_val_ser.py:221: error: Incompatible types in assignment (expression has type "MockValSer[SchemaValidator | PluggableSchemaValidator]", variable has type "SchemaValidator | PluggableSchemaValidator") [assignment]
PyGithub (https://github.com/PyGithub/PyGithub)
+ github/Repository.py:1730: error: Unused "type: ignore" comment [unused-ignore]
+ github/Repository.py:1737: error: Unused "type: ignore" comment [unused-ignore]
+ github/Repository.py:3236: error: Unused "type: ignore" comment [unused-ignore]
+ github/Issue.py:460: error: Unused "type: ignore" comment [unused-ignore]
meson (https://github.com/mesonbuild/meson)
+ mesonbuild/backend/ninjabackend.py:2328:40: error: Incompatible types in assignment (expression has type "list[str]", variable has type "list[Program | BuildTarget | CustomTarget | CustomTargetIndex | File | str]") [assignment]
+ mesonbuild/backend/ninjabackend.py:2328:40: note: "list" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
+ mesonbuild/backend/ninjabackend.py:2328:40: note: Consider using "Sequence" instead, which is covariant
+ mesonbuild/backend/ninjabackend.py:2328:78: error: Unsupported operand types for + ("list[str]" and "list[Program | BuildTarget | CustomTarget | CustomTargetIndex | File | str]") [operator]
|
Fixes #17383 (and a significant bunch of duplicates)
This looks like an important edge case that keeps coming. And I kind of understand why, it makes common pattern
assert_not_none()practically unusable with unions.We already have special casing for
T :> A | Bavoid accidentally inferring joins from unions. Unfortunately, it doesn't work if the type variable is "squeezed between two unions", i.e. we have something likeT | A :> B | C. This is because we split the actual first in this case (and I am not sure I want to try flipping the order of the split, ~dozen tests fail if I do it naively).I propose to pro-actively reconstruct any unions that were split. To do this more reliably I remove shared items from both unions, because
T | A :> Abehaves specially (again, I am not sure I want to change this). In theory, I need to do a subtype check to make this more robust, but I am a bit worried about performance. I may need to think a bit more and/or do this later, if people will ask.Anyway, let's first see the primer here, because inference with unions is always fun.