From the Python documentation of the import system (bold emphasis mine):
5.8. Special considerations for
__main__
The
__main__
module is a special case relative to Python’s import system. As noted elsewhere, the__main__
module is directly initialized at interpreter startup, much likesys
andbuiltins
. However, unlike those two, it doesn’t strictly qualify as a built-in module. This is because the manner in which__main__
is initialized depends on the flags and other options with which the interpreter is invoked.5.8.1.
__main__.__spec__
Depending on how
__main__
is initialized,__main__.__spec__
gets set appropriately or toNone
.When Python is started with the
-m
option,__spec__
is set to the module spec of the corresponding module or package.__spec__
is also populated when the__main__
module is loaded as part of executing a directory, zipfile or othersys.path
entry.In the remaining cases
__main__.__spec__
is set toNone
, as the code used to populate the__main__
does not correspond directly with an importable module:
- interactive prompt
-c
option- running from stdin
- running directly from a source or bytecode file
Note that
__main__.__spec__
is alwaysNone
in the last case, even if the file could technically be imported directly as a module instead. Use the-m
switch if valid module metadata is desired in__main__
.Note also that even when
__main__
corresponds with an importable module and__main__.__spec__
is set accordingly, they’re still considered distinct modules. This is due to the fact that blocks guarded byif __name__ == "__main__":
checks only execute when the module is used to populate the__main__
namespace, and not during normal import.
Why isn’t a source/byte code file imported as a module when run as a script?
As specified in the documentation, a source/byte code file is not imported as a module when run as a script (python <file path>
) because running the code as a module is already the purpose of the -m
argument (python -m <module name>
).