AlgoMaster Logo

History of Python

Low Priority7 min readUpdated June 17, 2026
Listen to this chapter
Unlock Audio

Python didn't start as a data science language, a web language, or the default scripting tool of the AI era. It started as a holiday project by one person trying to fix the irritations of a language he had spent years working on. The path from that holiday project in 1989 to the language used today by everyone from beginners to OpenAI explains a lot about why Python looks the way it does. This chapter walks that timeline.

Origins at CWI in the Netherlands

In December 1989, a researcher named Guido van Rossum started work on a new language during the Christmas break at CWI (Centrum voor Wiskunde en Informatica), the national research institute for mathematics and computer science in Amsterdam. He was looking for a project to keep him busy over the holidays, and he had a specific itch to scratch.

Guido had been working on a language called ABC, also at CWI, aimed at teaching programming. ABC was elegant in some ways and frustrating in others. It was hard to extend, hard to connect to the operating system, and not really meant for serious system scripting. Guido wanted something that kept ABC's readability and beginner-friendliness, but felt practical for writing the kind of small tools sysadmins and researchers actually needed.

So he started building. The new language borrowed indentation-based blocks and a few syntactic ideas from ABC. It pulled the curly-brace-free, expression-oriented feel from Modula-3, especially around exceptions and modules. It was implemented in C, which made it easy to call into existing C libraries, something ABC had been bad at.

The name had nothing to do with snakes. Guido was a fan of the British comedy group Monty Python's Flying Circus, and he wanted a name that was short, slightly mysterious, and a little unserious. "Python" fit. The snake imagery came later, mostly through book covers and logos.

Python 1.0 and the Early Years

Guido released Python 0.9.0 publicly in February 1991 on the alt.sources Usenet newsgroup. Even that first public version already had most of the things people now think of as defining Python: classes, exception handling, functions, the core data types (str, list, dict), and modules. Indentation-based blocks were there from day one.

Python 1.0 shipped in January 1994, with lambda functions, map, filter, and reduce (borrowed from Lisp). The 1.x series ran through the late 1990s, picking up small but important pieces: keyword arguments, complex numbers, a richer standard library, and the first wave of third-party adoption. Python started showing up in scripting roles at NASA, in scientific computing, and in early web tooling.

This is also when Guido picked up the title BDFL: Benevolent Dictator For Life. Final decisions on language design came down to him. It wasn't formal, just how the community worked.

One thing worth knowing about the 1.x era: the language was already prioritizing readability and a small, consistent set of rules over raw expressive power. The famous Zen of Python ("readability counts", "there should be one obvious way to do it") wasn't written yet (Tim Peters wrote it in 2004 as PEP 20), but the spirit was already baked in.

The Python 2 to 3 Split

Python 2.0 was released in October 2000. It was a big jump from 1.x: it added list comprehensions, garbage collection that could handle reference cycles, full Unicode support (as a separate unicode type), and a more open development model under the newly formed Python Software Foundation.

The 2.x series ran for almost two decades and is probably the version most older code in the wild was written for. Python 2.7, the last 2.x release, came out in 2010.

But while Python 2 was maturing, Guido and the core team were quietly accumulating a list of things they wished they could fix. Some were small annoyances. Others were genuine design mistakes that couldn't be cleaned up without breaking existing code. By the mid-2000s, the list had grown enough that the team made a decision: instead of patching forever, they would do one big break.

Python 3.0 was released in December 2008. It was deliberately not backward compatible with Python 2. The headline changes:

ChangePython 2Python 3
printStatement: print "hello"Function: print("hello")
Default string typestr was bytes, unicode was textstr is Unicode text, bytes is bytes
Integer division5 / 2 gave 25 / 2 gives 2.5 (use // for floor division)
range()Returned a listReturns a lazy iterator
xrange()Existed alongside range()Removed; range() does the lazy thing
dict.keys() / .values()Returned listsReturn views
Exception syntaxexcept Exception, e:except Exception as e:

Each of these had a reason. Unicode-by-default fixed a decade of "why does my script crash on non-English text" pain. Making print a function meant you could use it like any other function, including passing it as an argument or replacing it. True division by default matched what beginners actually expect.

But the reasons didn't help anyone whose codebase already had thousands of print statements and string-vs-bytes assumptions wired in. The transition was painful. A whole ecosystem of libraries had to be ported. 2to3, a tool included with Python that mechanically rewrote 2.x source into 3.x, helped with the syntactic parts but couldn't fix subtler issues like the bytes/text split.

For roughly the first half of the 2010s, "are you on Python 2 or Python 3?" was a real question on most teams. Major libraries (NumPy, Django, requests) gradually shipped 3-compatible versions. Linux distributions, scientific computing platforms, and large companies migrated on different schedules.

Python 2 officially reached end of life on January 1, 2020. No more bug fixes, no more security patches from the core team. Some long-tail systems still run 2.7, but the language community has moved on.

Modern Python: Annual Releases and Key Milestones

After Python 3 stabilized, the release model went through one more change. For years, new 3.x versions shipped roughly every 18 months, but the schedule slipped a lot in practice. In 2019, PEP 602 proposed switching to a strict annual release cadence: one new minor version (3.x) every October.

PEP 602 took effect starting with Python 3.9 (released October 2020). Each minor release now gets:

  • 18 months of full bug fix support (regular releases with bug fixes).
  • About 5 years total of security support from the initial release (security patches only, after the bug fix window ends).

That means several Python versions are supported at any given time, and teams have a predictable upgrade target.

Here is the timeline of releases that actually changed how Python code looks.

The diagram marks the releases worth remembering. The early 1.x and 2.x dots set the foundation. Python 3.0 is the breaking change. Everything after 3.0 is incremental refinement, and the boxes from 3.5 onward are the ones that introduced features you'll see in modern codebases every day.

A version-by-version summary of the 3.x milestones:

VersionReleasedSignature Feature
3.5Sep 2015async / await keywords, type hints (PEP 484)
3.6Dec 2016f-strings (f"{name}"), variable annotations, ordered dicts (implementation detail)
3.7Jun 2018dataclasses, ordered dicts (officially guaranteed), breakpoint()
3.8Oct 2019Walrus operator (:=), positional-only parameters
3.9Oct 2020Dict merge operators (`
3.10Oct 2021Structural pattern matching (match / case), better error messages
3.11Oct 202210-60% faster interpreter, much clearer tracebacks, exception groups
3.12Oct 2023More precise error messages, per-interpreter GIL groundwork, f-string parser cleanup
3.13Oct 2024Experimental free-threaded build (no-GIL), improved interactive REPL

If you only memorize a few of these, the high-value ones for interviews are 3.5 (async/await), 3.6 (f-strings), 3.10 (match-case), and 3.11 (the performance jump).

A small snippet that uses features from several versions at once:

That same function, written for Python 2.7, would have looked noticeably older: no type hints, %-style or .format() strings, no match, no walrus. The surface of the language has changed more in the last decade than in the decade before it.

Governance: From BDFL to the Steering Council

For most of Python's life, the answer to "who decides?" was Guido. He had final say on language design through the PEP (Python Enhancement Proposal) process. Anyone could write a PEP. The community would discuss it on mailing lists. Guido, the BDFL, would either approve it, reject it, or send it back for revision.

That model worked for thirty years. Then in 2018, after a particularly heated debate over PEP 572 (the walrus operator), Guido posted a now-famous message titled "Transfer of Power" announcing that he was stepping down as BDFL. He stayed involved in the community but stopped being the final decision-maker.

The community then had to figure out how to govern itself. After several proposals (documented in PEP 8000 through PEP 8016), the community settled on a Steering Council model in PEP 13: a five-person elected council that has final authority over the language. Members serve for one release cycle and are elected by Python core developers. PEPs still go through the same discussion process, but the council, not a single person, signs off on the big calls.

The diagram above shows the rough path a proposal takes today. A core developer or community member writes a PEP. Discussion happens on the Python mailing lists and discuss.python.org. The Steering Council reviews and either accepts or rejects it.

Alongside the technical governance sits the Python Software Foundation (PSF), a non-profit founded in 2001 that holds Python's intellectual property, organizes PyCon, funds community work, and supports Python development through grants and sponsorships. The PSF doesn't decide language design (that's the Steering Council's job), but it owns the trademarks and handles the legal and financial side of the ecosystem.

Quiz

History of Python Quiz

7 quizzes