Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/joblib/_utils.py: 45%
22 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
1# Adapted from https://stackoverflow.com/a/9558001/2536294
3import ast
4from dataclasses import dataclass
5import operator as op
7# supported operators
8operators = {
9 ast.Add: op.add,
10 ast.Sub: op.sub,
11 ast.Mult: op.mul,
12 ast.Div: op.truediv,
13 ast.FloorDiv: op.floordiv,
14 ast.Mod: op.mod,
15 ast.Pow: op.pow,
16 ast.USub: op.neg,
17}
20def eval_expr(expr):
21 """
22 >>> eval_expr('2*6')
23 12
24 >>> eval_expr('2**6')
25 64
26 >>> eval_expr('1 + 2*3**(4) / (6 + -7)')
27 -161.0
28 """
29 try:
30 return eval_(ast.parse(expr, mode="eval").body)
31 except (TypeError, SyntaxError, KeyError) as e:
32 raise ValueError(
33 f"{expr!r} is not a valid or supported arithmetic expression."
34 ) from e
37def eval_(node):
38 if isinstance(node, ast.Num): # <number>
39 return node.n
40 elif isinstance(node, ast.BinOp): # <left> <operator> <right>
41 return operators[type(node.op)](eval_(node.left), eval_(node.right))
42 elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
43 return operators[type(node.op)](eval_(node.operand))
44 else:
45 raise TypeError(node)
48@dataclass(frozen=True)
49class _Sentinel:
50 """A sentinel to mark a parameter as not explicitly set"""
51 default_value: object
53 def __repr__(self):
54 return f"default({self.default_value!r})"