From d3e87351bda31466357d7b7aa4000afc786fec52 Mon Sep 17 00:00:00 2001 From: Abhik Sarkar Date: Sat, 20 Jun 2026 11:48:19 +0530 Subject: [PATCH 1/2] docs: finish pylings-to-pythonlings rename in CLAUDE.md The rename shipped in published 0.3.0 (package, dist, and the pythonlings command), but CLAUDE.md still documented the old pylings command, package paths, stylesheet, and entry point. Update them so contributors and agents run the command that actually ships. Bump to 0.3.1 (docs/packaging cleanup, no behavior change) and add the CHANGELOG entry. The unrelated pylings PyPI package belongs to a different project; pythonlings is the only command this project ships. Closes #24 --- CHANGELOG.md | 10 ++++++++++ CLAUDE.md | 14 +++++++------- Readme.md | 2 +- pyproject.toml | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24f30cb..778d3b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project are documented here. Pythonlings follows Semantic Versioning. +## [0.3.1] - 2026-06-20 + +### Fixed + +- Corrected stale `pylings` references in the contributor guide (`CLAUDE.md`): + the smoke-test command, manual-testing flows, package paths, stylesheet, and + entry point now consistently use the `pythonlings` name the project adopted + in 0.3.0. (The unrelated `pylings` PyPI package belongs to a different + project; `pythonlings` is the only command this project ships.) + ## [0.3.0] - 2026-06-10 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index dbf8214..e881eeb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,21 +13,21 @@ python -m pytest -q # full suite python -m pytest tests/unit/test_runner.py -q # one file python -m pytest tests/unit/test_state.py::test_name -q # one test -pylings --root tests/fixtures/passing_curriculum verify # smoke-test: all solutions pass their checks +pythonlings --root tests/fixtures/passing_curriculum verify # smoke-test: all solutions pass their checks python -m build # sdist + wheel ``` -Manual testing of flows: `pylings init --path ./learn-python` (create a learner workspace), `pylings` (TUI), `pylings run variables1`, `pylings dry-run variables1`, `pylings solution variables1`, `pylings hint`, `pylings list`, `pylings topics`, `pylings reset`. `--root` points any command at an arbitrary workspace (used heavily by tests against `tests/fixtures/`). +Manual testing of flows: `pythonlings init --path ./learn-python` (create a learner workspace), `pythonlings` (TUI), `pythonlings run variables1`, `pythonlings dry-run variables1`, `pythonlings solution variables1`, `pythonlings hint`, `pythonlings list`, `pythonlings topics`, `pythonlings reset`. `--root` points any command at an arbitrary workspace (used heavily by tests against `tests/fixtures/`). ## Architecture Two distinct trees in this repo: -1. **The application** — `pylings/` (installable package) +1. **The application** — `pythonlings/` (installable package) 2. **The curriculum** — repo-root `exercises/`, `checks/`, `solutions/`, and `info.toml` -At build time, hatch `force-include` maps the curriculum into the wheel as `pylings/curriculum/` (see `pyproject.toml`). `pylings init` copies that bundled curriculum into a self-contained learner workspace; progress lives in `/.pylings/state.json` (written atomically, with `.bak` recovery on corruption). +At build time, hatch `force-include` maps the curriculum into the wheel as `pythonlings/curriculum/` (see `pyproject.toml`). `pythonlings init` copies that bundled curriculum into a self-contained learner workspace; progress lives in `/.pythonlings/state.json` (written atomically, with `.bak` recovery on corruption). ### Curriculum model @@ -38,7 +38,7 @@ Each exercise is a triple that must stay in sync, plus a manifest entry: - `solutions/.py` — reference answer - `info.toml` — ordered `[[exercises]]` entries with `name`, `path`, `hint`, `docs` URL; this file is the source of truth for exercise order and topics -When changing curriculum, update all four, then run the relevant tests plus `pylings --root tests/fixtures/passing_curriculum verify`. Exercise names are topic + ordinal (`variables1`, `collections10`). +When changing curriculum, update all four, then run the relevant tests plus `pythonlings --root tests/fixtures/passing_curriculum verify`. Exercise names are topic + ordinal (`variables1`, `collections10`). ### How checks run (`core/runner.py`) @@ -47,8 +47,8 @@ An exercise passes when a generated runner script `exec()`s the exercise source ### Layering - `pythonlings/core/` — all filesystem, manifest, state, reset, solutions, and runner logic. No UI imports. (Checks rerun on a debounce in the TUI editor, not a filesystem watcher.) -- `pylings/screens/` and `pylings/widgets/` — Textual UI only; `pylings/app.py` wires them up; `pylings.tcss` holds styles. -- `pylings/cli.py` — argparse subcommands; entry point `pylings = "pylings.cli:main"`. +- `pythonlings/screens/` and `pythonlings/widgets/` — Textual UI only; `pythonlings/app.py` wires them up; `pythonlings.tcss` holds styles. +- `pythonlings/cli.py` — argparse subcommands; entry point `pythonlings = "pythonlings.cli:main"`. Keep UI behavior in screens/widgets and behavior logic in core — tests depend on this split (`tests/unit/` for core, `tests/integration/` for CLI/workspace flows, `tests/tui/` for Textual pilot tests, fixtures in `tests/fixtures/`). diff --git a/Readme.md b/Readme.md index cdbcfca..b750e61 100644 --- a/Readme.md +++ b/Readme.md @@ -27,7 +27,7 @@ cd learn-python && uvx pythonlings How it works: **edit** the broken exercise in the built-in editor → checks rerun as you type and advance you to the next one. That's the whole loop. -Status: `v0.3.0`, alpha — published on PyPI as `pythonlings`. +Status: `v0.3.1`, alpha — published on PyPI as `pythonlings`. ![Coding screen](docs/assets/screenshots/coding-screen.png) diff --git a/pyproject.toml b/pyproject.toml index 1ff9083..924dc03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pythonlings" -version = "0.3.0" +version = "0.3.1" description = "Python learnings, Rustlings-style, in a terminal TUI." readme = "Readme.md" requires-python = ">=3.9" From d8e391da4f3068612bc2663bc7c75e2a07c6d2d0 Mon Sep 17 00:00:00 2001 From: Abhik Sarkar Date: Sat, 20 Jun 2026 12:01:27 +0530 Subject: [PATCH 2/2] fix: derive pythonlings --version from package metadata cli.py hardcoded __version__ = "0.3.0" as a second version source separate from pyproject.toml, so 'pythonlings --version' reported the wrong number after the 0.3.1 bump. Read the version from installed package metadata instead, with a source-checkout fallback, so it can never drift from pyproject again. Surfaced while running the RELEASE.md pre-release checklist for 0.3.1. --- CHANGELOG.md | 4 ++++ pythonlings/cli.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 778d3b3..7351947 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ Semantic Versioning. ### Fixed +- `pythonlings --version` now reports the installed package version instead of + a separate hardcoded string in `cli.py` (which had drifted to `0.3.0`). The + version is read from package metadata, so it can no longer fall out of sync + with `pyproject.toml`. - Corrected stale `pylings` references in the contributor guide (`CLAUDE.md`): the smoke-test command, manual-testing flows, package paths, stylesheet, and entry point now consistently use the `pythonlings` name the project adopted diff --git a/pythonlings/cli.py b/pythonlings/cli.py index 0001a69..9ffccb1 100644 --- a/pythonlings/cli.py +++ b/pythonlings/cli.py @@ -3,9 +3,13 @@ import argparse import sys +from importlib.metadata import PackageNotFoundError, version as _package_version from pathlib import Path -__version__ = "0.3.0" +try: + __version__ = _package_version("pythonlings") +except PackageNotFoundError: # running from a source checkout without an install + __version__ = "0.0.0+unknown" def _build_parser() -> argparse.ArgumentParser: