docs: def add_node(self, node, attr_dict=None, **attr):
          """Adds a node to the graph, along with any related attributes
             of the node.
  
          :param node: reference to the node being added.
          :param attr_dict: dictionary of attributes of the node.
          :param attr: keyword arguments of attributes of the node;
                      attr's values will override attr_dict's values
                      if both are provided.
  
          Examples:
          ::
  
              >>> H = DirectedHypergraph()
              >>> attributes = {label: "positive"}
              >>> H.add_node("A", attributes)
              >>> H.add_node("B", label="negative")
              >>> H.add_node("C", attributes, root=True)
  
          """
          attr_dict = self._combine_attribute_arguments(attr_dict, attr)
  
          # If the node hasn't previously been added, add it along
          # with its attributes
          if not self.has_node(node):
              self._node_attributes[node] = attr_dict
              self._forward_star[node] = set()
              self._backward_star[node] = set()
          # Otherwise, just update the node's attributes
          else:
              self._node_attributes[node].update(attr_dict)