Multiple extensions using `get_base_class_hook` interfere with each other
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
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 ofNone.
mypy_plugin1.pyfrom 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 Plugin1mypy_plugin2.pyfrom 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.iniand addplugins = 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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the behavior with mypy_plugin1.py and mypy_plugin2.py, configured through mypy.ini, and run poetry run mypy. Read the get_base_class_hook documentation and trace how the configured plugins are queried; done means both plugins' callbacks are invoked for the same class definitions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100