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

False negative: Incorrect return type overlooked when it is an alias to Union[T, …] #15803

Closed
lukasjuhrich opened this issue Aug 2, 2023 · 1 comment
Labels
bug mypy got something wrong

Comments

@lukasjuhrich
Copy link

lukasjuhrich commented Aug 2, 2023

Bug Report

This may be related to #12211.
When extracting a type annotation like -> t.AnyStr | int to a t.Union alias, mypy fail to detect incorrect return types.

The actual problem for me was that annotating flask view functions with ResponseValueType did not find obvious return type violations, but (as I found out during writing of this issue) a workaround seems to have been added.

I'm unsure what to expect of mypy here but silently allowing everything seems like a big hazard to me.

To Reproduce
See the functions foo2 and bar2 in the following gist:
https://mypy-play.net/?mypy=latest&python=3.11&gist=04f598b90124f58021cf19209a7df967.

Expected Behavior

the return statements of foo2 and bar2 should cause an error, either the same error as foo and bar or the same as foo3 and bar3.

Actual Behavior

foo2 and bar2 don't cause an error

Your Environment

  • Mypy version used: 1.4.1
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11
@lukasjuhrich lukasjuhrich added the bug mypy got something wrong label Aug 2, 2023
lukasjuhrich added a commit to agdsn/pycroft that referenced this issue Aug 2, 2023
@erictraut
Copy link

I think mypy is doing the right thing here. You're using type variables incorrectly. AnyStr is a type variable. It is not equivalent to str | bytes.

The signature def foo() -> AnyStr | int is using the type variable AnyStr incorrectly because it appears only once in the signature. You probably mean def foo() -> str | bytes | int in this case.

The statement R = t.Union[t.AnyStr, int] defines a type alias R that is generic and accepts a single type argument. A proper use of R would be R[bytes] or R[str]. If you don't specify the type argument, a type checker will fill in Any, so the union effectively becomes Any | int.

The same logic applies to your other examples that use type variable T.

In general, if a type variable appears only once within a function signature, you are using the type variable incorrectly.

lukasjuhrich added a commit to agdsn/pycroft that referenced this issue Aug 10, 2023
lukasjuhrich added a commit to agdsn/pycroft that referenced this issue Aug 11, 2023
lukasjuhrich added a commit to agdsn/pycroft that referenced this issue Aug 11, 2023
lukasjuhrich added a commit to agdsn/pycroft that referenced this issue Aug 11, 2023
@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

3 participants