Initialization of sys.path in interpreters spawned with multiprocessing

The following code adds a canary to the PYTHONPATH environment variable and then spawns a child process.

The canary is taken over by the PYTHONPATH variable of the child (as expected) but NOT by the sys.path of the child, indicating that its sys.path is not populated in the normal manner.

import multiprocessing
import os
import sys

def print_path():
    print(f"Child process PYTHONPATH: {os.environ.get('PYTHONPATH', '')}")  # has canary, ok
    print(f"Child process sys.path: {sys.path}")  # No CANARY?

if __name__ == '__main__':
    os.environ['PYTHONPATH'] = R"C:\CANARY"
    ctx = multiprocessing.get_context('spawn')
    p = ctx.Process(target=print_path)
    p.start()
    p.join()

This seems to contradict the docs for sys.path:

A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default.

I found no further info in the multiprocessing docs besides this:

The child process will only inherit those resources necessary to run the process object’s run() method.

so … bug or intentional?

(Tested on windows 11 with python 3.12 and 3.13)

2 Likes

I am pretty sure what happens is that sys.path is set to the same value as sys.path in the parent process.

What the correct behavior for these kinds of settings is is kind of arbitrary and different people want different contradictory behaviors.

If you need the canary to be part of the sys.path of the child, add it there - don’t try to use global state via os.environ