@@ -933,32 +933,7 @@ def read_properties(subschema: dict, from_schema: ReferencedSchema,
933933
934934 cached_schema_contexts = {}
935935 cached_schema_paths : dict [str , list [str ]] = {}
936- copy_log : list [tuple [list [str ], list [str ], str ]] = []
937-
938- # ------------------------------------------------------------------
939-
940- def copy_resolved_props (src_path : list [str ], dst_path : list [str ]) -> None :
941- """
942- Copy all ResolvedProperty entries rooted at *src_path* to *dst_path*.
943- Fallback for $ref cache-hits at unnamed nodes (allOf / root) where there
944- is no rp entry to hang a `ref` pointer on.
945- """
946- if src_path == dst_path :
947- return
948- sep = '\x00 '
949- src_len = len (src_path )
950- for k , v in list (self ._resolved_properties .items ()):
951- if len (v .path ) > src_len and v .path [:src_len ] == src_path :
952- new_path = dst_path + v .path [src_len :]
953- new_key = sep .join (new_path )
954- if new_key in self ._resolved_properties :
955- merged = copy .deepcopy (v )
956- merged .path = new_path
957- self ._resolved_properties [new_key ].merge (merged )
958- else :
959- new_rp = copy .deepcopy (v )
960- new_rp .path = new_path
961- self ._resolved_properties [new_key ] = new_rp
936+ ref_log : list [tuple [list [str ], list [str ], str ]] = []
962937
963938 # ------------------------------------------------------------------
964939
@@ -999,8 +974,8 @@ def process_subschema(subschema: dict, from_schema: ReferencedSchema,
999974 else :
1000975 if cache_key in cached_schema_paths :
1001976 src = cached_schema_paths [cache_key ]
1002- copy_resolved_props ( src , schema_path )
1003- copy_log .append ((list (src ), list (schema_path ), cache_key ))
977+ if src and schema_path :
978+ ref_log .append ((list (src ), list (schema_path ), cache_key ))
1004979 merge_contexts (onto_context , ref_ctx )
1005980 else :
1006981 # local_refs_only blocks this ref's context contribution, but we still
@@ -1152,7 +1127,7 @@ def _flatten(bl):
11521127
11531128 merge_contexts (own_context , process_subschema (root_schema .subschema , root_schema , []))
11541129 self ._hoist_common_branch_properties ()
1155- self ._dedup_to_defs (copy_log )
1130+ self ._dedup_to_defs (ref_log )
11561131 self ._renumber_branches ()
11571132
11581133 for imported_et in imported_extra_terms .values ():
@@ -1406,14 +1381,14 @@ def _all_descendants(key: str) -> list[tuple[str, ResolvedProperty]]:
14061381 elif group_key in rp :
14071382 _del (group_key )
14081383
1409- def _dedup_to_defs (self , copy_log : list [tuple [list [str ], list [str ], str ]]) -> None :
1384+ def _dedup_to_defs (self , ref_log : list [tuple [list [str ], list [str ], str ]]) -> None :
14101385 """
1411- Post-hoist deduplication: for each (src_path, dst_path, cache_key) in copy_log ,
1412- if the dst subtree still has entries (not all hoisted), move the src subtree
1413- into _resolved_property_defs[cache_key] with relative paths and replace both
1414- the src and dst nodes with ``ref`` pointers .
1386+ For each (src_path, dst_path, cache_key) recorded at $ref cache-hit time ,
1387+ move the src subtree into _resolved_property_defs[cache_key] with relative
1388+ paths (first occurrence only) and set a ``ref`` pointer on both the src node
1389+ and the dst node. No pre-copying is needed — dst has no inline children .
14151390 """
1416- if not copy_log :
1391+ if not ref_log :
14171392 return
14181393
14191394 rp = self ._resolved_properties
@@ -1446,19 +1421,18 @@ def _remove_descendants(path: list[str]) -> None:
14461421 children .pop (k , None )
14471422 children .pop (path_key , None )
14481423
1449- for src_path , dst_path , cache_key in copy_log :
1424+ for src_path , dst_path , cache_key in ref_log :
14501425 if not src_path or not dst_path or src_path == dst_path :
14511426 continue
14521427
14531428 dst_key = sep .join (dst_path )
1454- dst_descendants = _get_descendants (dst_path )
1455- if not dst_descendants :
1456- continue # all hoisted away; nothing to dedup
1429+ if dst_key not in rp :
1430+ continue
14571431
14581432 if cache_key not in self ._resolved_property_defs :
14591433 src_descendants = _get_descendants (src_path )
14601434 if not src_descendants :
1461- continue
1435+ continue # all hoisted away; nothing to put in a def
14621436 src_len = len (src_path )
14631437 def_entries = []
14641438 for _ , v in src_descendants :
@@ -1471,8 +1445,7 @@ def _remove_descendants(path: list[str]) -> None:
14711445 if src_key in rp :
14721446 rp [src_key ].ref = cache_key
14731447
1474- _remove_descendants (dst_path )
1475- if dst_key in rp :
1448+ if dst_key in rp : # may have been removed if dst was under src
14761449 rp [dst_key ].ref = cache_key
14771450
14781451 def _renumber_branches (self ) -> None :
0 commit comments