Skip to content

fix: Global - custom information keys with characters outside the identifier table no longer crash conversion - #1282

Open
aaronkanzer wants to merge 1 commit into
Benchling-Open-Source:mainfrom
aaronkanzer:fix/custom-info-key-characters
Open

aaronkanzer wants to merge 1 commit into
Benchling-Open-Source:mainfrom
aaronkanzer:fix/custom-info-key-characters

Conversation

@aaronkanzer

Copy link
Copy Markdown

Custom information keys are turned into dataclass field names through DICT_KEY_TO_MODEL_KEY_REPLACEMENTS. A key containing a character outside that table that is not valid verbatim in a Python identifier raises TypeError from make_dataclass and fails the whole conversion. That includes common lab column headers:

  • the micro sign in Dilution Volume (µL): Python NFKC-normalizes identifiers, turning U+00B5 MICRO SIGN into U+03BC GREEK SMALL LETTER MU, so the generated field no longer matches the keyword argument
  • ², ³, ±, ×, +, ;, |, !, ", <, >, {, } and backtick

An empty key raises IndexError.

For example, an Unchained Labs Lunatic export with an extra Dilution Volume (µL) column fails with:

TypeError: __create_fn__() got an unexpected keyword argument '_type_dilution_volume__OPAREN_µl_CPAREN_'

After the existing replacements, any remaining character that cannot appear verbatim in an identifier is now written as _U<hex>_ and decoded back when unstructuring, and an empty key gets its own token, so every key round-trips unchanged. Keys that already worked map to the same field names as before.

Testing: 7 new parametrized round-trip cases in tests/allotrope/converter_test.py, which fail without the change. The Lunatic example above converts and keeps the column as custom information. Full suite passes locally (1,270 tests; tests/schema_gen excluded for optional dependencies missing in my environment). black 22.3.0 and mypy are clean on the changed files.

…ntifier table no longer crash conversion

Custom information keys are turned into dataclass field names through a fixed
replacement table. A key containing any character outside that table that is
not valid verbatim in a Python identifier raised TypeError from
make_dataclass and failed the whole conversion. That includes common lab
column headers: MICRO SIGN in "Dilution Volume (µL)" (Python NFKC-normalizes
identifiers, turning U+00B5 into GREEK SMALL LETTER MU, so the generated field
no longer matches the keyword argument), and also ², ³, ±, ×, +, ;, |, !, ",
<, >, {, }, and `. An empty key raised IndexError.

For example, an Unchained Labs Lunatic export with an extra
"Dilution Volume (µL)" column failed with:
  TypeError: __create_fn__() got an unexpected keyword argument
  '_type_dilution_volume__OPAREN_µl_CPAREN_'

Remaining characters are now written as _U<hex>_ and decoded back on
unstructure, and an empty key gets its own token, so every key round-trips
unchanged. Keys that already worked map to the same field names as before.
@aaronkanzer
aaronkanzer requested review from a team and slopez-b as code owners October 20, 2026 21:22
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