Conversation
…foster13#124) cmd2 >=4.0 requires every parser factory used with @cmd2.with_argparser to return a Cmd2ArgumentParser (or subclass) -- plain argparse.ArgumentParser now raises a TypeError from cmd2's internal _build_parser. All 17 parser factories in lib/parsers/parsers.py returned plain argparse.ArgumentParser, so every single command in the interactive shell was broken under cmd2 >=4.0, not just get_device as the issue title suggests. Verified with a throwaway venv running real cmd2 4.2.2: every one of a representative sample of commands (get_device, get_user, get_collection, cd, interact, sessionhunter, cat) raised the exact TypeError from the issue on unpatched main, and none do after this fix -- confirmed both in isolation and by importing the real SHELL class from lib/attacks/admin, and live against a real lab (reproduced the crash on main, confirmed a clean run on this branch). Also: - Fixed do_decrypt_parsers(), which was missing its `return parser` entirely (currently dead code -- not wired to any command -- but a real bug in the same file). - Relaxed requirements.txt's `cmd2<4.0.0` pin (added as a workaround, per the issue) now that the actual incompatibility is fixed, and aligned it with pyproject.toml's unbounded `cmd2>=2.7.0` so both dependency declarations agree. Added tests/test_parsers.py asserting every *_parser factory returns a Cmd2ArgumentParser -- this doesn't require cmd2 >=4.0 to be installed to catch a regression, since it checks the same thing cmd2's runtime check enforces. Confirmed it fails against the pre-fix code and passes after. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI-assisted contribution — please read before reviewing
This patch was developed with AI assistance (Claude/Anthropic), directed and tested by me. I'm submitting it in good faith that it's correct, not as an expert assertion that it is. Please treat it with whatever scrutiny you'd want for an AI-assisted contribution.
What this fixes
Closes #124. cmd2 ≥4.0 requires every parser factory used with
@cmd2.with_argparserto return aCmd2ArgumentParser(or subclass) — a plainargparse.ArgumentParsernow raises aTypeErrorfrom cmd2's internal_build_parser. All 17 parser factories inlib/parsers/parsers.pyreturned a plainargparse.ArgumentParser, so on cmd2 ≥4.0 every single command in the interactive shell is broken, not justget_device—get_user,get_collection,cd,interact,sessionhunter,application, the script commands, the admin commands, all of it.The fix is: switch all 17 factories to build a
cmd2.Cmd2ArgumentParserinstead. Also fixeddo_decrypt_parsers(), which was missing itsreturn parserentirely — currently dead code (not wired to any command), but a real bug sitting in the same file I was already touching.Also relaxed the
requirements.txtpin. It already hadcmd2<4.0.0(the workaround mentioned in the issue), whilepyproject.tomlhad no upper bound (cmd2>=2.7.0) — so which cmd2 version you got, and whether you hit this bug at all, depended on which of the two files your install path used. Now that the actual incompatibility is fixed, I aligned both tocmd2>=2.7.0with no upper bound, rather than leaving a workaround pin in place indefinitely for a bug that's now fixed. Happy to leave the pin in place instead if you'd rather be conservative here — this part is more of a judgment call than the rest of the fix.Reproduction: unpatched
main, real cmd2 4.2.2, against a real labThe dev environment here has cmd2 2.7.0 installed (which doesn't hit the bug), so I built a throwaway venv with real cmd2 4.2.2 to actually reproduce and verify this, rather than just trusting the traceback in the issue.
I also checked this wasn't limited to
get_device/interactby instantiating the realSHELLclass fromlib/attacks/admindirectly (no network) and running a representative set of commands under cmd2 4.2.2 — every single one failed with the sameTypeError:After the fix: same lab, same cmd2 4.2.2 venv
No
TypeError— the command reaches the actual AdminService query and fails only on the lookup itself (ps1-pssisn't an exact match in this environment'sSMS_R_System, unrelated to this fix). Same result for the representative command set above run against the realSHELLclass: all 7 correctly proceed past parsing into their actual request logic (verified they reach real HTTP calls, either succeeding or failing on network/lookup grounds — never on the parser-type check).Regression / no-breakage checks
python -m unittest tests/test_parsers.py -v— new test asserting every*_parser/*_parsersfactory inPARSERSreturns aCmd2ArgumentParser. Confirmed it fails against the pre-fix code (AssertionError: ... got ArgumentParser) and passes after — this doesn't need cmd2 ≥4.0 installed to catch a future regression.python -m py_compile lib/parsers/parsers.py— clean.git diff --check— clean.