|
| 1 | +"""Shim to load the marshmallow_dataclass.mypy plugin. |
| 2 | +
|
| 3 | +This shim is needed when running mypy from pre-commit. |
| 4 | +
|
| 5 | +Pre-commit runs mypy from its own venv (into which we do not want |
| 6 | +to install marshmallow_dataclass). Because of this, loading the plugin |
| 7 | +by module name, e.g. |
| 8 | +
|
| 9 | + [tool.mypy] |
| 10 | + plugins = "marshmallow_dataclass.mypy" |
| 11 | +
|
| 12 | +does not work. Mypy also supports specifying a path to the plugin |
| 13 | +module source, which would normally get us out of this bind, however, |
| 14 | +the fact that our plugin is in a file named "mypy.py" causes issues. |
| 15 | +
|
| 16 | +If we set |
| 17 | +
|
| 18 | + [tool.mypy] |
| 19 | + plugins = "marshmallow_dataclass/mypy.py" |
| 20 | +
|
| 21 | +mypy `attempts to load`__ the plugin module by temporarily prepending |
| 22 | + ``marshmallow_dataclass`` to ``sys.path`` then importing the ``mypy`` |
| 23 | +module. Sadly, mypy's ``mypy`` module has already been imported, |
| 24 | +so this doesn't end well. |
| 25 | +
|
| 26 | +__ https://github.com/python/mypy/blob/914901f14e0e6223077a8433388c367138717451/mypy/build.py#L450 |
| 27 | +
|
| 28 | +
|
| 29 | +Our solution, here, is to manually load the plugin module (with a better |
| 30 | +``sys.path``, and import the ``plugin`` from the real plugin module into this one. |
| 31 | +
|
| 32 | +Now we can configure mypy to load this file, by path. |
| 33 | +
|
| 34 | + [tool.mypy] |
| 35 | + plugins = "mypy_plugin.py" |
| 36 | +
|
| 37 | +""" |
| 38 | +import importlib |
| 39 | +import sys |
| 40 | +from os import fspath |
| 41 | +from pathlib import Path |
| 42 | + |
| 43 | +src = fspath(Path(__file__).parent) |
| 44 | +sys.path.insert(0, src) |
| 45 | +plugin_module = importlib.import_module("marshmallow_dataclass.mypy") |
| 46 | +del sys.path[0] |
| 47 | + |
| 48 | +plugin = plugin_module.plugin |
0 commit comments