Skip to content

Commit

Permalink
Will this be the last case? #1225
Browse files Browse the repository at this point in the history
  • Loading branch information
Bo Peng committed Mar 1, 2019
1 parent e51ecec commit e55aba7
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 13 deletions.
15 changes: 8 additions & 7 deletions src/sos/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,18 @@ def get_accessed(node):
return names


def accessed_vars(statement: str, filename: str = '<string>', mode: str = 'exec') -> Set[str]:
def accessed_vars(statement: str, mode: str = 'exec') -> Set[str]:
'''Parse a Python statement and analyze the symbols used. The result
will be used to determine what variables a step depends upon.'''
try:
return get_accessed(ast.parse(statement, filename, mode))
if mode == 'exec':
return get_accessed(ast.parse(statement, '<string>', 'exec'))
else:
res = get_accessed(ast.parse('__NULL__(' + statement + ')', '<string>', 'eval'))
res.remove('__NULL__')
return res
except:
# try to treat them as parameters
try:
return get_accessed(ast.parse('__NULLFUNC__(' + statement + ')', filename, mode))
except:
raise RuntimeError(f'Failed to parse statement: {statement}')
raise RuntimeError(f'Failed to parse statement: {statement} in {mode} mode')

def get_used_in_func(node):
'''Get names, but ignore variables names to the left hand side
Expand Down
4 changes: 2 additions & 2 deletions src/sos/section_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ def get_all_used_vars(section):
elif statement[0] == '!':
all_used_vars |= accessed_vars(statement[1])
elif statement[0] == ':':
all_used_vars |= accessed_vars(statement[2])
all_used_vars |= accessed_vars(statement[2], mode='eval')
if statement[1] != 'input':
continue
if 'paired_with' in statement[2]:
try:
pws = get_names_of_param('paired_with', statement[2], extra_dict=env.sos_dict.dict())
pws = get_names_of_param('paired_with', statement[2], extra_dict=env.sos_dict.dict())
all_used_vars |= set(pws)
except Exception as e:
raise ValueError(f'Failed to parse parameter paired_with: {e}')
Expand Down
4 changes: 2 additions & 2 deletions src/sos/step_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,14 @@ def parse_shared_vars(option):
shared_vars.add(option)
elif isinstance(option, Mapping):
for val in option.values():
shared_vars |= accessed_vars(val)
shared_vars |= accessed_vars(val, mode='eval')
elif isinstance(option, Sequence):
for item in option:
if isinstance(item, str):
shared_vars.add(item)
elif isinstance(item, Mapping):
for val in item.values():
shared_vars |= accessed_vars(val)
shared_vars |= accessed_vars(val, mode='eval')
return shared_vars

def evaluate_shared(vars, option):
Expand Down
6 changes: 4 additions & 2 deletions test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,14 @@ def testAccessedVars(self):
self.assertEqual(accessed_vars('''a = "C" + f"{D}"'''), {'D'})
self.assertEqual(accessed_vars(
'''a = 1 + f"{D + 20:f}" '''), {'D'})
self.assertEqual(accessed_vars('''k, "a.txt", "b.txt", par=f(something) '''), {
'k', 'f', 'something', '__NULLFUNC__'})
self.assertEqual(accessed_vars('''k, "a.txt", "b.txt", par=f(something) ''',
mode='eva'), {'k', 'f', 'something'})
# this is a complicated case because the actual variable depends on the
# result of an expression... However, in the NO-evaluation case, this is
# the best we can do.
self.assertEqual(accessed_vars('''c + f"{D + 1}" '''), {'c', 'D'})
self.assertEqual(accessed_vars('''a, b=2, c=d ''', mode='eva'), {'a', 'd'})


def testProgressBar(self):
'''Test progress bar'''
Expand Down

0 comments on commit e55aba7

Please sign in to comment.