python / python/mypy

Mypy not detecting abstract methods returning undefined types

Open
#14,545 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug topic-runtime-semantics
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

Bug Report

I have a class with a couple of abstract methods that return a particular custom type. That custom type is then defined right after the class. Then a global variable referencing that class is created:

To Reproduce

# test.py
from abc import ABC, abstractmethod
from typing import NamedTuple, List

class F(ABC):
    @abstractmethod
    async def m1(self) -> Result:
        pass
    
    @abstractmethod
    async def m2(self) -> Result:
        pass

class Result(NamedTuple):
    f1: str
    f2: int
    
foo: List[F] = []
> mypy --strict test.py
Success: no issues found in 1 source file
> python test.py
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    class F(ABC):
  File "test.py", line 6, in F
    async def m1(self) -> Result:
NameError: name 'Result' is not defined

Expected Behavior

I would expect mypy to detect that Result is not defined before its use in class F.

Actual Behavior

Mypy is happy with the code as it is, even under --strict, while Python can't even run the code as is. Moving the declaration of Result above class F solves the problem and both Python and mypy are then happy.

Your Environment

  • Mypy version used: 0.991
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.9.13

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the behavior from test.py by running mypy --strict and then Python to compare the static result with the runtime NameError. Trace how mypy analyzes the abstract method return annotations before Result is declared. Done means mypy reports the undefined Result reference in this case without breaking valid annotations.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.