# This apes hook-matplotlib.backends.py, but REMOVES backends, all but # the ones in the list below. # Courtesy of https://github.com/bpteague/cytoflow/blob/70f9291/packaging/hook-matplotlib.backends.py KEEP = ["WXAgg", "WX", "agg"] 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: if backend_name in KEEP: continue 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": removed' % backend_name) return module_names # Freeze all importable backends, as PyInstaller is unable to determine exactly # which backends are required by the current program. e=get_matplotlib_backend_module_names() print(e) excludedimports = e