python / python/mypy

Using `Never` as return type for `__new__` results in classmethods not being recognised. Inferred type for class is `Callable[[], NoReturn]`.

Offen
#16,981 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

If the classmethod __new__ of a class is marked as returning Never, Mypy does not recognise the existence of attributes for the class (whose type it believes to be Callable[[], NoReturn]).

To Reproduce

from typing import Never, Self

class A:
    x: int

    @classmethod
    def _new(cls, x: int) -> Self:
        instance = super().__new__(cls)
        instance.x = x
        return instance

    def __new__(cls) -> Never:
        raise TypeError("Class 'A' should not be instanced directly.")

a = A._new(10) # Mypy Error: attr-defined
# "Callable[[], NoReturn]" has no attribute "_new"

Gist URL: https://gist.github.com/mypy-play/b40fec12cb83d7683c6832320aecc4d8
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=b40fec12cb83d7683c6832320aecc4d8

from typing import ClassVar, Never

class A:
    attr: ClassVar[int] = 20

    def __new__(cls) -> Never:
        raise TypeError("Class 'A' should not be instanced directly.")

a = A.attr # Mypy Error: attr-defined
# "Callable[[], NoReturn]" has no attribute "attr"

Gist URL: https://gist.github.com/mypy-play/46b45241159045b55d7dfd9d871280f1
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=46b45241159045b55d7dfd9d871280f1

Expected Behavior

I expect Mypy to recognise that the classmethod A._new() can be called to produce an instance of A, or that A has a class attribute attr.

Actual Behavior

Mypy does not recognise that classmethod A._new() exists, nor that the class attribute A.attr exists.

Your Environment

  • Mypy version used: 1.7.1 (checked with 1.8.0 on playground)
  • Mypy command-line flags: --strict
  • Python version used: 3.12

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

Reproduziere beide Beispiele aus dem Issue mit mypy 1.8.0 oder höher, unter Verwendung von --strict und Python 3.12, und vergleiche sie mit den verlinkten Playgrounds. Verfolge die Behandlung einer Klasse, deren new Never zurückgibt; als erledigt gilt die Aufgabe, wenn A._new() und A.attr ohne attr-defined-Fehler erkannt werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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