0

Hello I am trying to get a list of the variables used by an eval expression. I managed to get something working using the mock module:

import mock

def get_eval_vars(expr):
    # Use a mock dictionary to check which items are called
    mock_var = mock.MagicMock()
    eval(expr, {"__builtins__": {}}, mock_var)
    return [args[0][0] for args in mock_var.__getitem__.call_args_list]

print(get_eval_vars("a+b+10")) # Correctly outputs [a, b]
print(get_eval_vars("a<10"))   # Raises TypeError: '<' not supported between instances of 'MagicMock' and 'int'

However, as explained in the comments, the mock throws an error because the inequalities are not defined in MagicMock. Looking at mock issue #196 it seems like they have no plans to change this.

Is there any correct way to override the inequality operators for MagicMock? Is there any alternative to using mock?

Iñigo Moreno
  • 529
  • 2
  • 15

1 Answers1

0

Well, I managed to do this on my own usin ast:

import ast

def get_eval_vars(expr):
    st = ast.parse(expr, mode="eval")
    return [node.id for node in ast.walk(st) if isinstance(node,ast.Name) and isinstance(node.ctx, ast.Load)]

print(get_eval_vars("a+b+10")) # Correctly outputs [a, b]
print(get_eval_vars("a<10"))   # Correctly outputs [a]
Iñigo Moreno
  • 529
  • 2
  • 15