Repository navigation
Conversation
Three of the parser tests fed input to a single implementation, so whether the other one behaved the same was untested. Both parsers reject a control character in a header value, a bare LF used as a header terminator, and a header line that isn't valid UTF-8, only with different error detail. Add the missing lowercase-method case for the C parser too, which rejects what the Python parser normalises.
Test run (Cython extensions installed, C parser available)The three remaining xfails are pre-existing ( |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #13271 +/- ##
=======================================
Coverage 98.98% 98.98%
=======================================
Files 131 132 +1
Lines 48993 49020 +27
Branches 2550 2552 +2
=======================================
+ Hits 48496 48523 +27
Misses 373 373
Partials 124 124
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
Merging this PR will not alter performance
Comparing Footnotes
|
|
@Dreamsorcerer this is the parity pass you suggested on #13246 — the three inputs both parsers reject are now parametrised over both, and the lowercase-method case that only they differ on has a C-side test next to the Python one. Tests only, no parser changes. |
|
I'm not sure why new tests are being added, rather than fixing existing ones. |
Rework per review: rather than adding parametrised tests next to the narrow ones, convert the narrow ones. test_unpaired_surrogate_in_header_py and test_py_parser_normalises_method_to_uppercase both hand-rolled a single implementation. They now take the parser fixture and run against both, keeping the implementation-specific expectations: the Python parser raises InvalidHeader and canonicalises a lowercase method, llhttp raises BadHttpMessage and BadHttpMethod respectively. Distinguishing the two needs a module check rather than isinstance(), because HttpRequestParserPy aliases the same class the annotations name, which makes the negative branch statically unreachable. The two genuinely new cases are dropped: control characters in a header value are already covered for both parsers by test_ctl_host_header_bad_characters, and the bare-LF case belongs with the divergence noted on the pull request rather than in this change.
|
Fair point — reworked in 184eac6 so the PR now only widens existing tests and adds none. Converted:
Dropped both of the ones that were genuinely new rather than parity work: control characters in a header value are already covered for both parsers by One thing worth a decision separately. A bare LF terminating a header line leaves the Python parser waiting for more data instead of failing. Move the LF into the middle of the header block — Verified locally with the C extension built: |

What do these changes do?
Follow-up to the suggestion in #13246: some parser tests only ever fed input to one implementation, so nobody knew whether the other one agreed.
I checked the three request-parser tests that construct a parser class directly and ran their input through both implementations:
Set-Cookie: abc\x01def)InvalidHeaderBadHttpMessageHost: a\nX-Evil: b)InvalidHeaderBadHttpMessage\xff)InvalidHeaderBadHttpMessageget /test HTTP/1.1)GETBadHttpMethodThe first three agree — both reject, only the error detail differs (
InvalidHeaderis aBadHttpMessage), so they are now parametrised over both parsers. The existing C-only tests keep their error-snippet assertions, which really are C-specific.The method case genuinely differs, and only the Python side was covered, so the C side now has an explicit test next to it. That difference is intentional (llhttp rejects lowercase upstream) but it was invisible in the test suite.
No production code is touched.
Are there changes in behavior for the user?
No, tests only.
Is it a substantial burden for the maintainers to support this?
No. It removes single-implementation blind spots rather than adding anything to maintain, and it makes any future divergence between the two parsers fail a test instead of going unnoticed.
Related issue number
Refs #13246.
Checklist
CONTRIBUTORS.txt— already listedCHANGES/folderDrafted with Claude Code; reviewed by @LuShadowX.