Treat a blank at the start of a value block as layout, not as value - #205
Merged
Merged
Conversation
gdevenyi
force-pushed
the
fix/jcampdx-leading-blank
branch
from
August 8, 2026 19:50
1634d1f to
351cc6f
Compare
`ruff format --check` reported twelve files as unformatted, so any change touching one of them dragged unrelated reflow into its diff. Run the formatter once, on its own, so subsequent changes show only what they actually change. Formatting only: no behaviour changes, and `ruff check` is clean before and after. The suite is unchanged at 2140 passed, 12 skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017SNrm3jFhpTPShP8xGkePC
_normalize_line_breaks only rstrip()ed, so a blank ParaVision writes after
an opening `(` stayed glued to the first element of the value.
parse_value tests the string shape with val_str.startswith("<"), which is
then False, so the only branch that calls unquote_string is skipped and the
lone remaining token is returned verbatim -- brackets included. Later
elements have no leading blank and are unquoted, so the PV6/PV360
(name, display-name) enum tuple came back asymmetric:
##$SUBJECT_study_adj_config=( <MRI_Default> , <MRI Default> )
-> ['<MRI_Default>', 'MRI Default']
Comparing such a value against its documented symbol silently never
matched, and writing it back re-quoted the delimiters it had kept
(<<MRI_Default>>). The same missing lstrip mistyped a leading number:
parse_value('( 1, 2 )') gave ['1', 2].
Strip both ends of the block instead. A value block begins after `##$name=`
or after a `(` / `, ` delimiter and ends where the next ## record begins, so
blanks at either end are layout. Blanks *inside* the value are untouched:
ParaVision's wrap puts the space before the newline it inserts, so joining
the lines still reassembles the string.
613 parameter occurrences across the corpus were affected --
CONFIG_SCAN_operation_mode, AdjConfigurationMode, CONFIG_SCAN_RxCoilsNames,
CONFIG_SCAN_TxCoilsNames, SHIM_status_check_sum_components,
SUBJECT_study_adj_config and PVM_StartupShimList.
Closes isi-nmr#193
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017SNrm3jFhpTPShP8xGkePC
gdevenyi
force-pushed
the
fix/jcampdx-leading-blank
branch
from
August 8, 2026 20:50
351cc6f to
bb7d4a9
Compare
Contributor
Author
|
Rebased onto #213 ( Integration check across all eleven conformance PRs merged together: 2164 passed, 12 skipped; corpus load test 3202 → 3207 of 3478 with zero newly broken datasets. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #193.
_normalize_line_breaksonlyrstrip()ed, so the blank ParaVision writes after an opening(stayed glued to element 0.parse_valuetests the string shape withval_str.startswith("<"), which is then False, so the only branch that callsunquote_stringis skipped and the token is returned verbatim:On real files:
so
value[0] == 'MRI_Default'was silently False, and the write path re-quoted the kept delimiters into<<MRI_Default>>. 613 parameter occurrences across the corpus were affected —CONFIG_SCAN_operation_mode(the spec's own worked example for this shape),AdjConfigurationMode,CONFIG_SCAN_RxCoilsNames,CONFIG_SCAN_TxCoilsNames,SHIM_status_check_sum_components,SUBJECT_study_adj_config,PVM_StartupShimList.Change
rstrip()→strip(), at the one shared point. That repairs the string case and the numeric case together. A value block begins after##$name=or after a(/,delimiter and ends where the next##record begins, so blanks at either end are layout. Blanks inside the value are untouched — ParaVision's wrap puts the space before the newline it inserts, so joining the lines still reassembles the string.After the fix, on real files:
Tests
test_a_blank_after_the_opening_paren_is_layout_not_value— the three shapes plus asubjectfile written inline. Fails on master.test_blanks_inside_a_wrapped_string_are_kept— a wrap inside a<...>string, guarding the blanks the change must not touch.Suite: 2140 passed, 12 skipped (unchanged). Corpus load test unchanged at 3202/3478 with an identical failure breakdown.