fumitoh / modelx

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

Circular reference crashing the model #64

Closed alexeybaran closed 2 years ago

alexeybaran commented 2 years ago

The following circular reference code crashes the model without any warning or explanation:

import modelx as mx
m, s = mx.new_model(), mx.new_space()
@mx.defcells
def a():
    return b()

@mx.defcells
def b():
    return a()

s.a()
fumitoh commented 2 years ago

@alexeybaran I ran the code above on my PC and got the following error as expected.

modelx.core.errors.FormulaError: Error raised during formula execution
modelx.core.errors.DeepReferenceError: Formula chain exceeded the 50000 limit
Formula traceback:
0: Model1.Space1.a(), line 2
49998: Model1.Space1.a(), line 2
49999: Model1.Space1.b(), line 2
50000: Model1.Space1.a(), line 2
Formula source:
def a():
    return b()
alexeybaran commented 2 years ago

I get the following error code, if I wait long enough: Process finished with exit code -2147483647

On a slightly unrelated topic. When I define a() and b() in the way above, I get the following Warning: UserWarning: Cannot retrieve source code for function 'a'. a.source set to None. It later crashes Formula traceback functionality. Do you know what the reason of the Warning is?

fumitoh commented 2 years ago

Are you using Python's default iterpreter? modelx needs IPython to be executed interactively.

alexeybaran commented 2 years ago

Yes, it is default interpreter. What does it mean "Python to be executed interactively"?

fumitoh commented 2 years ago

To run modelx code interactively in read–eval–print loops, you need IPython. If you run modelx code in a .py file, you don't need IPython, just need Python.

alexeybaran commented 2 years ago

I don't follow. I always ran this kind of code

@mx.defcells
def a():
    return b()

in pyCharm Python console. It seems to do what is called "read–eval–print loops". In the past I had pyCharm linked to Anaconda Python installation. Now it is linked directly to Python installed without Anaconda.

alexeybaran commented 2 years ago

Is it a recent change making modelx more integrated with Jupiter notebooks?

fumitoh commented 2 years ago

No, it's been always like that. Try get_ipython() in your pyCharm Python console and see if it returns some object.

alexeybaran commented 2 years ago
>>> get_ipython()
Traceback (most recent call last):
  File "C:\Python64\3.9\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
NameError: name 'get_ipython' is not defined
fumitoh commented 2 years ago

How come your PyCharm not using IPython!? You should set up your PyCharm to use IPython, not the default interpreter.

The prompt would be like In [2]: intead of >>> once you get IPython work in PyCharm console.

This may help: iPython instead of Python for console? – IDEs Support (IntelliJ Platform) | JetBrains

image

alexeybaran commented 2 years ago

This helped. I have iPython now and there is no issue with @defcells. 50000 recursion still doesn't work. 10000 does.

fumitoh commented 2 years ago

There's a point between 10000 and 50000 where the code starts to crash on your machine. The point seems to differ by hardware & software enviroments. I want to keep the default max depth as high as possible but may lower it to avoid the crash by anyone. Anyway, Python 3.11 is coming out later this year and it's expected to solve this max depth problem once and for all. I was also thinking about placing an init file in user's home directory so that the user can customize modelx parameters like max depth.

alexeybaran commented 2 years ago

Clear. Thank you very much.