#791·codon

Accessing Attributes of Subclasses

Author: 01110011011101010110010001101111Created Apr 8, 2026Updated Apr 21, 2026

Hello! I'm trying to access attributes of subclasses. For example, I'm trying to run something like this:

python
@dataclass
class Statement:
    pass

@dataclass
class Block(Statement):
    bodies: list[str]

@dataclass
class Assign(Statement):
    var: str
    val: Statement

@dataclass
class Function:
    name: str
    body: Statement

func_body = Block(bodies=["a = 1", "return a"])

test = Function(
        name="foo", 
        body=func_body
)

v1 = test.body

if isinstance(v1, Block):
    bodies = v1.bodies
    if bodies is not None:
        for stmt in bodies:
            print(stmt)
    else:
        print("fail")

For the above example, if the body attribute of the Function class is a Block, I want to be able to iterate through the values in its bodies attribute. The above fails with codon_experiments.py:39 (14-23): error: 'Statement' object has no attribute 'bodies'.

I instead tried to use a Union with NoneType in the parent class:

python
@dataclass
class Statement:
    bodies: list[str] | NoneType = None
    var: str | NoneType = None
    val: Statement | NoneType = None

@dataclass
class Block(Statement):
    bodies: list[str] | NoneType

@dataclass
class Assign(Statement):
    var: str | NoneType
    val: Statement | NoneType

@dataclass
class Function:
    name: str
    body: Statement

func_body = Block(bodies=["a = 1", "return a"])

test = Function(
        name="foo", 
        body=func_body
)

v1 = test.body

if isinstance(v1, Block):
    bodies = v1.bodies
    if bodies is not None:
        for stmt in bodies:
            print(stmt)
    else:
        print("fail")

The above, however, fails with:

Assert failed:  union already sealed [core.codon:237:1]
Expression:     !isSealed()
Source:         /github/workspace/codon/parser/ast/types/union.cpp:107
Aborted (core dumped)

Finally, I tried to use the Optional type but this resulted in the value always being None:

python
@dataclass
class Statement:
    bodies: Optional[list[str]] = None
    var: Optional[str] = None
    val: Optional[Statement] = None

@dataclass
class Block(Statement):
    bodies: Optional[list[str]]

@dataclass
class Assign(Statement):
    var: Optional[str]
    val: Optional[Statement]

@dataclass
class Function:
    name: str
    body: Statement

func_body = Block(bodies=["a = 1", "return a"])

test = Function(
        name="foo", 
        body=func_body
)

v1 = test.body

if isinstance(v1, Block):
    bodies = v1.bodies
    if bodies is not None:
        for stmt in bodies:
            print(stmt)
    else:
        print("fail")

The above compiles and runs but always prints fail.

Do you have any suggestions on how to approach this? Thanks!