Skip to content

Type aliases in class definitions #9238

Closed

Description

@evhub

Under MyPy 0.780, the code

from typing import List

class ABC:
    ABCInputType = List

x: ABC.ABCInputType = []

throws

test.py:6: error: Variable "test.ABC.ABCInputType" is not valid as a type
test.py:6: note: See https://mypy.readthedocs.io/en/latest/common_issues.html#variables-vs-type-aliases
Found 1 error in 1 file (checked 1 source file)

while

from typing import List

ABCInputType = List

x: ABCInputType = []

works just fine.

The use of type aliases in classes seems both like a pretty legitimate use case to me (consider for example the ability to have an input type for the class as an attribute of the class as above) and also seems consistent with both the typing documentation and mypy's documentation, neither of which seem to mention that type aliases can only appear at the top level (only that they need to be plain assignments, as they are in the above code).

Activity

  1. ilevkivskyi commented on Aug 3, 2020

    @ilevkivskyi
    Member

    Yeah that doc section you linked is incomplete. The PR that added it closed the relevant issue but didn't address all points, in particular the special case about plain names at class scope creating variables.

    cc @TH3CHARLie

    Btw the fix is simply to use:

    class ABC:
        ABCInputType = List[Any]
  2. evhub commented on Aug 3, 2020

    @evhub
    ContributorAuthor

    Btw the fix is simply to use:

    What causes List[Any] to work there but List to fail? Shouldn't those be identical? And is there any equivalent of this fix that works for the more generic case where I just want some alias?

  3. ilevkivskyi commented on Aug 3, 2020

    @ilevkivskyi
    Member

    And is there any equivalent of this fix that works for the more generic case where I just want some alias?

    A trick that should work if you want to force type alias for plain name at class scope is use a single element union.

  4. TH3CHARLie commented on Aug 3, 2020

    @TH3CHARLie
    Collaborator

    Yeah that doc section you linked is incomplete. The PR that added it closed the relevant issue but didn't address all points, in particular the special case about plain names at class scope creating variables.

    cc @TH3CHARLie

    Btw the fix is simply to use:

    class ABC:
        ABCInputType = List[Any]

    I did recall that when doing the docs PR we did mention about the alias should appear at top level but somehow I must have forgotten to include that in the final version. I'll file a PR to fix that.

  5. tmke8 commented on Apr 5, 2022

    @tmke8
    Contributor

    The problem as stated in the issue above is solved now with PEP 613:

    from typing import List, TypeAlias
    
    class ABC:
        ABCInputType: TypeAlias = List
    
    x: ABC.ABCInputType = []

    -> no errors

    However, this does not work in dataclasses (or any dataclass-like class), where you have to use ClassVar to exclude the variable from being used

    from dataclasses import dataclass
    from typing import ClassVar, List, TypeAlias
    
    @dataclass
    class ABC:
        ABCInputType: ClassVar[TypeAlias] = List
    
    x: ABC.ABCInputType = []
    reveal_type(x)  # Revealed type is "Any"

    There's no error in mypy 0.942, but it thinks the type of x is Any.

  6. AlexWaygood commented on Apr 5, 2022

    @AlexWaygood
    Member

    The problem as stated in the issue above is solved now with PEP 613

    Thanks! I'm closing this now since the original issue is now solved for most cases. Please feel free to open a new issue for the dataclasses- specific issue.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions