Skip to content

Mypy does not check bounds of variable type aliases #13086

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

Closed
harahu opened this issue Jul 7, 2022 · 5 comments
Closed

Mypy does not check bounds of variable type aliases #13086

harahu opened this issue Jul 7, 2022 · 5 comments
Labels
bug mypy got something wrong topic-type-alias TypeAlias and other type alias issues topic-type-variables

Comments

@harahu
Copy link

harahu commented Jul 7, 2022

Bug Report

When having defined a TypeAlias dependent on a TypeVar, mypy does not allays that instances of these are actually allowed. That is, that they respect the bounds or restrictions of the used TypeVar. This is in contrast to the behavior for generic types, which are checked.

To Reproduce

from typing import Generic, TypeVar, TypeAlias

T = TypeVar("T", bound=bytes | str)
U = TypeVar("U", bytes, str)

BoundedTuple: TypeAlias = tuple[T]
RestrictedTuple: TypeAlias = tuple[U]


i_am_illegal1: BoundedTuple[int]  # Passes, even though this type shouldn't be possible!
i_am_illegal2: RestrictedTuple[int]  # Passes, even though this type shouldn't be possible!


class Bounded(Generic[T]):
    pass
    
class Restricted(Generic[U]):
    pass


i_am_illegal3: Bounded[int]  # Behaves as expected, resulting in `error: Type argument "int" of "Bounded" must be a subtype of "Union[bytes, str]"`
i_am_illegal4: Restricted[int]  # Behaves as expected, resulting in `error: Value of type variable "U" of "Restricted" cannot be "int"`

https://mypy-play.net/?mypy=latest&python=3.10&flags=strict&gist=f5763650eba54f25b51553dbdd58179f

Expected Behavior

I expect four errors instead of two from the example code above.

Actual Behavior

As can be seen, I was allowed to define types that shouldn't be allowed, given the restrictions of the type variables in use.

Your Environment

  • Mypy version used: 0.961
  • Mypy command-line flags: --strict
  • Python version used: 3.10
@harahu harahu added the bug mypy got something wrong label Jul 7, 2022
@AlexWaygood
Copy link
Member

According to PEP 484, if T = TypeVar("T", bound=complex | str), T can be solved as being int where necessary, since PEP 484 states that type checkers should consider int and float to be implicit subtypes of complex. In "The Numeric Tower", the PEP states:

when an argument is annotated as having type float, an argument of type int is acceptable; similar, for an argument annotated as having type complex, arguments of type float or int are acceptable.

This explains why mypy does not emit an error for your first and third example.

Your second example does seem to be buggy to me, however. Constrained TypeVars should only be solveable with one of the exact constraints, i.e., subtypes should not be permitted. So I believe you're correct when you say that mypy should be emitting an error for the following:

from typing import Generic, TypeVar, TypeAlias

U = TypeVar("U", complex, str)
BoundTupleU: TypeAlias = tuple[U]
i_am_illegal2: BoundTupleU[int]

@harahu harahu changed the title Mypy does not check bounds of all generic types Mypy does not check bounds of variable type aliases Jul 7, 2022
@harahu
Copy link
Author

harahu commented Jul 7, 2022

[...] This explains why mypy does not emit an error for your first and third example.

Good catch! Appreciate it. Changed the example, but the first example also remains faulty, so it seems this is an issue for variable type aliases, but not for generics. Please let me know whether the issue is worded more clearly (and correctly) now.

@AlexWaygood
Copy link
Member

AlexWaygood commented Jul 7, 2022

Oh yikes — yup, your revised first example definitely looks like a bug to me!

@AlexWaygood AlexWaygood added topic-type-variables topic-type-alias TypeAlias and other type alias issues labels Jul 7, 2022
@AlexWaygood
Copy link
Member

Oh yikes — yup, your revised first example definitely looks like a bug to me!

... But it's a duplicate of #10445. Your example using the constrained TypeVar is new, but I'm closing this so that we can keep all the discussion in one place, since it's the same bug :)

@AlexWaygood AlexWaygood closed this as not planned Won't fix, can't repro, duplicate, stale Jul 7, 2022
@harahu
Copy link
Author

harahu commented Jul 7, 2022

... But it's a duplicate of #10445. Your example using the constrained TypeVar is new, but I'm closing this so that we can keep all the discussion in one place, since it's the same bug :)

Thank you for noticing! Not sure how that issue slipped past me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-type-alias TypeAlias and other type alias issues topic-type-variables
Projects
None yet
Development

No branches or pull requests

2 participants