@@ -176,6 +176,7 @@ def write_compatible_names(
176176 encoding = encoding ,
177177 compatible_replacements = replacements ,
178178 known_compatible_names = [name for _record , name in primary_variables ],
179+ known_long_names = [long_name for _short_name , long_name in pairs ],
179180 )
180181 record_replacements .update (reference_replacements )
181182
@@ -419,16 +420,49 @@ def _assert_dictionary_semantics(
419420 raise RawDictionaryError ("Multiple-response Reader readback changed semantics." )
420421
421422
423+ def _rewrite_reference_member (
424+ raw_member : bytes ,
425+ * ,
426+ subtype : int ,
427+ encoding : str ,
428+ known_compatible : dict [str , str ],
429+ known_long : dict [str , str ],
430+ encoded_replacements : dict [str , bytes ],
431+ ) -> bytes :
432+ try :
433+ compatible = raw_member .decode ("ascii" )
434+ _validated_compatible_name (compatible )
435+ except (UnicodeDecodeError , RawDictionaryError ):
436+ compatible = None
437+ if compatible is not None and compatible .casefold () in known_compatible :
438+ return encoded_replacements .get (compatible .casefold (), raw_member )
439+ try :
440+ long_name = raw_member .decode (encoding )
441+ except UnicodeDecodeError as error :
442+ raise RawDictionaryError (
443+ f"Invalid subtype-{ subtype } variable member token."
444+ ) from error
445+ if long_name .casefold () in known_long :
446+ return raw_member
447+ raise RawDictionaryError (
448+ f"Subtype-{ subtype } references unknown variable { long_name !r} ."
449+ )
450+
451+
422452def _rewrite_reference_records (
423453 data : bytes , * , byte_order : str , records : list [_Record ], encoding : str ,
424454 compatible_replacements : dict [str , str ], known_compatible_names : Iterable [str ],
455+ known_long_names : Iterable [str ],
425456) -> tuple [dict [int , bytes ], dict [int , tuple [bytes , ...]]]:
426457 known_names = list (known_compatible_names )
427458 _require_unique_names (known_names , "reference-compatible variable" )
428459 known = {name .casefold (): name for name in known_names }
429460 encoded_replacements = {
430461 key : value .encode ("ascii" ) for key , value in compatible_replacements .items ()
431462 }
463+ long_names = list (known_long_names )
464+ _require_unique_names (long_names , "reference long variable" )
465+ known_long = {name .casefold (): name for name in long_names }
432466 replacements : dict [int , bytes ] = {}
433467 expected : dict [int , list [bytes ]] = {5 : [], 7 : [], 19 : []}
434468 seen_variable_sets : dict [str , str ] = {}
@@ -463,19 +497,14 @@ def _rewrite_reference_records(
463497 seen [set_key ] = set_name
464498 members : list [bytes ] = []
465499 for raw_member in parsed .members :
466- try :
467- member = raw_member .decode ("ascii" )
468- _validated_compatible_name (member )
469- except (UnicodeDecodeError , RawDictionaryError ) as error :
470- raise RawDictionaryError (
471- f"Invalid subtype-{ subtype } compatible member token."
472- ) from error
473- member_key = member .casefold ()
474- if member_key not in known :
475- raise RawDictionaryError (
476- f"Subtype-{ subtype } references unknown compatible variable { member !r} ."
477- )
478- members .append (encoded_replacements .get (member_key , raw_member ))
500+ members .append (_rewrite_reference_member (
501+ raw_member ,
502+ subtype = subtype ,
503+ encoding = encoding ,
504+ known_compatible = known ,
505+ known_long = known_long ,
506+ encoded_replacements = encoded_replacements ,
507+ ))
479508 updated_lines .append (_ReferenceLine (
480509 set_name = parsed .set_name ,
481510 segments = parsed .segments ,
@@ -648,7 +677,7 @@ def _very_long_string_entries(
648677 return _very_long_string_pairs (payload ), True
649678
650679def _very_long_string_pairs (payload : bytes ) -> list [tuple [str , bytes ]]:
651- if not payload or not payload .endswith (b"\x00 " ):
680+ if not payload or not payload .endswith (b" " ):
652681 raise RawDictionaryError ("Invalid SAV very-long-string record terminator." )
653682 raw_pairs = payload .split (b" " )
654683 if raw_pairs [- 1 ] != b"" :
@@ -722,6 +751,7 @@ def _assert_compatible_name_rewrite(
722751 encoding = encoding ,
723752 compatible_replacements = {},
724753 known_compatible_names = expected_primary_names ,
754+ known_long_names = [long_name for _short_name , long_name in pairs ],
725755 )
726756 if observed_reference_payloads != expected_reference_payloads :
727757 raise RawDictionaryError (
@@ -844,7 +874,7 @@ def _document_record(lines: Iterable[str], *, encoding: str, byte_order: str) ->
844874
845875
846876def _records (data : bytes ) -> tuple [str , list [_Record ]]:
847- if len (data ) < _HEADER_SIZE or data [:4 ] not in {b"$FL2" , b"$FL3" }:
877+ if len (data ) < _HEADER_SIZE or bytes ( data [:4 ]) not in {b"$FL2" , b"$FL3" }:
848878 raise RawDictionaryError ("Not a supported SAV or ZSAV system file." )
849879 byte_order = _byte_order (data )
850880 offset = _HEADER_SIZE
0 commit comments