Possible regression: incorrectly ret type detected in of __new__
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 20.6k
- Fork
- 3.3k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
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
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo l’esempio riprodotto in t.py con le versioni documentate di mypy e confronta le due diagnosi per new. Leggi il pattern analogo di pathlib.Path.new e segui l’analisi del tipo restituito per i rami cls protetti; il lavoro è completato quando l’errore relativo al valore restituito incompatibile non compare più, mentre la prima diagnosi esistente rimane invariata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100