Skip to content

Decompile boolean lambda function inconsistency #29

@viralogic

Description

@viralogic

When I try to decompile a lambda function I get an assertion error:

func = lambda x: x.gpa < 20 or ((x.first_name == u'Bruce' and x.last_name == u'Fenske') or x.first_name == u'Dustin')
tree = meta.decompiler.decompile_func(func)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Python27\lib\site-packages\meta\decompiler\__init__.py", line 37, in decompile_func
    ast_node = make_function(code, defaults=[], lineno=code.co_firstlineno)
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 70, in make_function
    stmnts = instructions.stmnt()
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 283, in stmnt
    self.visit(instr)
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 297, in visit
    method(instr)
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 702, in JUMP_IF_TRUE_OR_POP
    hi = self.process_logic([instr] + and_block)
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 654, in process_logic
    right = self.process_logic(logic_block[1:])
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 680, in process_logic
    assert right.parent is None
AssertionError
func = lambda x: x.gpa < 20 and ((x.first_name == u'Bruce' and x.last_name == u'Fenske') or x.first_name == u'Dustin')
tree = meta.decompiler.decompile_func(func)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Python27\lib\site-packages\meta\decompiler\__init__.py", line 37, in decompile_func
    ast_node = make_function(code, defaults=[], lineno=code.co_firstlineno)
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 70, in make_function
    stmnts = instructions.stmnt()
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 283, in stmnt
    self.visit(instr)
  File "C:\Python27\lib\site-packages\meta\decompiler\instructions.py", line 297, in visit
    method(instr)
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 803, in JUMP_IF_FALSE_OR_POP
    hi = self.process_logic([instr] + and_block)
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 654, in process_logic
    right = self.process_logic(logic_block[1:])
  File "C:\Python27\lib\site-packages\meta\decompiler\control_flow_instructions.py", line 680, in process_logic
    assert right.parent is None
AssertionError

However, when I try to decompile this lambda function, it is successful even though they are equivalent:

func = lambda x: ((x.first_name == u'Bruce' and x.last_name == u'Fenske') or x.first_name == u'Dustin') or x.gpa > 10
tree = meta.decompiler.decompile_func(func)
print ast.dump(tree)
Lambda(args=arguments(args=[Name(id='x', ctx=Param())], vararg=None, kwarg=None, defaults=[]), body=BoolOp(op=Or(), values=[BoolOp(op=And(), values=[Compare(left=Attribute(value=Name(id='x', ctx=Load()), attr='first_name', ctx=Load()), ops=[Eq()], comparators=[u'Bruce']), Compare(left=Attribute(value=Name(id='x', ctx=Load()), attr='last_name', ctx=Load()), ops=[Eq()], comparators=[u'Fenske'])]), BoolOp(op=Or(), values=[Compare(left=Attribute(value=Name(id='x', ctx=Load()), attr='first_name', ctx=Load()), ops=[Eq()], comparators=[u'Dustin']), Compare(left=Attribute(value=Name(id='x', ctx=Load()), attr='gpa', ctx=Load()), ops=[Gt()], comparators=[Num(n=10)])])]))

From my perspective, this isn't a huge deal. I can always rewrite my lambdas in my code to use form from the successful example.

Thanks for your hard work on this library. It has proven to be very useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions