Skip to content

cli: reject init --force at the curriculum source #71

Description

@abhiksark

Motivation

Running forced initialization from a source checkout can crash after Pythonlings resolves the destination to the same directory as its bundled curriculum. A contributor-facing command should reject that target before attempting any copy.

Current evidence

Deep QA on dev at e1d4dae37234b75124bd6a53f06734296ebbbdee reproduced this twice in disposable copies:

PYTHONPATH=<source-copy> python -m pythonlings init --path <source-copy> --force
shutil.SameFileError: <source-copy>/info.toml and <source-copy>/info.toml are the same file

The command exits 1 with a traceback. init_workspace() starts copying before checking whether path equals source_root(). update_workspace() already rejects the equivalent source target.

Exact scope

Reject forced initialization when the resolved destination is the curriculum source, before any file is copied or removed. Return a concise pythonlings: error through the existing CLI error path.

Acceptance checklist

  • init --path <curriculum-source> --force exits non-zero without a traceback.
  • The source checkout is unchanged after the rejected command.
  • The error identifies that the curriculum source cannot be initialized in place.
  • Forced initialization of a different existing workspace retains its current behavior.
  • First initialization and repeated non-forced initialization retain their current behavior.
  • Regression coverage exercises the resolved same-path case.

Explicit exclusions

Do not change update target precedence, overwrite semantics for a normal learner workspace, curriculum copy layout, or automatic workspace discovery.

Likely files

  • pythonlings/core/curriculum.py
  • pythonlings/cli.py
  • tests/unit/test_curriculum.py
  • tests/integration/test_cli_workspace.py

Verification

python -m pytest tests/unit/test_curriculum.py tests/integration/test_cli_workspace.py -q
python -m pytest -q
pythonlings --root tests/fixtures/passing_curriculum verify

Repeat the same-path command against a disposable source copy and confirm its tree hash is unchanged.

Sprint coordination

See Discussion #37 and tracker #52. This issue is intentionally unassigned. A coordination comment is welcome, but it does not reserve the issue. The first pull request that satisfies every acceptance criterion and verification requirement is considered for merge.

Activity

  1. added
    bugSomething isn't working
    dev sprintPythonlings Community Dev Sprint August 2026
    area: cliCommand-line interface behavior
    size: SSmall, focused contribution
    on Aug 18, 2026
  2. coderabbitai commented on Aug 18, 2026

    @coderabbitai
    🔗 Related PRs

    #53 - fix: preserve workspace gitignore entries [merged]
    #54 - fix: wrap malformed info.toml failures in ManifestError [merged]
    #66 - release: promote v0.4.2 to main [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  3. Azaucifer commented on Sep 16, 2026

    @Azaucifer

    I've submitted a fix for this in #147.

    The change adds a same-path guard in init_workspace() before any copy, mirroring the existing guard in update_workspace(). It also adds unit and integration regression tests for the resolved same-path case.

    All acceptance criteria are met, and I verified:

    • Exit code 1, no traceback
    • Source checkout unchanged (tree hash comparison)
    • 25 targeted tests pass
    • Full suite passes

    Closes #71

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: cliCommand-line interface behaviorbugSomething isn't workingdev sprintPythonlings Community Dev Sprint August 2026good first issueGood for newcomerssize: SSmall, focused contribution

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions