Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ labels: bug
- OS:
- Python:
- Terminal:
- Pylings version:
- Pythonlings version:
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ jobs:
python-version: ${{ matrix.python-version }}
- run: pip install -e ".[dev]"
- run: pytest -v
- run: pylings --root tests/fixtures/passing_curriculum verify
- run: pythonlings --root tests/fixtures/passing_curriculum verify
- run: python -m pip install build
- run: python -m build
- run: python -m pip install --force-reinstall dist/*.whl
- run: pylings init --path /tmp/pylings-workspace
- run: pylings --root /tmp/pylings-workspace list
- run: pythonlings init --path /tmp/pythonlings-workspace
- run: pythonlings --root /tmp/pythonlings-workspace list
12 changes: 6 additions & 6 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ jobs:
- run: python -m pip install build
- run: python -m build
- run: python -m pip install --force-reinstall dist/*.whl
- run: pylings --version
- run: pylings init --path /tmp/pylings-workspace
- run: pylings --root /tmp/pylings-workspace list
- run: pylings --root /tmp/pylings-workspace solution variables1
- run: pylings --root /tmp/pylings-workspace reset variables1 --yes
- run: pylings --root tests/fixtures/passing_curriculum verify
- run: pythonlings --version
- run: pythonlings init --path /tmp/pythonlings-workspace
- run: pythonlings --root /tmp/pythonlings-workspace list
- run: pythonlings --root /tmp/pythonlings-workspace solution variables1
- run: pythonlings --root /tmp/pythonlings-workspace reset variables1 --yes
- run: pythonlings --root tests/fixtures/passing_curriculum verify
- uses: pypa/gh-action-pypi-publish@release/v1
14 changes: 7 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ dmypy.json
# Pyre type checker
.pyre/

# Pylings runtime state (root install and any nested fixture roots)
.pylings/
# Pythonlings runtime state (root install and any nested fixture roots)
.pythonlings/
.superpowers/
.worktrees

# Local artifacts from older pylings workspaces; not part of this package.
/pylings/.gitignore
/pylings/.git/
/pylings/.pylings.toml
/pylings/exercises/
# Local artifacts from older pythonlings workspaces; not part of this package.
/pythonlings/.gitignore
/pythonlings/.git/
/pythonlings/.pythonlings.toml
/pythonlings/exercises/
14 changes: 7 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

## Project Structure & Module Organization

`pylings/` contains the installable application package. Core exercise loading, workspace setup, state, reset, solutions, and runner logic live in `pylings/core/`; CLI entry points are in `pylings/cli.py` and `pylings/__main__.py`; Textual screens/widgets live in `pylings/screens/` and `pylings/widgets/`; `pylings/pylings.tcss` holds TUI styles.
`pythonlings/` contains the installable application package. Core exercise loading, workspace setup, state, reset, solutions, and runner logic live in `pythonlings/core/`; CLI entry points are in `pythonlings/cli.py` and `pythonlings/__main__.py`; Textual screens/widgets live in `pythonlings/screens/` and `pythonlings/widgets/`; `pythonlings/pythonlings.tcss` holds TUI styles.

Curriculum files are split between `exercises/<topic>/<exercise>.py` for learner code, `checks/<topic>/<exercise>.py` for hidden assertions, and `solutions/<exercise>.py` for reference answers. Keep these trees aligned with `info.toml`, which defines order, hints, and docs URLs. Tests live in `tests/unit/`, `tests/integration/`, and `tests/tui/`, with fixtures in `tests/fixtures/`.

## Build, Test, and Development Commands

- `pip install -e ".[dev]"`: install pylings locally with pytest dependencies.
- `pylings init --path ./learn-python`: create a self-contained learner workspace.
- `pylings`, `pylings topics`, `pylings list`: launch the TUI or inspect progress.
- `pylings run variables1`, `pylings dry-run variables1`, `pylings solution variables1`: test exercise and solution flows.
- `pylings --root tests/fixtures/passing_curriculum verify`: smoke-test a known passing fixture.
- `pip install -e ".[dev]"`: install pythonlings locally with pytest dependencies.
- `pythonlings init --path ./learn-python`: create a self-contained learner workspace.
- `pythonlings`, `pythonlings topics`, `pythonlings list`: launch the TUI or inspect progress.
- `pythonlings run variables1`, `pythonlings dry-run variables1`, `pythonlings solution variables1`: test exercise and solution flows.
- `pythonlings --root tests/fixtures/passing_curriculum verify`: smoke-test a known passing fixture.
- `python -m pytest -q`: run the full suite configured in `pyproject.toml`.
- `python -m build`: build source and wheel distributions.

Expand All @@ -22,7 +22,7 @@ Use Python 3.11+ idioms and 4-space indentation. Prefer small, typed functions w

## Testing Guidelines

Use pytest for all tests; async tests are supported by `pytest-asyncio` in auto mode. Add unit tests for core behavior, integration tests for CLI/workspace flows, and TUI tests for Textual interactions. When changing curriculum, update `exercises/`, `checks/`, `solutions/`, and `info.toml`, then run relevant pytest files plus `pylings --root tests/fixtures/passing_curriculum verify`.
Use pytest for all tests; async tests are supported by `pytest-asyncio` in auto mode. Add unit tests for core behavior, integration tests for CLI/workspace flows, and TUI tests for Textual interactions. When changing curriculum, update `exercises/`, `checks/`, `solutions/`, and `info.toml`, then run relevant pytest files plus `pythonlings --root tests/fixtures/passing_curriculum verify`.

## Commit & Pull Request Guidelines

Expand Down
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
# Changelog

All notable changes to this project are documented here. Pylings follows
All notable changes to this project are documented here. Pythonlings follows
Semantic Versioning.

## [0.3.0] - 2026-06-10

### Changed

- The project is renamed from pylings to **pythonlings**. The PyPI package
(previously `python-learnings`), the CLI command (previously `pylings`),
and the Python package are all now `pythonlings`. Existing workspaces are
migrated automatically: a legacy `.pylings/` state directory is renamed to
`.pythonlings/` on the next run, preserving progress and reset snapshots.

## [0.2.0] - 2026-05-30

### Added
Expand Down Expand Up @@ -34,7 +44,7 @@ Semantic Versioning.
- 292 Python exercises across 31 topics with mirrored hidden checks.
- Bundled local Python documentation snippets generated from official docs.
- In-app documentation modal with `F5`, `Esc`, and `O` keyboard flow.
- PyPI distribution name `python-learnings`, which installs the `pylings` command.
- PyPI distribution name `pythonlings`, which installs the `pythonlings` command.
- Contributor guide, screenshots, release flow notes, and MIT license.

### Verified
Expand Down
61 changes: 61 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Pythonlings is "Rustlings for Python": a terminal TUI (Textual) where learners fix small broken exercises and checks rerun on save. Published on PyPI as `pythonlings` (formerly `python-learnings`; the unrelated `pylings` PyPI name belongs to a different project).

## Commands

```bash
pip install -e ".[dev]" # local install with pytest deps

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

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".


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.


## Architecture

Two distinct trees in this repo:

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).
Comment on lines +27 to +30

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.


### Curriculum model

Each exercise is a triple that must stay in sync, plus a manifest entry:

- `exercises/<topic>/<name>.py` — the broken code the learner edits, containing the `# I AM NOT DONE` marker (defined in `core/exercise.py`)
- `checks/<topic>/<name>.py` — hidden bare `assert` statements (not pytest)
- `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.


### How checks run (`core/runner.py`)

An exercise passes when a generated runner script `exec()`s the exercise source and then the check source in a shared namespace, in a fresh subprocess with a 5s timeout. The check sees the exercise's variables directly — that's why checks are bare asserts. Passing checks alone aren't enough: the learner must also remove `# I AM NOT DONE` to advance.

### Layering

- `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.

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/`).

## Conventions

- `requires-python = ">=3.9"`: guard newer-stdlib usage (e.g. `tomllib` falls back to `tomli` in `core/manifest.py`); `from __future__ import annotations` at the top of modules.
- Async tests run under `pytest-asyncio` in auto mode (configured in `pyproject.toml`).
- Tests are named `test_<behavior>.py` / `test_<expected_behavior>`.
- Commits use conventional prefixes (`feat:`, `fix:`, `docs:`, `chore:`); work flows through `feature/*` → `dev` → `main`.
- `AGENTS.md` holds the same contributor guidelines in long form.
2 changes: 1 addition & 1 deletion CNAME
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pylings.abhik.ai
pythonlings.abhik.ai
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Code of Conduct

Pylings follows the Contributor Covenant Code of Conduct, version 2.1.
Pythonlings follows the Contributor Covenant Code of Conduct, version 2.1.

## Our Standards

Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Contributing

Pylings is actively developed and **open to contributors** — beginners welcome.
The fastest way in is a [`good first issue`](https://github.com/abhiksark/pylings/issues?q=is%3Aopen+label%3A%22good+first+issue%22).
Pythonlings is actively developed and **open to contributors** — beginners welcome.
The fastest way in is a [`good first issue`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22good+first+issue%22).

## Where the work is

- **[0.3.0 roadmap](docs/roadmap/0.3.0.md)** — the current focus (wider adoption
for beginners). Each roadmap issue is written to be picked up cold: it has
context, scope, the exact files to touch, and how to verify.
- Browse open issues by label: [`good first issue`](https://github.com/abhiksark/pylings/issues?q=is%3Aopen+label%3A%22good+first+issue%22),
[`help wanted`](https://github.com/abhiksark/pylings/issues?q=is%3Aopen+label%3A%22help+wanted%22).
- Browse open issues by label: [`good first issue`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22good+first+issue%22),
[`help wanted`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22help+wanted%22).

## Claiming an issue

Expand All @@ -23,8 +23,8 @@ No need to wait for a formal assignment; claiming by comment is enough.
## Development Setup

```bash
git clone git@github.com:abhiksark/pylings.git
cd pylings
git clone git@github.com:abhiksark/pythonlings.git
cd pythonlings
pip install -e ".[dev]" # or: uv pip install -e ".[dev]"
python -m pytest -q
```
Expand Down
34 changes: 19 additions & 15 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,44 @@
# Release Checklist

Pylings follows Semantic Versioning. Use full `MAJOR.MINOR.PATCH` versions in
Pythonlings follows Semantic Versioning. Use full `MAJOR.MINOR.PATCH` versions in
package metadata and annotated git tags such as `v0.1.0`.

## Package Name

The PyPI name `pylings` is already owned by another project. This repository's
distribution name is `python-learnings`; installing it provides the `pylings`
console command. Do not document `pip install pylings` for this project unless
the package name is transferred.
The distribution name on PyPI is `pythonlings`; installing it provides the
`pythonlings` console command. Releases before 0.3.0 were published as
`python-learnings`. The PyPI name `pylings` belongs to an unrelated project
never publish or document it for this repository.

## Pre-Release Verification

Run these checks from a clean working tree before tagging:

```bash
python -m pytest -q
pylings --root tests/fixtures/passing_curriculum verify
pythonlings --root tests/fixtures/passing_curriculum verify
python -m build
python -m pip install --force-reinstall dist/python_learnings-*.whl
pylings --version
tmp=$(mktemp -d /tmp/pylings-release.XXXXXX)
pylings init --path "$tmp"
pylings --root "$tmp" list
pylings --root "$tmp" solution variables1
pylings --root "$tmp" reset variables1 --yes
python -m pip install --force-reinstall dist/pythonlings-*.whl
pythonlings --version
tmp=$(mktemp -d /tmp/pythonlings-release.XXXXXX)
pythonlings init --path "$tmp"
pythonlings --root "$tmp" list
pythonlings --root "$tmp" solution variables1
pythonlings --root "$tmp" reset variables1 --yes
```

Expected release version for `v0.1.0`:
Expected release version for `v0.3.0`:

```text
pylings 0.1.0
pythonlings 0.3.0
```

## Tag And Publish

0. One-time setup: the PyPI project `pythonlings` must have a trusted publisher
configured (repository `abhiksark/pythonlings`, workflow `publish.yml`,
environment `pypi`). For a first release under a new name, add it as a
pending publisher on pypi.org before tagging.
1. Commit the release changes.
2. Create an annotated tag, for example `git tag -a v0.1.0 -m "Release v0.1.0"`.
3. Push the branch and tag.
Expand Down
Loading
Loading