NiklasRosenstein / python-builddsl

A superset of the Python programming language with support for closures and multi-line lambdas
https://niklasrosenstein.github.io/craftr-dsl/
MIT License
2 stars 2 forks source link

Names imported via wildcard import (`from ... import *`) are not resolved correctly in Closure mode #19

Open NiklasRosenstein opened 1 year ago

NiklasRosenstein commented 1 year ago

Example:

$ cat <<EOF | python -m builddsl -EC
from re import *
from sys import argv

print(search)
print(argv)
EOF
from re import *
from sys import argv
__closure__['print'](__closure__['search'])
__closure__['print'](argv)

The transpiler can't know that search was imported from the re module, and currently this will result in a NameError:

import builddsl

builddsl.Closure.from_map({}).run_code("""
from re import *
from sys import argv

print(search)
print(argv)
""")
Traceback (most recent call last):
  File "/home/coder/kraken/test.py", line 3, in <module>
    builddsl.Closure.from_map({}).run_code("""
  File "/home/coder/kraken/.venvs/3.10/lib/python3.10/site-packages/builddsl/_runtime.py", line 245, in run_code
    exec(module, scope)
  File "<string>", line 5, in <module>
  File "/home/coder/kraken/.venvs/3.10/lib/python3.10/site-packages/builddsl/_runtime.py", line 263, in __getitem__
    raise NameError(f"{key!r} in {self!r}")
NameError: 'search' in Closure(target={})

We should probably do the following two things:

  1. Don't have the transpiler try to optimize name access for imported names because this means you cannot access the same name from the closure target if it is available (e.g. in the above example, if a target provides the argv member you still read the global argv)
  2. Have Closure.__getitem__ resolve names in the locals and globals of the current frame