From a74d529a2d652ecc00c81466feeab1c89968fa97 Mon Sep 17 00:00:00 2001 From: Saurabh Kumar <151380951+kmr-srbh@users.noreply.github.com> Date: Wed, 1 May 2024 22:34:28 +0530 Subject: [PATCH] Add support for `dict` methods with `Const` (#2567) * Implement attributes for `Const dict` * Remove duplicate changes * Improve checking for `Const` types * Simplify type checking for `Const dict`. * Add tests * Update test * Update fetching attribute name logic Co-authored-by: Thirumalai Shaktivel <74826228+Thirumalai-Shaktivel@users.noreply.github.com> * Update test references * Update fetching `dict_type` Co-authored-by: Thirumalai Shaktivel <74826228+Thirumalai-Shaktivel@users.noreply.github.com> * Formatting changes * Update test references * Update error test references * Tests: Update test references * Tests: Add runtime tests and update test references * Remove checks on the absent `Const` node * Remove call to `get_contained_type()` * Tests: Add tests and update references * Style changes * Tests: Update tests and add to CMakeLists * Delete tests/reference/asr-test_const_dict-151acad.json * Delete tests/reference/asr-test_const_dict-151acad.stdout * Delete tests/reference/asr-test_const_dict-59445d7.json * Delete tests/reference/asr-test_dict_const-69479e2.json * Delete tests/reference/asr-test_dict_const-69479e2.stderr * Delete tests/reference/asr-test_dict_const-69479e2.stdout * Delete tests/reference/runtime-test_dict_const-62054df.json * Delete tests/reference/runtime-test_dict_const-62054df.stderr * Delete tests/reference/asr-test_const_dict-59445d7.stderr * Tests: Update error references * Undo formatting changes * Remove extra newline --------- Co-authored-by: Thirumalai Shaktivel <74826228+Thirumalai-Shaktivel@users.noreply.github.com> --- integration_tests/CMakeLists.txt | 1 + integration_tests/test_const_dict.py | 24 +++++++++++++++++++ src/lpython/semantics/python_attribute_eval.h | 3 +++ tests/errors/test_const_dict.py | 9 +++++++ .../asr-test_const_dict-59445d7.json | 13 ++++++++++ .../asr-test_const_dict-59445d7.stderr | 5 ++++ tests/tests.toml | 4 ++++ 7 files changed, 59 insertions(+) create mode 100644 integration_tests/test_const_dict.py create mode 100644 tests/errors/test_const_dict.py create mode 100644 tests/reference/asr-test_const_dict-59445d7.json create mode 100644 tests/reference/asr-test_const_dict-59445d7.stderr 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