1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- #-----------------------------------------------------------------------------
- # Copyright (c) 2013-2021, PyInstaller Development Team.
- #
- # Distributed under the terms of the GNU General Public License (version 2
- # or later) with exception for distributing the bootloader.
- #
- # The full license is in the file COPYING.txt, distributed with this software.
- #
- # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
- #-----------------------------------------------------------------------------
- from PyInstaller.compat import is_darwin
- from PyInstaller.utils.hooks import eval_statement, exec_statement, logger
- def get_matplotlib_backend_module_names():
- """
- List the names of all matplotlib backend modules importable under the current Python installation.
- Returns
- ----------
- list
- List of the fully-qualified names of all such modules.
- """
- # Statement safely importing a single backend module.
- import_statement = """
- import os, sys
- # Preserve stdout.
- sys_stdout = sys.stdout
- try:
- # Redirect output printed by this importation to "/dev/null", preventing such output from being erroneously
- # interpreted as an error.
- with open(os.devnull, 'w') as dev_null:
- sys.stdout = dev_null
- __import__('%s')
- # If this is an ImportError, print this exception's message without a traceback. ImportError messages are human-readable
- # and require no additional context.
- except ImportError as exc:
- sys.stdout = sys_stdout
- print(exc)
- # Else, print this exception preceded by a traceback. traceback.print_exc() prints to stderr rather than stdout and must
- # not be called here!
- except Exception:
- sys.stdout = sys_stdout
- import traceback
- print(traceback.format_exc())
- """
- # List of the human-readable names of all available backends.
- backend_names = eval_statement('import matplotlib; print(matplotlib.rcsetup.all_backends)')
- # List of the fully-qualified names of all importable backend modules.
- module_names = []
- # If the current system is not OS X and the "CocoaAgg" backend is available, remove this backend from consideration.
- # Attempting to import this backend on non-OS X systems halts the current subprocess without printing output or
- # raising exceptions, preventing its reliable detection.
- if not is_darwin and 'CocoaAgg' in backend_names:
- backend_names.remove('CocoaAgg')
- # For safety, attempt to import each backend in a unique subprocess.
- for backend_name in backend_names:
- module_name = 'matplotlib.backends.backend_%s' % backend_name.lower()
- stdout = exec_statement(import_statement % module_name)
- # If no output was printed, this backend is importable.
- if not stdout:
- module_names.append(module_name)
- logger.info(' Matplotlib backend "%s": added' % backend_name)
- else:
- logger.info(' Matplotlib backend "%s": ignored\n %s' % (backend_name, stdout))
- return module_names
- # Freeze all importable backends, as PyInstaller is unable to determine exactly which backends are required by the
- # current program.
- hiddenimports = get_matplotlib_backend_module_names()
|