Ejemplo n.º 1
0
def hook(hook_api):
    """
    SQLAlchemy 0.9 introduced the decorator 'util.dependencies'.  This
    decorator does imports.  eg:

            @util.dependencies("sqlalchemy.sql.schema")

    This hook scans for included SQLAlchemy modules and then scans those modules
    for any util.dependencies and marks those modules as hidden imports.
    """

    if not is_module_satisfies('sqlalchemy >= 0.9'):
        return

    # this parser is very simplistic but seems to catch all cases as of V1.1
    depend_regex = re.compile(r'@util.dependencies\([\'"](.*?)[\'"]\)')

    hidden_imports_set = set()
    known_imports = set()
    for node in hook_api.module_graph.flatten(start=hook_api.module):
        if isinstance(node, SourceModule) and \
                node.identifier.startswith('sqlalchemy.'):
            known_imports.add(node.identifier)
            with open(node.filename) as f:
                for match in depend_regex.findall(f.read()):
                    hidden_imports_set.add(match)

    hidden_imports_set -= known_imports
    if len(hidden_imports_set):
        logger.info("  Found %d sqlalchemy hidden imports",
                    len(hidden_imports_set))
        hook_api.add_imports(*list(hidden_imports_set))
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
def hook(hook_api):
    """
    SQLAlchemy 0.9 introduced the decorator 'util.dependencies'.  This
    decorator does imports.  eg:

            @util.dependencies("sqlalchemy.sql.schema")

    This hook scans for included SQLAlchemy modules and then scans those modules
    for any util.dependencies and marks those modules as hidden imports.
    """

    if not is_module_satisfies('sqlalchemy >= 0.9'):
        return

    # this parser is very simplistic but seems to catch all cases as of V1.1
    depend_regex = re.compile(r'@util.dependencies\([\'"](.*?)[\'"]\)')

    hidden_imports_set = set()
    known_imports = set()
    for node in hook_api.module_graph.flatten(start=hook_api.module):
        if isinstance(node, SourceModule) and \
                node.identifier.startswith('sqlalchemy.'):
            known_imports.add(node.identifier)
            with open(node.filename) as f:
                for match in depend_regex.findall(f.read()):
                    hidden_imports_set.add(match)

    hidden_imports_set -= known_imports
    if len(hidden_imports_set):
        logger.info("  Found %d sqlalchemy hidden imports",
                    len(hidden_imports_set))
        hook_api.add_imports(*list(hidden_imports_set))
Ejemplo n.º 4
0
def pre_find_module_path(api):
    # FIXME: for reusability, move this into a new PyInstaller.configure.get_fake_modules_dir() utility function.
    # Absolute path of the faked sub-package.
    fake_dir = os.path.join(PACKAGEPATH, 'fake-modules')

    api.search_dirs = [fake_dir]
    logger.info('site: retargeting to fake-dir %r', fake_dir)
Ejemplo n.º 5
0
def pre_find_module_path(api):
    #FIXME: For reusability, move this into a new
    #PyInstaller.configure.get_fake_modules_dir() utility function.
    # Absolute path of the faked sub-package.
    fake_dir = os.path.join(PACKAGEPATH, 'fake-modules')

    api.search_dirs = [fake_dir]
    logger.info('site: retargeting to fake-dir %r', fake_dir)
Ejemplo n.º 6
0
def pre_find_module_path(api):
    # Absolute path of the system-wide "distutils" package when run from within
    # a venv or None otherwise.
    distutils_dir = getattr(distutils, 'distutils_path', None)
    if distutils_dir is not None:
        # Find this package in its parent directory.
        api.search_dirs = [os.path.dirname(distutils_dir)]
        logger.info('distutils: retargeting to non-venv dir %r' % distutils_dir)
Ejemplo n.º 7
0
def pre_find_module_path(api):
    # Absolute path of the system-wide "distutils" package when run from within
    # a venv or None otherwise.
    distutils_dir = getattr(distutils, 'distutils_path', None)
    if distutils_dir is not None:
        # Find this package in its parent directory.
        api.search_dirs = [os.path.dirname(distutils_dir)]
        logger.info('distutils: retargeting to non-venv dir %r' %
                    distutils_dir)
Ejemplo n.º 8
0
def _collect_tcl_tk_files(hook_api):
    """
    Get a list of TOC-style 3-tuples describing all external Tcl/Tk data files.

    Returns
    -------
    Tree
        Such list.
    """
    tcl_root, tk_root = _find_tcl_tk(hook_api)

    # On macOS, we do not collect system libraries. Therefore, if system
    # Tcl/Tk framework is used, it makes no sense to collect its data,
    # either. In this case, _find_tcl_tk() will return None, None - either
    # deliberately (we found the data paths, but ignore them) or not
    # (starting with macOS 11, the data path cannot be found until shared
    # library discovery is fixed).
    if is_darwin and not tcl_root and not tk_root:
        logger.info('Not collecting Tcl/Tk data - either python is using '
                    'macOS\' system Tcl/Tk framework, or Tcl/Tk data '
                    'directories could not be found.')
        return []

    # TODO Shouldn't these be fatal exceptions?
    if not tcl_root:
        logger.error('Tcl/Tk improperly installed on this system.')
        return []
    if not os.path.isdir(tcl_root):
        logger.error('Tcl data directory "%s" not found.', tcl_root)
        return []
    if not os.path.isdir(tk_root):
        logger.error('Tk data directory "%s" not found.', tk_root)
        return []

    tcltree = Tree(tcl_root,
                   prefix='tcl',
                   excludes=['demos', '*.lib', 'tclConfig.sh'])
    tktree = Tree(tk_root,
                  prefix='tk',
                  excludes=['demos', '*.lib', 'tkConfig.sh'])

    # If the current Tcl installation is a Teapot-distributed version of
    # ActiveTcl and the current platform is OS X, warn that this is bad.
    if is_darwin:
        _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree)

    # Collect Tcl modules
    tclmodulestree = _collect_tcl_modules(tcl_root)

    return (tcltree + tktree + tclmodulestree)
Ejemplo n.º 9
0
def pre_find_module_path(api):
    # Absolute path of the system-wide "distutils" package when run from within a venv or None otherwise.

    # opcode is not a virtualenv module, so we can use it to find the stdlib. Technique taken from virtualenv's
    # "distutils" package detection at
    # https://github.com/pypa/virtualenv/blob/16.3.0/virtualenv_embedded/distutils-init.py#L5
    import opcode

    system_module_path = os.path.normpath(os.path.dirname(opcode.__file__))
    loaded_module_path = os.path.normpath(os.path.dirname(distutils.__file__))
    if system_module_path != loaded_module_path:
        # Find this package in its parent directory.
        api.search_dirs = [system_module_path]
        logger.info('distutils: retargeting to non-venv dir %r', system_module_path)
def hook(hook_api):
    module_versions = get_hook_config(hook_api, 'gi', 'module-versions')
    if module_versions:
        version = module_versions.get('GtkSource', '3.0')
    else:
        version = '3.0'
    logger.info(f'GtkSource version is {version}')

    binaries, datas, hiddenimports = get_gi_typelibs('GtkSource', version)

    datas += collect_glib_share_files(f'gtksourceview-{version}')
    hook_api.add_datas(datas)
    hook_api.add_binaries(binaries)
    hook_api.add_imports(*hiddenimports)
Ejemplo n.º 11
0
def pre_find_module_path(api):
    try:
        # Test if a module named 'pyi_splash' is locally installed.
        # This prevents that a potentially required dependency is not
        # packed
        import pyi_splash  # noqa: F401
    except ImportError:
        module_dir = os.path.join(PACKAGEPATH, 'fake-modules')

        api.search_dirs = [module_dir]
        logger.info('Adding pyi_splash module to application dependencies.')
    else:
        logger.info('A local module named "pyi_splash" is installed. '
                    'Use the installed one instead.')
        return
Ejemplo n.º 12
0
def pre_find_module_path(api):
    # Absolute path of the system-wide "distutils" package when run from within
    # a venv or None otherwise.
    distutils_dir = getattr(distutils, 'distutils_path', None)
    if distutils_dir is not None:
        # workaround for https://github.com/pyinstaller/pyinstaller/issues/4064
        if distutils_dir.endswith('__init__.py'):
            distutils_dir = os.path.dirname(distutils_dir)

        # Find this package in its parent directory.
        api.search_dirs = [os.path.dirname(distutils_dir)]

        logger.info(
            '>>>>>>> CUSTOM >>>>>>>>> distutils: retargeting to non-venv dir %r'
            % distutils_dir)
Ejemplo n.º 13
0
                    run_path = os.path.join(exec_path, run_path)
                # Stop looking for lib when found in first location.
                if os.path.exists(os.path.join(run_path, lib)):
                    final_lib = os.path.abspath(os.path.join(run_path, lib))
                    rslt.add(final_lib)
                    break
            # Log error if no existing file found.
            if not final_lib:
                logger.error('Can not find path %s (needed by %s)', lib, pth)

        # Macholib has to be used to get absolute path to libraries.
        else:
            # macholib can't handle @loader_path. It has to be
            # handled the same way as @executable_path.
            # It is also replaced by 'exec_path'.
            if lib.startswith('@loader_path'):
                lib = lib.replace('@loader_path', '@executable_path')
            try:
                lib = dyld_find(lib, executable_path=exec_path)
                rslt.add(lib)
            except ValueError:
                logger.error('Can not find path %s (needed by %s)', lib, pth)

    return rslt

if PyInstaller.compat.is_darwin:
   logger.info("Monkey-patching bindep._getImports_macholib")
   PyInstaller.depend.bindepend._getImports_macholib = getImports_macholib


Ejemplo n.º 14
0
def pre_find_module_path(api):
    # Absolute path of the faked sub-package.
    fake_dir = os.path.join(PACKAGEPATH, "fake-modules")
    api.search_dirs = [fake_dir]
    logger.info("site: retargeting to fake-dir %r", fake_dir)
from PyInstaller.compat import is_darwin
from PyInstaller.utils.hooks import (eval_statement, exec_statement, logger)
logger.info('######removing unused mpl-backend ######')
excl_backend_names = eval_statement(
    'import matplotlib; print(matplotlib.rcsetup.all_backends)')

excl_backend_names.remove('WX')
excl_backend_names.remove('WXAgg')

print("Entering custom hook for matplotlib-backends")
excl_module_names = []
for backend_name in excl_backend_names:
    module_name = 'matplotlib.backends.backend_%s' % backend_name.lower()
    excl_module_names.append(module_name)
    logger.info('##  Matplotlib backend "%s": removed' % module_name)
logger.info('###### end mpl-backend removal #########')
excludedimports = excl_module_names
Ejemplo n.º 16
0
def pre_safe_import_module(api):
    logger.info("Pre-safe import module hook for pyi_hooksample was executed.")
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
                if not os.path.isabs(run_path):
                    run_path = os.path.join(exec_path, run_path)
                # Stop looking for lib when found in first location.
                if os.path.exists(os.path.join(run_path, lib)):
                    final_lib = os.path.abspath(os.path.join(run_path, lib))
                    rslt.add(final_lib)
                    break
            # Log error if no existing file found.
            if not final_lib:
                logger.error('Can not find path %s (needed by %s)', lib, pth)

        # Macholib has to be used to get absolute path to libraries.
        else:
            # macholib can't handle @loader_path. It has to be
            # handled the same way as @executable_path.
            # It is also replaced by 'exec_path'.
            if lib.startswith('@loader_path'):
                lib = lib.replace('@loader_path', '@executable_path')
            try:
                lib = dyld_find(lib, executable_path=exec_path)
                rslt.add(lib)
            except ValueError:
                logger.error('Can not find path %s (needed by %s)', lib, pth)

    return rslt


if PyInstaller.compat.is_darwin:
    logger.info("Monkey-patching bindep._getImports_macholib")
    PyInstaller.depend.bindepend._getImports_macholib = getImports_macholib
Ejemplo n.º 19
0
def pre_find_module_path(api):
    logger.info("Running pre-find module path hook for pyi_hooksample.")
Ejemplo n.º 20
0
def pre_find_module_path(api):
    # Absolute path of the faked sub-package.
    fake_dir = os.path.join(PACKAGEPATH, 'fake-modules')
    api.search_dirs = [fake_dir]
    logger.info('site: retargeting to fake-dir %r', fake_dir)