A Python source file is plain text with no header. The interpreter decodes it to Unicode, splits it into tokens, compiles it to bytecode and runs it from the first statement to the last. This page covers the file itself. How the text is split into tokens is on the Lexical structure page.
Kinds of file
| File | Contents | Used by |
|---|---|---|
.py | Source code: a script or a module | The interpreter, and everything that imports it |
.pyw | Source code, normally run with no console window | pythonw.exe on Windows; on other systems it is treated as any other file name |
.pyi | A stub: type hints only, no running code | Type checkers and editors, never the interpreter |
__init__.py | Source code, run when its directory is imported as a regular package | The import system |
__main__.py | Source code, run when its package, directory or zip file is run as a program | The interpreter |
The name of a module comes from its file name, so a file that is meant to be imported needs a name that is also a valid identifier. A script run directly can have any name.
On Windows the import system accepts .pyw as source as well as
.py. On other systems only .py is imported as source.
Text and lines
A file holds a sequence of statements. The grammar for a whole file is short (Language Reference 9.2):
file_input: (NEWLINE | statement)* ENDMARKER
The same rule is used for a complete program, for a module, and for a string passed to
exec(). An empty file is a valid module.
- Lines may end in LF, CR LF or CR, and a file may mix them. Each is replaced by a single LF, even inside string literals (Language Reference 2.1.2).
- The last line needs no line ending. The end of the file ends it.
- A NUL byte is not allowed anywhere in source and raises
SyntaxError. - Indentation is part of the syntax, so spaces and tabs at the start of a line matter. See Indentation.
Source encoding
Source is UTF-8 unless the file says otherwise (PEP 3120, Python 3.0). Python 2 assumed ASCII. To use another encoding, the file carries an encoding declaration (PEP 263, Language Reference 2.1.4): a comment in the first or second line that matches this regular expression.
coding[=:]\s*([-\w.]+)
The first group names the encoding, and the name must be one Python's codecs know. The usual forms are written for editors, which recognise the same line:
# -*- coding: latin-1 -*-
# vim: set fileencoding=latin-1 :
# coding=latin-1
The rules are strict about where the comment goes:
| Case | Result |
|---|---|
| Matching comment on line 1 | Used as the declaration |
| Matching comment on line 2, after a comment line or a blank line | Used as the declaration |
| Matching comment on line 2, after a line of code | An ordinary comment; the file stays UTF-8 |
| Matching comment on line 3 or later | An ordinary comment |
| The name is not a known encoding | SyntaxError: unknown encoding |
| No declaration, and the file is not valid UTF-8 | SyntaxError |
A declaration covers the whole file, including its comments and string literals. It changes only how the source is decoded. Strings in the running program are always Unicode. Bytes literals may contain only ASCII characters whatever the source encoding is.
The source encoding has nothing to do with the encoding open() uses for
data files. That default became UTF-8 in Python 3.15 (PEP 686).
Byte order mark
A UTF-8 byte order mark (the bytes EF BB BF) at the very start of the
file is allowed and is skipped (Language Reference 2.1.4). A file with a BOM must be
UTF-8: if it also declares a different encoding, the compiler raises
SyntaxError. The BOM is optional and most tools leave it out.
A BOM before #! stops Unix from recognising the
shebang line, so an executable script should not have one.
The #! line
On Unix, a script that is marked executable can start with a #! line
naming the interpreter. The operating system reads that line when the file is run as a
command. To Python it is only a comment, so a file with one runs the same way under
python file.py.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Print a greeting."""
print("Hello, world")
#! line, then an encoding declaration on line 2, then the module docstringUsing /usr/bin/env python3 finds the interpreter through
PATH, which also picks up the active virtual environment. A file that has a
shebang must have it on line 1 starting at the first byte, so any encoding declaration
then goes on line 2.
Windows ignores the line, but the py launcher reads it to choose a Python
version (PEP 397, Python 3.3).
Modules
Each source file is one module, and its top-level code is the module body. The
body runs once, in order, the first time the module is imported. def and
class are statements like any other: they run when they are reached and
bind a name to a new object, so there is no separate declaration stage. Code can use a
name only after the statement that binds it has run.
Python does not fix the order of the parts of a file, except that a future statement must come before other code. By convention (PEP 8) a module is laid out like this:
#!/usr/bin/env python3
"""Count the words in a file."""
from __future__ import annotations
import sys
from collections import Counter
MAX_WORDS = 20
def count_words(path: str) -> Counter:
with open(path, encoding="utf-8") as file:
return Counter(file.read().split())
def main() -> int:
for word, count in count_words(sys.argv[1]).most_common(MAX_WORDS):
print(f"{count:6} {word}")
return 0
if __name__ == "__main__":
sys.exit(main())
Docstrings
A string literal that is the first statement of a module, class or function is its
docstring, stored in __doc__ and shown by
help(). It must be a plain string, so an f-string does not count.
Since Python 3.13 the compiler removes the common leading indentation from
docstring lines. The -OO option removes docstrings entirely.
Module attributes
These names are set on a module object by the import system (Language Reference 3.2.9):
| Attribute | Meaning |
|---|---|
__name__ | The module's name, such as email.mime.text; '__main__' when it is run as the program |
__doc__ | The docstring, or None |
__file__ | The path of the file it was loaded from. Not set for some modules, such as built-in ones |
__spec__ | The ModuleSpec holding the details the import system used. The cached path is __spec__.cached |
__path__ | Packages only: where to search for submodules |
__package__ | The name of the containing package. Deprecated; use __spec__.parent |
__loader__ | The loader. Deprecated; use __spec__.loader |
__dict__ | The module's namespace |
__builtins__ | The built-in namespace, an implementation detail |
__annotations__, __annotate__ | The module's annotations |
__cached__ is no longer set from Python 3.15. Use
__spec__.cached.
Running a file
A running program has a top-level module whose name is '__main__'. The
usual ways of starting Python all create it:
| Command | What runs | First entry on sys.path |
|---|---|---|
python file.py | The file | The file's directory |
python -m name | The module found on the path; for a package, its __main__ submodule | The current directory |
python dir or python app.zip | The __main__.py inside | The directory or zip file |
python -c code | The string given | The current directory |
python - | The text on standard input | The current directory |
The -P option leaves that first entry off, and -I (isolated
mode) implies it. A complete program starts with only sys,
builtins and __main__ initialised (Language Reference 9.1).
def main():
...
if __name__ == "__main__":
main()
main runs when the file is the program, and not when it is importedA package's __main__.py is usually short and imports the real code from
elsewhere in the package. Details of how modules are found are on
Modules and packages.
.pyw on Windows
A .pyw file holds the same language as a .py file. Windows
associates it with pythonw.exe, which runs the program without opening
a console. It suits programs with their own windows. sys.stdin,
sys.stdout and sys.stderr can be None under
pythonw.exe, so printing is not safe to rely on.
.pyi stub files
A stub file gives the types of a module without its code, for example for a module
written in C. It uses the same syntax as Python, with ... in place of
function bodies, and the extension .pyi lets it sit beside the matching
.py file. The interpreter never imports it. Only type checkers and editors
read it. The rules are on Type hints.
def greet(name: str, *, loud: bool = ...) -> str: ...
class Greeter:
prefix: str
def __init__(self, prefix: str) -> None: ...
.pyi stubHow a file becomes a .pyc
In CPython, the reference implementation, source goes through these stages. They are an implementation detail, not part of the language.
- Decoding. The bytes are decoded to text using the source encoding.
- Tokenising. The text becomes tokens, including NEWLINE, INDENT and
DEDENT. The
tokenizemodule shows them. - Parsing. A PEG parser (PEP 617, Python 3.9) builds an abstract
syntax tree, which
ast.parseexposes. - Compiling. A symbol table works out each name's
scope, then the tree is compiled
to a code object of bytecode, which
disdisassembles. - Running. The interpreter loop executes the code object.
When a module is imported from source, the code object is also stored in a
.pyc file, so the next import can skip
compiling. The script named on the command line is compiled but never cached.
The cached files live in a __pycache__ folder beside the source, named
with the interpreter's tag so that different versions can share the folder (PEP 3147,
Python 3.2):
| Source | Cached bytecode | Built by |
|---|---|---|
spam.py | __pycache__/spam.cpython-315.pyc | Default |
spam.py | __pycache__/spam.cpython-315.opt-1.pyc | -O: removes assert statements and code conditional on __debug__ |
spam.py | __pycache__/spam.cpython-315.opt-2.pyc | -OO: also removes docstrings |
The tag is sys.implementation.cache_tag. The .opt-N names
come from PEP 488 (Python 3.5), which ended the old .pyo files.
The .pyc header
A .pyc is a 16-byte header followed by the module's code object in
marshal format (PEP 552, Python 3.7):
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | Magic number: changes with the bytecode format, ending in CR LF |
| 4 | 4 | Flags. Bit 0 set means hash-based; bit 1 is check_source |
| 8 | 4 | Timestamp-based: the source's modification time |
| 12 | 4 | Timestamp-based: the source's size |
| 8 | 8 | Hash-based: a 64-bit SipHash of the source |
A timestamp-based .pyc (flags zero) is valid when the stored time and
size match the source. A hash-based one compares a hash of the source instead,
which suits reproducible builds. If check_source is clear, the import
system does not check at all.
The full layout is on the .PYC page.
Controlling the cache
| Option | Effect |
|---|---|
-B or PYTHONDONTWRITEBYTECODE | Do not write .pyc files on import |
-X pycache_prefix=PATH or PYTHONPYCACHEPREFIX | Keep the files in a mirror tree under PATH instead of __pycache__ |
--check-hash-based-pycs | Override whether hash-based files are validated |
python -m compileall | Compile a whole tree ahead of time, for directories users cannot write to |
A .pyc can stand in for missing source only as spam.pyc in
the place of spam.py. Files in __pycache__ are never used
without the source.