nucleic / enaml

Declarative User Interfaces for Python
http://enaml.readthedocs.io/en/latest/
Other
1.52k stars 130 forks source link

TryBegin object has no attribute name with python 3.12 in rewrite_to_fast_locals #548

Closed frmdstryr closed 2 months ago

frmdstryr commented 3 months ago

Not sure how to reproduce in a test yet but it seems like an isinstance(instr, bc.Instr) check is needed in rewrite_to_fast_locals.


  File "/app/lib/python3.12/site-packages/enaml/core/import_hooks.py", line 139, in exec_module
    code, _ = self.get_code()
              ^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/import_hooks.py", line 400, in get_code
    return self.compile_code()
           ^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/import_hooks.py", line 365, in compile_code
    code = EnamlCompiler.compile(ast, file_info.src_path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_compiler.py", line 179, in compile
    return compiler.visit(node)
           ^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_ast.py", line 420, in visit
    result = visitor(node, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_compiler.py", line 195, in visit_Module
    self.visit(item)
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_ast.py", line 420, in visit
    result = visitor(node, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_compiler.py", line 264, in visit_Template
    code = TemplateCompiler.compile(node, cg.filename)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/template_compiler.py", line 303, in compile
    return compiler.visit(node)
           ^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_ast.py", line 420, in visit
    result = visitor(node, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/template_compiler.py", line 315, in visit_Template
    first_code, index_map = FirstPassTemplateCompiler.compile(
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/template_compiler.py", line 97, in compile
    compiler.visit(node)
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_ast.py", line 420, in visit
    result = visitor(node, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/template_compiler.py", line 134, in visit_Template
    self.visit(item)
  File "/app/lib/python3.12/site-packages/enaml/core/enaml_ast.py", line 420, in visit
    result = visitor(node, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/app/lib/python3.12/site-packages/enaml/core/block_compiler.py", line 82, in visit_TemplateInst
    cmn.gen_template_inst_node(cg, node, self.local_names)
  File "/app/lib/python3.12/site-packages/enaml/core/compiler_common.py", line 629, in gen_template_inst_node
    safe_eval_ast(cg, arg.ast, node.name, arg.lineno, local_names)
  File "/app/lib/python3.12/site-packages/enaml/core/compiler_common.py", line 399, in safe_eval_ast
    expr_cg.rewrite_to_fast_locals(local_names)
  File "/app/lib/python3.12/site-packages/enaml/core/code_generator.py", line 591, in rewrite_to_fast_locals
    if instr.name == "STORE_NAME":
       ^^^^^^^^^^
AttributeError: 'TryBegin' object has no attribute 'name'

It is when generating templates.

enaml==0.17.0 bytecode==0.15.1

MatthieuDartiailh commented 3 months ago

Out of curiosity can you reproduce on 3.11 ? TryBegin was not introduced for 3.12 so I suspect the bug exists also on 3.11.

MatthieuDartiailh commented 3 months ago

I agree that a simple isinstance to check if we are dealing with an Instr is the way to go here. Could you provide a reproducer even if it is not minimal.

frmdstryr commented 3 months ago

I was able to reproduce it by inlining the Spec argument in the AutoFormBody from the templates/advanced.enaml example

Eg replace

template AutoFormBody(ModelType):
    const Spec: tuple = form_spec(ModelType)
    ForEach(Spec, FormItem):
        pass

with

template AutoFormBody(ModelType):
    const Spec: tuple = tuple([
        (name, type(member))
        for name, member in ModelType.members().items()
        if not name.startswith('_')
    ])
    ForEach(Spec, FormItem):
        pass
frmdstryr commented 3 months ago

I cannot reproduce it with 3.11