diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index 4ddd08c540..f2a6bbc995 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -562,6 +562,7 @@ RUN(NAME test_tuple_03 LABELS cpython llvm llvm_jit c) RUN(NAME test_tuple_04 LABELS cpython llvm llvm_jit c) RUN(NAME test_tuple_concat LABELS cpython llvm llvm_jit) RUN(NAME test_tuple_nested LABELS cpython llvm llvm_jit) +RUN(NAME test_const_dict LABELS cpython llvm llvm_jit) RUN(NAME test_dict_01 LABELS cpython llvm llvm_jit c) RUN(NAME test_dict_02 LABELS cpython llvm llvm_jit c NOFAST) RUN(NAME test_dict_03 LABELS cpython llvm llvm_jit NOFAST) diff --git a/integration_tests/test_const_dict.py b/integration_tests/test_const_dict.py new file mode 100644 index 0000000000..e06578fc45 --- /dev/null +++ b/integration_tests/test_const_dict.py @@ -0,0 +1,24 @@ +from lpython import i32, f64, Const + +CONST_DICTIONARY_INTEGR: Const[dict[str, i32]] = {"a": 1, "b": 2, "c": 3} + +print(CONST_DICTIONARY_INTEGR.get("a")) +assert CONST_DICTIONARY_INTEGR.get("a") == 1 + +print(CONST_DICTIONARY_INTEGR.keys()) +assert len(CONST_DICTIONARY_INTEGR.keys()) == 3 + +print(CONST_DICTIONARY_INTEGR.values()) +assert len(CONST_DICTIONARY_INTEGR.values()) == 3 + +CONST_DICTIONARY_FLOAT: Const[dict[str, f64]] = {"a": 1.0, "b": 2.0, "c": 3.0} + +print(CONST_DICTIONARY_FLOAT.get("a")) +assert CONST_DICTIONARY_FLOAT.get("a") == 1.0 + +print(CONST_DICTIONARY_FLOAT.keys()) +assert len(CONST_DICTIONARY_FLOAT.keys()) == 3 + +print(CONST_DICTIONARY_FLOAT.values()) +assert len(CONST_DICTIONARY_FLOAT.values()) == 3 + diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index aa0d37f42d..1aa5b06f0b 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -395,6 +395,9 @@ struct AttributeHandler { static ASR::asr_t* eval_dict_pop(ASR::expr_t *s, Allocator &al, const Location &loc, Vec &args, diag::Diagnostics &diag) { + if (ASRUtils::is_const(s)) { + throw SemanticError("cannot pop elements from a const dict", loc); + } if (args.size() != 1) { throw SemanticError("'pop' takes only one argument for now", loc); } diff --git a/tests/errors/test_const_dict.py b/tests/errors/test_const_dict.py new file mode 100644 index 0000000000..7c0e33d33e --- /dev/null +++ b/tests/errors/test_const_dict.py @@ -0,0 +1,9 @@ +from lpython import i32, f64, dict, Const + + +def test_const_dict(): + CONST_DICTIONARY: Const[dict[str, i32]] = {"a": 1, "b": 2, "c": 3} + print(CONST_DICTIONARY.pop("a")) + + +test_const_dict() diff --git a/tests/reference/asr-test_const_dict-59445d7.json b/tests/reference/asr-test_const_dict-59445d7.json new file mode 100644 index 0000000000..69906db3c2 --- /dev/null +++ b/tests/reference/asr-test_const_dict-59445d7.json @@ -0,0 +1,13 @@ +{ + "basename": "asr-test_const_dict-59445d7", + "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", + "infile": "tests/errors/test_const_dict.py", + "infile_hash": "51130e98c759eb3cdbd50848e59879e4689d241c7a8674aa06a5b3c7", + "outfile": null, + "outfile_hash": null, + "stdout": null, + "stdout_hash": null, + "stderr": "asr-test_const_dict-59445d7.stderr", + "stderr_hash": "1d3729d80a7895dd01baaf0905c6cc9ebadd7f7ce623f4ae5970e2b8", + "returncode": 2 +} \ No newline at end of file diff --git a/tests/reference/asr-test_const_dict-59445d7.stderr b/tests/reference/asr-test_const_dict-59445d7.stderr new file mode 100644 index 0000000000..3b7757fec4 --- /dev/null +++ b/tests/reference/asr-test_const_dict-59445d7.stderr @@ -0,0 +1,5 @@ +semantic error: cannot pop elements from a const dict + --> tests/errors/test_const_dict.py:6:11 + | +6 | print(CONST_DICTIONARY.pop("a")) + | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/tests.toml b/tests/tests.toml index 3e6589aef1..b106996999 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -1109,6 +1109,10 @@ run = true filename = "errors/test_dict16.py" run = true +[[test]] +filename = "errors/test_const_dict.py" +asr = true + [[test]] filename = "errors/test_zero_division.py" asr = true