Inconsistent results when streaming to unidiff (does not happen with urlopen or requests) #3736
Replies: 2 comments
|
This is with |
|
I reproduced the corruption without a network connection by passing the same synthetic diff through different chunk boundaries. There is no need for a nested-diff parsing bug: the parser is being given chunks as if they were lines. For your checksum comparison, preserve line endings too. import httpx
import unidiff
def diff_lines(response):
pending = ""
for chunk in response.iter_text():
parts = (pending + chunk).split("\n")
pending = parts.pop()
for line in parts:
yield line + "\n"
if pending:
yield pending
def sophisticated_httpx():
with httpx.stream("GET", diffurl) as r:
r.raise_for_status()
r.encoding = "utf-8"
patches = unidiff.PatchSet(diff_lines(r))
check(patches)Here Tested locally with HTTPX 0.28.1, unidiff 0.7.5, and Python 3.10.12: 514 controlled chunk layouts across LF, CRLF, and missing-final-newline inputs all matched The relevant contracts are in HTTPX's streaming documentation and unidiff's line-by-line parser. Prepared with AI assistance; the reproduction and adapter were executed locally. |
Uh oh!
There was an error while loading. Please reload this page.
In an LLM code review project we've been looking at different ways of parsing diffs. Today I was looking at different ways of reading diffs from a forge (GitHub, GitLab etc.) into unidiff, a diff parser. I encountered some weird behavior which I first reported to unidiff but now think is probably an httpx issue.
Here's the reproducer:
as you can see, that implements various ways of getting the same diff file, feeding it to
unidiff, and checking that it generates the expected result.If you run the 50-iteration loop for
naive,sophisticated_requests, orsophisticated_urlopen, they pass: they print OK 50 times. If you run it forsophisticated_httpx, it will produce some OKs but also fail in various interesting ways, documented in detail in the issue I reported to unidiff - it either misses some content, or crashes.All three 'sophisticated' methods use the same amount of memory, indicating they all are actually streaming the content to unidiff. But urlopen and requests work reliably, while httpx doesn't. I'm not sure why this is.
All reactions