I am getting some module not found excepiton when setting PYTHONPATH and then executing some py script :
$ PYTHONPATH=somepath/a/b
$ python myscript.py
Exception has occurred: ModuleNotFoundError (note: full exception trace is shown but execution is paused at: _run_module_as_main)
No module named 'c'
but if I export PYTHONPATH, everything works fine
$ export PYTHONPATH=somepath/a/b
$ python myscript.py
==>ok
It is also working when I am inlining the PYTHONPATH assignation :
$ PYTHONPATH=somepath/a/b python myscript.py
==>ok
Why do we have this behavior ?
I'm amazed this doesn't seem to be a duplicate, but:
"Why ...?" -- because you're using a traditional (Bourne/Korn-family) shell on Unix or a Unix-alike such as WSL, although you don't identify which in your Q. This is the type of shell required by POSIX, and often described as such. Other Unixy shells like csh-family or fish are different and so are Windows command processors, although those do have some way to set environment variables.
In a POSIX shell, each variable has an attribute to select whether it is 'exported', that is, passed as an environment variable (an OS feature) when running as a child process a program such as python (or a script).
Any of the following commands or sequences (possibly separated by other unrelated commands) sets a variable as 'exported':
IF the shell option
-ais set, a simple assignmentfoo=baralso sets the export attribute.These settings are 'permanent'; the exported variables are passed to all programs (and scripts) run subsequently, unless and until explicitly unset or changed or the shell exits.
In addition, a 'word'
foo=barat the beginning of a simple-command, prior to the word which specifies the program to be run, adds or replaces an environment variable for that command/process only -- unless the command is shell builtin, in which case the POSIX behavior is unspecified and actual shells may vary.But an assignment
foo=barby itself -- not as a prefix to a simple-command and not preceded or followed by setting the export attribute and without option-ain effect -- only sets a shell variable which is NOT 'exported' so it is not passed to or seen by a child process such as python.