Hello everyone, This is my first email to the python list, I'll try my best to do it well.
TL;DR I have recently read the documentation about how imports work on python, and I was wondering why, when you execute a python file, the current directory is not added by default to the PYTHONPATH ? Extended: Let's assume we have this directory structure for a python package: $ tree A A ├── B1 │ ├── b1.py │ ├── C1 │ │ ├── c1_1.py │ │ ├── c1.py │ │ └── __init__.py │ └── __init__.py ├── B2 │ ├── b2.py │ ├── C2 │ │ ├── c2.py │ │ └── __init__.py │ └── __init__.py ├── __init__.py └── toto.py 4 directories, 11 files with the file A/B2/C2/c2.py content being: import sys print(sys.path) import A from A.B2.b2 import PLOP from A.B1.C1.c1 import TOTO print(TOTO) If I do, from the top level directory containing the package A: $ python A/B2/C2/c2.py I get an : ['/tmp/A/B2/C2', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/cris/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist- packages/gtk-2.0'] Traceback (most recent call last): File "A/B2/C2/c2.py", line 9, in <module> import A ImportError: No module named A Which is normal according to the documentation of Python 2 (https://docs.python.org/2/tutorial/modules.html#the-module-search-path): When a module named spam is imported, the interpreter first searches for a > built-in module with that name. If not found, it then searches for a file > named spam.py in a list of directories given by the variable sys.path > <https://docs.python.org/2/library/sys.html#sys.path>. sys.path > <https://docs.python.org/2/library/sys.html#sys.path> is initialized from > these locations: > > - the directory containing the input script (or the current directory). > - PYTHONPATH > <https://docs.python.org/2/using/cmdline.html#envvar-PYTHONPATH> (a > list of directory names, with the same syntax as the shell variable > PATH). > - the installation-dependent default. > > After initialization, Python programs can modify sys.path > <https://docs.python.org/2/library/sys.html#sys.path>. The directory > containing the script being run is placed at the beginning of the search > path, ahead of the standard library path. This means that scripts in that > directory will be loaded instead of modules of the same name in the library > directory. This is an error unless the replacement is intended. See section > Standard > Modules > <https://docs.python.org/2/tutorial/modules.html#tut-standardmodules> for > more information. > Meanwhile when I do: $ python -m A.B2.C2.c2 I get the script running correctly: ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/home/cris/.local/lib/python2.7/site-packages', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0'] 42 An empty string is now pre-pended to the value of sys.path, which means, if I correctly interpret the documentation of Python 3, that the current directory is added to the PYTHONPATH (https://docs.python.org/3/ reference/import.html#path-entry-finders): The current working directory – denoted by an empty string – is handled > slightly differently from other entries on sys.path > <https://docs.python.org/3/library/sys.html#sys.path>. First, if the > current working directory is found to not exist, no value is stored in > sys.path_importer_cache > <https://docs.python.org/3/library/sys.html#sys.path_importer_cache>. > Second, the value for the current working directory is looked up fresh for > each module lookup. Third, the path used for sys.path_importer_cache > <https://docs.python.org/3/library/sys.html#sys.path_importer_cache> and > returned by importlib.machinery.PathFinder.find_spec() > <https://docs.python.org/3/library/importlib.html#importlib.machinery.PathFinder.find_spec> > will be the actual current working directory and not the empty string. > What I am interested in is what is the reason of this difference ? P.S.: - My english may suck a bit, please blame it on me being a French native speaker - Sorry if the colours hurt 😅 *Adrien OYONO* -- https://mail.python.org/mailman/listinfo/python-list