Skip to content

Design of structs in LPython #2276

Description

@certik

We want to map our structs into ordinary CPython. For now we use dataclasses, but #2275 shows that Python 3.11 changed a few things. So let's use this opportunity to design it in such a way that we just use the dataclass decorator directly from CPython, we do not wrap it in anyway.

Here are all the ways to use dataclasses that work in all Python versions including 3.11.

No Default Values

The first way is without initializing the members:

fromdataclassesimportdataclassfromnumpyimportarray, ndarray@dataclassclassX:
a: intb: boolc: list[int]
d: ndarraydefmain0():
x: X=X(123, True, [1, 2, 3], array([4, 5, 6]))
print(x)
assertx.a==123assertx.b==Trueassertx.c[0] ==1assertx.d[1] ==5x.c[0] =3x.d[0] =3print(x)
assertx.c[0] ==3assertx.d[0] ==3main0()

The fields are mutable, and there is no problem at all, it works with lists and numpy arrays also.

Default Values

First of all, I don't think we need to provide default values. But if we do, here is how to do it:

fromdataclassesimportdataclass, fieldfromnumpyimportarray, ndarray@dataclassclassX:
a: int=123b: bool=Truec: list[int] =field(default_factory=lambda: [1, 2, 3])
d: ndarray=field(default_factory=lambda: array([4, 5, 6]))
defmain0():
x: X=X()
print(x)
assertx.a==123assertx.b==Trueassertx.c[0] ==1assertx.d[1] ==5x.c[0] =3x.d[0] =3print(x)
assertx.c[0] ==3assertx.d[0] ==3main0()

This works for all Python versions including 3.11.

Arrays of Structs

This works in all Python versions.

fromdataclassesimportdataclass, fieldfromnumpyimportarray, ndarray@dataclassclassX:
a: int=123b: bool=Truec: list[int] =field(default_factory=lambda: [1, 2, 3])
d: ndarray=field(default_factory=lambda: array([4, 5, 6]))
defmain0():
x: ndarray=array([X(), X(), X()])
print(x)
x[0].a=10x[0].c[1] =10x[0].d[1] =10x[2].a=11x[2].c[1] =11x[2].d[1] =11print(x)
main0()

Using i32[3] Syntax

This seems to work for all Python versions.

fromdataclassesimportdataclassfromnumpyimportarray, ndarrayfromlpythonimporti32@dataclassclassX:
a: intb: boolc: list[int]
d: i32[3]
defmain0():
x: X=X(123, True, [1, 2, 3], array([4, 5, 6]))
print(x)
assertx.a==123assertx.b==Trueassertx.c[0] ==1assertx.d[1] ==5x.c[0] =3x.d[0] =3print(x)
assertx.c[0] ==3assertx.d[0] ==3main0()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions