EVE Online's Python 3 Migration Is a Masterclass in Legacy Runtime Risk
CCP Games is finally moving 2.4 million lines of EVE Online off Python 2 — six years after the interpreter stopped receiving security fixes. It's a useful case study in how technical debt in a runtime, not just an application, becomes a security liability.
Key Takeaways
- CCP Games has begun migrating EVE Online's 2.4-million-line codebase from Python 2 to Python 3, sixteen years after its last major runtime upgrade and six years after Python 2 reached end of life.
- Python 2 stopped receiving security fixes on January 1, 2020 — any vulnerability found in the interpreter itself since then has gone unpatched for anyone still running it.
- The migration's first stage alone required auditing roughly 20,000 lines where Python 2 and 3 silently behave differently, illustrating how expensive it becomes to remediate a runtime dependency the longer it's deferred.
- For security teams, an unsupported language runtime is a supply-chain risk indistinguishable in kind from an unpatched library — it just sits lower in the stack and is harder to see.
EVE Online launched in 2003 on Stackless Python and took its last major runtime upgrade in 2010, to Stackless Python 2.7. That version has now been running in production for sixteen years. On 25 August 2026, CCP Games announced it has begun a staged migration of the game's 2.4-million-line Python codebase to Python 3 — a project first flagged by Simon Willison.
The headline number isn't the code volume, it's the calendar. Python 2 reached official end of life on 1 January 2020. From that date, the Python core team stopped issuing bug fixes or security patches — a policy stated plainly on python.org's sunset page: "we will not improve it anymore after that day, even if someone finds a security problem in it." Any vulnerability class discovered in the CPython 2.7 interpreter since 2020 — memory safety issues, parsing bugs, anything — has had no upstream fix path for six years.
Why this matters beyond one game studio
It's tempting to file this under nostalgia — a beloved MMO finally catching up on tech debt. From a security standpoint it's a more general problem: an unsupported language runtime is a supply-chain dependency like any other, except it sits underneath every line of application code rather than in a single package.json or requirements.txt entry. Application-level CVE scanning, SCA tooling, and dependency-update bots don't reach it. The interpreter itself becomes the unpatched component, and because it's load-bearing for the entire product, replacing it is orders of magnitude harder than bumping a library version.
CCP's own numbers illustrate the cost of deferral. According to its announcement, 95.9% of files already parse under both Python 2.7 and Python 3 — the easy part. The remaining work splits into two tiers: about 3,300 lines needing straightforward syntax fixes (old print statements, deprecated exception syntax), and a much harder set of roughly 20,000 lines that run under both interpreters but produce different results — the classic example being 1 / 2, which evaluates to 0 in Python 2 and 0.5 in Python 3. CCP is using Python's futurize conversion tool for the mechanical pass, but the 20,000-line behavioral set requires manual, case-by-case review because no linter can prove intent.
The practitioner takeaway
This is what remediation cost curves for deferred runtime upgrades actually look like: not a single migration ticket, but a multi-stage program where the hard part is finding the silent behavioral divergences that a test suite written for the old runtime was never designed to catch. For teams carrying similarly old interpreters, framework versions, or OS base images in production — game backends, industrial control software, and internal line-of-business tools are all common offenders — the lesson isn't "upgrade Python." It's that the true cost of staying on an unsupported runtime compounds every year, and the earlier an inventory of EOL runtimes gets built, the cheaper the eventual migration is.
- Inventory your runtimes, not just your dependencies. SCA and SBOM tooling typically catalogue application libraries; interpreter and OS-level runtime versions need the same treatment.
- Track vendor/community EOL dates as a security control, not a project-management footnote — an EOL date is the day your patch pipeline for that component stops existing.
- Budget migrations before they become forced. CCP had the luxury of a planned, staged rewrite; a mandatory move driven by an active exploit in an unsupported runtime is a far worse position to migrate from.
FAQ
Frequently Asked Questions
Is EVE Online currently vulnerable because it runs Python 2?
Neither CCP's announcement nor Simon Willison's post mentions an active exploit or known vulnerability driving this specific migration; CCP frames it around performance, tooling, and maintainability. The underlying risk is structural: Python 2 has received no security patches since January 2020, so any interpreter-level vulnerability found since then would go unfixed for as long as a codebase stays on it.
What made this migration so labor-intensive after 16 years on the same runtime?
CCP reports 95.9% of its ~2.4 million lines already parse identically under Python 2 and 3. The expensive part is roughly 20,000 lines that run under both versions but produce different results — silent behavioral divergence, like integer division, that automated conversion tools such as `futurize` can flag but not safely resolve without human review.
What should security and engineering leaders take from this outside the gaming industry?
Treat language runtimes and OS base images as inventoried, EOL-tracked assets alongside application dependencies. The longer an unsupported runtime stays in production, the larger the eventual remediation project — CCP's staged, multi-year approach is a reasonable model for large legacy estates, but it only works if the migration starts before an unpatched vulnerability forces it.
Sources
- 1The Move to Python 3 Begins — CCP Games / EVE Online
- 2EVE Online: The Move to Python 3 Begins! — Simon Willison
- 3Sunsetting Python 2 — Python Software Foundation