None of the major Python implementations do any AoT compilation.
Python is probably the poster-child language of "interpreted". It's run, line-by-line through an interpreter, and turned into byte-code, which is executed by the VM. There's no compilation, and in CPython, very little optimisation. PyPy is obviously different on that last point as it's a JIT, but the larger point still stands.
> It's run, line-by-line through an interpreter, and turned into byte-code, which is executed by the VM.
Just a small technical correction: you can pre-complie to .py source files to .pyc bytecode files without waiting for the interpreter to do it line by line, many distro package managers already perform this step automatically when a package is installed. Though you're right in the sense that it doesn't really improve performance, CPython itself is the slowest part, not bytecode generation.
> There's no compilation, and in CPython, very little optimisation.
+1. This was actually a deliberate design choice [0]. Guido van Rossum himself said, "Python is about having the simplest, dumbest compiler imaginable." CPython was designed for ease of learning and use, it was never designed to be a high-performance language. Pure Python code (without C extensions like NumPy) can never be good at number-crunching tasks.
There are still some basic optimizations the Python compiler makes. It has, for example, a keyhole optimizer, and some built in optimizations around integer objects to name two.
Itβs nothing too fancy, but it still does the basics.
Python is probably the poster-child language of "interpreted". It's run, line-by-line through an interpreter, and turned into byte-code, which is executed by the VM. There's no compilation, and in CPython, very little optimisation. PyPy is obviously different on that last point as it's a JIT, but the larger point still stands.