def test_parse_existing_namespace(): test_dict = { "all": { "work": { "no": { "play": { "dull_boy": {} } } } }, "hackers": { "on": { "planet": { "earth": {} } } } } ns = Namespace() nscp = NamespaceConfigParser2(namespace=ns) nscp.parse(dictConfig=test_dict) for nsid in get_nsid_ancestry('.all.work.no.play.dull_boy'): assert isinstance(ns.get(nsid), NamespaceNodeBase) for nsid in get_nsid_ancestry('.hackers.on.planet.earth'): assert isinstance(ns.get(nsid), NamespaceNodeBase)
def test_get_new_ancestry(self): new_nsid1 = '.a.b.c.d' deepest_ancestor_nsid = '.a' starting_point = strip_common_prefix( deepest_ancestor_nsid, new_nsid1)[1] new_ancestry = get_nsid_ancestry(starting_point) self.assertEqual(new_ancestry, ['b', 'b.c', 'b.c.d'])
def test_parse_when_namespace_is_a_handle(): test_dict = {"all": {"work": {"no": {"play": {"dull_boy": {}}}}}} nscp = NamespaceConfigParser2() ns = nscp.parse(dictConfig=test_dict) handle = ns.get_handle('.all.work.no') test_dict_2 = { "meaning": { "will": { "leave": { "you": { "empty_inside": {} } } } } } nscp = NamespaceConfigParser2(namespace=handle) nscp.parse(test_dict_2) for nsid in get_nsid_ancestry( '.all.work.no.meaning.will.leave.you.empty_inside'): assert isinstance(ns.get(nsid), NamespaceNodeBase)
def add(self, nsid: Union[str, Nsid], node_factory: Union[callable, None] = None, *args, **kwargs) -> List[NamespaceNodeBase]: """ Description: add a new nsid to this namespace Input: nsid: the nsid to create in this namespace node_factory: what factory to use to create the node NOTE: parent nodes will be created with this namespaces default_node_factory method *args: passed into the node_factory as args **kwargs: passed into the node_factory as kwargs """ log = LoggerAdapter(logger, dict(name_ext=f"{self.__class__.__name__}.add")) if find_common_prefix(str(self.root.nsid), nsid) is None: err_msg = f'child nsid ({nsid}) must share a common prefix with Namespace root node nsid' err_msg += f'({str(self.root.nsid)})' raise InvalidNsidError(err_msg) _nsid = Nsid(nsid) if node_factory is None: node_factory = self.default_node_factory #- find the deepest existing ancestor of the node we wish to add deepest_ancestor = self.root for current_nsid in get_nsid_ancestry(nsid): try: deepest_ancestor = self.get(current_nsid) except NamespaceLookupError: break else: #- we never hit break, so every single nsid in the entire ancestry exists, including the one we want to add raise NamespaceCollisionError( f'A node with the nsid "{nsid}" already exists in the namespace.' ) #- if here, we have a valid deepest ancestor to start from child_nsid_tail = strip_common_prefix(str(deepest_ancestor.nsid), str(_nsid))[1] common_prefix = find_common_prefix(str(deepest_ancestor.nsid), str(_nsid)) created_nodes = list( ) #- keep track of all the nodes we create to return them nsid_segments = list_nsid_segments(child_nsid_tail) for i, child_attribute_name in enumerate(nsid_segments): new_node_nsid = make_child_nsid(str(deepest_ancestor.nsid), child_attribute_name) #- use the node factory on the last node only if i == len(nsid_segments) - 1: log.debug(f"creating node: {node_factory=})") try: new_node = node_factory(*args, nsid=new_node_nsid, namespace=self, **kwargs) except TypeError as e: raise TypeError( f"node_factory failed to create node: {str(e)}") from e else: new_node = self.default_node_factory(nsid=new_node_nsid, namespace=self) created_nodes.append(new_node) setattr(deepest_ancestor, child_attribute_name, new_node) deepest_ancestor = getattr(deepest_ancestor, child_attribute_name) return created_nodes
def test_get_nsid_ancestry(self): nsid1 = '.a.b.c' nsid1_ancestry = ['.','.a','.a.b', '.a.b.c' ] self.assertEqual(get_nsid_ancestry(nsid1), nsid1_ancestry)