mypy sometimes confuses nested classes-in-functions which share the same name

未关闭
#17,047 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
python

调研方向

使用 mypy 1.9.0 重现最小示例,并与 0.800 进行比较,然后检查二分定位得到的 commit 以及它修改的语义分析文件,尤其是 mypy/semanal.py。从提到的测试位置 test-data/unit/check-incremental.test 开始;当两个分别处于不同作用域的 SomeClass 定义不再产生 incompatible-assignment 错误时即表示完成。

由索引模型根据 Issue 内容生成。

描述

bug

Bug Report

In some circumstances, mypy will confuse two classes of the same name, even if they're declared in non-overlapping scopes.

To Reproduce

Check the following ~minimal example with mypy:

[mypy-play.net]

# from __future__ import annotations  # with or without makes no difference

def test_a() -> None:

    class SomeClass:  # line 5
        def some_method(self) -> None:
            _ = some_var  # line 7

    some_var = None  # not necessary for repro; stops error on line 7

def test_b() -> None:

    instance: SomeClass

    class SomeClass:  # line 15
        pass

    instance = SomeClass()
            # error: Incompatible types in assignment (expression
            #        has type "SomeClass@15", variable has type
            #        "SomeClass@5")  [assignment]

Expected Behavior

No errors.

Actual Behavior

The tool confuses the two classes of the same name (SomeClass), despite these being declared in entirely different scopes.

Bisection

The problem appears to have been introduced by https://github.com/python/mypy/commit/389a1725c1df7fad4e2605360157c9f910cb502c (which made its way into mypy 0.900):

389a1725c1df7fad4e2605360157c9f910cb502c is the first bad commit
commit 389a1725c1df7fad4e2605360157c9f910cb502c
Author: Jukka Lehtosalo <jukka.lehtosalo@iki.fi>
Date:   Thu May 6 14:32:36 2021 +0100

    Fix crash with nested NamedTuple in incremental mode (#10431)

    The name of the nested tuple type was inconsistent. Sometimes if was stored
    using the full name in the module symbol table.

    Also improve the internal API for creating classes to be less error-prone.

    Work on #7281.

 mypy/semanal.py                       | 10 +++++++---
 mypy/semanal_enum.py                  |  9 +++++----
 mypy/semanal_namedtuple.py            |  2 +-
 mypy/semanal_newtype.py               | 11 ++++++-----
 mypy/semanal_shared.py                |  2 +-
 mypy/semanal_typeddict.py             | 14 ++++++++------
 test-data/unit/check-incremental.test | 26 ++++++++++++++++++++++++++
 7 files changed, 54 insertions(+), 20 deletions(-)

Probably relates to #7281, #10431.

Your Environment

  • Mypy version used: 1.9.0, 0.900, but not 0.800 (see: "bisection")
  • Mypy command-line flags: none necessary
  • Mypy configuration options from mypy.ini (and other config files): none necessary
  • Python version used: 3.8, 3.12
主要语言
Python
星标
20.6k
派生
3.3k
平均合并
1 天 18 小时
30 天内合并 PR
54

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

python/mypy 的其他 Issue

查看 python/mypy 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。