Repository navigation
Fix line counting in get_location and print_block_string - #295
Conversation
Use the same GraphQL line terminator set (LF, CR, CRLF) that graphql-js and print_source_location() use, instead of str.splitlines() which also splits on VT, FF, FS/GS/RS, NEL and U+2028/U+2029 and drops a trailing empty line segment. This fixes three issues: - characters right after a line terminator were reported on the previous line - characters after non-GraphQL line breaks got wrong line numbers - print_source_location() could crash with IndexError when an error location pointed past the last printed line (issue #294) print_block_string() also splits raw values into lines and had the same drift: values containing e.g. VT printed as multi-line in Python but single-line in graphql-js.
|
Thanks for reporting and fixing this! It is a clear improvement, so I merge it as it is. I still plan some follow-up changes to bring this code fully in line with GraphQL.js. Fixed by this PR on
Planned as part of the regular porting from GraphQL.js:
Also planned:
I'll take care of that, you don't need to send a separate PR. |
|
The follow-up is done, on
The upstream performance changes that share location lookups (graphql/graphql-js#4936 and graphql/graphql-js#4958) follow with the regular porting. Thanks again for reporting and fixing this! |
|
The follow-up is done, on
The upstream performance changes that share location lookups (graphql/graphql-js#4936 and graphql/graphql-js#4958) are ported as well ( Thanks again for reporting and fixing this! |
Fixes #294
Summary
Source.get_location()andprint_block_string()usedstr.splitlines(), which recognizes more line boundaries than the GraphQL spec / graphql-js (\r\n,\n,\ronly). This produced three issues, all fixed by splitting on\r\n|[\n\r]— the same regexprint_source_location()already uses:IndexErrorcrash: an error location computed viaget_location()could reference a line that doesn't exist inprint_source_location()'s line array (e.g. source containing a vertical tab), makingstr(GraphQLSyntaxError)itself raise.splitlines()drops the trailing segment after a final newline, so every character immediately following a line terminator was reported on the previous line (Source("a\nb").get_location(2)→(1,2)instead of(2,1)).\v,\f,\x1c–\x1e,\x85,,were counted as line breaks inget_location()(graphql-js counts only\r\n|[\n\r]), andprint_block_string()split values on the same too-broad set.Found by differential-fuzzing parse/print output against graphql-js on mutated documents. After the fix, error locations and printed block strings match graphql-js byte-for-byte on the cases that previously diverged (e.g.
"Q\x0b…→ both reportUnterminated stringat1:30).Test plan
pytest tests/— 3,369 passed, 17 skippedtest_source.py),get_location-derived location rendering (test_print_location.py), non-GraphQL line breaks inprint_block_string(test_block_string.py)ruff check+ruff format --checkclean on all touched files