From 866b1c0583f4385c61256f9a869b9cb9ab2209db Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 13 Mar 2026 11:45:03 -0400 Subject: [PATCH 1/3] Arg checking for Information & expression testing Specifically: * Information * Between * BooleanQ * TrueQ --- mathics/builtin/atomic/symbols.py | 2 ++ mathics/builtin/testing_expressions/equality_inequality.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/mathics/builtin/atomic/symbols.py b/mathics/builtin/atomic/symbols.py index 52a88535d..8593d9ddc 100644 --- a/mathics/builtin/atomic/symbols.py +++ b/mathics/builtin/atomic/symbols.py @@ -448,6 +448,8 @@ class Information(PrefixOperator): """ attributes = A_HOLD_ALL | A_SEQUENCE_HOLD | A_PROTECTED | A_READ_PROTECTED + eval_error = Builtin.generic_argument_error + expected_args = (1, 2) messages = {"notfound": "Expression `1` is not a symbol"} options = { "LongForm": "True", diff --git a/mathics/builtin/testing_expressions/equality_inequality.py b/mathics/builtin/testing_expressions/equality_inequality.py index 993692e28..d27ed2ddb 100644 --- a/mathics/builtin/testing_expressions/equality_inequality.py +++ b/mathics/builtin/testing_expressions/equality_inequality.py @@ -381,6 +381,8 @@ class Between(Builtin): "Between[range_List][x_]": "Between[x, range]", # operator form } + eval_error = Builtin.generic_argument_error + expected_args = (1, 2) summary_text = "test if value or values are in range" @@ -408,6 +410,8 @@ class BooleanQ(Builtin): = True """ + eval_error = Builtin.generic_argument_error + expected_args = 1 rules = { "BooleanQ[expr_]": "If[expr, True, True, False]", } @@ -850,6 +854,8 @@ class TrueQ(Builtin): = False """ + eval_error = Builtin.generic_argument_error + expected_args = 1 rules = { "TrueQ[expr_]": "If[expr, True, False, False]", } From 0348b0415c22051bf0ff525824b505838cc2276c Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 13 Mar 2026 13:07:17 -0400 Subject: [PATCH 2/3] Add arg tests --- test/builtin/atomic/test_symbols.py | 33 ++++++++++++++---------- test/builtin/test_testing_expressions.py | 32 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/test/builtin/atomic/test_symbols.py b/test/builtin/atomic/test_symbols.py index 94db2f448..0639f8a97 100644 --- a/test/builtin/atomic/test_symbols.py +++ b/test/builtin/atomic/test_symbols.py @@ -84,31 +84,36 @@ def test_symbol(str_expr, warnings, str_expected, fail_msg): @pytest.mark.parametrize( - ("str_expr", "msgs", "fail_msg"), + ("function_name", "msg_fragment"), [ ( - "Symbol[]", - ["Symbol called with 0 arguments; 1 argument is expected."], - "Symbol argument number error", + "Information", + "1 or 2 arguments are", ), ( - "SymbolName[]", - ["SymbolName called with 0 arguments; 1 argument is expected."], - "SymbolName[] argument number error", + "Symbol", + "1 argument is", ), ( - "ValueQ[]", - ["ValueQ called with 0 arguments; 1 argument is expected."], - "ValueQ[] argument number error", + "SymbolName", + "1 argument is", + ), + ( + "ValueQ", + "1 argument is", ), ], ) -def test_symbols_arg_errors(str_expr, msgs, fail_msg): +def test_symbols_arg_errors(function_name, msg_fragment): """ """ - + str_expr = f"{function_name}[]" + expected_msgs = [ + f"{function_name} called with 0 arguments; {msg_fragment} expected." + ] + failure_message = f"{function_name} argument number error" check_evaluation( str_expr, str_expr, - failure_message=fail_msg, - expected_messages=msgs, + failure_message=failure_message, + expected_messages=expected_msgs, ) diff --git a/test/builtin/test_testing_expressions.py b/test/builtin/test_testing_expressions.py index a1ced6d6b..8ed5d1a13 100644 --- a/test/builtin/test_testing_expressions.py +++ b/test/builtin/test_testing_expressions.py @@ -8,6 +8,38 @@ import pytest +@pytest.mark.parametrize( + ("function_name", "msg_fragment"), + [ + ( + "Between", + "1 or 2 arguments are", + ), + ( + "BooleanQ", + "1 argument is", + ), + ( + "TrueQ", + "1 argument is", + ), + ], +) +def test_arg_errors(function_name, msg_fragment): + """ """ + str_expr = f"{function_name}[]" + expected_msgs = [ + f"{function_name} called with 0 arguments; {msg_fragment} expected." + ] + failure_message = f"{function_name} argument number error" + check_evaluation( + str_expr, + str_expr, + failure_message=failure_message, + expected_messages=expected_msgs, + ) + + @pytest.mark.parametrize( ("str_expr", "msgs", "str_expected", "fail_msg"), [ From 339993c4f726941a1a601861b13557e1d8f54fe8 Mon Sep 17 00:00:00 2001 From: rocky Date: Fri, 13 Mar 2026 13:13:16 -0400 Subject: [PATCH 3/3] DRY arg checking routine --- test/builtin/atomic/test_symbols.py | 14 ++------------ test/builtin/test_testing_expressions.py | 14 ++------------ test/helper.py | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/test/builtin/atomic/test_symbols.py b/test/builtin/atomic/test_symbols.py index 0639f8a97..6c9180289 100644 --- a/test/builtin/atomic/test_symbols.py +++ b/test/builtin/atomic/test_symbols.py @@ -2,7 +2,7 @@ """ Unit tests from mathics.builtin.atomic.symbols. """ -from test.helper import check_evaluation +from test.helper import check_arg_counts, check_evaluation import pytest @@ -106,14 +106,4 @@ def test_symbol(str_expr, warnings, str_expected, fail_msg): ) def test_symbols_arg_errors(function_name, msg_fragment): """ """ - str_expr = f"{function_name}[]" - expected_msgs = [ - f"{function_name} called with 0 arguments; {msg_fragment} expected." - ] - failure_message = f"{function_name} argument number error" - check_evaluation( - str_expr, - str_expr, - failure_message=failure_message, - expected_messages=expected_msgs, - ) + check_arg_counts(function_name, msg_fragment) diff --git a/test/builtin/test_testing_expressions.py b/test/builtin/test_testing_expressions.py index 8ed5d1a13..4b85437ec 100644 --- a/test/builtin/test_testing_expressions.py +++ b/test/builtin/test_testing_expressions.py @@ -3,7 +3,7 @@ Unit tests for mathics.builtin.testing_expressions """ -from test.helper import check_evaluation +from test.helper import check_arg_counts, check_evaluation import pytest @@ -27,17 +27,7 @@ ) def test_arg_errors(function_name, msg_fragment): """ """ - str_expr = f"{function_name}[]" - expected_msgs = [ - f"{function_name} called with 0 arguments; {msg_fragment} expected." - ] - failure_message = f"{function_name} argument number error" - check_evaluation( - str_expr, - str_expr, - failure_message=failure_message, - expected_messages=expected_msgs, - ) + check_arg_counts(function_name, msg_fragment) @pytest.mark.parametrize( diff --git a/test/helper.py b/test/helper.py index e03a4e5ad..dc0900eb4 100644 --- a/test/helper.py +++ b/test/helper.py @@ -34,6 +34,21 @@ def evaluate(str_expr: str, form=None): return session.evaluate(str_expr, form=form) +def check_arg_counts(function_name, msg_fragment): + """ """ + str_expr = f"{function_name}[]" + expected_msgs = [ + f"{function_name} called with 0 arguments; {msg_fragment} expected." + ] + failure_message = f"{function_name} argument number error" + check_evaluation( + str_expr, + str_expr, + failure_message=failure_message, + expected_messages=expected_msgs, + ) + + def check_evaluation( str_expr: Optional[str], str_expected: Optional[str] = None,