Skip to content

Preserve literal percent escapes in decoded fragment replacement - #203

Open
AryanRG wants to merge 1 commit into
python-hyper:masterfrom
AryanRG:fix/decoded-fragment-replacement
Open

AryanRG wants to merge 1 commit into
python-hyper:masterfrom
AryanRG:fix/decoded-fragment-replacement

Conversation

@AryanRG

@AryanRG AryanRG commented Oct 17, 2026

Copy link
Copy Markdown

Summary

DecodedURL.replace(fragment=...) treats the supplied decoded fragment as an already-encoded URL fragment. Consequently, a literal fragment such as %41 becomes A, and %FF raises UnicodeDecodeError. Encode explicit fragment replacements using the same decoded-input rules already applied to the other URL components. Omitting fragment retains its existing behavior.

from hyperlink import DecodedURL

url = DecodedURL.from_text("https://example.com/").replace(fragment="%41")
assert url.fragment == "%41"
assert url.to_text().endswith("#%2541")

The base instead returns "A" for the fragment. The patch adds regression and control tests, plus a changelog note.

Validation

  • New tests before the fix: 2 failed, 1 passed.
  • Focused URL tests and doctests after the fix: 110 passed.
  • Full suite after the fix: 137 passed, 1 failed. The sole Hypothesis filtering-health failure is unchanged from the base (base: 134 passed, 1 failed, with the three new tests excluded).
  • Black, Flake8, and git diff --check passed. Mypy reports the same 16 diagnostics in unchanged Hypothesis files on base and patch.

Validation ran on Python 3.9.25. Other Python versions and hosted CI remain unverified locally.

AI assistance was used to prepare the implementation and regression tests.

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