Before you write much code, it helps to know what Python is, where it came from and what actually happens when you run a program. This unit gives you that picture: a short history, the release cycle that decides which version you should use, how the standard interpreter turns your text into running code, and the typing model behind many of the error messages you will meet.
None of this is trivia. Knowing that Python checks types while the program runs, for example, explains why some mistakes only show up when a particular line executes, and why tests and type checkers matter. Knowing the release cycle tells you when a tutorial is out of date.
You will be able to:
- Describe what Python is and name the main areas where it is used
- Outline Python's history and explain the yearly release cycle and support period
- Explain how CPython runs a program, from source code to bytecode to the interpreter
- Show with examples why Python is dynamically and strongly typed
- Find your way around the ecosystem: the PSF, PEPs, PyPI and the official documentation
What Python is
Python is a general purpose, high level programming language. General purpose means it isn't tied to one kind of task; high level means you work with ideas such as lists, text and files rather than memory addresses and CPU registers. Its design puts readability first: blocks of code are marked by indentation instead of braces, and the syntax uses plain English keywords such as and, not, in and with.
Python is free and open source. It is released under the PSF License, an OSI approved open source licence that also allows commercial use. A large standard library ships with every installation, so you can read JSON, talk to web servers, work with dates or zip files without installing anything extra.
You will find Python in many places:
| Area | Typical use |
|---|---|
| Web back ends | Django, Flask and FastAPI applications and APIs |
| Data analysis | Cleaning and summarising tables with pandas and NumPy |
| Machine learning | Training and serving models with PyTorch or scikit-learn |
| Automation | Scripts that rename files, call APIs or generate reports |
| DevOps and cloud | Deployment tooling, infrastructure scripts, cloud SDKs |
| Testing | Test suites for Python and non Python systems, using pytest |
| Science and education | Notebooks, simulations, first programming courses |
Here is a complete Python program. It sorts some words without caring about upper or lower case and prints each one with its length:
Notice what is missing: there are no type declarations, no semicolons and no braces. The indented line belongs to the for loop because it is indented, and that indentation is required, not a matter of style. Don't worry about the details yet; every piece of this program is explained in later units.
A short history
Guido van Rossum started work on Python in late 1989 at CWI, a research institute in Amsterdam. The name comes from the comedy series Monty Python's Flying Circus, not the snake.
| When | Milestone |
|---|---|
| February 1991 | Version 0.9.0 is published. It already has functions, exceptions, classes and the core types list, dict and str. |
| January 1994 | Python 1.0, which adds lambda, map, filter and reduce. |
| October 2000 | Python 2.0: list comprehensions, a garbage collector that can free reference cycles, and Unicode strings. |
| December 2008 | Python 3.0, a deliberate cleanup that breaks compatibility: print becomes a function, str becomes Unicode text with a separate bytes type, and 1 / 2 gives 0.5. |
| July 2018 | Guido van Rossum steps down as "Benevolent Dictator For Life". Since 2019 an elected five person Steering Council leads the language (PEP 13). |
| 1 January 2020 | Python 2 reaches its end of life and gets no more fixes, not even for security. |
| October 2024 | Python 3.13: a new interactive interpreter, an experimental JIT compiler and an experimental free threaded build. |
| October 2025 | Python 3.14: the free threaded build becomes officially supported. |
| October 2026 | Python 3.15: UTF-8 mode is on by default (PEP 686), and explicit lazy imports arrive (PEP 810). |
Note. If a tutorial uses
print "hello"without parentheses,raw_input()orxrange(), it was written for Python 2. Python 2 is no longer supported, and everything in this course is Python 3.
The yearly release cycle
Since Python 3.9, a new feature release (3.X.0) comes out every October, as described in PEP 602. Each version is supported for about five years. From 3.13 onwards that means two years of regular bug fix releases, followed by three years in which only security fixes are made. After that the version reaches its end of life.
In practice:
- Use a version that is still supported. This course targets Python 3.13 or newer, and every example was tested on CPython 3.15.
- The page Status of Python versions in the developer's guide lists the end of life date of each version.
- Read the "What's New" page in the documentation when you upgrade. It lists every change, including anything removed.
Implementations
"Python" names a language. A program that runs Python code is an implementation of that language, and there are several:
| Implementation | What it is | Good to know |
|---|---|---|
| CPython | The reference implementation, written in C, that you download from python.org | The default almost everywhere; new versions appear here first |
| PyPy | An implementation with a just in time (JIT) compiler | Long running pure Python code can run much faster; support for C extensions is less complete, and it usually trails CPython by a few versions |
| MicroPython | A small implementation for microcontrollers | Boards with a few hundred kilobytes of memory; it implements a subset of the standard library |
You can ask the running interpreter which implementation it is:
This course uses CPython throughout, so "Python" from here on means CPython.
How CPython runs your code
People often ask whether Python is compiled or interpreted. The honest answer is that this is a property of an implementation, not of the language, and CPython does both:
- It reads your
.pyfile and the tokeniser and parser turn the text into an abstract syntax tree (AST), a structured representation of the program. Syntax errors are reported at this stage, before any line runs. - The compiler turns the AST into bytecode: compact instructions for a virtual machine, not for your CPU.
- The interpreter, a loop written in C, executes the bytecode one instruction at a time.
Seeing the bytecode
The standard dis module ("disassembler") shows the bytecode of a function:
On CPython 3.15 the output looks like this. Your output will differ on other versions, because bytecode is an internal detail that changes in every release:
The numbers on the left are line numbers in the script, and each name in capitals is one bytecode instruction. You never need to read bytecode to write good Python. It is still useful to know it exists: it explains why a syntax error anywhere in a file stops the whole file from running, while a misspelt name only fails when that line executes.
The __pycache__ folder
When you import a module, CPython saves its bytecode in a __pycache__ folder next to the source file, so the next import can skip parsing and compiling. The file name includes a cache tag such as cpython-315, so several Python versions can share one folder. The script you run directly is compiled every time and is not cached.
This example writes a small module, imports it and lists the cache folder:
On 3.15 you see the output below; on another version the cache tag in the second line will differ:
Tip.
__pycache__folders are safe to delete; Python recreates them. Don't commit them to version control.
The JIT compiler and free threaded builds
Two newer pieces of CPython are worth knowing by name, even though you won't need them for a while.
- The JIT compiler (PEP 744). A just in time compiler translates frequently run bytecode into machine code while the program runs. CPython's JIT appeared as an experimental build option in 3.13. Since 3.14 the official Windows and macOS installers include it, switched off by default; setting the environment variable
PYTHON_JIT=1turns it on. It is still experimental, and speedups depend heavily on the program. - Free threaded builds (PEP 703). Normally CPython has a global interpreter lock (GIL): only one thread at a time can run Python bytecode, so threads can't use several CPU cores for pure Python work. A free threaded build removes the GIL. It was experimental in 3.13 and has been officially supported since 3.14 (PEP 779), but it is still a separate, optional build, installed as a command such as
python3.14t. The standard build keeps the GIL.
You can check which kind of build you are running:
On the standard build you see:
sys._is_gil_enabled() exists since 3.13. The leading underscore marks it as a low level function, but it is documented. The Concurrency unit explains what the GIL means for real programs.
Dynamic and strong typing
Two words describe Python's type system, and they are often confused.
Dynamic means that names don't have types; objects do. A name is a label that can point at any object, and the type is checked when an operation actually runs, not before. The same name can refer to an integer now and to a string later:
Strong means that Python won't silently convert one type into an unrelated one to make an operation work. Adding a number to a string is an error, not a guess:
The last line of the error report reads:
Some languages are weakly typed in this respect. In JavaScript, for example, "1" + 1 quietly produces the string "11". Python makes you say what you mean:
The last two lines aren't exceptions to strong typing. Numbers of different kinds combine because they are all numbers, and bool is a subclass of int; you will see why in Values, names and types.
Pitfall. "Dynamically typed" doesn't mean "untyped" or "anything goes". Every object has exactly one type, fixed for its whole life. What can change is which object a name refers to.
Type hints
Since Python 3.5 you can add optional type hints (PEP 484) that say what types you expect. The interpreter stores them but does not enforce them at run time:
Separate tools called type checkers, such as mypy and pyright (pyright also drives the type checking in VS Code's Python extension), read the hints and report mismatches before you run anything. Hints also make code easier to read and help your editor's autocompletion. You will write them throughout this course; the Functions unit covers them properly, and Packaging and tooling shows how to run a type checker.
The Zen of Python
In 1999 Tim Peters summed up the language's design philosophy in 20 aphorisms and left the last one unwritten, so 19 remain. They are recorded as PEP 20 and built into every installation as an "Easter egg": importing the module this prints them.
These lines are guidance, not rules, but you will see them at work throughout the course:
- Readability counts shows in indentation being part of the syntax, and in the style guide, PEP 8.
- Errors should never pass silently and refuse the temptation to guess are exactly what you saw with
"1" + 1: Python raises an error instead of inventing an answer. - Explicit is better than implicit is why you will pass
encoding="utf-8"when opening text files, even where it is the default. - There should be one obvious way to do it explains why the course often shows a first draft and then the idiomatic version.
The "Dutch" line is a nod to Guido van Rossum, who is Dutch.
The ecosystem
Python is more than an interpreter. These are the organisations and resources you will use most:
| Name | What it is |
|---|---|
| Python Software Foundation (PSF) | The nonprofit that holds Python's intellectual property and trademark, supports the infrastructure (including PyPI) and runs PyCon US. |
| PEPs | Python Enhancement Proposals: design documents for changes to the language and its processes, at peps.python.org. PEP 1 explains the process, PEP 8 is the style guide and PEP 20 is the Zen. |
| Steering Council | Five core developers, elected after each feature release, who accept or reject PEPs. |
| PyPI | The Python Package Index at pypi.org, where third party packages such as requests and pandas are published. You install from it with pip. |
| docs.python.org | The official documentation: a tutorial, the library reference, the language reference, a glossary and a "What's New" page for each release. |
| Community | Local user groups, PyCon conferences around the world and the forum at discuss.python.org. |
Pitfall. Anyone can publish a package on PyPI. Before you install one, check its exact name (attackers register lookalike names such as
reqeusts), its project page and whether it is maintained.
The next unit, Setting up Python, gets a current Python running on your computer.
Check yourself
- Is Python a compiled or an interpreted language?
- What is stored in a
__pycache__folder, and which files end up there? - Under PEP 602, how often does a new Python version appear, and for how long is it supported?
- Why does
"1" + 1raise an error while1 + 2.5works? - You annotate a parameter as
list[float]and then pass a tuple of integers. What happens when the code runs? - What does the free threaded build change, and is it the default in 3.14?
- Name one reason to choose PyPy and one reason to stay with CPython.
Suggested answers
- Neither label fits on its own; it depends on the implementation. CPython compiles source code to bytecode and then interprets the bytecode, optionally with an experimental JIT.
- Bytecode for imported modules, in files such as
greet.cpython-315.pyc. The script you run directly is not cached. - One feature release every October. Each gets about five years of support: since 3.13, two years of bug fixes and then three years of security fixes.
- Python is strongly typed: it won't convert a
strand anintinto each other implicitly. Integers and floats are both numbers, so mixing them is a defined numeric operation that produces a float. - It runs normally. Type hints are not enforced at run time; a type checker such as mypy or pyright would report the mismatch before you run the code.
- It removes the global interpreter lock, so threads can run Python code on several cores at once. It is officially supported since 3.14 but is a separate, optional build; the standard build still has the GIL.
- PyPy's JIT can make long running pure Python code much faster. CPython is the reference implementation, gets new versions first and has the most complete support for C extensions.
Exercises
These exercises are optional practice. Pick the ones that help you.
Each solution wraps the answer in a small function so it can be tested with assert. You will learn to write functions properly in the Functions unit; for now, copy the pattern. The exercises need a working Python, and their solutions use if, raise and try from later units. If you are new to programming, read them now for the ideas, and come back to do them after Setting up Python and Control flow.
- Release calendar. Under PEP 602, version 3.9 was released in October 2020 and each later minor version one year after the previous one. Support ends five years after release. Write
release_year(minor)andend_of_life_year(minor)for versions 3.9 and later. For example,release_year(13)is2024andend_of_life_year(15)is2031. For a minor number below 9, raiseValueError. - Counting the Zen. Importing
thisprints the Zen. Capture that text into a string instead of printing it (hint:contextlib.redirect_stdoutwith anio.StringIO()), then print how many aphorisms there are and how many contain the word "better". Expected output:19 aphorisms, 8 mention "better". - Type report. Write
describe(value)that returns the type name and the value's representation, separated by a colon, for exampledescribe(42)→"int: 42"anddescribe("42")→"str: '42'". Usetype(value).__name__andrepr(value). Test it with an int, a float, a string, a list andNone. - No silent conversions. Write
label(item, count)that returns text such as"apples: 3"forlabel("apples", 3), without raisingTypeError. Then show, usingtry/except TypeError, that"apples: " + 3fails, and print the error message.
Solutions
1. Release calendar.
2. Counting the Zen.
A module's code runs only on its first import, so this works only in a fresh interpreter where this hasn't been imported yet.
3. Type report.
4. No silent conversions.