Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b70bfdf

Browse files
authored
Merge pull request #2280 from Shaikh-Ubaid/support_field_in_dataclass_mem_init
Support field in dataclass member initialization
2 parents 303da17 + 9bdb90e commit b70bfdf

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ RUN(NAME structs_31 LABELS cpython llvm c)
685685
RUN(NAME structs_32 LABELS cpython llvm c)
686686
RUN(NAME structs_33 LABELS cpython llvm c)
687687
RUN(NAME structs_34 LABELS cpython llvm c)
688+
RUN(NAME structs_35 LABELS cpython llvm)
688689

689690
RUN(NAME symbolics_01 LABELS cpython_sym c_sym llvm_sym NOFAST)
690691
RUN(NAME symbolics_02 LABELS cpython_sym c_sym llvm_sym NOFAST)

integration_tests/structs_35.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from lpython import dataclass, field, i32
2+
from numpy import array
3+
4+
@dataclass
5+
class X:
6+
a: i32 = 123
7+
b: bool = True
8+
c: list[i32] = field(default_factory=lambda: [1, 2, 3])
9+
d: i32[3] = field(default_factory=lambda: array([4, 5, 6]))
10+
e: i32 = field(default=-5)
11+
12+
def main0():
13+
x: X = X()
14+
print(x)
15+
assert x.a == 123
16+
assert x.b == True
17+
assert x.c[0] == 1
18+
assert x.d[1] == 5
19+
assert x.e == -5
20+
x.c[0] = 3
21+
x.d[0] = 3
22+
print(x)
23+
assert x.c[0] == 3
24+
assert x.d[0] == 3
25+
26+
main0()

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7802,6 +7802,35 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
78027802
tmp = ASR::make_SizeOfType_t(al, x.base.base.loc,
78037803
arg_type, size_type, nullptr);
78047804
return ;
7805+
} else if( call_name == "field" ) {
7806+
if (x.n_args != 0) {
7807+
throw SemanticError("'field' expects only keyword arguments", x.base.base.loc);
7808+
}
7809+
7810+
if (x.n_keywords != 1) {
7811+
throw SemanticError("'field' expects one keyword argument", x.base.base.loc);
7812+
}
7813+
7814+
args.reserve(al, 1);
7815+
visit_expr_list(x.m_args, x.n_args, args);
7816+
7817+
if( std::string(x.m_keywords[0].m_arg) != "default_factory" && std::string(x.m_keywords[0].m_arg) != "default" ) {
7818+
throw SemanticError("Unrecognised keyword argument, " +
7819+
std::string(x.m_keywords[0].m_arg), x.base.base.loc);
7820+
}
7821+
7822+
if ( std::string(x.m_keywords[0].m_arg) == "default_factory") {
7823+
if (!AST::is_a<AST::Lambda_t>(*x.m_keywords[0].m_value)) {
7824+
throw SemanticError("Only lambda functions currently supported as default_factory value", x.base.base.loc);
7825+
}
7826+
7827+
AST::Lambda_t* lambda_fn = AST::down_cast<AST::Lambda_t>(x.m_keywords[0].m_value);
7828+
this->visit_expr(*lambda_fn->m_body);
7829+
} else {
7830+
// field has default argument provided
7831+
this->visit_expr(*x.m_keywords[0].m_value);
7832+
}
7833+
return ;
78057834
} else if(
78067835
call_name == "f64" ||
78077836
call_name == "f32" ||

src/runtime/lpython/lpython.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
import ctypes
44
import platform
5-
from dataclasses import dataclass as py_dataclass, is_dataclass as py_is_dataclass
5+
from dataclasses import dataclass as py_dataclass, is_dataclass as py_is_dataclass, field
66
import functools
77

88

@@ -11,7 +11,7 @@
1111
"overload", "ccall", "TypeVar", "pointer", "c_p_pointer", "Pointer",
1212
"p_c_pointer", "vectorize", "inline", "Union", "static",
1313
"packed", "Const", "sizeof", "ccallable", "ccallback", "Callable",
14-
"Allocatable", "In", "Out", "InOut", "dataclass", "S"]
14+
"Allocatable", "In", "Out", "InOut", "dataclass", "field", "S"]
1515

1616
# data-types
1717

0 commit comments

Comments
 (0)