0

I'm seeing different package handling behavior in python3 when I'm running something like python -m moduala.test and python moduala/testa.py. In the -m case imports for moduala.modualb.pkgx in testa.py work and in the other case they don't work.

python --version
# Python 3.6.9

mkdir -p testpyproj/pkga/pkgb
cd testpyproj/

touch pkga/__init__.py
touch pkga/pkgb/__init__.py

echo 'print("# python!")' >pkga/pkgb/modx.py
echo 'from pkga.pkgb import modx' > pkga/test.py

python -m pkga.test
# python!

python pkga/test.py 
# Traceback (most recent call last):
#  File "pkga/test.py", line 1, in <module>
#     from pkga.pkgb import modx
# ImportError: No module named pkga.pkgb

From the man page I would expect these to be the same:

  -m module-name
         Searches sys.path for the named module and 
         runs the corresponding .py file as a script.

What is the difference between python -m and python [file] for loading modules and handling packages?

Why does the python [file] not find pkga.pkgb?

Brian C.
  • 6,455
  • 3
  • 32
  • 42

1 Answers1

1

When python runs a script from the command line, like:

$ python pkga/test.py

it knows that it is running a relative script. And so, as a result, it changes the value of sys.path[0] to be the directory of the script.

When python opens a module from the command line, it has to have a module search path (aka sys.path) in order to find the module. So it sets sys.path[0] to "" (empty string) to indicate "the current directory". Then it searches through all the places indicated by sys.path trying to find the module name you have given.

The result of this is that in one case, your sys.path[0] is going to be "" while in the other case it will be /path/to/current/directory/pkga. And then it cannot resolve pkga.pkgb when the search path starts from that location.

You can confirm this by adding:

import sys
print(sys.path)

to the start of pkga/test.py, before any other imports. You will see the print output just before the module import exception.

aghast
  • 14,785
  • 3
  • 24
  • 56