fumitoh / modelx

Use Python like a spreadsheet!
https://modelx.io
GNU Lesser General Public License v3.0
90 stars 20 forks source link

BUG: Formula traceback breaks when Cells are referenced in listcomp #31

Closed fumitoh closed 4 years ago

fumitoh commented 4 years ago

Thank you for this development. Unfortunately it breaks in case function is used within the cell:

from modelx import *
m, s = new_model(), new_space()
@defcells
def a(t):
    if t > 0:
        return sum([a(t - i) for i in range(1, 2)])
    else:
        raise ValueError()

a(1)

Originally posted by @alexeybaran in https://github.com/fumitoh/modelx/issues/16#issuecomment-619886334

fumitoh commented 4 years ago

@alexeybaran Fixed. Thanks for the bug report.

alebaran commented 4 years ago

The check isn't dicriminative enough:

from modelx import *
m, s = new_model(), new_space()

@defcells
def a(t):
    def my_sum(*args):
        return sum(args)

    return my_sum('a')

a(1)

More resilient algorithm would be check name correspondence: frame.name == node.name. If the name doesn't match, frame content should still be shown, but without extra mx details

fumitoh commented 4 years ago

I also noticed that frame.name can be <lambda>. cab61ce should fix both your case and the lambda case, as the additional tests show.

alebaran commented 4 years ago
i = 0
while len(rolledback) > 0:
    node = rolledback.pop()
    while tbexc.stack[i].name != node[0].name:
        i += 1
    self.append(
        (node, frame.lineno)
    )

?

fumitoh commented 4 years ago

Won't work. tbexc.stack[i].name can be "<lambda>" and node[0].name can be "lam".

import modelx as mx

s = mx.new_space()

s.new_cells("lam", formula=lambda x: qux(x-1) if x > 0 else 1/0)

@mx.defcells
def qux(x):
    return lam(x)

s.lam(1)
alebaran commented 4 years ago

Clear. Now the error messaging works for me. Thank you very much!

alebaran commented 4 years ago

Will you share the fix through pip version?

fumitoh commented 4 years ago

Just released v0.6.1