python / python/mypy

Differed Protocol / runtime_checkable import inconsistently causes incompatible type error

Aperta
#10,851 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Merge medio
1g 18h
PR unite (30g)
54

Descrizione

Bug Report

An incompatible type error is raised for compatible types when Protocol & runtime_checkable are imported via a helper module (see # Option A: Via Helper), but not when they are imported within the module (see # Option B: Directly). Elsewhere in the codebase, importing via the helper module results in the expected behaviour.

Raises: error: Argument 1 to "handle" of "Interpreter" has incompatible type "ComposedAdapter"; expected "Adapter"

To Reproduce

# Option A: Via helper
from tickit.core.utils.compat.typing_compat import Protocol, runtime_checkable
# Option B: Directly
import sys

if sys.version_info >= (3, 8):
    from typing import Protocol, runtime_checkable
else:
    from typing_extensions import Protocol, runtime_checkable
@runtime_checkable
class Adapter(Protocol):
    interrupt: bool

    def __init__(self, device: Device) -> None:
        ...

    async def run_forever(self) -> None:
        ...

class ComposedAdapter:
    _interpreter: Interpreter
    _server: Server
    interrupt: bool = False

    def __init__(self, device: Device) -> None:
        assert isinstance(self._interpreter, Interpreter)
        assert isinstance(self._server, Server)
        self._device = device

    async def run_forever(self) -> None:
        async for interrupt in self._server.run_forever(
            lambda message: self._interpreter.handle(self, message) # Error raised here
        ):
            self.interrupt |= interrupt

Where tickit.utils.compat.typing_compat is implemented as:

import sys

if sys.version_info >= (3, 8):
    from typing import Protocol, runtime_checkable
else:
    from typing_extensions import Protocol, runtime_checkable

__all__ = ["Protocol", "runtime_checkable"]

Expected Behavior

No error is raised when importing via the helper module & behaviour is consistent across the codebase.

Actual Behavior

An error is raised when importing via the helper module.

Your Environment

  • Mypy version used: 0.910
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): ignore_missing_imports = True
  • Python version used: 3.7.9, 3.9.5
  • Operating system and version: Red Hat Enterprise Linux release 8.4 (Ootpa)

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Riproduci l’errore di tipo incompatibile utilizzando l’importazione helper da tickit.core.utils.compat.typing_compat e confrontalo con le importazioni dirette da typing o typing_extensions mostrate nel report. Traccia il modo in cui mypy gestisce Protocol e runtime_checkable attraverso il modulo helper, quindi verifica che entrambi gli stili di importazione producano un comportamento coerente nel controllo dei tipi per l’esempio con Adapter e ComposedAdapter.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.