Coverage for /usr/lib/python3/dist-packages/sympy/core/parameters.py: 41%

34 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1"""Thread-safe global parameters""" 

2 

3from .cache import clear_cache 

4from contextlib import contextmanager 

5from threading import local 

6 

7class _global_parameters(local): 

8 """ 

9 Thread-local global parameters. 

10 

11 Explanation 

12 =========== 

13 

14 This class generates thread-local container for SymPy's global parameters. 

15 Every global parameters must be passed as keyword argument when generating 

16 its instance. 

17 A variable, `global_parameters` is provided as default instance for this class. 

18 

19 WARNING! Although the global parameters are thread-local, SymPy's cache is not 

20 by now. 

21 This may lead to undesired result in multi-threading operations. 

22 

23 Examples 

24 ======== 

25 

26 >>> from sympy.abc import x 

27 >>> from sympy.core.cache import clear_cache 

28 >>> from sympy.core.parameters import global_parameters as gp 

29 

30 >>> gp.evaluate 

31 True 

32 >>> x+x 

33 2*x 

34 

35 >>> log = [] 

36 >>> def f(): 

37 ... clear_cache() 

38 ... gp.evaluate = False 

39 ... log.append(x+x) 

40 ... clear_cache() 

41 >>> import threading 

42 >>> thread = threading.Thread(target=f) 

43 >>> thread.start() 

44 >>> thread.join() 

45 

46 >>> print(log) 

47 [x + x] 

48 

49 >>> gp.evaluate 

50 True 

51 >>> x+x 

52 2*x 

53 

54 References 

55 ========== 

56 

57 .. [1] https://docs.python.org/3/library/threading.html 

58 

59 """ 

60 def __init__(self, **kwargs): 

61 self.__dict__.update(kwargs) 

62 

63 def __setattr__(self, name, value): 

64 if getattr(self, name) != value: 

65 clear_cache() 

66 return super().__setattr__(name, value) 

67 

68global_parameters = _global_parameters(evaluate=True, distribute=True, exp_is_pow=False) 

69 

70@contextmanager 

71def evaluate(x): 

72 """ Control automatic evaluation 

73 

74 Explanation 

75 =========== 

76 

77 This context manager controls whether or not all SymPy functions evaluate 

78 by default. 

79 

80 Note that much of SymPy expects evaluated expressions. This functionality 

81 is experimental and is unlikely to function as intended on large 

82 expressions. 

83 

84 Examples 

85 ======== 

86 

87 >>> from sympy import evaluate 

88 >>> from sympy.abc import x 

89 >>> print(x + x) 

90 2*x 

91 >>> with evaluate(False): 

92 ... print(x + x) 

93 x + x 

94 """ 

95 

96 old = global_parameters.evaluate 

97 

98 try: 

99 global_parameters.evaluate = x 

100 yield 

101 finally: 

102 global_parameters.evaluate = old 

103 

104 

105@contextmanager 

106def distribute(x): 

107 """ Control automatic distribution of Number over Add 

108 

109 Explanation 

110 =========== 

111 

112 This context manager controls whether or not Mul distribute Number over 

113 Add. Plan is to avoid distributing Number over Add in all of sympy. Once 

114 that is done, this contextmanager will be removed. 

115 

116 Examples 

117 ======== 

118 

119 >>> from sympy.abc import x 

120 >>> from sympy.core.parameters import distribute 

121 >>> print(2*(x + 1)) 

122 2*x + 2 

123 >>> with distribute(False): 

124 ... print(2*(x + 1)) 

125 2*(x + 1) 

126 """ 

127 

128 old = global_parameters.distribute 

129 

130 try: 

131 global_parameters.distribute = x 

132 yield 

133 finally: 

134 global_parameters.distribute = old 

135 

136 

137@contextmanager 

138def _exp_is_pow(x): 

139 """ 

140 Control whether `e^x` should be represented as ``exp(x)`` or a ``Pow(E, x)``. 

141 

142 Examples 

143 ======== 

144 

145 >>> from sympy import exp 

146 >>> from sympy.abc import x 

147 >>> from sympy.core.parameters import _exp_is_pow 

148 >>> with _exp_is_pow(True): print(type(exp(x))) 

149 <class 'sympy.core.power.Pow'> 

150 >>> with _exp_is_pow(False): print(type(exp(x))) 

151 exp 

152 """ 

153 old = global_parameters.exp_is_pow 

154 

155 clear_cache() 

156 try: 

157 global_parameters.exp_is_pow = x 

158 yield 

159 finally: 

160 clear_cache() 

161 global_parameters.exp_is_pow = old