Repository navigation
xport: preserve trailing period when reconstructing formats - #415
Merged
evanmiller merged 2 commits intoOct 20, 2026
Merged
Conversation
xport_construct_format() only emitted a period when the format had decimals, so a format written as DATE9. was read back as DATE9. Since the format name, width, and decimals are stored separately in the namestr, the trailing period must be re-added whenever a width is present (formats with no width, like $, are unaffected). Reported in tidyverse/haven#782.
hadley
added a commit
to tidyverse/haven
that referenced
this pull request
Oct 20, 2026
`read_xpt()` now takes `meta()@width` from the namestr format width (nfl, exposed by ReadStat as `display_width`) instead of the storage width, so width metadata round-trips through `write_xpt()`. sas7bdat is unaffected since it doesn't set `display_width`. The trailing-period part of #782 is fixed upstream in WizardMac/ReadStat#415 and will land with the next vendored ReadStat update. Also disable clang-format for the vendored `src/readstat/` directory. Fixes #782.
8 of 9 tasks
Contributor
|
Looks like tests are failing? |
Contributor
Author
|
Oops, I will go castigate my AI. |
XPORT can't record whether a format had a trailing period, and now always reconstructs it, so test with formats that include it.
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.
🤖 Written by AI 🤖
The XPT namestr stores format name, width, and decimals as separate fields, so
xport_parse_format()consumes the period when writing. Butxport_construct_format()only re-added a period when the format had decimals, so formats round-trip lossily:DATE9.→ read back asDATE9DATETIME20.2→ read back correctly (has decimals)This trips up workflows that compare attributes between a dataset and the XPT written from it (e.g. tidyverse/haven#782), and disagrees with the sas7bdat reader, which stores the format string verbatim.
The fix appends the period whenever a width is present; formats with no width (e.g.
$) are unaffected. Verified via haven's XPT round-trip tests:DATE9.now round-trips asDATE9., and$,10.3,COMMA10.3etc. are unchanged.