MCPcopy Index your code
hub / github.com/apache/fory / compute_struct_fingerprint

Function compute_struct_fingerprint

python/pyfory/struct.py:1071–1139  ·  view source on GitHub ↗

Computes the fingerprint string for a struct type used in schema versioning. Fingerprint Format: Each field contributes: , , , [ ]; Fields are sorted by tag ID (if >=0) or snake_case field name when no ID is configured. F

(type_resolver, field_names, serializers, nullable_map=None, field_infos_list=None)

Source from the content-addressed store, hash-verified

1069
1070
1071def compute_struct_fingerprint(type_resolver, field_names, serializers, nullable_map=None, field_infos_list=None):
1072 """
1073 Computes the fingerprint string for a struct type used in schema versioning.
1074
1075 Fingerprint Format:
1076 Each field contributes: <field_id_or_name>,<type_id>,<ref>,<nullable>[<child...>];
1077 Fields are sorted by tag ID (if >=0) or snake_case field name when no ID is configured.
1078
1079 Field Components:
1080 - field_id_or_name: Tag ID as string if id >= 0, otherwise snake_case field name
1081 - type_id: Fory TypeId as decimal string (e.g., "4" for INT32)
1082 - ref: "1" if field has ref=True in pyfory.field(), "0" otherwise
1083 (based on field annotation, NOT runtime config)
1084 - nullable: "1" if null flag is written, "0" otherwise
1085
1086 Example fingerprints:
1087 With tag IDs: "0,4,0,0;1,12,0,1;2,0,0,1;"
1088 With field names: "age,4,0,0;email,12,0,1;name,9,0,0;"
1089
1090 This format is consistent across Go, Java, Rust, C++, and Python implementations.
1091 """
1092 if nullable_map is None:
1093 nullable_map = {}
1094
1095 # Build field info list for fingerprint: (sort_key, field_id_or_name, type_fingerprint)
1096 fp_fields = []
1097
1098 # Build a lookup for field_infos by name if available
1099 field_info_map = {}
1100 if field_infos_list:
1101 field_info_map = {fi.name: fi for fi in field_infos_list}
1102
1103 for i, field_name in enumerate(field_names):
1104 serializer = serializers[i]
1105
1106 # Get field metadata if available
1107 fi = field_info_map.get(field_name)
1108 tag_id = fi.tag_id if fi else -1
1109 nullable = fi.nullable if fi else nullable_map.get(field_name, False)
1110 ref = fi.ref if fi else False
1111 type_hint = fi.type_hint if fi else (serializer.type_ if serializer is not None else typing.Any)
1112 type_fingerprint = _build_schema_fingerprint_type(
1113 type_resolver,
1114 type_hint,
1115 nullable=nullable,
1116 track_ref=ref,
1117 include_ref=True,
1118 )
1119
1120 # Determine field identifier for fingerprint
1121 if tag_id >= 0:
1122 field_id_or_name = str(tag_id)
1123 sort_key = (0, tag_id, "") # 0 = tag ID fields come first
1124 else:
1125 field_id_or_name = _to_snake_case(field_name)
1126 # Sort by snake_case field name for name-based fields.
1127 sort_key = (1, field_id_or_name, field_name) # 1 = name fields come after
1128

Callers 6

__init__Method · 0.70
compute_struct_metaFunction · 0.70
TESTFunction · 0.50

Calls 5

_to_snake_caseFunction · 0.85
sortMethod · 0.80
getMethod · 0.65
appendMethod · 0.45