python / python/mypy

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

Offen
#10,068 7 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

affects-typeshed bug topic-pep-585 topic-type-alias
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Führe zunächst den gemeldeten Python-3.9-Reproducer in generictype.py mit mypy aus und bestätige den alias-spezifischen Fehler. Verfolge, wie mypy Aliase generischer Built-ins behandelt, füge dann einen Regressionstest hinzu, der Type = type abdeckt, und überprüfe, dass die Prüfung erfolgreich ist, ohne das bestehende Verhalten von list und dict zu beeinträchtigen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
48/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.