Skip to content

Commit b85d9b2

Browse files
committed
base module import on iter_asts
1 parent dc2363c commit b85d9b2

File tree

1 file changed

+8
-15
lines changed

1 file changed

+8
-15
lines changed

pythoned/__init__.py

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import ast
22
import importlib
33
import os
4-
import re
54
from types import ModuleType
65
from typing import Any, Dict, Iterator, Set
76

87
LINE_IDENTIFIER = "_"
98
_TYPE_ERROR_MSG = "The provided expression must be an str (editing) or a bool (filtering), but got {}."
109

1110

12-
def iter_identifiers(expr: str) -> Iterator[str]:
13-
for node in iter_asts(ast.parse(expr, mode="eval").body):
11+
def iter_identifiers(expression: str) -> Iterator[str]:
12+
for node in iter_asts(ast.parse(expression, mode="eval").body):
1413
if isinstance(node, ast.Name):
1514
yield node.id
1615

@@ -27,19 +26,13 @@ def iter_asts(node: ast.AST) -> Iterator[ast.AST]:
2726

2827
def auto_import_eval(expression: str, globals: Dict[str, Any]) -> Any:
2928
globals = globals.copy()
30-
encountered_name_errors: Set[str] = set()
31-
while True:
32-
try:
33-
return eval(expression, globals)
34-
except NameError as name_error:
35-
if str(name_error) in encountered_name_errors:
36-
raise
37-
encountered_name_errors.add(str(name_error))
38-
match = re.match(r"name '([A-Za-z]+)'.*", str(name_error))
39-
if match:
40-
module = match.group(1)
41-
globals[module] = importlib.import_module(module)
29+
for identifier in iter_identifiers(expression):
30+
if identifier != LINE_IDENTIFIER:
31+
try:
32+
globals[identifier] = importlib.import_module(identifier)
33+
except ModuleNotFoundError:
4234
continue
35+
return eval(expression, globals=globals)
4336

4437

4538
def edit(lines: Iterator[str], expression) -> Iterator[str]:

0 commit comments

Comments
 (0)