python / python/mypy

Possible regression: incorrectly ret type detected in of __new__

Offen
#11,835 2 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

new versions of mypy seem to misinterpret the return type of the __new__ method defined below

To Reproduce

# t.py
class A:
    def __new__(cls, *args, **kwargs) -> "B | C":
        if cls is A:
            cls = B
        else:
            cls = C
        return object.__new__(cls)

class B(A):
    pass

class C(A):
    pass

checking this file gives

$ mypy t.py
t_typ.py:2: error: "__new__" must return a class instance (got "Union[B, C]")
t_typ.py:7: error: Incompatible return value type (got "A", expected "Union[B, C]")
Found 2 errors in 1 file (checked 1 source file)

The first error is not new and was already discussed in https://github.com/python/mypy/issues/1020, I'm okay with it being marked as "won't fix" even though my opinion diverges.
The second error however (error: Incompatible return value type (got "A", expected "Union[B, C]")) appeared at some point after mypy 0.910 and mypy 0.920, and I believe that it is not correct.
Indeed the return type of the method is detected as A, but it is guarded against by the if/else clause above.

For reference, a pattern similar to the one I'm usin described can be found in CPython's standard library, in pathlib.Path.__new__:

    def __new__(cls, *args, **kwargs):
        if cls is Path:
            cls = WindowsPath if os.name == 'nt' else PosixPath
        self = cls._from_parts(args)
        if not self._flavour.is_supported:
            raise NotImplementedError("cannot instantiate %r on your system"
                                      % (cls.__name__,))
        return self

Expected Behavior
Only the first error should show up. None at all would be ideal in my opinion, but that seems out of line here.

Your Environment

  • Mypy version used: 0.910 and 0.930
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.10.0
  • Operating system and version: MacOS 12.0.1

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

Beginne damit, das reproduzierte Beispiel in t.py mit den dokumentierten mypy-Versionen auszuführen und die beiden Diagnosen für new zu vergleichen. Lies das analoge pathlib.Path.new-Muster und verfolge die Rückgabetypanalyse für die bewachten cls-Zweige; erledigt ist es, wenn der Fehler wegen eines inkompatiblen Rückgabewerts nicht mehr auftritt, während die bestehende erste Diagnose unverändert bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

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

Neue Issues direkt in Ihr Postfach

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