Repository navigation
fix(parser): unescape backslash pairs before the character after them - #2042
rahul05ranjan wants to merge 3 commits into
Conversation
_unescape_char applied its replacements as a sequential str.replace chain with "\\\\" collapsed last, so in a serialized value like C:\\numbers the "\\n" rule consumed the second backslash of the escaped-backslash pair first and turned the value into C:\ + a newline + "umbers". The function is documented as reversing _escape_char, but the round trip corrupted any value in which a literal backslash is followed by "n" or "N". Unescape in one left-to-right pass with a compiled alternation, the same approach unescape_backslash already uses, so a "\\" pair is consumed as a unit before the character after it is considered. Fixes PyCalendar#2041 Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
|
Thanks for the pull request, @rahul05ranjan! A maintainer will review it shortly. |
Automation signalsActivity patterns show signs of automation. Evidence
Last 5 PRs: This is an automated analysis by AgentScan |
|
One or more PR-quality checks did not pass. Review the PR Quality Checks summary in the workflow run for the failed checks and their details, then make any necessary updates. Checklist items may remain unchecked while work is in progress. Please tick each item as you complete it. If you used AI assistance, follow the project's Responsible AI use policy and provide the required disclosures. |
|
@rahul05ranjan I understand this is an automated account. Still, you need to follow the project guidelines & update the PR template. We will not review this otherwise. |
Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
|
Hi @niccokunzmann — sorry about that. The description now follows the PR template: issue linked, the existing details reorganized into the template sections, and the checklist items that apply (change log entry, tests) ticked. I also pushed f447218, which applies the One note on the remaining CI: the only failing test on 3.14 and in the source-distribution job is |
|
There are still unchecked items in the PR description. Please work on them and when done, check them. |
|
Thanks @angatha — I worked on the unchecked items:
I will address the AI-policy item separately. |
Model: GLM (Z.ai) model versions served via OpenRouter, as configured at the time of each commit; this session runs GLM-5.3. Use: an LLM agent (OpenClaw) operating the rahul05ranjan account analyzed the reported unescaping corruption, wrote the fix in src/icalendar/parser/string.py, added the regression tests in src/icalendar/tests/test_parsing.py, and drafted the change log entry and pull request description; each iteration ran the test suite locally before pushing. The account owner assigns the work and reviews the submissions. Output: this commit adds the AI disclosure to the change log entry; the pull request checklist item for the AI policy is checked with it. Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>
|
Done — thanks for pointing at the remaining item. The AI policy checklist box is now checked, and f838599 adds the disclosure the policy asks for: the change log entry now says the fix was drafted with AI assistance, and that commit's message names the model family and summarizes how it was used (analysis, fix, tests, and PR text, with the suite run locally each iteration). |
|
One note on the red ReadTheDocs check: it is not caused by the recent commits. This branch predates the sphinx-design card migration that landed on |

Linked issue
Description
_unescape_charunescaped with a sequentialstr.replacechain that collapsed the backslash pair last:In the serialized form
C:\\numbersthe\\nrule consumes the second backslash and thenfirst, producingC:\+ newline +umbersinstead ofC:\numbers. The same happens via the\\Nnormalization forC:\\Numbers.Repro (stdlib only)
The unescaped value is
Read C:+ backslash + newline +umbers.csv first.Fix
Unescape in one left-to-right pass with a compiled alternation — the same approach
unescape_backslashinsrc/icalendar/parser/property.pyalready uses — so a\\pair is consumed as a unit before the character after it is considered:A separate bytes pattern handles the
bytesinput path; theTypeErrorguard is unchanged.Checklist
Additional information
123,\n→ newline,\N→ newline,\\→ backslash,\,/\;,\\then\n(double-escaped), odd trailing backslashes, unknown escapes (\x), empty string, raw CRLF normalization — all identical to the old behavior except the fixed cases.pytest src/icalendar/tests/test_parsing.py: 327 passed (323 before + 4 new tests added in this PR).test_parsing.py): 234 failed / 14486 passed both before and after the change on this machine (pre-existing failures: missing tzdata/hypothesis on the dev box), i.e. no regressions from this patch.The new tests pin the round trip
_unescape_char(_escape_char(x)) == xfor a backslash +n/Nvalue, and the case of a double-escaped backslash followed by an escaped newline.