Beispiel #1
0
def die_unless_macos() -> None:
    '''
    Raise an exception unless the current platform is Apple macOS.

    See Also
    ----------
    :func:`is_macos`
        Further details.
    '''

    # Avoid circular import dependencies.
    from betse.util.os import oses

    # If the current platform is *NOT* macOS, raise an exception.
    if not is_macos():
        raise BetseOSException('{} not macOS.'.format(oses.get_name()))
Beispiel #2
0
def die_unless_posix() -> None:
    '''
    Raise an exception unless the current platform is POSIX-compatible.

    See Also
    ----------
    :func:`is_posix`
        Further details.
    '''

    # Avoid circular import dependencies.
    from betse.util.os import oses

    # If the current platform is POSIX-incompatible, raise an exception.
    if not is_posix():
        raise BetseOSException(
            '{} not POSIX-compatible.'.format(oses.get_name()))
Beispiel #3
0
def die_unless_windows() -> None:
    '''
    Raise an exception unless the current platform is Microsoft Windows.

    See Also
    ----------
    :func:`is_windows`
        Further details.
    '''

    # Avoid circular import dependencies.
    from betse.util.os import oses

    # If the current platform is *NOT* Windows, raise an exception.
    if not is_windows():
        raise BetseOSException('Current platform {} not Windows.'.format(
            oses.get_name()))
Beispiel #4
0
def log_header() -> None:
    '''
    Log a single-line human-readable sentence synopsizing the state of the
    current application (e.g., name, codename, version).
    '''

    logs.log_info('Welcome to <<'
                  '{program_name} {program_version} | '
                  '{py_name} {py_version} | '
                  '{os_name} {os_version}'
                  '>>.'.format(
                      program_name=metadata.NAME,
                      program_version=metadata.VERSION,
                      py_name=pyimpl.get_name(),
                      py_version=pys.get_version(),
                      os_name=oses.get_name(),
                      os_version=oses.get_version(),
                  ))
Beispiel #5
0
def iter_linked_filenames(filename: str) -> GeneratorType:
    '''
    Generator iteratively yielding the 2-tuple of the basename and absolute
    filename of each shared library dynamically linked to (and hence required
    at runtime by) the shared library with the passed filename.

    Parameters
    ----------
    filename : str
        Absolute or relative filename of the shared library to inspect.

    Yields
    ----------
    (str, str)
        2-tuple ``(linked_lib_basename, linked_lib_pathname``) such that:

        * ``linked_lib_basename`` is the basename of a shared library
          dynamically linked to the shared library with the passed path.
        * ``linked_lib_pathname`` is the absolute pathname of the same library.
    '''

    # Avoid circular import dependencies.
    from betse.util.os import oses
    from betse.util.os.brand import linux
    from betse.util.os.command import cmdrun
    from betse.util.type.text import regexes

    # If this library does *NOT* exist, raise an exception.
    die_unless_dll(filename)

    # If the current platform is Linux...
    if linux.is_linux():
        # String listing all libraries linked to by this library captured from
        # stdout printed by this command. For example, when passed the absolute
        # path of the file defining the "numpy.core.multiarray" C extension,
        # this command prints stdout resembling:
        #
        # multiarray.cpython-34.so:
        # 	linux-vdso.so.1 (0x00007fff049ca000)
        # 	libopenblas_threads.so.0 => /usr/lib64/libopenblas_threads.so.0 (0x00007f9af3ad5000)
        # 	libm.so.6 => /lib64/libm.so.6 (0x00007f9af37d9000)
        # 	libpython3.4.so.1.0 => /usr/lib64/libpython3.4.so.1.0 (0x00007f9af3357000)
        # 	libc.so.6 => /lib64/libc.so.6 (0x00007f9af2fc1000)
        # 	/lib64/ld-linux-x86-64.so.2 (0x000055e2dd7f3000)
        # 	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9af2da5000)
        # 	libdl.so.2 => /lib64/libdl.so.2 (0x00007f9af2ba0000)
        # 	libutil.so.1 => /lib64/libutil.so.1 (0x00007f9af299d000)
        ldd_stdout = cmdrun.get_stdout_or_die(command_words=('ldd', filename))

        # For each line containing a "=>"-delimited basename and absolute path
        # pair and hence ignoring both pseudo-libraries that do *NOT* actually
        # exist (e.g., "linux-vdso") or ubiquitous libraries required by the
        # dynamic linking mechanism and hence guaranteed to *ALWAYS* exist
        # (e.g., "ld-linux-x86-64")...
        for line_match in regexes.iter_matches_line(
                text=ldd_stdout,
                regex=r'^\s+(\S+)\s+=>\s+(\S+)\s+\(0x[0-9a-fA-F]+\)$',
        ):
            # Yield the 2-tuple corresponding exactly to the match groups
            # captured by this match.
            yield line_match.groups()

    # Else, library inspection is currently unsupported on this platform.
    raise BetseOSException(
        'Shared library inspection currently unsupported under {}.'.format(
            oses.get_name()))