exaloop / exaloop/codon

Accessing Attributes of Subclasses

Open
#791 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
16.8k
Forks
603
Avg merge
4d 23h
Merged PRs (30d)
6

Description

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!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.