Skip to content

← Modules, Packaging and Tooling step 4 of 41

Medium Framework

Work Out the First Entry on sys.path

Write a function that predicts the entry Python puts at the front of sys.path for a launch command. It works on strings alone, and it returns only that one entry.

sys_path_for(["run.py"], "/proj", False)   # ["/proj"]
sys_path_for(["run.py"], "/proj", True)    # [], because -P drops it
sys_path_for(["app.zip"], "/proj", True)   # ["/proj/app.zip"], -P keeps it

What to write

sys_path_for(argv, cwd, safe_path) -> list[str] returns a list with zero or one path.

  • argv holds the arguments after python. An empty argv means stdin or the REPL.
  • If the first item is -c or -m, the launch runs a command or a module. Ignore every later item.
  • If the first item ends in .py, it is a script.
  • Any other first item is a folder or zip file for Python to run.
  • cwd is an absolute, normalized POSIX path.
  • safe_path is True when Python runs with -P.

Return this for each launch form:

Form safe_path=False safe_path=True
Empty argv or -c [""] []
-m [cwd] []
.py script The script's folder, made absolute []
Folder or zip file The path to it, made absolute The path to it, made absolute

Each path in the last two rows goes in a one-item list.

To make a path absolute, join a relative path to cwd with posixpath.join, then remove . and .. parts with posixpath.normpath. Use posixpath so the result is the same on every platform. For a script with no folder part, such as run.py, the script's folder is cwd.

Edge cases

  • For an empty argv and for -c, return the empty string itself, instead of cwd.
  • normpath works on the text alone, so symlinks stay as they are, unlike at real Python startup.
  • Do not change argv.

Your solution must pass mypy --strict.