Skip to content

TypeVar bound is ignored in generic alias #10445

Closed
@JelleZijlstra

Description

@JelleZijlstra
Member

Bug Report

A generic alias using a TypeVar with a bound allows type arguments that don't match the bound

To Reproduce

% cat tvbound.py 
import typing

FooT = typing.TypeVar("FooT", bound=str)
FooIsh = typing.Union[int, FooT]

bat2: FooIsh[float] = 1.0

% mypy tvbound.py
Success: no issues found in 1 source file
% mypy --version
mypy 0.820+dev.e8afde621531880c2b9c51acba8e565a29cde0b1

Expected Behavior

I would expect an error saying that the value of FooT cannot be float.

Found this as a result of microsoft/pyright#1839.

Activity

UnquietCode

UnquietCode commented on Nov 1, 2021

@UnquietCode

I would like to mention that using mypy 0.91 I see a more general version of this error where the resolved GenericAlias isn't type checked at all regardless of the bound on the TypeVar. That is:

FooT = typing.TypeVar("FooT")
FooIsh = typing.Union[int, FooT]

bat2: FooIsh[float] = "passes"

fails to report an error.

AlexWaygood

AlexWaygood commented on Jul 7, 2022

@AlexWaygood
Member

I just closed #13086 as a duplicate of this issue, but @harahu notes in that issue that this bug is also present for generic type aliases that use constrained TypeVars (as well as those that use bound TypeVars):

from typing import Generic, TypeVar, TypeAlias

U = TypeVar("U", bytes, str)
RestrictedTuple: TypeAlias = tuple[U]
i_am_illegal: RestrictedTuple[int]  # Passes, even though this type shouldn't be possible!
added a commit that references this issue on Nov 24, 2022
13bd201
harahu

harahu commented on Nov 24, 2022

@harahu

@ilevkivskyi Are you sure this should be closed? I just made a minimal playground example out of the issue I pointed out in #13086, that @AlexWaygood mentioned above:

https://mypy-play.net/?mypy=master&python=3.11&flags=strict&gist=b251ba96b0e4c9632c8ba162f81280e8

This example still fails when run with mypy from the master branch.

AlexWaygood

AlexWaygood commented on Nov 24, 2022

@AlexWaygood
Member

@harahu, if I run mypy with the master branch checked out locally on this snippet:

import typing

FooT = typing.TypeVar("FooT", bound=str)
FooIsh = typing.Union[int, FooT]
bat: FooIsh[float] = 1.0

FooT2 = typing.TypeVar("FooT2")
FooIsh2 = typing.Union[int, FooT]
bat2: FooIsh[float] = "fails"

U = typing.TypeVar("U", bytes, str)
RestrictedTuple: typing.TypeAlias = tuple[U]
i_am_illegal: RestrictedTuple[int]

Then this is the output:

test.py:5: error: Type argument "float" of "FooIsh" must be a subtype of "str"  [type-var]
test.py:9: error: Incompatible types in assignment (expression has type "str", variable has type "Union[int, float]")  [assignment]
test.py:13: error: Value of type variable "U" of "RestrictedTuple" cannot be "int"  [type-var]
Found 3 errors in 1 file (checked 1 source file)

This seems like the correct output to me; I think it was correct for this issue to be closed.

The "run mypy with the master branch" option on mypy playground is often quite out of sync with what mypy's actual master branch is, unfortunately. (I sort-of think having that option is not particularly helpful if it's not going to be automatically synced with mypy's latest commit). Note that mypy playground isn't run by mypy; it's a third-party project that you can report issues to here: https://github.com/ymyzk/mypy-playground.

harahu

harahu commented on Nov 24, 2022

@harahu

I see. You correctly pointed out where I was mistaken. I assumed playground was up to date. Sorry about the confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @UnquietCode@JelleZijlstra@harahu@AlexWaygood

      Issue actions

        TypeVar bound is ignored in generic alias · Issue #10445 · python/mypy