Coverage for /usr/lib/python3/dist-packages/sympy/printing/python.py: 21%
58 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1import keyword as kw
2import sympy
3from .repr import ReprPrinter
4from .str import StrPrinter
6# A list of classes that should be printed using StrPrinter
7STRPRINT = ("Add", "Infinity", "Integer", "Mul", "NegativeInfinity",
8 "Pow", "Zero")
11class PythonPrinter(ReprPrinter, StrPrinter):
12 """A printer which converts an expression into its Python interpretation."""
14 def __init__(self, settings=None):
15 super().__init__(settings)
16 self.symbols = []
17 self.functions = []
19 # Create print methods for classes that should use StrPrinter instead
20 # of ReprPrinter.
21 for name in STRPRINT:
22 f_name = "_print_%s" % name
23 f = getattr(StrPrinter, f_name)
24 setattr(PythonPrinter, f_name, f)
26 def _print_Function(self, expr):
27 func = expr.func.__name__
28 if not hasattr(sympy, func) and func not in self.functions:
29 self.functions.append(func)
30 return StrPrinter._print_Function(self, expr)
32 # procedure (!) for defining symbols which have be defined in print_python()
33 def _print_Symbol(self, expr):
34 symbol = self._str(expr)
35 if symbol not in self.symbols:
36 self.symbols.append(symbol)
37 return StrPrinter._print_Symbol(self, expr)
39 def _print_module(self, expr):
40 raise ValueError('Modules in the expression are unacceptable')
43def python(expr, **settings):
44 """Return Python interpretation of passed expression
45 (can be passed to the exec() function without any modifications)"""
47 printer = PythonPrinter(settings)
48 exprp = printer.doprint(expr)
50 result = ''
51 # Returning found symbols and functions
52 renamings = {}
53 for symbolname in printer.symbols:
54 # Remove curly braces from subscripted variables
55 if '{' in symbolname:
56 newsymbolname = symbolname.replace('{', '').replace('}', '')
57 renamings[sympy.Symbol(symbolname)] = newsymbolname
58 else:
59 newsymbolname = symbolname
61 # Escape symbol names that are reserved Python keywords
62 if kw.iskeyword(newsymbolname):
63 while True:
64 newsymbolname += "_"
65 if (newsymbolname not in printer.symbols and
66 newsymbolname not in printer.functions):
67 renamings[sympy.Symbol(
68 symbolname)] = sympy.Symbol(newsymbolname)
69 break
70 result += newsymbolname + ' = Symbol(\'' + symbolname + '\')\n'
72 for functionname in printer.functions:
73 newfunctionname = functionname
74 # Escape function names that are reserved Python keywords
75 if kw.iskeyword(newfunctionname):
76 while True:
77 newfunctionname += "_"
78 if (newfunctionname not in printer.symbols and
79 newfunctionname not in printer.functions):
80 renamings[sympy.Function(
81 functionname)] = sympy.Function(newfunctionname)
82 break
83 result += newfunctionname + ' = Function(\'' + functionname + '\')\n'
85 if renamings:
86 exprp = expr.subs(renamings)
87 result += 'e = ' + printer._str(exprp)
88 return result
91def print_python(expr, **settings):
92 """Print output of python() function"""
93 print(python(expr, **settings))