Skip to content

Improve the support for promotions inside unions. #19245

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

tyralla
Copy link
Collaborator

@tyralla tyralla commented Jun 6, 2025

Fixes #14987

I was puzzled as to why my previous attempts to avoid false unreachable warnings for loops failed for issue #14987. After some debugging, I realised that the underlying problem is that type narrowing does not work with promotions if both the declared type and the constraining type are unions:

x: float | None
y: int | None
x = y
reveal_type(x)  #  None !!!

The fix seems straightforward (but let's see what the Mypy primer says) and is checked by the test cases testNarrowPromotionsInsideUnions1 and testNarrowPromotionsInsideUnions2.

This comment has been minimized.

@tyralla
Copy link
Collaborator Author

tyralla commented Jun 6, 2025

The test suite currently fails due to a previous merge conflict that will be resolved by #19118.

The Mypy primer differences are only due to different union item orders.

@ilevkivskyi: Would you like to review this simple change? It is a small extension of one of your code sections.

@tyralla tyralla requested a review from ilevkivskyi June 6, 2025 22:52
Copy link
Contributor

github-actions bot commented Jun 7, 2025

Diff from mypy_primer, showing the effect of this PR on open source code:

ibis (https://github.com/ibis-project/ibis)
- ibis/backends/mssql/__init__.py:702: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/mssql/__init__.py:702: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/mssql/__init__.py:749: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]"; expected "Schema"  [arg-type]
+ ibis/backends/mssql/__init__.py:702: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/mssql/__init__.py:702: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/mssql/__init__.py:749: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any"; expected "Schema"  [arg-type]
- ibis/backends/databricks/__init__.py:215: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | None" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/databricks/__init__.py:215: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | None" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/databricks/__init__.py:215: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any | None" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/databricks/__init__.py:215: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any | None" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/databricks/__init__.py:215: error: Item "None" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | None" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/databricks/__init__.py:215: error: Item "None" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any | None" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/risingwave/__init__.py:573: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/risingwave/__init__.py:573: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/risingwave/__init__.py:611: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]"; expected "Schema"  [arg-type]
+ ibis/backends/risingwave/__init__.py:573: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/risingwave/__init__.py:573: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/risingwave/__init__.py:611: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any"; expected "Schema"  [arg-type]
- ibis/backends/postgres/__init__.py:655: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/postgres/__init__.py:655: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/postgres/__init__.py:687: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]"; expected "Schema"  [arg-type]
+ ibis/backends/postgres/__init__.py:655: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/postgres/__init__.py:655: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/postgres/__init__.py:687: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any"; expected "Schema"  [arg-type]
- ibis/backends/mysql/__init__.py:432: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/mysql/__init__.py:432: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/mysql/__init__.py:459: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]"; expected "Schema"  [arg-type]
+ ibis/backends/mysql/__init__.py:432: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/mysql/__init__.py:432: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/mysql/__init__.py:459: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any"; expected "Schema"  [arg-type]
- ibis/backends/exasol/__init__.py:395: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/exasol/__init__.py:395: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/exasol/__init__.py:420: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]"; expected "Schema"  [arg-type]
+ ibis/backends/exasol/__init__.py:395: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/exasol/__init__.py:395: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/exasol/__init__.py:420: error: Argument "schema" to "DatabaseTable" has incompatible type "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any"; expected "Schema"  [arg-type]
- ibis/backends/duckdb/__init__.py:177: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "null_fields"  [union-attr]
- ibis/backends/duckdb/__init__.py:177: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "null_fields"  [union-attr]
- ibis/backends/duckdb/__init__.py:190: error: Item "Mapping[str, str | DataType]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
- ibis/backends/duckdb/__init__.py:190: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Any | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]]" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/duckdb/__init__.py:177: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "null_fields"  [union-attr]
+ ibis/backends/duckdb/__init__.py:177: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "null_fields"  [union-attr]
+ ibis/backends/duckdb/__init__.py:190: error: Item "Mapping[str, str | DataType]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]
+ ibis/backends/duckdb/__init__.py:190: error: Item "Iterable[tuple[str, str | DataType]]" of "Schema | Mapping[str, str | DataType] | Iterable[tuple[str, str | DataType]] | Any" has no attribute "to_sqlglot"  [union-attr]

narrow_declared_type(x, narrowed)
for x in declared.relevant_items()
narrow_declared_type(d, n)
for d, n in product(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like the correct way of doing that, despite higher comp complexity. What's more mypyc-friendly - itertools.product or a plain listcomp with two for clauses?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

False positive unreachable when variable is set and reset inside loop
2 participants