godot-python
godot-python copied to clipboard
Can't pass a python dict or array to godot
In pyobj_to_variant, in tools.py, it converts python objects to Godot Variants. Unfortunately there is no case in there for a python dict or even a python array. You get a TypeError if you try.
Yep, that's by design. The thing is list/dict require being converted to Godot Dictionary and List which is obviously costly so I wasn't sure it was a good idea to allow using native python type here. Beside, given the Godot and Python types are not strictly 100% compatible I had concern it could cause subtle bugs.
Anyway, a lot of things have changed since this design choice so I wouldn't be surprised if it's no longer relevant, so if you think it's safe to do this I trust you on this ;-)
Please add support for dict and array even if it is very slow. A performance warning could be shown. At the current stage I just use Python for prototyping and I would have to write many iterator like interfaces to pass larger data structures.
Yes I agree, at least a direct conversion from Bytes to PoolByteArray would help.
I wrote some code for converting between gd and py types, you're welcome to use it or submit it as a pull request.
I have added the code to a init.py in my scripts folder, to make it easy to access from my GD python scripts.
import it as:
from . import gd2py, py2gd
then use like this:
py_obj = gd2py(gd_obj)
gd_obj = py2gd(py_obj)
Here is the code, I'll be pleased if someone uses it or suggests a performance improvement - I'm having to call it many times per frame...:
"""Utilities for use by Godot Python scripts"""
from godot import *
# CONVERTING GODOT TYPES TO PYTHON
def gdDict2py(gtype):
d = {}
for key, value in gtype.items():
d[gd2py(key)] = gd2py(value)
return d
def gdArray2py(gtype):
l = []
for i in gtype:
l.append(gd2py(i))
return l
if not 'gd2py_funcs' in locals():
gd2py_funcs = {}
gd2py_funcs[builtins.GDString] = str
gd2py_funcs[builtins.Array] = gdArray2py
gd2py_funcs[builtins.Dictionary] = gdDict2py
def gd2py(gtype):
"""Looks up the object's type and uses appropriate converter.
If you know the type in advance, it's more performant to use
the specific type converters.
"""
return gd2py_funcs.get(type(gtype),_nothing)(gtype)
# CONVERTING PYTHON TYPES TO GODOT
def pyList2gd(ptype):
l = builtins.Array()
for i in ptype:
l.append(py2gd(i))
return l
def pyDict2gd(ptype):
d = builtins.Dictionary()
for key, value in ptype.items():
d[py2gd(key)] = py2gd(value)
return d
if not 'py2gd_funcs' in locals():
py2gd_funcs = {}
py2gd_funcs[str] = builtins.GDString
py2gd_funcs[list] = pyList2gd
py2gd_funcs[dict] = pyDict2gd
def py2gd(ptype):
"""Looks up the object's type and uses appropriate converter.
If you know the type in advance, it's more performant to use
the specific type converters.
"""
return py2gd_funcs.get(type(ptype),_nothing)(ptype)
def _nothing(_type):
return _type