`SymbolTableNode.kind` is incorrect for `from <module> import <name>` imports in a function body
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Python
- Estrellas
- 20.6k
- Forks
- 3.3k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
Bug Report, Expected Behaviour, & Actual Behaviour
I'm writing a mypy plugin which needs to distinguish between the origin of variables (whether they're from the global scope or local scope). When analysing names from ImportFrom nodes, the kind value appears to be incorrect:
# module.py
import typing as t
TypeT = t.TypeVar("TypeT", bound=type[object])
def reveal_name_expr_kinds(Class: TypeT, /) -> TypeT:
return Class
@reveal_name_expr_kinds
class A:
def method(self, /) -> None:
import os
from os import chdir, path
x = 1
# Correct behaviour
os # N: Revealed kind is "Ldef"
x # N: Revealed kind is "Ldef"
# Correct behaviour
t # N: Revealed kind is "Gdef"
TypeT # N: Revealed kind is "Gdef"
# Incorrect behaviour (expected both of these to be "Ldef")
chdir # N: Revealed kind is "Gdef"
path # N: Revealed kind is "Gdef"
Potential fix
I believe the issue is here: https://github.com/python/mypy/blob/e9a813c32637e0c9eb1c6cff6426dab504d9656d/mypy/semanal.py#L2853
Changing it to the following seems to fix the problem:
node = module.names.get(id)
+ if node is not None:
+ node = SymbolTableNode(self.current_symbol_kind(), node.node)
However, It's not obvious how to write a test for this. I'm looking at https://github.com/python/mypy/blob/master/test-data/unit/semanal-symtable.test but the tests here rely on str()ingifying a mypy.nodes.SymbolTable object, which is an attribute of mypy.nodes.MypyFile and mypy.nodes.TypeInfo; there is no equivalent attribute in mypy.nodes.FuncDef (function body symbol tables only temporarily exist at https://github.com/python/mypy/blob/e9a813c32637e0c9eb1c6cff6426dab504d9656d/mypy/semanal.py#L444-L446).
Is there is an obvious way to test the local definition kinds directly (that is, without employing a mypy plugin into the tests)?
To Reproduce
Along with module.py above, put the following files in any directory, navigate inside the directory, and just run mypy in the command line:
# mypy.ini
[mypy]
plugins = plugin.py
files = module.py
# plugin.py
from __future__ import annotations
import typing as t
import mypy.nodes
import mypy.plugin
import mypy.server.subexpr
if t.TYPE_CHECKING:
import collections.abc as cx
STR_REVEAL_KINDS_DECO_NAME: t.Final = "reveal_name_expr_kinds"
def plugin(version: str) -> type[mypy.plugin.Plugin]:
return SymbolKindRevealer
class SymbolKindRevealer(mypy.plugin.Plugin):
def get_class_decorator_hook_2(
self, fullname: str
) -> cx.Callable[[mypy.plugin.ClassDefContext], bool] | None:
if fullname.endswith(f".{STR_REVEAL_KINDS_DECO_NAME}"):
return _reveal_symbol_kinds
def _reveal_symbol_kinds(ctx: mypy.plugin.ClassDefContext, /) -> bool:
expr_finder: t.Final = mypy.server.subexpr.SubexpressionFinder()
for cls_stmt in ctx.cls.defs.body:
if isinstance(cls_stmt, mypy.nodes.FuncDef):
for func_stmt in cls_stmt.body.body:
func_stmt.accept(expr_finder)
for expr in expr_finder.expressions:
if isinstance(expr, mypy.nodes.NameExpr) and (expr.kind is not None):
ctx.api.msg.note(
f'Revealed kind is "{mypy.nodes.node_kinds[expr.kind]}"', expr
)
return True
Your Environment
- Mypy version used: 1.15
- Python version used: 3.9
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza en mypy/semanal.py, alrededor del manejo de ImportFrom en la línea 2853, y compáralo con la construcción de SymbolTableNode indicada. Revisa test-data/unit/semanal-symtable.test y test/testsemanal.py; después, usa la reproducción proporcionada del plugin para confirmar que las importaciones en el cuerpo de una función informan de Ldef y determinar cómo cubrir este comportamiento en las pruebas.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- python
- Área
- compilers, devtools
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 45/100