Skip to content

Commit 7cba231

Browse files
jdevries3133geryogammerwokambv
authored
bpo-39452: Rewrite and expand __main__.rst (#26883)
Broadened scope of the document to explicitly discuss and differentiate between ``__main__.py`` in packages versus the ``__name__ == '__main__'`` expression (and the idioms that surround it), as well as ``import __main__``. Co-authored-by: Géry Ogam <gery.ogam@gmail.com> Co-authored-by: Éric Araujo <merwok@netwok.org> Co-authored-by: Łukasz Langa <lukasz@langa.pl>
1 parent a24676b commit 7cba231

File tree

5 files changed

+369
-17
lines changed

5 files changed

+369
-17
lines changed

Diff for: Doc/library/__main__.rst

+360-17
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,368 @@
1-
2-
:mod:`__main__` --- Top-level script environment
3-
================================================
1+
:mod:`__main__` --- Top-level code environment
2+
==============================================
43

54
.. module:: __main__
6-
:synopsis: The environment where the top-level script is run.
5+
:synopsis: The environment where top-level code is run. Covers command-line
6+
interfaces, import-time behavior, and ``__name__ == '__main__'``.
77

88
--------------
99

10-
``'__main__'`` is the name of the scope in which top-level code executes.
11-
A module's __name__ is set equal to ``'__main__'`` when read from
12-
standard input, a script, or from an interactive prompt.
10+
In Python, the special name ``__main__`` is used for two important constructs:
11+
12+
1. the name of the top-level environment of the program, which can be
13+
checked using the ``__name__ == '__main__'`` expression; and
14+
2. the ``__main__.py`` file in Python packages.
15+
16+
Both of these mechanisms are related to Python modules; how users interact with
17+
them and how they interact with each other. They are explained in detail
18+
below. If you're new to Python modules, see the tutorial section
19+
:ref:`tut-modules` for an introduction.
20+
21+
22+
.. _name_equals_main:
23+
24+
``__name__ == '__main__'``
25+
---------------------------
26+
27+
When a Python module or package is imported, ``__name__`` is set to the
28+
module's name. Usually, this is the name of the Python file itself without the
29+
``.py`` extension::
30+
31+
>>> import configparser
32+
>>> configparser.__name__
33+
'configparser'
34+
35+
If the file is part of a package, ``__name__`` will also include the parent
36+
package's path::
37+
38+
>>> from concurrent.futures import process
39+
>>> process.__name__
40+
'concurrent.futures.process'
41+
42+
However, if the module is executed in the top-level code environment,
43+
its ``__name__`` is set to the string ``'__main__'``.
44+
45+
What is the "top-level code environment"?
46+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47+
48+
``__main__`` is the name of the environment where top-level code is run.
49+
"Top-level code" is the first user-specified Python module that starts running.
50+
It's "top-level" because it imports all other modules that the program needs.
51+
Sometimes "top-level code" is called an *entry point* to the application.
52+
53+
The top-level code environment can be:
54+
55+
* the scope of an interactive prompt::
56+
57+
>>> __name__
58+
'__main__'
59+
60+
* the Python module passed to the Python interpreter as a file argument:
61+
62+
.. code-block:: shell-session
63+
64+
$ python3 helloworld.py
65+
Hello, world!
66+
67+
* the Python module or package passed to the Python interpreter with the
68+
:option:`-m` argument:
69+
70+
.. code-block:: shell-session
71+
72+
$ python3 -m tarfile
73+
usage: tarfile.py [-h] [-v] (...)
74+
75+
* Python code read by the Python interpreter from standard input:
76+
77+
.. code-block:: shell-session
78+
79+
$ echo "import this" | python3
80+
The Zen of Python, by Tim Peters
81+
82+
Beautiful is better than ugly.
83+
Explicit is better than implicit.
84+
...
85+
86+
* Python code passed to the Python interpreter with the :option:`-c` argument:
87+
88+
.. code-block:: shell-session
89+
90+
$ python3 -c "import this"
91+
The Zen of Python, by Tim Peters
92+
93+
Beautiful is better than ugly.
94+
Explicit is better than implicit.
95+
...
96+
97+
In each of these situations, the top-level module's ``__name__`` is set to
98+
``'__main__'``.
99+
100+
As a result, a module can discover whether or not it is running in the
101+
top-level environment by checking its own ``__name__``, which allows a common
102+
idiom for conditionally executing code when the module is not initialized from
103+
an import statement::
104+
105+
if __name__ == '__main__':
106+
# Execute when the module is not initialized from an import statement.
107+
...
108+
109+
.. seealso::
110+
111+
For a more detailed look at how ``__name__`` is set in all situations, see
112+
the tutorial section :ref:`tut-modules`.
113+
114+
115+
Idiomatic Usage
116+
^^^^^^^^^^^^^^^
117+
118+
Some modules contain code that is intended for script use only, like parsing
119+
command-line arguments or fetching data from standard input. When a module
120+
like this were to be imported from a different module, for example to unit test
121+
it, the script code would unintentionally execute as well.
122+
123+
This is where using the ``if __name__ == '__main__'`` code block comes in
124+
handy. Code within this block won't run unless the module is executed in the
125+
top-level environment.
126+
127+
Putting as few statements as possible in the block below ``if __name___ ==
128+
'__main__'`` can improve code clarity and correctness. Most often, a function
129+
named ``main`` encapsulates the program's primary behavior::
130+
131+
# echo.py
132+
133+
import shlex
134+
import sys
135+
136+
def echo(phrase: str) -> None:
137+
"""A dummy wrapper around print."""
138+
# for demonstration purposes, you can imagine that there is some
139+
# valuable and reusable logic inside this function
140+
print(phrase)
141+
142+
def main() -> int:
143+
"""Echo the input arguments to standard output"""
144+
phrase = shlex.join(sys.argv)
145+
echo(phrase)
146+
return 0
147+
148+
if __name__ == '__main__':
149+
sys.exit(main()) # next section explains the use of sys.exit
150+
151+
Note that if the module didn't encapsulate code inside the ``main`` function
152+
but instead put it directly within the ``if __name__ == '__main__'`` block,
153+
the ``phrase`` variable would be global to the entire module. This is
154+
error-prone as other functions within the module could be unintentionally using
155+
the global variable instead of a local name. A ``main`` function solves this
156+
problem.
157+
158+
Using a ``main`` function has the added benefit of the ``echo`` function itself
159+
being isolated and importable elsewhere. When ``echo.py`` is imported, the
160+
``echo`` and ``main`` functions will be defined, but neither of them will be
161+
called, because ``__name__ != '__main__'``.
162+
163+
164+
Packaging Considerations
165+
^^^^^^^^^^^^^^^^^^^^^^^^
166+
167+
``main`` functions are often used to create command-line tools by specifying
168+
them as entry points for console scripts. When this is done,
169+
`pip <https://pip.pypa.io/>`_ inserts the function call into a template script,
170+
where the return value of ``main`` is passed into :func:`sys.exit`.
171+
For example::
172+
173+
sys.exit(main())
174+
175+
Since the call to ``main`` is wrapped in :func:`sys.exit`, the expectation is
176+
that your function will return some value acceptable as an input to
177+
:func:`sys.exit`; typically, an integer or ``None`` (which is implicitly
178+
returned if your function does not have a return statement).
179+
180+
By proactively following this convention ourselves, our module will have the
181+
same behavior when run directly (i.e. ``python3 echo.py``) as it will have if
182+
we later package it as a console script entry-point in a pip-installable
183+
package.
184+
185+
In particular, be careful about returning strings from your ``main`` function.
186+
:func:`sys.exit` will interpret a string argument as a failure message, so
187+
your program will have an exit code of ``1``, indicating failure, and the
188+
string will be written to :data:`sys.stderr`. The ``echo.py`` example from
189+
earlier exemplifies using the ``sys.exit(main())`` convention.
190+
191+
.. seealso::
192+
193+
`Python Packaging User Guide <https://packaging.python.org/>`_
194+
contains a collection of tutorials and references on how to distribute and
195+
install Python packages with modern tools.
196+
197+
198+
``__main__.py`` in Python Packages
199+
----------------------------------
200+
201+
If you are not familiar with Python packages, see section :ref:`tut-packages`
202+
of the tutorial. Most commonly, the ``__main__.py`` file is used to provide
203+
a command-line interface for a package. Consider the following hypothetical
204+
package, "bandclass":
205+
206+
.. code-block:: text
207+
208+
bandclass
209+
├── __init__.py
210+
├── __main__.py
211+
└── student.py
212+
213+
``__main__.py`` will be executed when the package itself is invoked
214+
directly from the command line using the :option:`-m` flag. For example:
215+
216+
.. code-block:: shell-session
217+
218+
$ python3 -m bandclass
219+
220+
This command will cause ``__main__.py`` to run. How you utilize this mechanism
221+
will depend on the nature of the package you are writing, but in this
222+
hypothetical case, it might make sense to allow the teacher to search for
223+
students::
224+
225+
# bandclass/__main__.py
226+
227+
import sys
228+
from .student import search_students
229+
230+
student_name = sys.argv[2] if len(sys.argv) >= 2 else ''
231+
print(f'Found student: {search_students(student_name)}')
232+
233+
Note that ``from .student import search_students`` is an example of a relative
234+
import. This import style must be used when referencing modules within a
235+
package. For more details, see :ref:`intra-package-references` in the
236+
:ref:`tut-modules` section of the tutorial.
237+
238+
Idiomatic Usage
239+
^^^^^^^^^^^^^^^
240+
241+
The contents of ``__main__.py`` typically isn't fenced with
242+
``if __name__ == '__main__'`` blocks. Instead, those files are kept short,
243+
functions to execute from other modules. Those other modules can then be
244+
easily unit-tested and are properly reusable.
245+
246+
If used, an ``if __name__ == '__main__'`` block will still work as expected
247+
for a ``__main__.py`` file within a package, because its ``__name__``
248+
attribute will include the package's path if imported::
249+
250+
>>> import asyncio.__main__
251+
>>> asyncio.__main__.__name__
252+
'asyncio.__main__'
253+
254+
This won't work for ``__main__.py`` files in the root directory of a .zip file
255+
though. Hence, for consistency, minimal ``__main__.py`` like the :mod:`venv`
256+
one mentioned above are preferred.
257+
258+
.. seealso::
259+
260+
See :mod:`venv` for an example of a package with a minimal ``__main__.py``
261+
in the standard library. It doesn't contain a ``if __name__ == '__main__'``
262+
block. You can invoke it with ``python3 -m venv [directory]``.
263+
264+
See :mod:`runpy` for more details on the :option:`-m` flag to the
265+
interpreter executable.
266+
267+
See :mod:`zipapp` for how to run applications packaged as *.zip* files. In
268+
this case Python looks for a ``__main__.py`` file in the root directory of
269+
the archive.
270+
271+
272+
273+
``import __main__``
274+
-------------------
275+
276+
Regardless of which module a Python program was started with, other modules
277+
running within that same program can import the top-level environment's scope
278+
(:term:`namespace`) by importing the ``__main__`` module. This doesn't import
279+
a ``__main__.py`` file but rather whichever module that received the special
280+
name ``'__main__'``.
281+
282+
Here is an example module that consumes the ``__main__`` namespace::
283+
284+
# namely.py
285+
286+
import __main__
287+
288+
def did_user_define_their_name():
289+
return 'my_name' in dir(__main__)
290+
291+
def print_user_name():
292+
if not did_user_define_their_name():
293+
raise ValueError('Define the variable `my_name`!')
294+
295+
if '__file__' in dir(__main__):
296+
print(__main__.my_name, "found in file", __main__.__file__)
297+
else:
298+
print(__main__.my_name)
299+
300+
Example usage of this module could be as follows::
301+
302+
# start.py
303+
304+
import sys
305+
306+
from namely import print_user_name
307+
308+
# my_name = "Dinsdale"
309+
310+
def main():
311+
try:
312+
print_user_name()
313+
except ValueError as ve:
314+
return str(ve)
315+
316+
if __name__ == "__main__":
317+
sys.exit(main())
318+
319+
Now, if we started our program, the result would look like this:
320+
321+
.. code-block:: shell-session
322+
323+
$ python3 start.py
324+
Define the variable `my_name`!
325+
326+
The exit code of the program would be 1, indicating an error. Uncommenting the
327+
line with ``my_name = "Dinsdale"`` fixes the program and now it exits with
328+
status code 0, indicating success:
329+
330+
.. code-block:: shell-session
331+
332+
$ python3 start.py
333+
Dinsdale found in file /path/to/start.py
334+
335+
Note that importing ``__main__`` doesn't cause any issues with unintentionally
336+
running top-level code meant for script use which is put in the
337+
``if __name__ == "__main__"`` block of the ``start`` module. Why does this work?
338+
339+
Python inserts an empty ``__main__`` module in :attr:`sys.modules` at
340+
interpreter startup, and populates it by running top-level code. In our example
341+
this is the ``start`` module which runs line by line and imports ``namely``.
342+
In turn, ``namely`` imports ``__main__`` (which is really ``start``). That's an
343+
import cycle! Fortunately, since the partially populated ``__main__``
344+
module is present in :attr:`sys.modules`, Python passes that to ``namely``.
345+
See :ref:`Special considerations for __main__ <import-dunder-main>` in the
346+
import system's reference for details on how this works.
347+
348+
The Python REPL is another example of a "top-level environment", so anything
349+
defined in the REPL becomes part of the ``__main__`` scope::
13350

14-
A module can discover whether or not it is running in the main scope by
15-
checking its own ``__name__``, which allows a common idiom for conditionally
16-
executing code in a module when it is run as a script or with ``python
17-
-m`` but not when it is imported::
351+
>>> import namely
352+
>>> namely.did_user_define_their_name()
353+
False
354+
>>> namely.print_user_name()
355+
Traceback (most recent call last):
356+
...
357+
ValueError: Define the variable `my_name`!
358+
>>> my_name = 'Jabberwocky'
359+
>>> namely.did_user_define_their_name()
360+
True
361+
>>> namely.print_user_name()
362+
Jabberwocky
18363

19-
if __name__ == "__main__":
20-
# execute only if run as a script
21-
main()
364+
Note that in this case the ``__main__`` scope doesn't contain a ``__file__``
365+
attribute as it's interactive.
22366

23-
For a package, the same effect can be achieved by including a
24-
``__main__.py`` module, the contents of which will be executed when the
25-
module is run with ``-m``.
367+
The ``__main__`` scope is used in the implementation of :mod:`pdb` and
368+
:mod:`rlcompleter`.

Diff for: Doc/reference/import.rst

+2
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,8 @@ should expose ``XXX.YYY.ZZZ`` as a usable expression, but .moduleY is
975975
not a valid expression.
976976

977977

978+
.. _import-dunder-main:
979+
978980
Special considerations for __main__
979981
===================================
980982

0 commit comments

Comments
 (0)