Skip to content

feat: add opt-in JSON comments and trailing commas - #1231

Draft
MbappeWU wants to merge 2 commits into
msgspec:mainfrom
MbappeWU:feat/json-comments-trailing-commas
Draft

MbappeWU wants to merge 2 commits into
msgspec:mainfrom
MbappeWU:feat/json-comments-trailing-commas

Conversation

@MbappeWU

@MbappeWU MbappeWU commented Oct 6, 2026 •

Copy link
Copy Markdown

Adds explicit, independent allow_comments and allow_trailing_commas options to msgspec.json.decode and Decoder for configuration files discussed in #1078. Defaults retain strict JSON syntax; the existing strict option retains its type-coercion meaning. Both comment forms, JSONC line endings, typed decoding, Raw, skipped unknown values and decode_lines use the same syntax implementation. Encoding and formatting retain their existing behavior.

The implementation places syntax code in a single 2,494-line private header and compiles strict and comment-enabled recursive closures. This replaces an initial implementation that measurably slowed default decoding. The strict expansion excludes comment/slash checks, and decode_lines selects its closure once. The source distribution explicitly includes the header.

AI disclosure: the changes, tests and design work were generated with Codex and Luna agents. Two independent agents reviewed code and C input handling; these are AI reviews, not human review or sanitizer results.

Validation on CPython 3.12 / macOS arm64:

  • Original baseline: 6,497 tests passed, 116 skipped, and 7 doctests passed. Current source: 6,559 passed, the same 116 skips, and 7 doctests passed.
  • Original just test-typing, just check, and just doc-build passed. No checks or skip rules were weakened.
  • Native wheel/sdist build and strict Twine checks passed. Full archive reads, C/header source parity, and a fresh wheel installation passed 217 public-interface checks, including flag/carrier combinations, tagged unions, Raw and unknown-field skipping.
  • Five alternating baseline/current rounds reused the upstream Benchmark.run and deterministic Directory data at 10 and 1,000 objects, typed and untyped. The earlier 9–11% default-path regressions did not recur. These limited, noisy wall-time observations do not establish a general speedup or a CodSpeed result.

This remains a draft while original CI, sanitizer validation and the upstream CodSpeed gate are pending. The native artifacts used for validation are development snapshots; no upstream package release has been made.

Refs #1078.

@provinzkraut

Copy link
Copy Markdown
Member

This is too big a change to review in one step.

Adding support for comments should not be done in the same batch as moving and altering the core parser to such an extent. It also makes this much more difficult to review.

This replaces an initial implementation that measurably slowed default decoding

Can you elaborate? Do you have some benchmarks to share? Why does placing the current parser in a header file speed it up?

Preserve a slash that starts neither a line nor a block comment so the
normal parser rejects it at its original position instead of skipping it.
Cover decode, Decoder.decode, and decode_lines with both trailing-comma
settings, Raw values, skipped fields, and valid comment boundaries.
@MbappeWU

MbappeWU commented Oct 9, 2026

Copy link
Copy Markdown
Author

Thanks for looking. You're right that this is too much for one review.

On the header: it doesn't make the parser faster. It's a template. _core.c includes _json_syntax_impl.h twice, once with JSON_ALLOW_COMMENTS 0 and once with 1, so the default decoder is compiled with no comment checks at all. In my local runs (Benchmark.run with the Directory data, 10 and 1,000 objects), an earlier iteration of this change was 9–11% slower on the default path; the two-instantiation layout was the fix for that. Those were a few noisy wall-time rounds on one machine, not CodSpeed, so please treat them as a hint, not evidence.

To make this reviewable, I'd like to close this PR and split it:

  1. allow_trailing_commas only. It's a small, flag-guarded change at the array and object separators in the current _core.c parser, with no code moved.
  2. allow_comments as a separate follow-up, also in place. CodSpeed would show whether the default path regresses. If it does, the specialization question can get its own discussion.

Does that split work for you, or would you prefer a different order?

This branch has not been deployed

No deployments
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.

2 participants