Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

whatsnewt

A TUI text adventure through what's new in Python 3.15.

You wake up in the Startup Foyer, somewhere inside the interpreter, and work your way to the Release Gate. Along the way there are eighteen puzzles, and every one of them is a real 3.15 feature you have to actually use. You do not answer multiple choice questions about lazy imports; you write lazy import json in a code editor and the game checks that the name really did hold a proxy until something read it.

The exception is the Typing Sanctum, where the features are about what a type checker sees and running the code proves nothing: PEP 800 marks a class as a disjoint base and the interpreter still combines it quite happily. Those answers go to pyrefly, which is a dependency for exactly that reason, and the verdict quotes what it says back.

┌─ The Hall of Imports ──────────────────┬─ Progress ─────────────────────────┐
│ A hall the size of a cathedral, stacked│ Score    40 / 375                  │
│ to the vaulting with packages.  The    │ Puzzles  2 / 18                    │
│ moment anyone steps through the door,  │ Sigils   2 / 6                     │
│ every lid in the building flies open at│ Rooms    7 / 15                    │
│ once...                                ├─ Carrying ─────────────────────────┤
│                                        │ * the lazy lantern                 │
│ Puzzle: The packages that open         │ * the frozen seal                  │
│ themselves (PEP 810)                   ├─ Map ──────────────────────────────┤
│                                        │                ?                   │
│ > solve                                │   Crypt   -  Loop↓        ?        │
│                                        │                |                   │
│                                        │     ?       Gardens       ?        │
│                                        │                |                   │
│                                        │   Vault   ->Imports< -  Babel↑     │
│                                        │                |                   │
│                                        │              Foyer        ?        │
└────────────────────────────────────────┴────────────────────────────────────┘

Running it

$ ./play

That is a uv run shim. It fetches CPython 3.15 if that version isn't installed on your path, installs this checkout and its dependencies into a cached environment, and starts the game -- no virtual environment to create and nothing to activate first. It works from any directory, and it installs the checkout editable, so it runs your working tree rather than a snapshot of it.

Without a checkout:

$ uvx --python 3.15 whatsnewt

That runs straight from PyPI.

Useful flags, passed straight through by ./play:

Flag What it does
--text Play in a plain scrolling terminal instead of full screen
--load FILE Resume a saved game by name
--theme NAME textual-light, gruvbox, … — ctrl+p switches it while playing
--reset ROOM Unsolve a room so it can be played again — vault, the vault or Builtins, or all. Repeatable. Puts back the points and the reward too

Tab completes at the prompt: verbs first, then whatever the verb can take here -- ex<tab> gives examine, and examine st<tab> finds the staircase if this room has one. Ambiguous prefixes fill in as far as they agree and then show you the choice.

It needs Python 3.15

Since almost every puzzle is checked by running your answer against the feature it is about (such as : frozendict is the real built-in, math.integer is the real module, and the lazy-imports puzzle confirms the name really did hold a types.LazyImportType proxy until something read it) you actually need Python 3.15. A pre-release is acceptable.

Note that reading your source is still part of how answers are checked, and always will be: most of these puzzles have a boring answer that produces the right value the old way, so the checker looks at how you got there as well as what you got. A nested for loop that flattens correctly is still not what PEP 798 is for.

Commands

look north/n examine <thing> take drop inventory solve hint map score save load quit — and help for the rest.

Keys follow Emacs where Emacs has an opinion: ctrl+g aborts whatever is open, ctrl+h is help, ctrl+l re-shows the room, ctrl+r opens a puzzle — and checks your answer once you are inside it. The function keys still work, and every one of them is a command you can type instead.

Inside the editor: ctrl+r checks your answer, ctrl+h buys a hint for a point, ctrl+o hands the draft to $EDITOR and takes back whatever you save, and ctrl+g closes the window, keeping your draft for next time.

ctrl+o only suspends the game for editors that need the terminal. If yours opens a window of its own — emacsclient, code --wait, subl -w — the game stays up while you type, and takes the draft back when you save. Set WHATSNEWT_EDITOR_WINDOWED=1 (or =0) if the guess is wrong for yours.

Saving

The game saves itself after anything that changes it, so quitting, closing the terminal or losing the window costs you nothing — including whatever you had half-written in a puzzle editor. It writes to $XDG_STATE_HOME/whatsnewt/, falling back to ~/.local/state/whatsnewt/, rather than the working directory, since ./play deliberately runs from anywhere.

Start it again and it offers to resume your game. Declining doesn't throw it away: the old game is moved to previous-game.json beside it, so a mis-click is recoverable. save <file> and --load FILE still work for games you want to keep by name.

What it covers

Room Feature
The Startup Foyer PEP 829 — package startup configuration files
The Hall of Imports PEP 810 — explicit lazy imports
The Builtins Vault PEP 814 frozendict, PEP 661 sentinel
The Encoding Tower of Babel PEP 686 — UTF-8 as the default encoding
The Scriptorium Unicode 17.0.0 and unicodedata.iter_graphemes
The Threading Weir threading.serialize_iterator and friends
The Comprehension Gardens PEP 798 — unpacking in comprehensions
The Typing Sanctum PEP 728 TypedDict, PEP 747 TypeForm, PEP 800 disjoint_base
The Forge the upgraded JIT, mimalloc, bytearray.take_bytes
The Numerarium PEP 791 — math.integer
The Observatory PEP 799 — Tachyon, and PEP 831 frame pointers
The Deprecation Crypt what 3.15 removed
The Great Loop rather more color than there used to be
The Error Oracle improved error messages, re.prefixmatch
The Release Gate all of it, at once

Souvenirs lying around the place cover the rest: abi3t, Unicode 17 and grapheme clusters, slice[int], zlib.crc32_combine, the colored REPL completer.

Development

$ uv venv --python 3.15 && uv pip install -e '.[dev]'
$ pytest

The tests check that every puzzle rejects its own unedited starter, accepts the reference answer in tests/solutions.py, and survives being handed an empty string or something that is not Python at all. There is a full playthrough that walks every room, solves all eighteen and arrives at a perfect score, and the Textual front end is driven headlessly through Pilot rather than mocked. tests/test_shim.py keeps ./play, pyproject.toml and the version guard from disagreeing about which Python this needs.

tests/solutions.py doubles as the walkthrough, if you would rather read than play.

Everything the game teaches is answerable from Doc/whatsnew/3.15.rst.

Author

whatsnewt is Copyright (C) 2026 Barry Warsaw barry@python.org

Licensed under the terms of the Apache License Version 2.0. See the LICENSE file for details.

The game was largely co-written with Claude, so maybe Barry should be considered a Director or Producer in the music and film sense of the word. The game has been test run by Barry and several prominent Pythonistas before its release.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whatsnewt-3.15a1.tar.gz (112.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whatsnewt-3.15a1-py3-none-any.whl (82.5 kB view details)

Uploaded Python 3

File details

Details for the file whatsnewt-3.15a1.tar.gz.

File metadata

  • Download URL: whatsnewt-3.15a1.tar.gz
  • Upload date:
  • Size: 112.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for whatsnewt-3.15a1.tar.gz
Algorithm Hash digest
SHA256 f6f8b2d46e58e7e66caccb927f48f424cee73b0f6311c854191a4935d0c390de
MD5 7efd06341d7b95ec5659706ed45d54dc
BLAKE2b-256 8e6f96fd91f3382b68850707196e551f609d07694cf97d94c0045f6fd8ddefa4

See more details on using hashes here.

File details

Details for the file whatsnewt-3.15a1-py3-none-any.whl.

File metadata

  • Download URL: whatsnewt-3.15a1-py3-none-any.whl
  • Upload date:
  • Size: 82.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for whatsnewt-3.15a1-py3-none-any.whl
Algorithm Hash digest
SHA256 c4e3c6c7b4c424fd3c477a6ed3ebd09197ec9a1ed2d1cc1b24dfaed7d4f293d5
MD5 bb61eb3ff748d60214d6e1dcae64ee2f
BLAKE2b-256 74c977bc164c6b1d3eb7ffa2888a6e9e10206b63e7fefe03c795951d51acc1cd

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

3.15a1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page