From a25025a275c1d13d9ef9097ff851bbbb46dc05af Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Sun, 30 Nov 2025 15:05:20 -0300 Subject: [PATCH 1/3] use underscore as context mark in sympy symbols and function names --- mathics/builtin/numbers/calculus.py | 3 +- mathics/core/convert/sympy.py | 14 ++++---- mathics/core/symbols.py | 27 ++++++++++------ mathics/eval/drawing/plot_compile.py | 5 +-- test/core/test_sympy_python_convert.py | 44 +++++++++++++------------- 5 files changed, 51 insertions(+), 42 deletions(-) diff --git a/mathics/builtin/numbers/calculus.py b/mathics/builtin/numbers/calculus.py index a734822c3..96f02123b 100644 --- a/mathics/builtin/numbers/calculus.py +++ b/mathics/builtin/numbers/calculus.py @@ -57,6 +57,7 @@ SymbolPower, SymbolTimes, SymbolTrue, + sympy_name, ) from mathics.core.systemsymbols import ( SymbolAnd, @@ -528,7 +529,7 @@ def to_sympy(self, expr, **kwargs): return func = exprs[1].elements[0] - sym_func = sympy.Function(str(SYMPY_SYMBOL_PREFIX + func.__str__()))(*sym_args) + sym_func = sympy.Function(sympy_name(func))(*sym_args) counts = [element.get_int_value() for element in exprs[2].elements] if None in counts: diff --git a/mathics/core/convert/sympy.py b/mathics/core/convert/sympy.py index 2b3badb9d..e0df61ee9 100644 --- a/mathics/core/convert/sympy.py +++ b/mathics/core/convert/sympy.py @@ -236,7 +236,6 @@ def expression_to_sympy(expr: Expression, **kwargs): """ Convert `expr` to its sympy form. """ - if len(expr.elements) > 0: head_name = expr.get_head_name() if head_name.startswith("Global`"): @@ -250,6 +249,7 @@ def expression_to_sympy(expr: Expression, **kwargs): lookup_name = expr.get_lookup_name() builtin = mathics_to_sympy.get(lookup_name) + if builtin is not None: sympy_expr = builtin.to_sympy(expr, **kwargs) if sympy_expr is not None: @@ -346,7 +346,6 @@ def old_from_sympy(expr) -> BaseElement: """ converts a SymPy object to a Mathics3 element. """ - if isinstance(expr, (tuple, list)): return to_mathics_list(*expr, elements_conversion_fn=from_sympy) if isinstance(expr, int): @@ -371,16 +370,16 @@ def old_from_sympy(expr) -> BaseElement: name = str(expr) if isinstance(expr, sympy.Dummy): name = name[1:] - if "`" not in name: + if "_" not in name: name = f"sympy`dummy`Dummy${expr.dummy_index}" # type: ignore[attr-defined] else: - name = name[len(SYMPY_SYMBOL_PREFIX) :] + name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") # Probably, this should be the value attribute return Symbol(name) if is_Cn_expr(name): return Expression(SymbolC, Integer(int(name[1:]))) if name.startswith(SYMPY_SYMBOL_PREFIX): - name = name[len(SYMPY_SYMBOL_PREFIX) :] + name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") if name.startswith(SYMPY_SLOT_PREFIX): index = int(name[len(SYMPY_SLOT_PREFIX) :]) return Expression(SymbolSlot, Integer(index)) @@ -419,7 +418,8 @@ def old_from_sympy(expr) -> BaseElement: if isinstance(expr, sympy.core.numbers.NaN): return SymbolIndeterminate if isinstance(expr, sympy.core.function.FunctionClass): - return Symbol(str(expr)) + name = str(expr).replace("_", "`") + return Symbol(name) if expr is sympy.true: return SymbolTrue if expr is sympy.false: @@ -546,7 +546,7 @@ def old_from_sympy(expr) -> BaseElement: *[from_sympy(arg) for arg in expr.args], ) if name.startswith(SYMPY_SYMBOL_PREFIX): - name = name[len(SYMPY_SYMBOL_PREFIX) :] + name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") args = [from_sympy(arg) for arg in expr.args] builtin = sympy_to_mathics.get(name) if builtin is not None: diff --git a/mathics/core/symbols.py b/mathics/core/symbols.py index c5562f9f7..8b0b621ea 100644 --- a/mathics/core/symbols.py +++ b/mathics/core/symbols.py @@ -126,7 +126,7 @@ def sympy_strip_context(name) -> str: produce invalid code. In a next round, we would like to use another character for split contexts in sympy variables. """ - return strip_context(name) + return name.split("_")[-1] # system_symbols_dict({'SomeSymbol': ...}) -> {Symbol('System`SomeSymbol'): ...} @@ -342,6 +342,7 @@ class Symbol(Atom, NumericOperators, EvalMixin): name: str hash: int + sympy_dummy: Any _short_name: str # Dictionary of Symbols defined so far. @@ -354,7 +355,7 @@ class Symbol(Atom, NumericOperators, EvalMixin): # __new__ instead of __init__ is used here because we want # to return the same object for a given "name" value. - def __new__(cls, name: str): + def __new__(cls, name: str, sympy_dummy=None): """ Allocate an object ensuring that for a given ``name`` and ``cls`` we get back the same object, id(object) is the same and its object.__hash__() is the same. @@ -384,6 +385,18 @@ def __new__(cls, name: str): # For example, this can happen with String constants. self.hash = hash((cls, name)) + + # TODO: revise how we convert sympy.Dummy + # symbols. + # + # In some cases, SymPy returns a sympy.Dummy + # object. It is converted to Mathics as a + # Symbol. However, we probably should have + # a different class for this kind of symbols. + # Also, sympy_dummy should be stored as the + # value attribute. + self.sympy_dummy = sympy_dummy + self._short_name = strip_context(name) return self @@ -392,7 +405,7 @@ def __eq__(self, other) -> bool: return self is other def __getnewargs__(self): - return (self.name,) + return (self.name, self.sympy_dummy) def __hash__(self) -> int: """ @@ -690,12 +703,6 @@ def __new__(cls, name, value): self.hash = hash((cls, name)) return self - def __getnewargs__(self): - return ( - self.name, - self._value, - ) - @property def is_literal(self) -> bool: """ @@ -754,7 +761,7 @@ def symbol_set(*symbols: Symbol) -> FrozenSet[Symbol]: def sympy_name(mathics_symbol: Symbol): """Convert a mathics symbol name into a sympy symbol name""" - return SYMPY_SYMBOL_PREFIX + mathics_symbol.name + return SYMPY_SYMBOL_PREFIX + mathics_symbol.name.replace("`", "_") # Symbols used in this module. diff --git a/mathics/eval/drawing/plot_compile.py b/mathics/eval/drawing/plot_compile.py index 8afafe1cd..53d34572e 100644 --- a/mathics/eval/drawing/plot_compile.py +++ b/mathics/eval/drawing/plot_compile.py @@ -19,7 +19,7 @@ import sympy from mathics.core.convert.sympy import SympyExpression, mathics_to_sympy -from mathics.core.symbols import strip_context +from mathics.core.symbols import sympy_strip_context from mathics.core.util import print_expression_tree, print_sympy_tree @@ -82,7 +82,8 @@ def plot_compile(evaluation, expr, names, debug=0): # Strip symbols in sympy expression of context. subs = { - sym: sympy.Symbol(strip_context(str(sym))) for sym in sympy_expr.free_symbols + sym: sympy.Symbol(sympy_strip_context(str(sym))) + for sym in sympy_expr.free_symbols } sympy_expr = sympy_expr.subs(subs) diff --git a/test/core/test_sympy_python_convert.py b/test/core/test_sympy_python_convert.py index 31f4fd2dc..6a4ceb3ad 100644 --- a/test/core/test_sympy_python_convert.py +++ b/test/core/test_sympy_python_convert.py @@ -49,10 +49,10 @@ def compare(self, mathics_expr, sympy_expr, **kwargs): self.compare_to_mathics(mathics_expr, sympy_expr) def testSymbol(self): - self.compare(Symbol("Global`x"), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x")) + self.compare(Symbol("Global`x"), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")) self.compare( - Symbol("_Mathics_User_x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}System`_Mathics_User_x"), + Symbol("Mathics`User`x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Mathics_User_x"), ) def testReal(self): @@ -88,15 +88,15 @@ def testString(self): def testAdd(self): self.compare( Expression(SymbolPlus, Integer1, Symbol("Global`x")), - sympy.Add(sympy.Integer(1), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x")), + sympy.Add(sympy.Integer(1), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), ) def testIntegrate(self): self.compare( Expression(SymbolIntegrate, Symbol("Global`x"), Symbol("Global`y")), sympy.Integral( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`y"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), ), ) @@ -104,8 +104,8 @@ def testDerivative(self): self.compare( Expression(SymbolD, Symbol("Global`x"), Symbol("Global`y")), sympy.Derivative( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`y"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), ), ) @@ -118,12 +118,12 @@ def testDerivative2(self): ) expr = Expression(head, Symbol("Global`x"), Symbol("Global`y")) - sfxy = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global`f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`y"), + sfxy = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), ) sym_expr = sympy.Derivative( - sfxy, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x") + sfxy, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x") ) self.compare_to_sympy(expr, sym_expr, **kwargs) @@ -133,28 +133,28 @@ def testConvertedFunctions(self): kwargs = {"converted_functions": set(["Global`f"])} marg1 = Expression(Symbol("Global`f"), Symbol("Global`x")) - sarg1 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global`f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x") + sarg1 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x") ) self.compare(marg1, sarg1, **kwargs) marg2 = Expression(Symbol("Global`f"), Symbol("Global`x"), Symbol("Global`y")) - sarg2 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global`f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`y"), + sarg2 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), ) self.compare(marg2, sarg2, **kwargs) self.compare( Expression(SymbolD, marg2, Symbol("Global`x")), - sympy.Derivative(sarg2, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x")), + sympy.Derivative(sarg2, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), **kwargs, ) def testExpression(self): self.compare( Expression(SymbolSin, Symbol("Global`x")), - sympy.sin(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x")), + sympy.sin(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), ) def testConstant(self): @@ -164,13 +164,13 @@ def testConstant(self): def testGamma(self): self.compare( Expression(SymbolGamma, Symbol("Global`z")), - sympy.gamma(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`z")), + sympy.gamma(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_z")), ) self.compare( Expression(SymbolGamma, Symbol("Global`z"), Symbol("Global`x")), sympy.uppergamma( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`z"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global`x"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_z"), + sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), ), ) From e2c603b2d578a84151b955c16edffe52caf4a6c6 Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Mon, 1 Dec 2025 22:00:36 -0300 Subject: [PATCH 2/3] DRY --- mathics/core/convert/sympy.py | 18 +++++-- test/core/test_sympy_python_convert.py | 75 +++++++++++++------------- 2 files changed, 52 insertions(+), 41 deletions(-) diff --git a/mathics/core/convert/sympy.py b/mathics/core/convert/sympy.py index e0df61ee9..b0dbd7bcf 100644 --- a/mathics/core/convert/sympy.py +++ b/mathics/core/convert/sympy.py @@ -113,6 +113,16 @@ } +def sympy_decode_mathics_symbol_name(name: str): + """ + Remove the Prefix for Mathics symbols + and restore the context separator character. + """ + if name.startswith(SYMPY_SYMBOL_PREFIX): + return name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") + return name + + def is_Cn_expr(name: str) -> bool: """Check if name is of the form {prefix}Cnnn""" if name.startswith(SYMPY_SYMBOL_PREFIX) or name.startswith(SYMPY_SLOT_PREFIX): @@ -373,13 +383,12 @@ def old_from_sympy(expr) -> BaseElement: if "_" not in name: name = f"sympy`dummy`Dummy${expr.dummy_index}" # type: ignore[attr-defined] else: - name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") + name = sympy_decode_mathics_symbol_name(name) # Probably, this should be the value attribute return Symbol(name) if is_Cn_expr(name): return Expression(SymbolC, Integer(int(name[1:]))) - if name.startswith(SYMPY_SYMBOL_PREFIX): - name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") + name = sympy_decode_mathics_symbol_name(name) if name.startswith(SYMPY_SLOT_PREFIX): index = int(name[len(SYMPY_SLOT_PREFIX) :]) return Expression(SymbolSlot, Integer(index)) @@ -545,8 +554,7 @@ def old_from_sympy(expr) -> BaseElement: Expression(Symbol("C"), Integer(int(name[1:]))), *[from_sympy(arg) for arg in expr.args], ) - if name.startswith(SYMPY_SYMBOL_PREFIX): - name = name[len(SYMPY_SYMBOL_PREFIX) :].replace("_", "`") + name = sympy_decode_mathics_symbol_name(name) args = [from_sympy(arg) for arg in expr.args] builtin = sympy_to_mathics.get(name) if builtin is not None: diff --git a/test/core/test_sympy_python_convert.py b/test/core/test_sympy_python_convert.py index 6a4ceb3ad..c401a88f9 100644 --- a/test/core/test_sympy_python_convert.py +++ b/test/core/test_sympy_python_convert.py @@ -25,6 +25,7 @@ SYMPY_SYMBOL_PREFIX, Symbol, SymbolPlus, + sympy_name, ) from mathics.core.systemsymbols import ( SymbolD, @@ -36,6 +37,12 @@ SymbolSlot, ) +Symbol_f = Symbol("Global`f") +Symbol_x = Symbol("Global`x") +Symbol_y = Symbol("Global`y") +Symbol_z = Symbol("Global`z") +Symbol_Mathics_User_x = Symbol("Mathics`User`x") + class SympyConvert(unittest.TestCase): def compare_to_sympy(self, mathics_expr, sympy_expr, **kwargs): @@ -49,10 +56,10 @@ def compare(self, mathics_expr, sympy_expr, **kwargs): self.compare_to_mathics(mathics_expr, sympy_expr) def testSymbol(self): - self.compare(Symbol("Global`x"), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")) + self.compare(Symbol_x, sympy.Symbol(sympy_name(Symbol_x))) self.compare( - Symbol("Mathics`User`x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Mathics_User_x"), + Symbol_Mathics_User_x, + sympy.Symbol(sympy_name(Symbol_Mathics_User_x)), ) def testReal(self): @@ -87,25 +94,25 @@ def testString(self): def testAdd(self): self.compare( - Expression(SymbolPlus, Integer1, Symbol("Global`x")), - sympy.Add(sympy.Integer(1), sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), + Expression(SymbolPlus, Integer1, Symbol_x), + sympy.Add(sympy.Integer(1), sympy.Symbol(sympy_name(Symbol_x))), ) def testIntegrate(self): self.compare( - Expression(SymbolIntegrate, Symbol("Global`x"), Symbol("Global`y")), + Expression(SymbolIntegrate, Symbol_x, Symbol_y), sympy.Integral( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), + sympy.Symbol(sympy_name(Symbol_x)), + sympy.Symbol(sympy_name(Symbol_y)), ), ) def testDerivative(self): self.compare( - Expression(SymbolD, Symbol("Global`x"), Symbol("Global`y")), + Expression(SymbolD, Symbol_x, Symbol_y), sympy.Derivative( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), + sympy.Symbol(sympy_name(Symbol_x)), + sympy.Symbol(sympy_name(Symbol_y)), ), ) @@ -114,17 +121,15 @@ def testDerivative2(self): head = Expression( Expression(SymbolDerivative, Integer1, Integer0), - Symbol("Global`f"), + Symbol_f, ) - expr = Expression(head, Symbol("Global`x"), Symbol("Global`y")) + expr = Expression(head, Symbol_x, Symbol_y) - sfxy = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), - ) - sym_expr = sympy.Derivative( - sfxy, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x") + sfxy = sympy.Function(sympy_name(Symbol_f))( + sympy.Symbol(sympy_name(Symbol_x)), + sympy.Symbol(sympy_name(Symbol_y)), ) + sym_expr = sympy.Derivative(sfxy, sympy.Symbol(sympy_name(Symbol_x))) self.compare_to_sympy(expr, sym_expr, **kwargs) # compare_to_mathics fails because Derivative becomes D (which then evaluates to Derivative) @@ -132,29 +137,27 @@ def testDerivative2(self): def testConvertedFunctions(self): kwargs = {"converted_functions": set(["Global`f"])} - marg1 = Expression(Symbol("Global`f"), Symbol("Global`x")) - sarg1 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x") - ) + marg1 = Expression(Symbol_f, Symbol_x) + sarg1 = sympy.Function(sympy_name(Symbol_f))(sympy.Symbol(sympy_name(Symbol_x))) self.compare(marg1, sarg1, **kwargs) - marg2 = Expression(Symbol("Global`f"), Symbol("Global`x"), Symbol("Global`y")) - sarg2 = sympy.Function(str(f"{SYMPY_SYMBOL_PREFIX}Global_f"))( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_y"), + marg2 = Expression(Symbol_f, Symbol_x, Symbol_y) + sarg2 = sympy.Function(sympy_name(Symbol_f))( + sympy.Symbol(sympy_name(Symbol_x)), + sympy.Symbol(sympy_name(Symbol_y)), ) self.compare(marg2, sarg2, **kwargs) self.compare( - Expression(SymbolD, marg2, Symbol("Global`x")), - sympy.Derivative(sarg2, sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), + Expression(SymbolD, marg2, Symbol_x), + sympy.Derivative(sarg2, sympy.Symbol(sympy_name(Symbol_x))), **kwargs, ) def testExpression(self): self.compare( - Expression(SymbolSin, Symbol("Global`x")), - sympy.sin(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x")), + Expression(SymbolSin, Symbol_x), + sympy.sin(sympy.Symbol(sympy_name(Symbol_x))), ) def testConstant(self): @@ -163,14 +166,14 @@ def testConstant(self): def testGamma(self): self.compare( - Expression(SymbolGamma, Symbol("Global`z")), - sympy.gamma(sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_z")), + Expression(SymbolGamma, Symbol_z), + sympy.gamma(sympy.Symbol(sympy_name(Symbol_z))), ) self.compare( - Expression(SymbolGamma, Symbol("Global`z"), Symbol("Global`x")), + Expression(SymbolGamma, Symbol_z, Symbol_x), sympy.uppergamma( - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_z"), - sympy.Symbol(f"{SYMPY_SYMBOL_PREFIX}Global_x"), + sympy.Symbol(sympy_name(Symbol_z)), + sympy.Symbol(sympy_name(Symbol_x)), ), ) From e9565ccc63e0ffff337c581528950e36e968388a Mon Sep 17 00:00:00 2001 From: Juan Mauricio Matera Date: Mon, 1 Dec 2025 22:15:14 -0300 Subject: [PATCH 3/3] another test for symbols --- test/core/test_sympy_python_convert.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/core/test_sympy_python_convert.py b/test/core/test_sympy_python_convert.py index c401a88f9..e5f9fbb93 100644 --- a/test/core/test_sympy_python_convert.py +++ b/test/core/test_sympy_python_convert.py @@ -61,6 +61,12 @@ def testSymbol(self): Symbol_Mathics_User_x, sympy.Symbol(sympy_name(Symbol_Mathics_User_x)), ) + # Sympy symbols without prefix are mapped to symbols in + # System` context: + self.compare_to_mathics(Symbol("x"), sympy.Symbol("x")) + # Notice that a sympy Symbol named "x" is converted + # to the Mathics symbol "System`x", and then, when converted + # back to sympy, goes to sympy.Symbol("_uSystem_x"). def testReal(self): self.compare(Real("1.0"), sympy.Float("1.0"))