Skip to content

"error: 'type' expects no type arguments, but 1 given" if type is aliased to another name #10068

Open
@johnpmcconnell

Description

@johnpmcconnell

Bug Report

With the implementation of PEP 585 in Python 3.9, type now accepts a generic parameter. This makes typing.Type obsolete, reflected in its deprecation.

However, if the type built-in is assigned to another name and then used in a type declaration, mypy produces an error.

This does not occur with other types affected by PEP 585, or at least not all of them. I can confirm list and dict do not exhibit this behavior.

To Reproduce

Example code file:

generictype.py

Type = type

class MyInt(int):
    pass

x_type: Type[int] = MyInt
  1. Install mypy into a Python 3.9 environment.
  2. Execute mypy against the script: mypy .\generictype.py. No arguments or configuration are required.

Expected Behavior

This should result in a success run with no errors:

> mypy .\generictype.py
Success: no issues found in 1 source file

Actual Behavior

mypy identifies an error:

> mypy .\generictype.py
generictype.py:3: error: "type" expects no type arguments, but 1 given
Found 1 error in 1 file (checked 1 source file)

Also note that using x_type: type[int] = MyInt directly eliminates the error.

Your Environment

  • Mypy version used: mypy 0.800
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: Python 3.9.1 (inside a venv)
  • Operating system and version: Windows 10

Motivation

My actual code doesn't look exactly like the reproducing code above. I encountered it trying to make my code backwards compatible with Python 3.7+. My real usage looks more like this:

from __future__ import annotations

if sys.version_info >= (3, 9):
    List = list
    Type = type
else:
    # Legacy generic type annotation classes
    # Deprecated in Python 3.9
    # Remove once we no longer support Python 3.8 or lower
    from typing import List
    from typing import Type

class MyCustomContext:
    data: List[int]

    def __init__(self):
        self.data = []

    def __enter__(self) -> MyCustomContext:
        return self

    def add(i: int) -> None:
        self.data.append(i)

    def __exit__(
        self,
        ex_type: Optional[Type[Exception]],
        ex_value: Optional[Exception],
        ex_traceback: Optional[TracebackType],
    ) -> None:
        if ex_value is None and len(self.data) > 100:
            raise ValueError('Too much data')

For the time being, I can work around this by just continuing to use typing.Type, but I'd like to eliminate this deprecated class.

Metadata

Metadata

Assignees

No one assigned

    Labels

    affects-typeshedAnything that blocks a typeshed changebugmypy got something wrongtopic-pep-585PEP 585 (builtin generics)topic-type-aliasTypeAlias and other type alias issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions