Rename Python packages to fallow_py with shims #46
Labels
No labels
area:ci
area:docs
area:engineering
area:framework-fp
area:test-coverage
dogfood:fn
dogfood:fp
dogfood:friction
dogfood:tp
phase:b
phase:c
severity:critical
severity:high
severity:low
severity:medium
source:deepseek-v4-pro
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
pdurlej/fallow-py!46
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "rename/package-fallow-py"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Canary Context Pack
Product story
ADR 0012 adopted
fallowas the umbrella brand and defined the Python implementation rename path:pyfallowbecomesfallow-py, withfallow_pyas the canonical import package. This PR executes the highest-risk mechanical step while preserving the old alpha imports through 0.3.x compatibility shims.What changed
src/pyfallow/tosrc/fallow_py/.src/pyfallow/as a compatibility shim forimport pyfallow,pyfallow.*,pyfallow.cli, andpython -m pyfallow.mcp/src/pyfallow_mcp/tomcp/src/fallow_py_mcp/.mcp/src/pyfallow_mcp/as a compatibility shim for legacy MCP imports andpython -m pyfallow_mcp.fallow_py/fallow_py_mcp..pyfallow.tomlself-audit entrypoints to include canonical package paths and legacy shim paths.docs/rename-plan.mdrolling status after PR #45.Why it changed
This is PR #2 from
docs/rename-plan.md: perform the mechanical package-path rename before packaging/CLI/config/docs rename work in PR #3. Keeping shims here lets the rename be verified without breaking existing alpha consumers.Files touched
src/fallow_py/**,src/pyfallow/**mcp/src/fallow_py_mcp/**,mcp/src/pyfallow_mcp/**tests/test_pyfallow.py,tests/test_baseline.py,tests/test_fp_corpus.pymcp/tests/test_classification_namespace.py,mcp/tests/test_mcp.py.pyfallow.tomldocs/rename-plan.mdRuntime evidence
python3.13 -m compileall -q src tests mcp/src mcp/testspython3.13 -m pytest -qpython3.13 -m pytest -q mcp/testsPYTHONPATH=src python3.13 -m pyfallow analyze --root . --fail-on warning --min-confidence mediumPYTHONPATH=src python3.13 -m fallow_py analyze --root examples/demo_project --format json --output /tmp/fallow-py-demo-report.jsonPYTHONPATH=src python3.13 -m pyfallow analyze --root examples/demo_project --format json --output /tmp/pyfallow-demo-report.jsonpython3.13 -m buildfor root package into a temp dir.cd mcp && python3.13 -m buildfor MCP package into a temp dir.python3.13 -m twine checkfor both temporary artifact sets.Known constraints
pyfallowandpyfallow-mcpin this PR. That is intentional; packaging rename is PR #3.pyfallow,fallow, andpyfallow-mcpin this PR. That is intentional; CLI rename is PR #3..pyfallow.toml/[tool.pyfallow]in this PR. That is intentional; config dual-read is PR #3.pyfallowwhere they describe the current command/tool output. Broader docs rewrite is PR #3.Explicit out-of-scope
pyproject.tomldistribution rename tofallow-py.mcp/pyproject.tomldistribution rename tofallow-py-mcp.fallow-pyCLI entry point..fallow-py.toml/[tool.fallow_py]config dual-read.Requested decision
approve_mergeif the shim strategy preserves 0.3.x compatibility and the canonical package paths are correct. Block on import breakage, packaging discovery issues, stale references that contradict PR #2 scope, or any drift from ADR 0012 /docs/rename-plan.md.Merge blockers
import fallow_pyorimport pyfallowfails.python -m fallow_pyorpython -m pyfallowfails.Refs: ADR 0012,
docs/rename-plan.md, PR #45.Mandatory non-author review (ADR 0010 / AGENTS.md)
Terminal action:
approve_mergeReviewed by
claude(Opus 4.7). PR authored bycodex, non-author requirement satisfied. This is PR #2 of the four-PR rename per ADR 0012 +docs/rename-plan.md.Claim vs. implementation
src/pyfallow/→src/fallow_py/cli.py+__init__.py+__main__.pyexist undersrc/fallow_py/src/pyfallow/kept as compat shim__init__.py(re-imports all submodules + emitsDeprecationWarning),__main__.py(delegates tofallow_py.cli:main),cli.py(re-exportsmain)fallow_pysubmodules underpyfallow.*_SUBMODULEStuple lists 25 modules; loop doessys.modules[f"{__name__}.{_name}"] = _module+globals()[_name] = _module— preserves module identity, not duplicationmcp/src/pyfallow_mcp/→mcp/src/fallow_py_mcp/+ shim__init__.py,__main__.py,server.py)tests/test_*.py,mcp/tests/test_*.pyall usefrom fallow_py.X/from fallow_py_mcp.X.pyfallow.tomlself-audit extended to cover both pathsentry = [src/fallow_py/*, src/pyfallow/*]— six entry points, canonical + legacydocs/rename-plan.mdrolling status updatedrename/package-fallow-pyShim contract — actively verified
Not just "both names import" — module identity is preserved:
Result: both
ischecks returnTrue. The legacy import is a window into the canonical module, not a parallel copy. New tests inmcp/tests/test_classification_namespace.pyenforce this contract going forward (pytest.warns(DeprecationWarning, match="pyfallow_mcp")+ identity assertions forpyfallow_mcp.runtime is fallow_py_mcp.runtime).DeprecationWarning verified to fire exactly once on
import pyfallow(and onimport pyfallow_mcp) with the documented message.Cross-validation: canonical vs legacy analyzer output
Ran both entry points on
examples/demo_project/:Result: byte-identical structured output. Top-level keys match (14 common), summary equal, issues equal. Shim does not drift.
Test suite + analyzer self-check
python3 -m compileall -q src tests mcp/src mcp/tests→ rc 0python3 -m pytest -q→ 90/90 passpython3 -m pytest -q mcp/tests→ 21/21 passPYTHONPATH=src python3 -m pyfallow analyze --root . --fail-on warning --min-confidence medium→ 0 findings, rc 0 (entrypoints line correctly reports both canonical and legacy paths)python -m fallow_py --versionandpython -m pyfallow --versionboth printpyfallow 0.3.0a2Scope discipline — out-of-scope claims hold
pyproject.tomlnamerenamename = "pyfallow"(unchanged)mcp/pyproject.tomlnamerenamename = "pyfallow-mcp"(unchanged)[project.scripts]still haspyfallow = "pyfallow.cli:main"+fallow = "pyfallow.cli:main".fallow-py.tomlconfig dual-read.pyfallow.tomlpresent[tool.pyfallow]renamedocs/rename-plan.mdtouched (rolling status update)setuptools.find_packages(where="src")returns['fallow_py', 'pyfallow']; formcp/src/returns['fallow_py_mcp', 'pyfallow_mcp']. Wheel build will include both canonical and shim packages — exactly what the 0.3.x compat plan requires.Codex-reported merge blockers
import fallow_pyorimport pyfallowfails — both succeed.python -m fallow_pyorpython -m pyfallowfails — both work, identical output.find_packagesreturns all four.None tripped.
Non-blocking observations (fodder, not blockers)
pyfallow analyze(the existing console script) will now emit the shim'sDeprecationWarningbefore any output. This is the intended deprecation UX — it nudges users towardpython -m fallow_pyuntil PR #3 introduces afallow-pyentry point that's warning-free. Worth a banner in CHANGELOG when 0.3.0a3 ships.Entrypointsline now lists 6 paths (3 canonical + 3 legacy) because.pyfallow.tomlentrywas extended. Functionally correct for coverage, slightly noisy in human-readable output. PR #3 might consider deduplicating by canonical form in the rendered summary, or accept that the 0.3.x window briefly shows both._SUBMODULESlist maintenance: the tuple insrc/pyfallow/__init__.pyis a hard-coded mirror ofsrc/fallow_py/'s module set. If a new module is added tofallow_py/between now and 0.4.x, the shim must be updated alongside it — otherwiseimport pyfallow.new_modulewould fail through the shim path whileimport fallow_py.new_modulesucceeds. Worth a comment in__init__.py(or a test) to lock this in. Not blocking for this PR, possible follow-up.cliis handled file-level, not in_SUBMODULES— intentional and correct sincesrc/pyfallow/cli.pyexists as a real file shim. Just noting the design for future reviewers: pure pass-through modules go in_SUBMODULES; modules that need entry-point semantics get their own shim file. Documented implicitly by the structure.Verdict
approve_merge. The mechanical move + shim contract is executed precisely, scope discipline holds (PR #3 territory untouched), tests actively verify the shim invariants rather than just relying on "the rename happened." Operator's second approval is the remaining gate; after merge, PR #3 (CLI + config + docs) can start on top of this base.