Bug Report
The first plugin that uses get_base_class_hook and returns a callback appears to take exclusive ownership of that hook, preventing other plugins from intercepting the same class definitions.
I specifically noticed this with the mypy_zope plugin which uses get_base_class_hook to analyze every class. And then writing my own custom mypy plugin where I also want to use get_base_class_hook but it wasn't getting called at all.
To Reproduce
- Setup two plugins using
get_base_class_hook. To notice the effect, they should return a callback instead of None.
mypy_plugin1.py
from typing import Callable, Optional, Type
from mypy.plugin import (
ClassDefContext,
Plugin,
)
class Plugin1(Plugin):
def get_base_class_hook(
self, fullname: str
) -> Optional[Callable[[ClassDefContext], None]]:
def _analyze_class(classdef_ctx: ClassDefContext) -> None:
print("plugin1 get_base_class_hook", fullname)
return _analyze_class
def plugin(version: str) -> Type[Plugin1]:
return Plugin1
mypy_plugin2.py
from typing import Callable, Optional, Type
from mypy.plugin import (
ClassDefContext,
Plugin,
)
class Plugin2(Plugin):
def get_base_class_hook(
self, fullname: str
) -> Optional[Callable[[ClassDefContext], None]]:
def _analyze_class(classdef_ctx: ClassDefContext) -> None:
print("plugin2 get_base_class_hook", fullname)
return _analyze_class
def plugin(version: str) -> Type[Plugin2]:
return Plugin2
- Configure mypy to use those plugins. Edit
mypy.ini and add plugins = scripts-dev/mypy_plugin1.py, scripts-dev/mypy_plugin2.py
- Lint some files,
poetry run mypy
- Notice that there is only logs from
plugin1
Expected Behavior
mypy calls get_base_class_hook in every plugin (logs for plugin1 and plugin2 show up)
Actual Behavior
plugin1 blocks other plugins from hooking into get_base_class_hook (only logs from plugin1 show up).
Your Environment
- Mypy version used:
v1.16.1
- Mypy command-line flags: (none)
- Mypy configuration options from
mypy.ini (and other config files): plugins = scripts-dev/mypy_plugin1.py, scripts-dev/mypy_plugin2.py (real-life use case)
- Python version used:
3.13.3
Bug Report
The first plugin that uses
get_base_class_hookand returns a callback appears to take exclusive ownership of that hook, preventing other plugins from intercepting the same class definitions.I specifically noticed this with the
mypy_zopeplugin which usesget_base_class_hookto analyze every class. And then writing my own custom mypy plugin where I also want to useget_base_class_hookbut it wasn't getting called at all.To Reproduce
get_base_class_hook. To notice the effect, they should return a callback instead ofNone.mypy_plugin1.pymypy_plugin2.pymypy.iniand addplugins = scripts-dev/mypy_plugin1.py, scripts-dev/mypy_plugin2.pypoetry run mypyplugin1Expected Behavior
mypycallsget_base_class_hookin every plugin (logs forplugin1andplugin2show up)Actual Behavior
plugin1blocks other plugins from hooking intoget_base_class_hook(only logs fromplugin1show up).Your Environment
v1.16.1mypy.ini(and other config files):plugins = scripts-dev/mypy_plugin1.py, scripts-dev/mypy_plugin2.py(real-life use case)3.13.3