@@ -47,33 +47,44 @@ def find_refs_in_value(value: Any, parent_def: str) -> bool:
4747
4848def dereference_json_schema (schema : dict , max_depth : int = 5 ) -> dict :
4949 """
50- Dereference a JSON schema by resolving $ref references while preserving $defs.
50+ Dereference a JSON schema by resolving $ref references while preserving $defs only when corner cases occur .
5151
5252 This function flattens schema properties by:
53- 1. Check for self-reference - if found, return original schema
53+ 1. Check for self-reference - if found, return original schema with $defs
5454 2. When encountering $refs in properties, resolve them on-demand
5555 3. Track visited definitions globally to prevent circular expansion
56- 4. Preserve original $defs in the final result
56+ 4. Only preserve original $defs if corner cases are encountered:
57+ - Self-reference detected
58+ - Circular references between definitions
59+ - Reference depth exceeds max_depth
60+ - Reference not found in $defs
5761
5862 Args:
5963 schema: The JSON schema to flatten
6064 max_depth: Maximum depth for resolving references (default: 5)
6165
6266 Returns:
63- Schema with references resolved in properties, keeping original $defs
67+ Schema with references resolved in properties, keeping $defs only when corner cases occur
6468 """
6569 # Step 1: Check for self-reference
6670 if _detect_self_reference (schema ):
67- # Self-referencing detected, return original schema
71+ # Self-referencing detected, return original schema with $defs
6872 return schema
6973
7074 # Make a deep copy to work with
7175 result = deepcopy (schema )
7276
73- # Keep original $defs for the final result
77+ # Keep original $defs for potential corner cases
7478 defs = deepcopy (schema .get ("$defs" , {}))
7579
76- # Step 2: Define resolution function that tracks visits globally
80+ # Track corner cases that require preserving $defs
81+ corner_cases_detected = {
82+ "circular_ref" : False ,
83+ "max_depth_reached" : False ,
84+ "ref_not_found" : False ,
85+ }
86+
87+ # Step 2: Define resolution function that tracks visits globally and corner cases
7788 def resolve_refs_in_value (value : Any , depth : int , visiting : set [str ]) -> Any :
7889 """
7990 Recursively resolve $refs in a value.
@@ -84,9 +95,10 @@ def resolve_refs_in_value(value: Any, depth: int, visiting: set[str]) -> Any:
8495 visiting: Set of definitions currently being resolved (for cycle detection)
8596
8697 Returns:
87- Value with $refs resolved (or kept if max depth reached )
98+ Value with $refs resolved (or kept if corner cases occur )
8899 """
89100 if depth >= max_depth :
101+ corner_cases_detected ["max_depth_reached" ] = True
90102 return value
91103
92104 if isinstance (value , dict ):
@@ -100,6 +112,7 @@ def resolve_refs_in_value(value: Any, depth: int, visiting: set[str]) -> Any:
100112 # Check for circular reference
101113 if def_name in visiting :
102114 # Circular reference detected, keep the $ref
115+ corner_cases_detected ["circular_ref" ] = True
103116 return value
104117
105118 if def_name in defs :
@@ -123,6 +136,7 @@ def resolve_refs_in_value(value: Any, depth: int, visiting: set[str]) -> Any:
123136 return resolved
124137 else :
125138 # Definition not found, keep the $ref
139+ corner_cases_detected ["ref_not_found" ] = True
126140 return value
127141 else :
128142 # External ref or other type - keep as is
@@ -147,9 +161,14 @@ def resolve_refs_in_value(value: Any, depth: int, visiting: set[str]) -> Any:
147161 # This allows the same definition to be used in different contexts
148162 result [key ] = resolve_refs_in_value (value , 0 , set ())
149163
150- # Step 4: Preserve original $defs
151- if "$defs" in result :
152- result ["$defs" ] = defs
164+ # Step 4: Conditionally preserve $defs based on corner cases
165+ if any (corner_cases_detected .values ()):
166+ # Corner case detected, preserve original $defs
167+ if "$defs" in schema : # Only add if original schema had $defs
168+ result ["$defs" ] = defs
169+ else :
170+ # No corner cases, remove $defs if it exists
171+ result .pop ("$defs" , None )
153172
154173 return result
155174
0 commit comments