diff --git a/ChangeLog b/ChangeLog index 0eec5468c1..457e50a299 100644 --- a/ChangeLog +++ b/ChangeLog @@ -13,6 +13,8 @@ Release date: TBA Closes #1512 +* Allowed ``AstroidManager.clear_cache`` to reload necessary brain plugins. + * Rename ``ModuleSpec`` -> ``module_type`` constructor parameter to match attribute name and improve typing. Use ``type`` instead. diff --git a/astroid/manager.py b/astroid/manager.py index 4466279ce8..f1f5336d58 100644 --- a/astroid/manager.py +++ b/astroid/manager.py @@ -10,6 +10,7 @@ import os import types import zipimport +from importlib.util import find_spec, module_from_spec from typing import TYPE_CHECKING, ClassVar, List, Optional from astroid.exceptions import AstroidBuildingError, AstroidImportError @@ -362,5 +363,17 @@ def bootstrap(self): def clear_cache(self): """Clear the underlying cache. Also bootstraps the builtins module.""" + # import here because of cyclic imports + # pylint: disable=import-outside-toplevel + + from astroid import BRAIN_MODULES_DIRECTORY + self.astroid_cache.clear() self.bootstrap() + + # Load brain plugins: currently done in astroid.__init__.py + for module in BRAIN_MODULES_DIRECTORY.iterdir(): + if module.suffix == ".py": + spec = find_spec(f"astroid.brain.{module.stem}") + module_object = module_from_spec(spec) + spec.loader.exec_module(module_object) diff --git a/tests/unittest_manager.py b/tests/unittest_manager.py index 4785975692..6f0a7b16f4 100644 --- a/tests/unittest_manager.py +++ b/tests/unittest_manager.py @@ -16,6 +16,7 @@ from astroid import manager, test_utils from astroid.const import IS_JYTHON from astroid.exceptions import AstroidBuildingError, AstroidImportError +from astroid.nodes import Const from . import resources @@ -315,5 +316,13 @@ def test_borg(self) -> None: self.assertIs(built, second_built) +class ClearCacheTest(unittest.TestCase, resources.AstroidCacheSetupMixin): + def test_brain_plugins_reloaded_after_clearing_cache(self) -> None: + astroid.MANAGER.clear_cache() + format_call = astroid.extract_node("''.format()") + inferred = next(format_call.infer()) + self.assertIsInstance(inferred, Const) + + if __name__ == "__main__": unittest.main()