예제 #1
0
 def test_fsdecode_and_fsencode_are_idempotent(self):
     a = b'foo\xb1bar'
     b = u'foo\udcb1bar'
     assert a == fsencode(fsdecode(a))
     assert a == fsencode(fsdecode(b))
     assert b == fsdecode(fsencode(a))
     assert b == fsdecode(fsencode(b))
예제 #2
0
def update_path_var(existing_path_var, new_path, pathsep=PATH_ENV_SEP):
    """
    Return an updated value for the `existing_path_var` PATH-like environment
    variable value  by adding `new_path` to the front of that variable if
    `new_path` is not already part of this PATH-like variable.
    """
    if not new_path:
        return existing_path_var

    existing_path_var = existing_path_var or EMPTY_STRING

    # ensure we use unicode or bytes depending on OSes
    # TODO: deal also with Python versions
    if on_linux and py2:
        # bytes ...
        existing_path_var = fsencode(existing_path_var)
        new_path = fsencode(new_path)
        pathsep = fsencode(pathsep)
    else:
        # ... and unicode otherwise
        existing_path_var = fsdecode(existing_path_var)
        new_path = fsdecode(new_path)
        pathsep = fsdecode(pathsep)

    path_elements = existing_path_var.split(pathsep)

    if not path_elements:
        updated_path_var = new_path

    elif new_path not in path_elements:
        # add new path to the front of the PATH env var
        path_elements.insert(0, new_path)
        updated_path_var = pathsep.join(path_elements)

    else:
        # new path is already in PATH, change nothing
        updated_path_var = existing_path_var

    if py2:
        # always use bytes for env vars...
        if isinstance(updated_path_var, compat.unicode):
            updated_path_var = fsencode(updated_path_var)
    else:
        # ... else use unicode
        if not isinstance(updated_path_var, compat.unicode):
            updated_path_var = fsdecode(updated_path_var)

    # at this stage new_path_env is unicode on all OSes on Py3
    # and on Py2 it is bytes on Linux and unicode elsewhere
    return updated_path_var
예제 #3
0
def update_path_environment(new_path, _os_module=_os_module):
    """
    Update the PATH environment variable by adding `new_path` to the front
    of PATH if `new_path` is not alreday in the PATH.
    """
    # note: _os_module is used to facilitate mock testing using an
    # object with a sep string attribute and an environ mapping
    # attribute

    if not new_path:
        return

    new_path = new_path.strip()
    if not new_path:
        return

    path_env = _os_module.environ.get(b'PATH')
    if not path_env:
        # this is quite unlikely to ever happen, but here for safety
        path_env = ''

    # ensure we use unicode or bytes depending on OSes
    if on_linux:
        new_path = fsencode(new_path)
        path_env = fsencode(path_env)
        sep = _os_module.pathsep
    else:
        new_path = fsdecode(new_path)
        path_env = fsdecode(path_env)
        sep = unicode(_os_module.pathsep)

    path_segments = path_env.split(sep)

    # add lib path to the front of the PATH env var
    # this will use bytes on Linux and unicode elsewhere
    if new_path not in path_segments:
        if not path_env:
            new_path_env = new_path
        else:
            new_path_env = sep.join([new_path, path_env])

        if not on_linux:
            # recode to bytes using FS encoding
            new_path_env = fsencode(new_path_env)
        # ... and set the variable back as bytes
        _os_module.environ[b'PATH'] = new_path_env
예제 #4
0
def get_relative_path(path, len_base_path, base_is_dir):
    """
    Return a posix relative path from the posix 'path' relative to a
    base path of `len_base_path` length where the base is a directory if
    `base_is_dir` True or a file otherwise.
    """
    path = fileutils.fsdecode(path)
    if base_is_dir:
        rel_path = path[len_base_path:]
    else:
        rel_path = fileutils.file_name(path)

    return rel_path.lstrip('/')
예제 #5
0
def load_shared_library(dll_path, lib_dir):
    """
    Return the loaded shared library object from the dll_path and adding
    `lib_dir` to the path.
    """

    if not path.exists(dll_path):
        raise ImportError('Shared library does not exists: %(dll_path)r' %
                          locals())

    if lib_dir and not path.exists(lib_dir):
        raise ImportError(
            'Shared library "lib_dir" does not exists: %(lib_dir)r' % locals())

    if on_linux and py2:
        # bytes only there ...
        if not isinstance(dll_path, bytes):
            dll_path = fsencode(dll_path)

    else:
        # ... unicode everywhere else
        if not isinstance(dll_path, compat.unicode):
            dll_path = fsdecode(dll_path)

    try:
        with pushd(lib_dir):
            lib = ctypes.CDLL(dll_path)
    except OSError as e:
        from pprint import pformat
        import traceback
        msgs = tuple([
            'ctypes.CDLL(dll_path): {}'.format(dll_path),
            'lib_dir: {}'.format(lib_dir),
            'os.environ:\n{}'.format(pformat(dict(os.environ))),
            traceback.format_exc(),
        ])
        e.args = tuple(e.args + msgs)
        raise e

    if lib and lib._name:
        return lib

    raise ImportError(
        'Failed to load shared library with ctypes: %(dll_path)r and lib_dir: '
        '%(lib_dir)r' % locals())