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

1# Adapted from https://stackoverflow.com/a/9558001/2536294 

2 

3import ast 

4from dataclasses import dataclass 

5import operator as op 

6 

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} 

18 

19 

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 

35 

36 

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) 

46 

47 

48@dataclass(frozen=True) 

49class _Sentinel: 

50 """A sentinel to mark a parameter as not explicitly set""" 

51 default_value: object 

52 

53 def __repr__(self): 

54 return f"default({self.default_value!r})"