Hi, I’m trying to create a tree data structure in python to do this I have the following files:
# module/node.py
from collections.abc import Iterable
from module.exceptions import MultipleParentsError
class Node:
def __init__(self, initial_children: Iterable[Node] = ()) -> None:
self.parent: Node | None = None
self.children: list[Node] = []
for child in initial_children:
self.add_child(child)
def add_child(self, child):
if child.parent is not None:
raise MultipleParentsError(child, self, child.parent)
else:
self.children.append(child)
child.parent = self
and
# module/exceptions.py
from module.node import Node
class MultipleParentsError(RuntimeError):
def __init__(self, child: Node, new_parent: Node, preexisting_parent: Node, *args: object) -> None:
super().__init__(f"Tried to add child {child} to {new_parent} but child already has a parent: {preexisting_parent}", *args)
I only import Node in the exceptions.py for type checking, The problem is that this creates an import cycle. From what I could see by searching online, the variable typing.TYPE_CHECKING can be used to avoid this, however my type checker (basedpyright) still shows the import cycle error. This is apparently because this type of error is indicative of a larger issue with the program’s structure, I can see two solutions to this, but I don’t know which one is the best or if I am missing one:
- Move MultipleParentsError to the node.py file as it is related to the same functionality (so far this is my preferred solution)
- Give up and use type Any or no type hinting (but this seems like a bad idea)