All notable changes to switchlang are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- A User Guide on the docs site: Getting started, How a switch block runs, Keys and
matching, Fall-through, Results, Errors and validation, Patterns, and a comparison with
dict/if-elif/match. Every code example in the guide is executed when the site is built, so the output shown is the output you get.
- The README is now a guided tour of the library rather than a feature list. Same behavior, told better; every claim is pinned by a test or an executed guide example.
- Docs build: the navbar version badge is derived from
pyproject.tomland the datedCHANGELOG.mdheading instead of the latest GitHub Release, so a site built for a new version shows that version before the release exists.
0.1.3 - 2026-06-11
- An exception raised inside the
withblock now always aborts the switch, even when the exception object is falsy.__exit__guarded its re-raise withif exc_val:, a truthiness test that invokes the exception's__bool__/__len__. An exception whose__bool__returnedFalseslipped past the guard, so the matched case action ran before the exception propagated. The guard now testsexc_val is not None, restoring the documented "no case actions run on exception" guarantee for every exception type. (#15)
0.1.2 - 2026-06-11
This release brings switchlang's whole public-facing surface up to date — a documentation site, a shipped type-hint contract, refreshed docs — and fixes two correctness bugs in the public API (#13, #14).
- Type information now ships with the package. A
py.typedmarker makes the hints public API, so switchlang's signatures type-check and autocomplete in IDEs and type checkers. Every public signature is annotated —case() -> bool,__enter__() -> switch,__exit__(...),result -> Any, andclosed_range(...) -> range— using modern, Python 3.9-safe syntax (from __future__ import annotations). (#13) - Documentation site at
mkennedy.codes/docs/python-switch,
built with Great Docs (Quarto): a
landing page plus an API reference for
switchandclosed_range. Includesscripts/build_docs.pyandscripts/serve_docs.py. (#13) closed_range()now validates its step. Astepless than 1 raises a clearValueErrorinstead of surfacing a rawrangeerror (forstep=0) or silently producing an empty range (for a negative step). (#14)uv add switchlanginstallation instructions alongside pip. (#13)
- Packaging modernized to
pyproject.toml+ hatchling: the version is read from package metadata, a[dev]extra is provided, Python 3.9–3.15 classifiers and aTyping :: Typedclassifier are declared, and full project URLs (docs, repository, issues, PyPI, funding) are published. (#13) case()now always returnsbool. It previously returnedNoneon a scalar no-match butFalseon a list no-match; the return value is now a consistentbool. (#13)- Tooling: ruff pinned to
target-version = "py39"to matchrequires-python = ">=3.9". (#13)
closed_range(start, stop, step)no longer overshootsstopwhenstep > 1. The inclusive bound was built asrange(start, stop + step, step), which added a full extra step — e.g.closed_range(1, 6, 2)yielded[1, 3, 5, 7], letting7(a value outside the stated range) silently match the case. The bound is now computed asstop + 1, so values never passstopwhilestopis still included when a step lands on it exactly (closed_range(1, 7, 2)->1, 3, 5, 7). (#14).resultno longer breaks for matched cases that return an always-equal object. The "no result" sentinel was compared with==, so a returned object with a permissive__eq__(a NumPy array is the real-world case) made.resultraise "No result has been computed" even though a result existed. The sentinel is now compared by identity (is). (#14)
- README refreshed: version and docs badges, a prominent link to the
documentation site, an honest feature list ("Validates that case actions are
callable", replacing an inaccurate signature-verification claim), a new
s.resultbullet, a new "Fall-through and results" section, a new "Why not justmatch?" section, aclosed_rangeusage example, and f-strings throughout. (#13) - Docstrings rewritten to render as the API reference:
switchis described as a context manager;default()documents that ordering is not enforced (register it last);case()documents its return contract, theValueErrors it raises, and the internal no-match sentinel;resultdocuments that the last function executed wins under fall-through; andclosed_rangeis documented as returning arangeobject (not a "generator") with its step semantics andValueError. (#13)
0.1.1 - 2025-09-11
- Standardized string literals on double quotes across the codebase and added
an initial round of type annotations, including a fix for a potential type
warning on
s.result.
0.1.0 - 2020-03-20
- Initial public release of switchlang on PyPI: an explicit
switchblock for Python built on thewithstatement, with default cases, duplicate-case detection, list/range cases, opt-in fall-through, and theclosed_rangehelper.