Skip to content

release: v0.3.0 — rename to pythonlings#23

Merged
abhiksark merged 10 commits into
mainfrom
dev
Jun 18, 2026
Merged

release: v0.3.0 — rename to pythonlings#23
abhiksark merged 10 commits into
mainfrom
dev

Conversation

@abhiksark

@abhiksark abhiksark commented Jun 10, 2026

Copy link
Copy Markdown
Owner

What

Promotes the pythonlings rename to main as the 0.3.0 release.

  • feat!: rename project from pylings to pythonlings (feat!: rename project from pylings to pythonlings #22) — PyPI package (python-learningspythonlings), CLI command (pylingspythonlings), Python package, docs domain, GitHub URLs, CI/publish workflows, README, docs site. Existing learner workspaces migrate automatically (.pylings/.pythonlings/, preserving progress and reset snapshots).
  • chore: bump version to 0.3.0
  • docs: fix RELEASE.md after the rename — corrects the package-name section, wheel filename, and documents the trusted-publisher prerequisite.

Release checklist (after merge)

  • Add pending publisher on pypi.org for project pythonlings (repo abhiksark/pythonlings, workflow publish.yml, environment pypi) — required before tagging
  • Tag v0.3.0 on main and create the GitHub Release → publish.yml builds, smoke-tests, and publishes to PyPI via trusted publishing
  • Porkbun DNS: CNAME pythonlings.abhik.aiabhiksark.github.io (Pages custom domain is already set; the old pylings.abhik.ai record never existed)
  • Optional: final python-learnings release pointing users at pythonlings (its trusted publisher on PyPI must first be updated to the renamed repo)

Tests

125 passed locally and in CI (3.11/3.12/3.13); fixture verify, fresh init, and legacy workspace migration verified manually.

Note: the 0.3.0 version number now belongs to this rename release — the "wider adoption" roadmap (docs/roadmap/0.3.0.md, milestone #1) should be re-targeted to 0.4.0.

Summary by CodeRabbit

Release Notes

  • New Features

    • Project renamed to Pythonlings (formerly Pylings)
    • CLI command changed to pythonlings (formerly pylings)
    • Automatic workspace migration from legacy .pylings/ to .pythonlings/ on next run
  • Documentation

    • Updated all guides, quick-start, and roadmap references for the new project name and command naming

The PyPI package (previously python-learnings), the CLI command
(previously pylings), and the Python package are all now pythonlings.
Legacy .pylings/ workspace state directories are migrated automatically
on the next run, preserving progress and reset snapshots.

Historical design docs under docs/superpowers/ keep the old name as a
record of past work.
feat!: rename project from pylings to pythonlings
Correct the package-name section (pythonlings is this project's own PyPI
name; pylings is the unrelated one), fix the wheel filename in the
verification snippet, refresh the version example to 0.3.0, and document
the trusted-publisher prerequisite for publishing under a new name.
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@abhiksark, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 55 minutes and 43 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12722211-bc56-494e-bbe6-b1d7867dd478

📥 Commits

Reviewing files that changed from the base of the PR and between 74d19bf and c265d74.

📒 Files selected for processing (44)
  • CHANGELOG.md
  • CLAUDE.md
  • Readme.md
  • pyproject.toml
  • pythonlings/app.py
  • pythonlings/cli.py
  • pythonlings/core/docs.py
  • pythonlings/core/manifest.py
  • pythonlings/docs/topics/async.md
  • pythonlings/docs/topics/classes.md
  • pythonlings/docs/topics/collections.md
  • pythonlings/docs/topics/comprehensions.md
  • pythonlings/docs/topics/conditionals.md
  • pythonlings/docs/topics/context_managers.md
  • pythonlings/docs/topics/dataclasses.md
  • pythonlings/docs/topics/datetime.md
  • pythonlings/docs/topics/decorators.md
  • pythonlings/docs/topics/dictionaries.md
  • pythonlings/docs/topics/enums.md
  • pythonlings/docs/topics/exceptions.md
  • pythonlings/docs/topics/file_io.md
  • pythonlings/docs/topics/functional.md
  • pythonlings/docs/topics/functions.md
  • pythonlings/docs/topics/generators.md
  • pythonlings/docs/topics/itertools.md
  • pythonlings/docs/topics/json.md
  • pythonlings/docs/topics/lists.md
  • pythonlings/docs/topics/loops.md
  • pythonlings/docs/topics/modules.md
  • pythonlings/docs/topics/oop_advanced.md
  • pythonlings/docs/topics/pathlib.md
  • pythonlings/docs/topics/recursion.md
  • pythonlings/docs/topics/regex.md
  • pythonlings/docs/topics/sets.md
  • pythonlings/docs/topics/strings.md
  • pythonlings/docs/topics/testing.md
  • pythonlings/docs/topics/tuples.md
  • pythonlings/docs/topics/type_hints.md
  • pythonlings/docs/topics/variables.md
  • pythonlings/widgets/exercise_tree.py
  • scripts/fetch_python_docs.py
  • tests/integration/test_cli_workspace.py
  • tests/unit/test_docs.py
  • tests/unit/test_watcher.py
📝 Walkthrough

Walkthrough

This pull request renames the project from pylings/python-learnings to pythonlings throughout the codebase and documentation. The rename includes a version bump to 0.3.0, updates workspace state directories from .pylings/ to .pythonlings/, migrates all package imports and namespace references, renames the main TUI application class, and updates all test suites and documentation files.

Changes

Pythonlings Project Rename

Layer / File(s) Summary
Package identity and project metadata
pyproject.toml
Project name and distribution updated to pythonlings v0.3.0; console script entry point, package target, URLs, and keywords all switched from pylings/python-learnings to pythonlings.
CLI entry point and version
pythonlings/__main__.py, pythonlings/cli.py, pythonlings/app.py
CLI version constant bumped to 0.3.0; main application class renamed from PylingsApp to PythonlingsApp with CSS path updated; __main__.py fixed to import from pythonlings.cli.
Workspace state migration and directory naming
pythonlings/core/curriculum.py, pythonlings/core/state.py, pythonlings/core/reset.py, .gitignore
New migrate_legacy_state_dir() helper added to rename .pylings/.pythonlings/ on next run; state/reset/curriculum modules updated to target .pythonlings/state.json and .pythonlings/originals/ paths; workspace error messages and gitignore patterns updated.
CLI command handlers and main logic
pythonlings/cli.py
All command handlers updated to import pythonlings.core.* modules, standardize error prefixes to pythonlings:, call legacy workspace migration in main(), and update debug log file paths.
Core module namespace updates
pythonlings/core/*
All core modules updated: headers reflect pythonlings paths; imports switched from pylings.core to pythonlings.core; source_root() and bundled docs access updated to use pythonlings package namespace; default welcome message updated to "Welcome to pythonlings!".
TUI application and screen namespace updates
pythonlings/app.py, pythonlings/screens/*, pythonlings/widgets/*
Screens and widgets import from pythonlings core modules; new ProgressBar widget added; all dynamic imports updated to use pythonlings.screens and pythonlings.core paths.
Exercise and solution reference updates
exercises/*/, solutions/_answers.py, checks/pathlib/pathlib2.py
Exercise fixture data and solution answer references updated to use pythonlings names/paths (JSON project names, Path objects, test assertions).
Integration test infrastructure
tests/integration/test_cli_*.py
Test helpers invoke python -m pythonlings instead of pylings; CLI module imports and workspace/log file paths updated; test fixtures and assertions aligned with new naming.
Unit test imports and workspace assertions
tests/unit/test_*.py
All unit tests import from pythonlings.core.* modules; workspace initialization tests verify .pythonlings/ directory and state.json paths; default welcome message assertions updated.
TUI test updates
tests/tui/test_*.py
Test suite instantiates PythonlingsApp instead of PylingsApp; module imports use pythonlings.* paths; work-copy ignore pattern updated.
Documentation, configuration, and build files
CHANGELOG.md, CONTRIBUTING.md, Readme.md, RELEASE.md, AGENTS.md, mkdocs.yml, .gitignore, CNAME, docs-site/*, .github/workflows/*, docs/*, info.toml
All markdown docs, config files, workflows, and issue templates renamed to reference pythonlings; domain records updated to pythonlings.abhik.ai; new CLAUDE.md added with developer guidance.
Documentation generation and asset scripts
scripts/fetch_python_docs.py, scripts/generate_demo_gif.sh, docs/demo.tape, docs/DEMO_GIF.md
Doc fetcher and demo scripts updated to use pythonlings/docs output paths, pythonlings user-agent, and /tmp/pythonlings-demo workspace; demo tape and asset filenames updated to pythonlings-demo.gif.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 The project once called pylings takes a new name today,
With pythonlings branding in every file and every way,
From state dirs that migrate (.pylings to .pythonlings fine),
To CLI commands and core modules aligned,
Plus docs and solutions—a comprehensive, thoughtful design! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.98% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'release: v0.3.0 — rename to pythonlings' clearly and concisely summarizes the main change: a release promoting the project rename to pythonlings as version 0.3.0.
Description check ✅ Passed The PR description is comprehensive and well-structured. It includes a clear 'What' section explaining the changes, lists key improvements, provides a post-merge release checklist, includes test results, and notes version numbering implications.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
tests/integration/test_cli_run.py (1)

1-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

This test module is missing the required future-annotations import.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_cli_run.py` around lines 1 - 5, Add the required
future annotations import at the very top of the module by inserting "from
__future__ import annotations" as the first statement in
tests/integration/test_cli_run.py (before the existing imports like subprocess,
sys, and pathlib.Path) so the module uses postponed evaluation of annotations
per project guidelines.

Source: Coding guidelines

tests/integration/test_cli_verify.py (1)

1-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

Please add the required future-annotations import to keep this module guideline-compliant.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_cli_verify.py` around lines 1 - 5, This module is
missing the required future-annotations import; add the future import for
annotations at the very top of the file (before any other imports) in
tests/integration/test_cli_verify.py so the module complies with the guideline
that all .py files use future annotations.

Source: Coding guidelines

tests/integration/test_cli_topics.py (1)

1-7: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

The file is missing the required future import.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_cli_topics.py` around lines 1 - 7, Add the future
import "from __future__ import annotations" as the very first statement in the
module (before any other imports or code) in the test file that imports
subprocess, sys, Path and pythonlings.cli._build_parser; this ensures the file
uses postponed evaluation of annotations per project guidelines.

Source: Coding guidelines

docs-site/roadmap.md (1)

12-12: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update GitHub install version to v0.3.0.

The current release section references "v0.1.0" but this PR releases v0.3.0.

📝 Proposed fix
-- GitHub install path for `v0.1.0`.
+- GitHub install path for `v0.3.0`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs-site/roadmap.md` at line 12, Update the release version string in the
roadmap doc where it currently reads "v0.1.0" (the GitHub install path mention)
to "v0.3.0" so the release section reflects this PR; locate the text "GitHub
install path for `v0.1.0`" and change it to "GitHub install path for `v0.3.0`".
pythonlings/__main__.py (1)

1-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations import.

As per coding guidelines, all Python modules should include from __future__ import annotations at the top. All other modules in this PR (app.py, cli.py, curriculum.py, manifest.py) include this import.

📋 Proposed fix
+from __future__ import annotations
+
 from pythonlings.cli import main

 if __name__ == "__main__":
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pythonlings/__main__.py` around lines 1 - 5, Add the future annotations
import to this module by inserting "from __future__ import annotations" as the
first line of pythonlings/__main__.py so the module matches the project's typing
conventions; keep the existing "from pythonlings.cli import main" and the
"__main__" guard with raise SystemExit(main()) unchanged, only prepend the
future import at the top of the file.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLAUDE.md`:
- Line 16: Update the smoke-test command in CLAUDE.md to use the renamed CLI:
replace the legacy "pylings --root tests/fixtures/passing_curriculum verify"
invocation with "pythonlings --root tests/fixtures/passing_curriculum verify" so
the documented command matches the current tool name; locate the exact snippet
string "pylings --root tests/fixtures/passing_curriculum verify" and change only
the executable name to "pythonlings".
- Line 21: Replace every occurrence of the old CLI name "pylings" in the
CLAUDE.md text (specifically the manual testing flow line containing commands
like `pylings init --path ./learn-python`, `pylings run variables1`, `pylings
dry-run variables1`, `pylings solution variables1`, `pylings hint`, `pylings
list`, `pylings topics`, `pylings reset`, and the `--root` mention) with the new
CLI name "pythonlings" so the documentation reflects the updated command names.
- Around line 27-30: Update the package and state directory names: replace
occurrences of the package path string "pylings/" with "pythonlings/" (e.g.,
referenced where the application package is described) and replace the state
directory path ".pylings/" with ".pythonlings/" (e.g., where workspace progress
is described and the atomic write/.bak recovery is documented) so the
README/documentation matches the renamed package and state directory.
- Around line 49-52: Update the outdated package paths in the layering
documentation: replace all occurrences of the `pylings/*` package names with
`pythonlings/*` (e.g. `pylings/core/` → `pythonlings/core/`, `pylings/screens/`
→ `pythonlings/screens/`, `pylings/widgets/` → `pythonlings/widgets/`,
`pylings/app.py` → `pythonlings/app.py`, `pylings.tcss` → `pythonlings.tcss`,
and the entry point `pylings = "pylings.cli:main"` → `pythonlings =
"pythonlings.cli:main"`). Ensure every mention in this block is updated so the
docs match the renamed package.
- Line 41: The README text still references the old CLI name `pylings`; update
the verification command string to `pythonlings --root
tests/fixtures/passing_curriculum verify` wherever it appears (specifically the
sentence mentioning running `pylings --root tests/fixtures/passing_curriculum
verify`) so the document uses the current `pythonlings` command name.

In `@docs-site/index.md`:
- Line 22: Update the version reference in the sentence that currently reads
"stable v0.1.0 release" to "stable v0.3.0 release" (and ensure any accompanying
GitHub tag mention matches v0.3.0); locate the exact string in the docs-site
index content and replace the v0.1.0 token with v0.3.0 so the text and tag
reference reflect the current release.
- Around line 34-36: Update the project status line that currently reads
"Pythonlings is currently `v0.1.0` alpha." to reflect the new release by
replacing `v0.1.0` with `v0.3.0` so the sentence becomes "Pythonlings is
currently `v0.3.0` alpha."; locate the exact sentence in docs-site/index.md and
change only the version token, leaving the rest of the wording intact.
- Line 15: Update the installation command string that currently pins the repo
tag "v0.1.0" in the pipx command (the literal line pipx install
"git+https://github.com/abhiksark/pythonlings.git@v0.1.0") to use the new
release tag "v0.3.0"; locate the exact pipx install string and replace the tag
suffix `@v0.1.0` with `@v0.3.0` so docs install the released version.

In `@docs-site/quick-start.md`:
- Line 8: Update the installation tag in docs-site/quick-start.md by replacing
the outdated version string "`@v0.1.0`" in the pipx install command (the line
containing pipx install
"git+https://github.com/abhiksark/pythonlings.git@v0.1.0") with the new release
tag "`@v0.3.0`" so the docs install the correct released version.

In `@docs-site/roadmap.md`:
- Line 3: The roadmap text currently reads "Pythonlings is currently `v0.1.0`
alpha." but the release is v0.3.0; update that version string to `v0.3.0` and
adjust any related wording (e.g., "alpha" if no longer accurate) so the sentence
reads correctly with `v0.3.0`, and search the document for any other occurrences
of `v0.1.0` to replace them with `v0.3.0` for consistency.

In `@pythonlings/cli.py`:
- Around line 262-265: The workspace selection uses args.root before args.path
so --path is ignored (args.root has a default); update the assignment of
workspace to prefer args.path first and fall back to args.root (e.g., use
getattr(args, "path", None) or args.path or getattr(args, "root", None)) so
migrate_legacy_state_dir(Path(workspace)) runs against the explicit --path for
init/update; locate the workspace variable assignment in pythonlings.cli and
adjust it accordingly.

In `@tests/integration/test_cli_solution.py`:
- Around line 1-4: Add the future annotations import to the top of this test
module: insert "from __future__ import annotations" as the very first statement
in the file before any other imports in tests/integration/test_cli_solution.py
so the module (which imports pythonlings.cli.main) uses postponed evaluation of
annotations consistently with the project guidelines.

In `@tests/integration/test_cli_workspace.py`:
- Around line 1-4: Add the future import statement at the top of the module so
the file uses postponed evaluation of annotations; insert "from __future__
import annotations" as the very first import line in the
tests/integration/test_cli_workspace.py module (above the existing "from pathlib
import Path" and "from pythonlings.cli import main") to satisfy the project's
coding guideline.

In `@tests/integration/test_installed_package.py`:
- Around line 1-3: Add the required future import by inserting "from __future__
import annotations" at the very top of the module (before any other imports or
code) in tests/integration/test_installed_package.py so the file begins with
that future import followed by the existing imports (Path and
pythonlings.cli.main); ensure there is no blank line or other code above the
future import.

In `@tests/integration/test_solution_verify.py`:
- Around line 1-6: Add the future import statement at the very top of the module
(before any other imports) in test_solution_verify.py by inserting "from
__future__ import annotations" above the existing imports; ensure it appears
before the current imports that bring in load (pythonlings.core.manifest),
run_verify (pythonlings.core.runner) and solution_exercise
(pythonlings.core.solutions) so the module uses postponed evaluation of
annotations.

In `@tests/unit/test_runner.py`:
- Around line 3-6: Add the module-level future import "from __future__ import
annotations" as the very first statement in this test module (before any other
imports) to comply with the project header guideline; update
tests/unit/test_runner.py by inserting that import at the top of the file above
the existing imports (which currently include Exercise and run) and replicate
the same change across other test/fixture modules that lack it.

---

Outside diff comments:
In `@docs-site/roadmap.md`:
- Line 12: Update the release version string in the roadmap doc where it
currently reads "v0.1.0" (the GitHub install path mention) to "v0.3.0" so the
release section reflects this PR; locate the text "GitHub install path for
`v0.1.0`" and change it to "GitHub install path for `v0.3.0`".

In `@pythonlings/__main__.py`:
- Around line 1-5: Add the future annotations import to this module by inserting
"from __future__ import annotations" as the first line of
pythonlings/__main__.py so the module matches the project's typing conventions;
keep the existing "from pythonlings.cli import main" and the "__main__" guard
with raise SystemExit(main()) unchanged, only prepend the future import at the
top of the file.

In `@tests/integration/test_cli_run.py`:
- Around line 1-5: Add the required future annotations import at the very top of
the module by inserting "from __future__ import annotations" as the first
statement in tests/integration/test_cli_run.py (before the existing imports like
subprocess, sys, and pathlib.Path) so the module uses postponed evaluation of
annotations per project guidelines.

In `@tests/integration/test_cli_topics.py`:
- Around line 1-7: Add the future import "from __future__ import annotations" as
the very first statement in the module (before any other imports or code) in the
test file that imports subprocess, sys, Path and pythonlings.cli._build_parser;
this ensures the file uses postponed evaluation of annotations per project
guidelines.

In `@tests/integration/test_cli_verify.py`:
- Around line 1-5: This module is missing the required future-annotations
import; add the future import for annotations at the very top of the file
(before any other imports) in tests/integration/test_cli_verify.py so the module
complies with the guideline that all .py files use future annotations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b7b0d7d-2573-46da-a4cd-1e749bba7c93

📥 Commits

Reviewing files that changed from the base of the PR and between a6567e3 and 74d19bf.

⛔ Files ignored due to path filters (1)
  • docs/assets/demos/pythonlings-demo.gif is excluded by !**/*.gif
📒 Files selected for processing (116)
  • .github/ISSUE_TEMPLATE/bug_report.md
  • .github/workflows/ci.yml
  • .github/workflows/publish.yml
  • .gitignore
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • CNAME
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • RELEASE.md
  • Readme.md
  • checks/pathlib/pathlib2.py
  • docs-site/CNAME
  • docs-site/contributing.md
  • docs-site/curriculum.md
  • docs-site/index.md
  • docs-site/interface.md
  • docs-site/local-docs.md
  • docs-site/quick-start.md
  • docs-site/roadmap.md
  • docs-site/robots.txt
  • docs/DEMO_GIF.md
  • docs/RELEASE_PROCESS.md
  • docs/demo.tape
  • docs/roadmap/0.3.0.md
  • exercises/json/json5.py
  • exercises/json/json8.py
  • exercises/pathlib/pathlib2.py
  • info.toml
  • mkdocs.yml
  • pyproject.toml
  • pythonlings/__init__.py
  • pythonlings/__main__.py
  • pythonlings/app.py
  • pythonlings/cli.py
  • pythonlings/core/__init__.py
  • pythonlings/core/curriculum.py
  • pythonlings/core/docs.py
  • pythonlings/core/exercise.py
  • pythonlings/core/manifest.py
  • pythonlings/core/reset.py
  • pythonlings/core/runner.py
  • pythonlings/core/solutions.py
  • pythonlings/core/state.py
  • pythonlings/core/watcher.py
  • pythonlings/docs/NOTICE.md
  • pythonlings/docs/__init__.py
  • pythonlings/docs/index.json
  • pythonlings/docs/topics/__init__.py
  • pythonlings/docs/topics/async.md
  • pythonlings/docs/topics/classes.md
  • pythonlings/docs/topics/collections.md
  • pythonlings/docs/topics/comprehensions.md
  • pythonlings/docs/topics/conditionals.md
  • pythonlings/docs/topics/context_managers.md
  • pythonlings/docs/topics/dataclasses.md
  • pythonlings/docs/topics/datetime.md
  • pythonlings/docs/topics/decorators.md
  • pythonlings/docs/topics/dictionaries.md
  • pythonlings/docs/topics/enums.md
  • pythonlings/docs/topics/exceptions.md
  • pythonlings/docs/topics/file_io.md
  • pythonlings/docs/topics/functional.md
  • pythonlings/docs/topics/functions.md
  • pythonlings/docs/topics/generators.md
  • pythonlings/docs/topics/itertools.md
  • pythonlings/docs/topics/json.md
  • pythonlings/docs/topics/lists.md
  • pythonlings/docs/topics/loops.md
  • pythonlings/docs/topics/modules.md
  • pythonlings/docs/topics/oop_advanced.md
  • pythonlings/docs/topics/pathlib.md
  • pythonlings/docs/topics/recursion.md
  • pythonlings/docs/topics/regex.md
  • pythonlings/docs/topics/sets.md
  • pythonlings/docs/topics/strings.md
  • pythonlings/docs/topics/testing.md
  • pythonlings/docs/topics/tuples.md
  • pythonlings/docs/topics/type_hints.md
  • pythonlings/docs/topics/variables.md
  • pythonlings/pythonlings.tcss
  • pythonlings/screens/__init__.py
  • pythonlings/screens/docs.py
  • pythonlings/screens/topic_picker.py
  • pythonlings/screens/track.py
  • pythonlings/widgets/__init__.py
  • pythonlings/widgets/editor_pane.py
  • pythonlings/widgets/exercise_tree.py
  • pythonlings/widgets/output_panel.py
  • pythonlings/widgets/progress.py
  • scripts/fetch_python_docs.py
  • scripts/generate_demo_gif.sh
  • solutions/_answers.py
  • tests/integration/test_cli_cold_start.py
  • tests/integration/test_cli_dry_run.py
  • tests/integration/test_cli_hint.py
  • tests/integration/test_cli_reset.py
  • tests/integration/test_cli_run.py
  • tests/integration/test_cli_solution.py
  • tests/integration/test_cli_topics.py
  • tests/integration/test_cli_verify.py
  • tests/integration/test_cli_workspace.py
  • tests/integration/test_installed_package.py
  • tests/integration/test_solution_verify.py
  • tests/tui/test_app_pilot.py
  • tests/tui/test_editor_pane.py
  • tests/tui/test_output_panel.py
  • tests/unit/test_curriculum.py
  • tests/unit/test_docs.py
  • tests/unit/test_exercise.py
  • tests/unit/test_manifest.py
  • tests/unit/test_reset.py
  • tests/unit/test_runner.py
  • tests/unit/test_state.py
  • tests/unit/test_watcher.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (13)
tests/integration/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

Integration tests should be organized in tests/integration/ with file naming convention test_<behavior>.py and test function naming test_<expected_behavior>

Files:

  • tests/integration/test_cli_dry_run.py
  • tests/integration/test_installed_package.py
  • tests/integration/test_cli_run.py
  • tests/integration/test_cli_reset.py
  • tests/integration/test_cli_workspace.py
  • tests/integration/test_cli_solution.py
  • tests/integration/test_cli_hint.py
  • tests/integration/test_cli_cold_start.py
  • tests/integration/test_solution_verify.py
  • tests/integration/test_cli_verify.py
  • tests/integration/test_cli_topics.py
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Use pytest for all tests with async test support via pytest-asyncio in auto mode

Files:

  • tests/integration/test_cli_dry_run.py
  • tests/integration/test_installed_package.py
  • tests/integration/test_cli_run.py
  • tests/integration/test_cli_reset.py
  • tests/tui/test_output_panel.py
  • tests/unit/test_exercise.py
  • tests/integration/test_cli_workspace.py
  • tests/integration/test_cli_solution.py
  • tests/unit/test_curriculum.py
  • tests/integration/test_cli_hint.py
  • tests/integration/test_cli_cold_start.py
  • tests/unit/test_docs.py
  • tests/unit/test_manifest.py
  • tests/tui/test_editor_pane.py
  • tests/unit/test_runner.py
  • tests/integration/test_solution_verify.py
  • tests/integration/test_cli_verify.py
  • tests/unit/test_reset.py
  • tests/unit/test_watcher.py
  • tests/integration/test_cli_topics.py
  • tests/unit/test_state.py
  • tests/tui/test_app_pilot.py
**/*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Guard newer-stdlib usage with requires-python = ">=3.9" (e.g., tomllib falls back to tomli in core/manifest.py); use from __future__ import annotations at the top of modules

Files:

  • tests/integration/test_cli_dry_run.py
  • checks/pathlib/pathlib2.py
  • exercises/pathlib/pathlib2.py
  • tests/integration/test_installed_package.py
  • tests/integration/test_cli_run.py
  • pythonlings/__main__.py
  • pythonlings/core/reset.py
  • exercises/json/json8.py
  • pythonlings/widgets/progress.py
  • tests/integration/test_cli_reset.py
  • pythonlings/core/solutions.py
  • tests/tui/test_output_panel.py
  • tests/unit/test_exercise.py
  • solutions/_answers.py
  • pythonlings/widgets/editor_pane.py
  • tests/integration/test_cli_workspace.py
  • pythonlings/core/manifest.py
  • tests/integration/test_cli_solution.py
  • tests/unit/test_curriculum.py
  • pythonlings/widgets/exercise_tree.py
  • exercises/json/json5.py
  • tests/integration/test_cli_hint.py
  • tests/integration/test_cli_cold_start.py
  • pythonlings/core/runner.py
  • pythonlings/core/state.py
  • tests/unit/test_docs.py
  • pythonlings/screens/track.py
  • pythonlings/screens/topic_picker.py
  • scripts/fetch_python_docs.py
  • tests/unit/test_manifest.py
  • pythonlings/core/docs.py
  • pythonlings/core/exercise.py
  • tests/tui/test_editor_pane.py
  • tests/unit/test_runner.py
  • tests/integration/test_solution_verify.py
  • pythonlings/screens/docs.py
  • tests/integration/test_cli_verify.py
  • tests/unit/test_reset.py
  • tests/unit/test_watcher.py
  • tests/integration/test_cli_topics.py
  • pythonlings/app.py
  • tests/unit/test_state.py
  • pythonlings/core/curriculum.py
  • pythonlings/widgets/output_panel.py
  • tests/tui/test_app_pilot.py
  • pythonlings/cli.py
tests/**/test_*.py

📄 CodeRabbit inference engine (CLAUDE.md)

Test files should be named test_<behavior>.py or test_<expected_behavior>.py

Files:

  • tests/integration/test_cli_dry_run.py
  • tests/integration/test_installed_package.py
  • tests/integration/test_cli_run.py
  • tests/integration/test_cli_reset.py
  • tests/tui/test_output_panel.py
  • tests/unit/test_exercise.py
  • tests/integration/test_cli_workspace.py
  • tests/integration/test_cli_solution.py
  • tests/unit/test_curriculum.py
  • tests/integration/test_cli_hint.py
  • tests/integration/test_cli_cold_start.py
  • tests/unit/test_docs.py
  • tests/unit/test_manifest.py
  • tests/tui/test_editor_pane.py
  • tests/unit/test_runner.py
  • tests/integration/test_solution_verify.py
  • tests/integration/test_cli_verify.py
  • tests/unit/test_reset.py
  • tests/unit/test_watcher.py
  • tests/integration/test_cli_topics.py
  • tests/unit/test_state.py
  • tests/tui/test_app_pilot.py
checks/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Hidden exercise assertions should be organized in checks/<topic>/<exercise>.py

Use bare assert statements (not pytest) in check files that execute in a shared namespace with exercise source

Files:

  • checks/pathlib/pathlib2.py
exercises/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

exercises/**/*.py: Learner exercise code should be organized in exercises/<topic>/<exercise>.py
Curriculum exercise names should use topic plus ordinal, such as variables1.py or collections10.py

Include the # I AM NOT DONE marker in exercise files; learners must remove it to advance after passing checks

Files:

  • exercises/pathlib/pathlib2.py
  • exercises/json/json8.py
  • exercises/json/json5.py
pythonlings/{cli.py,__main__.py}

📄 CodeRabbit inference engine (AGENTS.md)

CLI entry points should be in pythonlings/cli.py and pythonlings/__main__.py

Files:

  • pythonlings/__main__.py
  • pythonlings/cli.py
pythonlings/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

pythonlings/**/*.py: Use Python 3.11+ idioms with 4-space indentation
Prefer small, typed functions in the codebase
Keep UI behavior in screens or widgets directories; keep filesystem, manifest, reset, and runner behavior in core directory

Files:

  • pythonlings/__main__.py
  • pythonlings/core/reset.py
  • pythonlings/widgets/progress.py
  • pythonlings/core/solutions.py
  • pythonlings/widgets/editor_pane.py
  • pythonlings/core/manifest.py
  • pythonlings/widgets/exercise_tree.py
  • pythonlings/core/runner.py
  • pythonlings/core/state.py
  • pythonlings/screens/track.py
  • pythonlings/screens/topic_picker.py
  • pythonlings/core/docs.py
  • pythonlings/core/exercise.py
  • pythonlings/screens/docs.py
  • pythonlings/app.py
  • pythonlings/core/curriculum.py
  • pythonlings/widgets/output_panel.py
  • pythonlings/cli.py
pythonlings/core/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Core exercise loading, workspace setup, state, reset, solutions, and runner logic should live in pythonlings/core/

Files:

  • pythonlings/core/reset.py
  • pythonlings/core/solutions.py
  • pythonlings/core/manifest.py
  • pythonlings/core/runner.py
  • pythonlings/core/state.py
  • pythonlings/core/docs.py
  • pythonlings/core/exercise.py
  • pythonlings/core/curriculum.py
pythonlings/{screens,widgets}/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Textual screens and widgets should live in pythonlings/screens/ and pythonlings/widgets/

Files:

  • pythonlings/widgets/progress.py
  • pythonlings/widgets/editor_pane.py
  • pythonlings/widgets/exercise_tree.py
  • pythonlings/screens/track.py
  • pythonlings/screens/topic_picker.py
  • pythonlings/screens/docs.py
  • pythonlings/widgets/output_panel.py
tests/tui/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

TUI tests should be organized in tests/tui/ with file naming convention test_<behavior>.py and test function naming test_<expected_behavior>

Files:

  • tests/tui/test_output_panel.py
  • tests/tui/test_editor_pane.py
  • tests/tui/test_app_pilot.py
tests/unit/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should be organized in tests/unit/ with file naming convention test_<behavior>.py and test function naming test_<expected_behavior>

Files:

  • tests/unit/test_exercise.py
  • tests/unit/test_curriculum.py
  • tests/unit/test_docs.py
  • tests/unit/test_manifest.py
  • tests/unit/test_runner.py
  • tests/unit/test_reset.py
  • tests/unit/test_watcher.py
  • tests/unit/test_state.py
solutions/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

Reference exercise solutions should be organized in solutions/<exercise>.py

Files:

  • solutions/_answers.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:18.405Z
Learning: Exercise, check, and solution trees must be kept aligned with `info.toml`, which defines order, hints, and documentation URLs
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:18.405Z
Learning: Add unit tests for core behavior, integration tests for CLI/workspace flows, and TUI tests for Textual interactions
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:18.405Z
Learning: When changing curriculum, update `exercises/`, `checks/`, `solutions/`, and `info.toml`, then run relevant pytest files plus `pythonlings --root tests/fixtures/passing_curriculum verify`
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:18.405Z
Learning: Use conventional commit prefixes such as `feat:`, `fix:`, `docs:`, and `chore:` with imperative messages, for example `fix: reset exercise originals`
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:18.405Z
Learning: Pull requests should explain the user-facing change, list tests run, link issues when applicable, and include screenshots or terminal output for TUI/CLI changes
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:36.393Z
Learning: Keep UI behavior in `pylings/screens/` and `pylings/widgets/` while placing behavior logic in `pylings/core/` to maintain separation of concerns for testing
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:36.393Z
Learning: Exercise curriculum must maintain sync across four components: `exercises/<topic>/<name>.py` (with `# I AM NOT DONE` marker), `checks/<topic>/<name>.py` (bare assert statements), `solutions/<name>.py` (reference answer), and `info.toml` manifest entry
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:36.393Z
Learning: Async tests should run under `pytest-asyncio` in auto mode (configured in `pyproject.toml`)
Learnt from: CR
Repo: abhiksark/pythonlings

Timestamp: 2026-06-10T16:33:36.393Z
Learning: Use conventional commit prefixes (`feat:`, `fix:`, `docs:`, `chore:`) for commit messages; work flows through `feature/*` → `dev` → `main`
🪛 markdownlint-cli2 (0.22.1)
docs/roadmap/0.3.0.md

[warning] 18-18: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 30-30: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 36-36: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)


[warning] 42-42: Tables should be surrounded by blank lines

(MD058, blanks-around-tables)

🪛 Ruff (0.15.15)
checks/pathlib/pathlib2.py

[error] 3-3: Undefined name source

(F821)

tests/integration/test_cli_reset.py

[error] 14-14: Function argument input is shadowing a Python builtin

(A002)


[error] 15-15: subprocess call: check for execution of untrusted input

(S603)

tests/integration/test_cli_topics.py

[error] 12-12: subprocess call: check for execution of untrusted input

(S603)

🔇 Additional comments (107)
checks/pathlib/pathlib2.py (1)

3-3: LGTM!

exercises/json/json5.py (1)

8-8: LGTM!

exercises/json/json8.py (1)

8-8: LGTM!

exercises/pathlib/pathlib2.py (1)

8-8: LGTM!

solutions/_answers.py (1)

1041-1041: LGTM!

Also applies to: 1053-1053, 1272-1272, 1479-1479

tests/integration/test_cli_cold_start.py (1)

15-15: LGTM!

Also applies to: 24-24

tests/integration/test_cli_dry_run.py (1)

1-1: LGTM!

tests/integration/test_cli_hint.py (1)

11-11: LGTM!

tests/integration/test_cli_reset.py (1)

9-10: LGTM!

Also applies to: 16-17, 46-47, 53-54

tests/tui/test_app_pilot.py (3)

10-15: LGTM!


22-22: LGTM!


37-37: LGTM!

Also applies to: 47-47, 59-59, 72-72, 84-84, 97-97, 111-111, 126-126, 141-141, 149-149, 160-160, 171-171, 182-182, 202-202, 220-220, 234-234, 247-247, 264-264, 278-278, 297-297, 312-312

tests/tui/test_editor_pane.py (1)

8-9: LGTM!

tests/tui/test_output_panel.py (1)

7-8: LGTM!

tests/unit/test_curriculum.py (3)

3-3: LGTM!


24-30: LGTM!


54-54: LGTM!

tests/unit/test_docs.py (1)

3-5: LGTM!

tests/unit/test_exercise.py (1)

8-8: LGTM!

tests/unit/test_manifest.py (2)

6-6: LGTM!


53-53: LGTM!

tests/unit/test_reset.py (5)

7-10: LGTM!


25-30: LGTM!


36-39: LGTM!


87-89: LGTM!


96-98: LGTM!

.github/ISSUE_TEMPLATE/bug_report.md (1)

18-18: LGTM!

AGENTS.md (1)

5-25: LGTM!

CHANGELOG.md (1)

6-47: LGTM!

CODE_OF_CONDUCT.md (1)

3-3: LGTM!

CONTRIBUTING.md (1)

3-27: LGTM!

RELEASE.md (1)

3-48: LGTM!

Readme.md (1)

1-224: LGTM!

docs-site/contributing.md (1)

9-19: LGTM!

docs-site/curriculum.md (1)

3-58: LGTM!

docs-site/index.md (1)

1-7: LGTM!

docs-site/interface.md (1)

5-19: LGTM!

docs-site/local-docs.md (1)

3-29: LGTM!

docs-site/quick-start.md (1)

14-50: LGTM!

docs-site/roadmap.md (1)

16-29: LGTM!

docs/DEMO_GIF.md (1)

4-65: LGTM!

docs/RELEASE_PROCESS.md (1)

3-3: LGTM!

Also applies to: 23-24

docs/demo.tape (1)

1-1: LGTM!

Also applies to: 11-11, 15-15, 19-19, 23-23, 27-27

docs/roadmap/0.3.0.md (1)

1-1: LGTM!

Also applies to: 3-3, 7-7, 11-15, 20-27, 32-33, 38-39, 44-44, 48-49, 56-56, 58-58

pythonlings/docs/NOTICE.md (1)

4-4: LGTM!

pythonlings/docs/topics/async.md (1)

5-5: LGTM!

pythonlings/docs/topics/classes.md (1)

5-5: LGTM!

pythonlings/docs/topics/collections.md (1)

5-5: LGTM!

pythonlings/docs/topics/comprehensions.md (1)

5-5: LGTM!

pythonlings/docs/topics/conditionals.md (1)

5-5: LGTM!

pythonlings/docs/topics/context_managers.md (1)

5-5: LGTM!

pythonlings/docs/topics/dataclasses.md (1)

5-5: LGTM!

pythonlings/docs/topics/datetime.md (1)

5-5: LGTM!

pythonlings/docs/topics/decorators.md (1)

5-5: LGTM!

pythonlings/docs/topics/dictionaries.md (1)

5-5: LGTM!

pythonlings/docs/topics/enums.md (1)

5-5: LGTM!

pythonlings/docs/topics/exceptions.md (1)

5-5: LGTM!

pythonlings/docs/topics/file_io.md (1)

5-5: LGTM!

pythonlings/docs/topics/functional.md (1)

5-5: LGTM!

pythonlings/docs/topics/functions.md (1)

5-5: LGTM!

pythonlings/docs/topics/generators.md (1)

5-5: LGTM!

pythonlings/docs/topics/itertools.md (1)

5-5: LGTM!

pythonlings/docs/topics/json.md (1)

5-5: LGTM!

pythonlings/docs/topics/lists.md (1)

5-5: LGTM!

pythonlings/docs/topics/loops.md (1)

5-5: LGTM!

pythonlings/docs/topics/modules.md (1)

5-5: LGTM!

pythonlings/docs/topics/oop_advanced.md (1)

5-5: LGTM!

pythonlings/docs/topics/pathlib.md (1)

5-5: LGTM!

pythonlings/docs/topics/recursion.md (1)

5-5: LGTM!

pythonlings/docs/topics/regex.md (1)

5-5: LGTM!

pythonlings/docs/topics/sets.md (1)

5-5: LGTM!

pythonlings/docs/topics/strings.md (1)

5-5: LGTM!

pythonlings/docs/topics/testing.md (1)

5-5: LGTM!

pythonlings/docs/topics/tuples.md (1)

5-5: LGTM!

pythonlings/docs/topics/type_hints.md (1)

5-5: LGTM!

pythonlings/docs/topics/variables.md (1)

5-5: LGTM!

scripts/fetch_python_docs.py (1)

4-4: LGTM!

Also applies to: 24-24, 144-144, 183-183, 218-218

scripts/generate_demo_gif.sh (1)

25-25: LGTM!

pyproject.toml (1)

1-78: LGTM!

mkdocs.yml (1)

1-47: LGTM!

CNAME (1)

1-1: LGTM!

.github/workflows/publish.yml (1)

33-38: LGTM!

pythonlings/core/state.py (2)

1-1: LGTM!

Also applies to: 10-10, 59-59


36-36: Ensure .pylings/.pythonlings/ migration runs before state.load() reads state.json.

pythonlings/core/state.py:load() reads directly from root / ".pythonlings" / "state.json" and contains no migration. The migration helper migrate_legacy_state_dir() (renaming .pylings.pythonlings) lives in pythonlings/core/curriculum.py, so confirm all entry points that call load_state() invoke this migration before state loading (no path bypasses it).

pythonlings/widgets/exercise_tree.py (1)

1-53: LGTM!

docs-site/CNAME (1)

1-1: LGTM!

docs-site/robots.txt (1)

4-4: LGTM!

pythonlings/core/runner.py (1)

1-1: LGTM!

Also applies to: 11-12, 89-89

pythonlings/screens/topic_picker.py (1)

1-1: LGTM!

Also applies to: 10-10, 28-28, 100-100

pythonlings/screens/track.py (1)

1-1: LGTM!

Also applies to: 11-17, 193-193, 211-211

pythonlings/widgets/output_panel.py (1)

1-1: LGTM!

Also applies to: 10-10

pythonlings/widgets/progress.py (1)

1-16: LGTM!

.github/workflows/ci.yml (1)

21-21: LGTM!

Also applies to: 25-26

pythonlings/core/docs.py (1)

1-1: LGTM!

Also applies to: 59-59, 67-67

pythonlings/core/exercise.py (1)

1-1: LGTM!

pythonlings/core/reset.py (1)

1-1: LGTM!

Also applies to: 8-8, 18-18, 24-24, 28-28, 41-41

pythonlings/core/solutions.py (1)

6-6: LGTM!

pythonlings/screens/docs.py (1)

1-1: LGTM!

Also applies to: 14-15

pythonlings/widgets/editor_pane.py (1)

1-1: LGTM!

Also applies to: 8-8

.gitignore (1)

131-140: LGTM!

info.toml (1)

2-2: LGTM!

pythonlings/app.py (1)

1-1: LGTM!

Also applies to: 8-11, 14-15, 81-81

pythonlings/cli.py (3)

8-8: LGTM!


12-13: LGTM!

Also applies to: 15-15, 30-30, 36-36


79-82: LGTM!

Also applies to: 91-92, 103-103, 110-111, 131-131, 161-161, 176-177, 183-184, 192-193, 198-199, 205-207, 213-214, 216-217, 228-230, 236-237, 248-249, 300-301, 312-313, 316-319

pythonlings/core/curriculum.py (1)

14-15: LGTM!

Also applies to: 21-31, 35-35, 69-69, 97-97

pythonlings/core/manifest.py (1)

1-1: LGTM!

Also applies to: 11-11, 105-105

Comment thread CLAUDE.md
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update command to use pythonlings instead of pylings.

The smoke-test command on line 16 still uses the old pylings command name. It should be pythonlings to match the project rename.

🐛 Proposed fix
-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
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` at line 16, Update the smoke-test command in CLAUDE.md to use the
renamed CLI: replace the legacy "pylings --root
tests/fixtures/passing_curriculum verify" invocation with "pythonlings --root
tests/fixtures/passing_curriculum verify" so the documented command matches the
current tool name; locate the exact snippet string "pylings --root
tests/fixtures/passing_curriculum verify" and change only the executable name to
"pythonlings".

Comment thread CLAUDE.md
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/`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update all commands to use pythonlings instead of pylings.

The manual testing flow description uses the old pylings command name throughout. All occurrences should be updated to pythonlings.

🐛 Proposed fix
-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/`).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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/`).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` at line 21, Replace every occurrence of the old CLI name "pylings"
in the CLAUDE.md text (specifically the manual testing flow line containing
commands like `pylings init --path ./learn-python`, `pylings run variables1`,
`pylings dry-run variables1`, `pylings solution variables1`, `pylings hint`,
`pylings list`, `pylings topics`, `pylings reset`, and the `--root` mention)
with the new CLI name "pythonlings" so the documentation reflects the updated
command names.

Comment thread CLAUDE.md
Comment on lines +27 to +30
1. **The application** — `pylings/` (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 `<workspace>/.pylings/state.json` (written atomically, with `.bak` recovery on corruption).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update package and state directory paths to use pythonlings naming.

Lines 27 and 30 reference the old pylings/ package directory and .pylings/ state directory. These should be updated to pythonlings/ and .pythonlings/ respectively to match the rename.

🐛 Proposed fix
-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 `<workspace>/.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 `<workspace>/.pythonlings/state.json` (written atomically, with `.bak` recovery on corruption).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
1. **The application**`pylings/` (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 `<workspace>/.pylings/state.json` (written atomically, with `.bak` recovery on corruption).
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 `pythonlings/curriculum/` (see `pyproject.toml`). `pythonlings init` copies that bundled curriculum into a self-contained learner workspace; progress lives in `<workspace>/.pythonlings/state.json` (written atomically, with `.bak` recovery on corruption).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 27 - 30, Update the package and state directory
names: replace occurrences of the package path string "pylings/" with
"pythonlings/" (e.g., referenced where the application package is described) and
replace the state directory path ".pylings/" with ".pythonlings/" (e.g., where
workspace progress is described and the atomic write/.bak recovery is
documented) so the README/documentation matches the renamed package and state
directory.

Comment thread CLAUDE.md
- `solutions/<name>.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`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update command to use pythonlings instead of pylings.

The verification command reference uses the old pylings command name.

🐛 Proposed fix
-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`).
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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`).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` at line 41, The README text still references the old CLI name
`pylings`; update the verification command string to `pythonlings --root
tests/fixtures/passing_curriculum verify` wherever it appears (specifically the
sentence mentioning running `pylings --root tests/fixtures/passing_curriculum
verify`) so the document uses the current `pythonlings` command name.

Comment thread CLAUDE.md Outdated
Comment on lines +49 to +52
- `pylings/core/` — all filesystem, manifest, state, reset, solutions, runner, and watcher logic. No UI imports.
- `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"`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update package paths to use pythonlings/ instead of pylings/.

The layering section references the old pylings/ package directory structure. All paths should use pythonlings/ to match the rename.

🐛 Proposed fix
-- `pylings/core/` — all filesystem, manifest, state, reset, solutions, runner, and watcher logic. No UI imports.
-- `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/core/` — all filesystem, manifest, state, reset, solutions, runner, and watcher logic. No UI imports.
+- `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"`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `pylings/core/` — all filesystem, manifest, state, reset, solutions, runner, and watcher logic. No UI imports.
- `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/core/` — all filesystem, manifest, state, reset, solutions, runner, and watcher logic. No UI imports.
- `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"`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 49 - 52, Update the outdated package paths in the
layering documentation: replace all occurrences of the `pylings/*` package names
with `pythonlings/*` (e.g. `pylings/core/` → `pythonlings/core/`,
`pylings/screens/` → `pythonlings/screens/`, `pylings/widgets/` →
`pythonlings/widgets/`, `pylings/app.py` → `pythonlings/app.py`, `pylings.tcss`
→ `pythonlings.tcss`, and the entry point `pylings = "pylings.cli:main"` →
`pythonlings = "pythonlings.cli:main"`). Ensure every mention in this block is
updated so the docs match the renamed package.

Comment on lines 1 to 4
from pathlib import Path

from pylings.cli import main
from pythonlings.cli import main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

This module currently omits the required future-annotations import.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_cli_solution.py` around lines 1 - 4, Add the future
annotations import to the top of this test module: insert "from __future__
import annotations" as the very first statement in the file before any other
imports in tests/integration/test_cli_solution.py so the module (which imports
pythonlings.cli.main) uses postponed evaluation of annotations consistently with
the project guidelines.

Source: Coding guidelines

Comment on lines 1 to 4
from pathlib import Path

from pylings.cli import main
from pythonlings.cli import main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

This module should include the required future import.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_cli_workspace.py` around lines 1 - 4, Add the future
import statement at the top of the module so the file uses postponed evaluation
of annotations; insert "from __future__ import annotations" as the very first
import line in the tests/integration/test_cli_workspace.py module (above the
existing "from pathlib import Path" and "from pythonlings.cli import main") to
satisfy the project's coding guideline.

Source: Coding guidelines

Comment on lines 1 to +3
from pathlib import Path

from pylings.cli import main
from pythonlings.cli import main

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

This test file is missing the required future import.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_installed_package.py` around lines 1 - 3, Add the
required future import by inserting "from __future__ import annotations" at the
very top of the module (before any other imports or code) in
tests/integration/test_installed_package.py so the file begins with that future
import followed by the existing imports (Path and pythonlings.cli.main); ensure
there is no blank line or other code above the future import.

Source: Coding guidelines

Comment on lines 1 to 6
from pathlib import Path

from pylings.core.manifest import load
from pylings.core.runner import run_verify
from pylings.core.solutions import solution_exercise
from pythonlings.core.manifest import load
from pythonlings.core.runner import run_verify
from pythonlings.core.solutions import solution_exercise

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add from __future__ import annotations at module top.

Please add the required future import at the top of this module.
As per coding guidelines, **/*.py: use from __future__ import annotations at the top of modules.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_solution_verify.py` around lines 1 - 6, Add the future
import statement at the very top of the module (before any other imports) in
test_solution_verify.py by inserting "from __future__ import annotations" above
the existing imports; ensure it appears before the current imports that bring in
load (pythonlings.core.manifest), run_verify (pythonlings.core.runner) and
solution_exercise (pythonlings.core.solutions) so the module uses postponed
evaluation of annotations.

Source: Coding guidelines

Comment thread tests/unit/test_runner.py
Comment on lines 3 to +6
from pathlib import Path

from pylings.core.exercise import Exercise
from pylings.core.runner import run
from pythonlings.core.exercise import Exercise
from pythonlings.core.runner import run

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List test files under tests/unit that match test_*.py
fd -t f '^test_.*\.py$' tests/unit -a 2>/dev/null | sort > /tmp/unit_tests.txt || true
echo "== Unit test files =="
cat /tmp/unit_tests.txt

echo
echo "== Check for 'from __future__ import annotations' in each unit test file =="
while read -r f; do
  if [ -f "$f" ]; then
    if rg -n "from __future__ import annotations" "$f" >/dev/null; then
      echo "OK  $f"
    else
      echo "MISS $f"
    fi
  fi
done < /tmp/unit_tests.txt

echo
echo "== Show header lines for tests/unit/test_runner.py =="
if [ -f tests/unit/test_runner.py ]; then
  nl -ba tests/unit/test_runner.py | sed -n '1,40p'
else
  echo "Missing tests/unit/test_runner.py"
fi

Repository: abhiksark/pythonlings

Length of output: 1168


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Header for tests/unit/test_runner.py =="
if [ -f tests/unit/test_runner.py ]; then
  cat -n tests/unit/test_runner.py | sed -n '1,40p'
else
  echo "Missing file: tests/unit/test_runner.py"
fi

echo
echo "== Check for 'from __future__ import annotations' in all tests/**/*.py =="
# List all python files under tests
fd -t f '*.py' tests | sort > /tmp/tests_py.txt

miss_count=0
while read -r f; do
  if [ -f "$f" ]; then
    if rg -n "from __future__ import annotations" "$f" >/dev/null; then
      :
    else
      echo "MISS $f"
      miss_count=$((miss_count+1))
    fi
  fi
done < /tmp/tests_py.txt

echo "Total missing in tests: $miss_count"

Repository: abhiksark/pythonlings

Length of output: 1853


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== All Python files under tests/ =="
fd -t f '.*\.py$' tests | sort > /tmp/tests_py.txt
wc -l /tmp/tests_py.txt

echo
echo "== Missing 'from __future__ import annotations' in tests/**/*.py =="
miss=0
while read -r f; do
  if rg -n "from __future__ import annotations" "$f" >/dev/null; then
    :
  else
    echo "MISS $f"
    miss=$((miss+1))
  fi
done < /tmp/tests_py.txt

echo
echo "Total missing: $miss"

Repository: abhiksark/pythonlings

Length of output: 2152


Add from __future__ import annotations to test modules
tests/unit/test_runner.py (and many other tests/**/*.py files) are missing from __future__ import annotations at the module header, violating the project-wide **/*.py guideline. Add the import consistently across the affected test/fixture modules to fix the repeated header drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_runner.py` around lines 3 - 6, Add the module-level future
import "from __future__ import annotations" as the very first statement in this
test module (before any other imports) to comply with the project header
guideline; update tests/unit/test_runner.py by inserting that import at the top
of the file above the existing imports (which currently include Exercise and
run) and replicate the same change across other test/fixture modules that lack
it.

Source: Coding guidelines

watchdog was a declared dependency but never imported; core/watcher.py
and its test had no callers; the --watch-files flag was plumbed through
to PythonlingsApp but never read. The save->rerun loop runs on a debounce
in the TUI editor, so none of this was wired to anything. Drop the dep,
the dead module, and the no-op flag. Also remove the unused
load_topic_snippet (load_snippet covers it).
The hero said 'edit in your own editor' but the only rerun loop is the
built-in editor's debounce; external-editor saves never reran. The
no-workspace error said 'info.toml not found' with no hint to run init.
Each topic's F5 reference now pulls a complementary docs.python.org
section in addition to the primary one, and the per-section line cap
goes 26->40. Topics grow from ~30 to ~94 lines on average.

The fetcher's section parser now triggers on any element bearing the
target id, not just <section>: a <dt> object/method anchor captures its
enclosing <dl> so the signature and description come together. Extra
sections are best-effort — a failed fetch is skipped, not fatal.
main() chose the workspace with 'getattr(args, "root") or getattr(args,
"path")', but --root defaults to cwd and is always truthy, so the --path
branch was dead. 'update --path <legacy-workspace>' run from another
directory never migrated the workspace's .pylings/, silently orphaning the
learner's progress behind a fresh empty .pythonlings/. Migrate both the
--path and --root targets (both no-ops without a legacy dir).
render_manifest had no callers (render_topic is the only one used);
its Manifest/State type imports went with it. Left reset's name-based
snapshot fallback in place — the reset unit tests construct Exercises
with rel_path=None and depend on it.
@abhiksark abhiksark merged commit 10e6bb0 into main Jun 18, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant