path_utils.py

#

Path Manipulation

import logging
import os
import sys
from typing import List, Optional

LOGGER = logging.getLogger(__name__)
#

Ensures current directory is on returned path, and argv0 directory is not

def _get_revised_path(
    current_python_path: List[str], script_path: str
) -> Optional[List[str]]:
#

Exception: argv0 dir is left alone if it’s also pydoc’s directory.

Returns a new path entry list, or None if no adjustment is needed.

Scripts may get the current directory in their path by default if they’re run with the -m switch, or directly from the current directory. The interactive prompt also allows imports from the current directory.

#

Accordingly, if the current directory is already present, don’t make any changes to the given_path

    if (
        "" in current_python_path
        or os.curdir in current_python_path
        or os.getcwd() in current_python_path
    ):
        return None
#

Otherwise, add the current directory to the given path, and remove the script directory (as long as the latter isn’t also pydoc’s directory.

    stdlib_dir = os.path.dirname(__file__)
    script_dir = os.path.dirname(script_path)
    revised_path = current_python_path.copy()
    if script_dir in current_python_path and not os.path.samefile(
        script_dir, stdlib_dir
    ):
        revised_path.remove(script_dir)
    revised_path.insert(0, os.getcwd())
    return revised_path
#

Note: the tests only cover _get_revised_path, not _adjust_cli_path itself Ensures current directory is on sys.path, and main directory is not.

def _adjust_cli_sys_path() -> None:
#

Exception: main dir is left alone if it’s also pydoc’s directory.

    revised_path = _get_revised_path(sys.path, sys.argv[0])
    if revised_path is not None:
        sys.path[:] = revised_path
#
Find file relative to a source file, e.g.
locate_file("foo/bar.txt", __file__)

Succeeds regardless to context of execution
def locate_file(file_name: str, executing_file: str) -> str:
#
    file_path = os.path.join(
        os.path.dirname(os.path.abspath(executing_file)), file_name
    )
    return file_path