This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: incomplete documentation of __main__.py
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, jack__d, mandolaerik
Priority: normal Keywords:

Created on 2021-07-02 14:08 by mandolaerik, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg396865 - (view) Author: Erik Carstensen (mandolaerik) Date: 2021-07-02 14:08
I can find partial information on how Python treats __main__.py here: https://docs.python.org/3/library/__main__.html

However, it is not documented how python handles __main__.py when passing the Python package to the interpreter without -m. If I have a program defined by /tmp/foo/bar.py and a file /tmp/foo/__main__.py, and I run

python /tmp/foo

... then Python will run __main__.py, with /tmp/foo prepended to sys.path.

I find this behaviour unfortunate; to me it would make more sense to prepend /tmp to sys.path, because then "python /tmp/foo" would be equivalent to "PYTHONPATH=/tmp python -m foo". With the current behaviour, if __main__.py wants to import bar.py, then it must write 'import bar' or 'import foo.bar' depending on whether the interpreter was invoked with -m.

Unfortunately, by Hyrum's Law, you can find people describing and encouraging reliance upon the current undocumented behaviour, e.g.:
https://www.geeksforgeeks.org/usage-of-__main__-py-in-python/
so perhaps the behaviour can't be changed that easily. Therefore, my request is to document how it works.
msg396875 - (view) Author: Jack DeVries (jack__d) * Date: 2021-07-02 20:05
This is documented in Doc/library/runpy.rst. Specifically, here:

> For a simple script, the specified code is simply executed in a fresh module namespace. For a valid sys.path entry (typically a zipfile or directory), the entry is first added to the beginning of sys.path. The function then looks for and executes a __main__ module using the updated path. Note that there is no special protection against invoking an existing __main__ entry located elsewhere on sys.path if there is no such module at the specified location.

https://docs.python.org/3/library/runpy.html#runpy.run_path


However, I fully agree that Doc/library/__main__.rst is severely lacking; that's why I've rewritten it! Please consider providing your feedback on the open PR, and see bpo-39452

https://github.com/python/cpython/pull/26883



Note that the new docs in __main__.rst does explicitly reference runpy, so once merged, it'll guide people looking for this information in __main__.rst to the right place.
msg396882 - (view) Author: Erik Carstensen (mandolaerik) Date: 2021-07-02 22:09
thanks for the pointer and sorry for the noise! I'll review your text.
History
Date User Action Args
2022-04-11 14:59:47adminsetgithub: 88718
2021-07-02 22:09:29mandolaeriksetstatus: open -> closed
resolution: not a bug
messages: + msg396882

stage: resolved
2021-07-02 20:05:24jack__dsetnosy: + jack__d
messages: + msg396875
2021-07-02 14:08:59mandolaerikcreate