utils.py 2.96 KB
Newer Older
1 2 3 4
"""
Useful functions used by HaaS proxy.
"""

Bogdan Bodnar's avatar
Bogdan Bodnar committed
5 6 7
import os
import sys

Bogdan Bodnar's avatar
Bogdan Bodnar committed
8

9 10 11 12 13 14 15 16 17 18
def force_text(value):
    """
    Helper to deal with bytes and str in Python 2 vs. Python 3. Needed to have
    always username and password as a string (i Python 3 it's bytes).
    """
    if issubclass(type(value), str):
        return value
    if isinstance(value, bytes):
        return str(value, 'utf-8')
    return str(value)
Bogdan Bodnar's avatar
Bogdan Bodnar committed
19 20 21


# This function is copy-pasted from shutils. It using for compatibility with python 2.7 and 3.6 because shutils
Bogdan Bodnar's avatar
Bogdan Bodnar committed
22
# hasn't which() function in python 2.7. It will be removed when support python 2.7 ends.
Michal Horejsek's avatar
Michal Horejsek committed
23
# pylint:disable=invalid-name,too-many-branches,unneeded-not
Bogdan Bodnar's avatar
Bogdan Bodnar committed
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
    """Given a command, mode, and a PATH string, return the path which
    conforms to the given mode on the PATH, or None if there is no such
    file.

    `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
    of os.environ.get("PATH"), or can be overridden with a custom search
    path.

    """

    # Check that a given file can be accessed with the correct mode.
    # Additionally check that `file` is not a directory, as on Windows
    # directories pass the os.access check.
    def _access_check(fn, mode):
        return (os.path.exists(fn) and os.access(fn, mode)
                and not os.path.isdir(fn))

    # If we're given a path with a directory part, look it up directly rather
    # than referring to PATH directories. This includes checking relative to the
    # current directory, e.g. ./script
    if os.path.dirname(cmd):
        if _access_check(cmd, mode):
            return cmd
        return None

    if path is None:
        path = os.environ.get("PATH", os.defpath)
    if not path:
        return None
    path = path.split(os.pathsep)

    if sys.platform == "win32":
        # The current directory takes precedence on Windows.
        if not os.curdir in path:
            path.insert(0, os.curdir)

        # PATHEXT is necessary to check on Windows.
        pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
        # See if the given file matches any of the expected path extensions.
        # This will allow us to short circuit when given "python.exe".
        # If it does match, only test that one, otherwise we have to try
        # others.
        if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
            files = [cmd]
        else:
            files = [cmd + ext for ext in pathext]
    else:
        # On other platforms you don't have things like PATHEXT to tell you
        # what file suffixes are executable, so just pass on cmd as-is.
        files = [cmd]

    seen = set()
Bogdan Bodnar's avatar
Bogdan Bodnar committed
77
    # pylint:disable=redefined-builtin
Bogdan Bodnar's avatar
Bogdan Bodnar committed
78 79 80 81 82 83 84 85 86
    for dir in path:
        normdir = os.path.normcase(dir)
        if not normdir in seen:
            seen.add(normdir)
            for thefile in files:
                name = os.path.join(dir, thefile)
                if _access_check(name, mode):
                    return name
    return None