Skip to content

Commit 84df409

Browse files
authored
Merge pull request #878 from namannimmo10/str_assign
Raise error while changing immutable objects
2 parents bcf8b25 + 6497982 commit 84df409

12 files changed

+107
-0
lines changed

src/libasr/asr_utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,11 @@ static inline std::string binop_to_str_python(const ASR::binopType t) {
809809
}
810810
}
811811

812+
static inline bool is_immutable(const ASR::ttype_t *type) {
813+
return ((ASR::is_a<ASR::Character_t>(*type) || ASR::is_a<ASR::Tuple_t>(*type)
814+
|| ASR::is_a<ASR::Complex_t>(*type)));
815+
}
816+
812817
// Returns a list of values
813818
static inline Vec<ASR::call_arg_t> get_arg_values(Allocator &al, const Vec<ASR::call_arg_t>& args) {
814819
Vec<ASR::call_arg_t> values;

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2588,6 +2588,24 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
25882588
ASR::make_Var_t(al, x.base.base.loc, s));
25892589
tmp = make_DictInsert_t(al, x.base.base.loc, se, key, val);
25902590
return;
2591+
} else if (ASRUtils::is_immutable(type)) {
2592+
throw SemanticError("'" + ASRUtils::type_to_str_python(type) + "' object does not support"
2593+
" item assignment", x.base.base.loc);
2594+
}
2595+
}
2596+
} else if (AST::is_a<AST::Attribute_t>(*x.m_targets[0])) {
2597+
AST::Attribute_t *attr = AST::down_cast<AST::Attribute_t>(x.m_targets[0]);
2598+
if (AST::is_a<AST::Name_t>(*attr->m_value)) {
2599+
std::string name = AST::down_cast<AST::Name_t>(attr->m_value)->m_id;
2600+
ASR::symbol_t *s = current_scope->get_symbol(name);
2601+
if (!s) {
2602+
throw SemanticError("Variable: '" + name + "' is not declared",
2603+
x.base.base.loc);
2604+
}
2605+
ASR::Variable_t *v = ASR::down_cast<ASR::Variable_t>(s);
2606+
ASR::ttype_t *type = v->m_type;
2607+
if (ASRUtils::is_immutable(type)) {
2608+
throw SemanticError("readonly attribute", x.base.base.loc);
25912609
}
25922610
}
25932611
}

tests/errors/test_assign6.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def f():
2+
s: str
3+
s = "abcde"
4+
s[0] = 'f'
5+
6+
f()

tests/errors/test_assign7.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def f():
2+
t: tuple[i32, i32]
3+
t = (1, 2)
4+
t[0] = 3
5+
6+
f()

tests/errors/test_assign8.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def f():
2+
c: c32
3+
c = complex(3, 4)
4+
c.real = 5.0
5+
6+
f()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-test_assign6-05cd64f",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/test_assign6.py",
5+
"infile_hash": "6837d07201b8680dbb63908d3ad27e4e9bfb1f1ff77b4bd6a77eddcf",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-test_assign6-05cd64f.stderr",
11+
"stderr_hash": "294865737572b9ab043b8ebab73fe949fa2bb73e9790c6a04d87dc50",
12+
"returncode": 2
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
semantic error: 'str' object does not support item assignment
2+
--> tests/errors/test_assign6.py:4:5
3+
|
4+
4 | s[0] = 'f'
5+
| ^^^^^^^^^^
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-test_assign7-beebac3",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/test_assign7.py",
5+
"infile_hash": "e54f67638add63131760d5eadda7e3944b34addacffa27d6fb45e128",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-test_assign7-beebac3.stderr",
11+
"stderr_hash": "d12f04efad566740bd562fbe9c00a058210a9adf0f5297475fc41fe6",
12+
"returncode": 2
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
semantic error: 'tuple[i32, i32]' object does not support item assignment
2+
--> tests/errors/test_assign7.py:4:5
3+
|
4+
4 | t[0] = 3
5+
| ^^^^^^^^
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-test_assign8-4b26e63",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/test_assign8.py",
5+
"infile_hash": "c88b84b8d7d21aec489288c9064cc9d5a46387b5e6528d30a947ff5c",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-test_assign8-4b26e63.stderr",
11+
"stderr_hash": "d3f4498398b59be4a1f83de67135842aa5a9a0921e1aa188dc743ca8",
12+
"returncode": 2
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
semantic error: readonly attribute
2+
--> tests/errors/test_assign8.py:4:5
3+
|
4+
4 | c.real = 5.0
5+
| ^^^^^^^^^^^^

tests/tests.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,18 @@ asr = true
630630
filename = "errors/test_assign5.py"
631631
asr = true
632632

633+
[[test]]
634+
filename = "errors/test_assign6.py"
635+
asr = true
636+
637+
[[test]]
638+
filename = "errors/test_assign7.py"
639+
asr = true
640+
641+
[[test]]
642+
filename = "errors/test_assign8.py"
643+
asr = true
644+
633645
[[test]]
634646
filename = "errors/test_binop1.py"
635647
asr = true

0 commit comments

Comments
 (0)