touilleMan / godot-python

Python support for Godot 🐍🐍🐍
Other
1.89k stars 143 forks source link

Infinite recursion getting object value #73

Open garyo opened 6 years ago

garyo commented 6 years ago

When I stop in the Godot debugger and it tries to get the value of a python object, I get RecursionError exceptions from python in the console. Adding a few traceback prints shows this is the infinite loop:

File "pythonscript\lib\godot\hazmat\lazy_bindings.py", line 242, in bind
    lib.godot_method_bind_ptrcall(methbind, self._gd_ptr, gdargs, ret)
  File "pythonscript\lib\godot\hazmat\ffi\instance.py", line 46, in pybind_instance_get_prop
    pyret = getattr(instance, name)
  File "pythonscript\lib\godot\hazmat\base.py", line 250, in __getattr__
    return self.get(name)
  File "pythonscript\lib\godot\hazmat\lazy_bindings.py", line 242, in bind
    lib.godot_method_bind_ptrcall(methbind, self._gd_ptr, gdargs, ret)
  ....

I think this is on a dictionary object, and it seems Object.get_script() is involved (that's from where the base.py call is). But adding print stmts changes it, probably because the print itself is calling similar methods.

Any ideas what could be going on here?

touilleMan commented 6 years ago

First I assume what you call Godot debugger is the debugger integrated into Godot (the one you use to debug GDscript code) and not the Python debugger.

lib.godot_method_bind_ptrcall(methbind, self._gd_ptr, gdargs, ret) will call the Godot API, which in turn seems to call back the Python wrapper pybind_instance_get_prop, which in turn call the Godot API etc.

So we are jumping back and forth between the Godot and Python worlds looking endlessly for a property...

My first guess would be the Godot debugger is looking for an attribute that doesn't exists in the current object (maybe a special attribute that change the debugger behavior if it is present...).

I don't remember if there is a unit test trying to get a non-existing property from a an exposed class instance. If not it would be interesting to add it to see if the recursion error is triggered only when we do the call from Godot or if we can do it from Python too. In the same idea, it would be good to try to access a bad attribute from GDscript (to see if the trouble is only triggered by the debugger, or by any foreign call to the Python-based scripts). There is a tests/work_with_gdscript project that is supposed to contain this kind of tests, but I've updated it for a while so it even possible it doesn't work anymore...