def recompose_base(self, obj: dict) -> Base: """Steps through a base object dictionary and recomposes the base object Arguments: obj {dict} -- the dictionary representation of the object Returns: Base -- the base object with all its children attached """ # make sure an obj was passed and create dict if string was somehow passed if not obj: return if isinstance(obj, str): obj = safe_json_loads(obj) if "speckle_type" in obj and obj["speckle_type"] == "reference": obj = self.get_child(obj=obj) speckle_type = obj.get("speckle_type") # if speckle type is not in the object definition, it is treated as a dict if not speckle_type: return obj # get the registered type from base register. object_type = Base.get_registered_type(speckle_type) # initialise the base object using `speckle_type` fall back to base if needed base = object_type() if object_type else Base.of_type( speckle_type=speckle_type) # get total children count if "__closure" in obj: if not self.read_transport: raise SpeckleException( message= "Cannot resolve reference - no read transport is defined") closure = obj.pop("__closure") base.totalChildrenCount = len(closure) for prop, value in obj.items(): # 1. handle primitives (ints, floats, strings, and bools) or None if isinstance(value, PRIMITIVES) or value is None: base.__setattr__(prop, value) continue # 2. handle referenced child objects elif "referencedId" in value: ref_hash = value["referencedId"] ref_obj_str = self.read_transport.get_object(id=ref_hash) if not ref_obj_str: raise SpeckleException( f"Could not find the referenced child object of id `{ref_hash}` in the given read transport: {self.read_transport.name}" ) ref_obj = safe_json_loads(ref_obj_str, ref_hash) base.__setattr__(prop, self.recompose_base(obj=ref_obj)) # 3. handle all other cases (base objects, lists, and dicts) else: base.__setattr__(prop, self.handle_value(value)) return base
def test_new_type_registration() -> None: """Test if a new subclass is registered into the type register.""" assert Base.get_registered_type("FakeModel") == FakeModel assert Base.get_registered_type("🐺️") is None