Skip to content

fix(init): report a malformed --extension URL cleanly, not raw urllib text - #4324

Open
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/init-extension-url-malformed
Open

fix(init): report a malformed --extension URL cleanly, not raw urllib text#4324
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/init-extension-url-malformed

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

  • _install_extension_during_init (src/specify_cli/commands/init.py) parses an --extension URL spec with a bare parsed = urlparse(ext_spec).
  • An unterminated or invalid bracketed IPv6 authority (e.g. https://[not-an-ip]/x.zip) makes urlparse() itself raise ValueError — this became eager in Python 3.14 (previously lazy, raised only on .hostname access). Since the call was unguarded, specify init --extension <bad-url> surfaced the raw urllib message ('not-an-ip' does not appear to be an IPv4 or IPv6 address) as the tracker's failure text instead of an actionable error.
  • Every sibling URL entry point in this codebase already guards this exact case with a clean domain error: extensions/__init__.py, presets/__init__.py, extensions/_commands.py, workflows/catalog.py (the #3435/#3484 lineage — each has an explicit comment about this). init.py's own _ext_spec_is_url classifier, defined right next to this function, already catches the same ValueError; this call site was the one outlier that didn't.
  • Fix: wrap the parse in the same try/except ValueError pattern as every sibling, raising a clean ValueError("Malformed extension URL: ...") that the caller already converts into a tracker error (per this function's own documented contract).

Test plan

  • Added test_install_extension_during_init_reports_malformed_url_cleanly to tests/test_init_output_markup.py, calling _install_extension_during_init directly with https://[not-an-ip]/ext.zip.
  • Verified the test fails without the fix — reproduced the exact raw urllib message ('not-an-ip' does not appear to be an IPv4 or IPv6 address) leaking through — and passes with it.
  • Ran the full tests/test_init_output_markup.py module — 9 passed, 3 skipped (pre-existing bash-requirement skips), no regressions.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01FW9fAYsCBCAgdKWovtSyqt

@Noor-ul-ain001
Noor-ul-ain001 requested a review from mnriem as a code owner August 25, 2026 15:18
… text

`_install_extension_during_init` (src/specify_cli/commands/init.py) parses
an --extension URL spec with a bare `urlparse(ext_spec)`. An unterminated
or invalid bracketed IPv6 authority (e.g. "https://[not-an-ip]/x.zip")
makes urlparse itself raise ValueError — this became eager in Python 3.14
(previously lazy, raised only on `.hostname` access). Since the call was
unguarded, `specify init --extension <bad-url>` reported the raw urllib
message ("'not-an-ip' does not appear to be an IPv4 or IPv6 address")
instead of an actionable error.

Every sibling URL entry point in this codebase already guards this exact
case with a clean domain error: extensions/__init__.py, presets/__init__.py,
extensions/_commands.py, workflows/catalog.py (the github#3435/github#3484 lineage).
init.py's own `_ext_spec_is_url` classifier next to this function already
catches the same ValueError; this call site was the outlier.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW9fAYsCBCAgdKWovtSyqt
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