diff --git a/SYMBOLS_MANIFEST.txt b/SYMBOLS_MANIFEST.txt index 87a2cbf3e..3497ec991 100644 --- a/SYMBOLS_MANIFEST.txt +++ b/SYMBOLS_MANIFEST.txt @@ -1218,6 +1218,7 @@ System`SyntaxQ System`Table System`TableForm System`TagBox +System`TagUnset System`TagSet System`TagSetDelayed System`Take diff --git a/admin-tools/check_benchmarks.py b/admin-tools/check_benchmarks.py index ee35b6b06..6145b84be 100644 --- a/admin-tools/check_benchmarks.py +++ b/admin-tools/check_benchmarks.py @@ -20,7 +20,6 @@ import argparse import json -import os import sys from pathlib import Path diff --git a/admin-tools/normalize_benchmarks.py b/admin-tools/normalize_benchmarks.py index 6d7b809a3..a6b18c21e 100644 --- a/admin-tools/normalize_benchmarks.py +++ b/admin-tools/normalize_benchmarks.py @@ -25,7 +25,9 @@ def normalize_benchmarks(target_file): break if ref_bench is None: - print(f"⚠️ Benchmark for the reference task '{REFERENCE_NAME} not found'. Exit.") + print( + f"⚠️ Benchmark for the reference task '{NORMALIZATION_TASK_KEY} not found'. Exit." + ) sys.exit(1) # Extract the reference value diff --git a/mathics/builtin/assignments/clear.py b/mathics/builtin/assignments/clear.py index 0777b699a..13c935479 100644 --- a/mathics/builtin/assignments/clear.py +++ b/mathics/builtin/assignments/clear.py @@ -286,3 +286,80 @@ def eval_unset_makeboxes(self, expr, evaluation): evaluation.message("Unset", "norep", expr, Symbol("System`MakeBoxes")) return SymbolFailed return SymbolNull + + +class TagUnset(PostfixOperator): + """ + + :WMA link: + https://reference.wolfram.com/language/ref/TagUnset.html + +
+
'TagUnset'[$f$, $patt$] +
'f/: $patt$=.' +
removes any value belonging to the patter $patt$ from $f$. +
+ + + + Let's consider we define an UpValue for a symbol g: + >> Sin[g[x_]]^:=Sing[x]; + in a way that + >> Sin[g[3]] + = Sing[3] + + TagUset allows to remove the rule: + >> g/: Sin[g[x_]]=. + >> Sin[g[3]] + = Sin[g[3]] + """ + + attributes = A_HOLD_ALL | A_PROTECTED + + messages = { + "norep": "Assignment on `2` for `1` not found.", + "sym": "Argument `1` at position 1 is expected to be a symbol.", + "tag": "Rule for `1` of `2` can only be attached to `3`.", + } + summary_text = "unset a value of the LHS, associated to a symbol." + + def eval_general(self, tag, expr, evaluation): + "TagUnset[tag_, expr_]" + + if not isinstance(tag, Symbol): + evaluation.message("TagSet", "sym", tag) + return SymbolNull + tag_name = tag.get_name() + head = expr.get_head() + if head in SYSTEM_SYMBOL_VALUES: + if len(expr.elements) != 1: + evaluation.message_args(expr.get_head_name(), len(expr.elements), 1) + return SymbolFailed + target_symbol = expr.elements[0] + if not target_symbol.sameQ(tag): + evaluation.message("TagUnset", "tag", target_symbol, expr, tag) + return SymbolFailed + symbol = target_symbol.get_name() + if not symbol: + evaluation.message(expr.get_head_name(), "fnsym", expr) + return SymbolFailed + if head is SymbolOptions: + empty = {} + else: + empty = [] + evaluation.definitions.set_values(symbol, expr.get_head_name(), empty) + return SymbolNull + + if not tag_name: + return SymbolNull + if not evaluation.definitions.unset(tag_name, expr): + evaluation.message("TagUnset", "norep", expr, tag) + return SymbolFailed + return SymbolNull + + def eval_unset_makeboxes(self, tag, expr, evaluation): + "TagUnset[tag_, expr:MakeBoxes[_, _]]" + if not evaluation.definitions.unset_format(tag.get_name(), "_MakeBoxes", expr): + evaluation.message("Unset", "norep", expr, tag) + return SymbolFailed + return SymbolNull diff --git a/mathics/eval/options/values.py b/mathics/eval/options/values.py index c59c97756..220361bff 100644 --- a/mathics/eval/options/values.py +++ b/mathics/eval/options/values.py @@ -1,5 +1,5 @@ from mathics.core.parser import parse_builtin_rule -from mathics.core.symbols import SymbolList, strip_context +from mathics.core.symbols import strip_context def filter_non_default_values(builtin): diff --git a/test/builtin/assumptions/test_assumptions.py b/test/builtin/assumptions/test_assumptions.py index e331af528..bde383848 100644 --- a/test/builtin/assumptions/test_assumptions.py +++ b/test/builtin/assumptions/test_assumptions.py @@ -152,7 +152,7 @@ def test_assumptions_integrate(str_expr, str_expected, message): LIST_TEST_ASSUMPTIONS_INTEGRATE_FAILING, ) @pytest.mark.xfail(reason="the Assumptions with Integrate is not fully working") -def test_assumptions_integrate(str_expr, str_expected, message): +def test_assumptions_integrate2(str_expr, str_expected, message): check_evaluation(str_expr, str_expected) diff --git a/test/core/convert/test_sympy.py b/test/core/convert/test_sympy.py index ce1117838..35df0c7c2 100644 --- a/test/core/convert/test_sympy.py +++ b/test/core/convert/test_sympy.py @@ -39,16 +39,7 @@ Symbol_F = Symbol("Global`F") Symbol_G = Symbol("Global`G") -from mathics.core.expression import Expression -from mathics.core.expression_predefined import MATHICS3_COMPLEX_INFINITY -from mathics.core.symbols import ( - Symbol, - SymbolNull, - SymbolPlus, - SymbolPower, - SymbolTimes, -) -from mathics.core.systemsymbols import SymbolE, SymbolExp, SymbolI, SymbolPi, SymbolSin +from mathics.core.symbols import Symbol Symbol_a = Symbol("Global`a") Symbol_b = Symbol("Global`b") diff --git a/test/timings/test_regressions.py b/test/timings/test_regressions.py index 096000980..968e84e66 100644 --- a/test/timings/test_regressions.py +++ b/test/timings/test_regressions.py @@ -152,9 +152,6 @@ param_ids = [name for name, _, _, _ in BENCHMARK_TASKS] -import pytest - - @pytest.mark.skipif( not os.environ.get("BENCHMARKS", 0), reason="benchmarks not required" )