Skip to content
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

Narrow falsey str/bytes/int to literal type #17818

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

Conversation

brianschubert
Copy link
Contributor

Closes #16891

Before

from typing import Literal

def f1(a: str) -> Literal[""]:
    return a and exit()  # E: Incompatible return value type (got "str", expected "Literal['']")

def f2(a: int) -> Literal[0]:
    return a and exit()  # E: Incompatible return value type (got "int", expected "Literal[0]")

def f3(a: bytes) -> Literal[b""]:
    return a and exit()  # E: Incompatible return value type (got "bytes", expected "Literal[b'']")

After

Success: no issues found in 1 source file

@brianschubert
Copy link
Contributor Author

This is consistent with how pyright applies narrowing: Pyright playground

This comment has been minimized.

@TeamSpen210
Copy link
Contributor

Looked through the primer results:

  • urllib3 and homeassistant: False positive, caused by accessing an attribute twice, but the attribute got modified in-between by other code. Kind of a general issue with narrowing, and having @property with side-effects.
  • packaging: True positive, detects the redundant check in if a followed by if not a and b.
  • prefect: Fixes an existing true positive, code treats "" differently to other strings and mypy is now able to understand how strings get narrowed out.
  • kornia: Same as prefect but with 0 instead.

@brianschubert
Copy link
Contributor Author

Thanks for the analysis! I agree with your assessment.

Re: the false positives from urllib3 and homeassistant, this behavior is at least consistent with pyright, which also assumes that the type of a property doesn't change between evaluations: Pyright playground

Copy link
Contributor

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

urllib3 (https://github.com/urllib3/urllib3)
+ test/test_response.py:179: error: Non-overlapping equality check (left operand type: "Literal[b'', ''] | None", right operand type: "Literal[b'foo']")  [comparison-overlap]

packaging (https://github.com/pypa/packaging)
+ src/packaging/version.py:496: error: Left operand of "and" is always true  [redundant-expr]

core (https://github.com/home-assistant/core)
+ homeassistant/components/vlc_telnet/media_player.py:181: error: Right operand of "and" is never evaluated  [unreachable]
+ homeassistant/components/vlc_telnet/media_player.py:184: error: Statement is unreachable  [unreachable]

prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/_internal/schemas/validators.py:820: error: Incompatible return value type (got "str", expected "Path")  [return-value]
+ src/prefect/_internal/schemas/validators.py:820: error: Incompatible return value type (got "Literal['']", expected "Path")  [return-value]
- src/prefect/deployments/runner.py:912: error: Item "str" of "str | DockerImage" has no attribute "reference"  [union-attr]
- src/prefect/deployments/runner.py:917: error: Item "str" of "str | DockerImage" has no attribute "build"  [union-attr]
- src/prefect/deployments/runner.py:921: error: Item "str" of "str | DockerImage" has no attribute "reference"  [union-attr]
- src/prefect/deployments/runner.py:933: error: Item "str" of "str | DockerImage" has no attribute "push"  [union-attr]
- src/prefect/deployments/runner.py:937: error: Item "str" of "str | DockerImage" has no attribute "reference"  [union-attr]
- src/prefect/deployments/runner.py:941: error: Item "str" of "str | DockerImage" has no attribute "reference"  [union-attr]

kornia (https://github.com/kornia/kornia)
+ kornia/contrib/extract_patches.py:390: error: Unused "type: ignore" comment  [unused-ignore]
+ kornia/contrib/extract_patches.py:395: error: Unused "type: ignore" comment  [unused-ignore]

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

Successfully merging this pull request may close these issues.

(🎁) narrow falsey string to Literal[""]
3 participants