Using AnyNode(anytree) with dataclasses fails to create children in parent class

26 views Asked by At

I am working on a large program, but have isolated my issue to a smaller example:

from dataclasses import dataclass, field
from anytree import AnyNode, RenderTree
from typing import Optional


@dataclass(kw_only=True)
class SimpleNode(AnyNode):
    name: str
    parent: AnyNode = field(default=None)

    def __init__(self, name: str, parent: AnyNode=None):
        self.name = name
        # Initialize AnyNode with the parent
        AnyNode.__init__(self, parent=parent)


@dataclass(kw_only=True)
class ChildNode(SimpleNode):
    value: int



# Creating a tree structure
root = SimpleNode(name="Root")
child1 = ChildNode(name="Child1", value=1, parent=root)
child2 = ChildNode(name="Child2", value=2, parent=root)

# Testing the tree structure
print(f"Root: {root.name}")
print(f"Root's children: {[child.name for child in root.children]}")

# Child details
print(f"Child1: {child1.name}, Value: {child1.value}, Parent: {child1.parent.name}")
print(f"Child2: {child2.name}, Value: {child2.value}")

Above you will see that I am creating a simple node that inherits from AnyNode, If you run the above you will see that children are not created. If you change parent: AnyNode = field(default=None) to 'parent: AnyNode' you will see that children are infact created.

  1. I do not understand why the creation of child nodes work when the parent Attribute is made mandatory.

  2. I need the children to be set when the parent attribute is not mandatory as there are use cases within the program where this is necessary.

Does anyone have any ideas?

I have tried everything I can think of (using post_init etc) but nothing seems to work. I am using python 3.11

PS. As an aside, using attr.s instead of dataclasses does seem to work. For this usecase however I have to use dataclasses.

Thanks all!

I tried messing around with the init of AnyNode, tried to include it in a post_init I even tried using attr.s instead of dataclasses (this worked) but I need to use dataclasses.

0

There are 0 answers