@@ -91,25 +91,27 @@ def _find(obj, predicate):
9191
9292def  _dereference (namespace , base_schema ):
9393    # In-place, recursively dereference objects 
94-     # This allows a referenced object to itself contain a reference 
95-     # A dependency graph could be constructed, but would likely be slower 
96-     # to build than to duplicate a couple dereferences 
94+     # This allows for referencing objects that contain references, 
95+     # as well as objects that do not exist until a parent is dereferenced. 
9796    for  struct  in  _find (namespace , lambda  obj : "$ref"  in  obj ):
9897        refs  =  struct ["$ref" ]
9998        if  isinstance (refs , str ):
10099            refs  =  [refs ]
101100        targets  =  []
102101        for  ref  in  refs :
103-             target  =  base_schema .get (ref )
104-             if  target  is  None :
105-                 raise  ValueError (f"Reference { ref }  )
102+             target  =  base_schema 
103+             for  part  in  ref .split ("." ):
104+                 target  =  target .get (part )
105+                 if  target  is  None :
106+                     raise  ValueError (f"Reference { ref }  )
107+                 if  "$ref"  in  target :
108+                     _dereference (target , base_schema )
106109            targets .append (target )
110+ 
107111        if  all (isinstance (target , Mapping ) for  target  in  targets ):
108112            struct .pop ("$ref" )
109113
110-             combined_target  =  dict (ChainMap (* targets ))
111-             _dereference (combined_target , base_schema )
112-             struct .update ({** combined_target , ** struct })
114+             struct .update ({** ChainMap (* targets ), ** struct })
113115
114116            # Use `key: null` to delete fields 
115117            for  key , value  in  list (struct .items ()):
0 commit comments