diff --git a/dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py b/dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py new file mode 100644 index 000000000..d73ba1ec3 --- /dev/null +++ b/dist_assets/pyinstaller_hooks/hook-matplotlib.backends.py @@ -0,0 +1,78 @@ +# 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 \ No newline at end of file