From 7b2b8e5466b1ccd5bf509f5ba92f114de4d434cd Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Wed, 17 Oct 2018 18:51:49 +0300 Subject: [PATCH] PY-32005 Importing matplotlib 3.0.0 crashes Python Console Wait for full pyplot import to get access to `matplotlib.rcParams` attribute, which was changed in version 3 --- .../pydev/_pydev_bundle/pydev_import_hook.py | 7 +++++-- .../helpers/pydev/pydev_ipython/matplotlibtools.py | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py b/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py index e393b09367ec..4e144e482f7e 100644 --- a/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py +++ b/python/helpers/pydev/_pydev_bundle/pydev_import_hook.py @@ -8,6 +8,7 @@ class ImportHookManager(ModuleType): ModuleType.__init__(self, name) self._system_import = system_import self._modules_to_patch = {} + self.inside_activation = False def add_module_name(self, module_name, activate_function): self._modules_to_patch[module_name] = activate_function @@ -19,11 +20,13 @@ class ImportHookManager(ModuleType): module = self._system_import(name, *args, **kwargs) try: - if activate_func: + if activate_func and not self.inside_activation: + self.inside_activation = True succeeded = activate_func() if succeeded and name in self._modules_to_patch: # Remove if only it was executed correctly self._modules_to_patch.pop(name) + self.inside_activation = False except: sys.stderr.write("Matplotlib support failed\n") traceback.print_exc() @@ -38,4 +41,4 @@ else: import_hook_manager = ImportHookManager(__name__ + '.import_hook', builtins.__import__) builtins.__import__ = import_hook_manager.do_import sys.modules[import_hook_manager.__name__] = import_hook_manager -del builtins \ No newline at end of file +del builtins diff --git a/python/helpers/pydev/pydev_ipython/matplotlibtools.py b/python/helpers/pydev/pydev_ipython/matplotlibtools.py index f2fc0d561835..e94eaafcd179 100644 --- a/python/helpers/pydev/pydev_ipython/matplotlibtools.py +++ b/python/helpers/pydev/pydev_ipython/matplotlibtools.py @@ -85,6 +85,10 @@ def patch_is_interactive(): matplotlib.is_interactive = patched_is_interactive +def _get_major_version(module): + return int(module.__version__.split('.')[0]) + + def activate_matplotlib(enable_gui_function): """Set interactive to True for interactive backends. enable_gui_function - Function which enables gui, should be run in the main thread. @@ -93,6 +97,16 @@ def activate_matplotlib(enable_gui_function): if not hasattr(matplotlib, 'rcParams'): # matplotlib module wasn't fully imported, try later return False + + if _get_major_version(matplotlib) >= 3: + # since matplotlib 3.0, accessing `matplotlib.rcParams` lead to pyplot import, + # so we need to wait until necessary pyplot attributes will be imported as well + if 'matplotlib.pyplot' not in sys.modules: + return False + pyplot = sys.modules['matplotlib.pyplot'] + if not hasattr(pyplot, 'switch_backend'): + return False + gui, backend = find_gui_and_backend() is_interactive = is_interactive_backend(backend) if is_interactive: