-
Notifications
You must be signed in to change notification settings - Fork 117
Open
Description
Lithops is incorrectly raising anytime I try to pass in a function decorated with functools.partial.
It complains that the function I decorated does not have a __call__ method
import functools
import lithops
fexec = lithops.FunctionExecutor()
iterable = ["foo", "bar"]
kwargs = {}
def f(s: str, **kwargs):
return s.upper()
futures = fexec.map(f, iterable, **kwargs) # this works fine
print(fexec.get_result(futures))
partial_f = functools.partial(f, **kwargs)
futures = fexec.map(partial_f, iterable) # this fails
print(fexec.get_result(futures)).venv/lib/python3.13/site-packages/lithops/executors.py:259: in map
job = create_map_job(
.venv/lib/python3.13/site-packages/lithops/job/job.py:81: in create_map_job
job = _create_job(
.venv/lib/python3.13/site-packages/lithops/job/job.py:245: in _create_job
func_and_data_ser, mod_paths = serializer([func] + iterdata, inc_modules, exc_modules)
.venv/lib/python3.13/site-packages/lithops/job/serialize.py:73: in __call__
ref_modules.update(self._module_inspect(obj))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <lithops.job.serialize.SerializeIndependent object at 0x12138c690>, obj = functools.partial(<function test_lithops_functools_partial_bug.<locals>.f at 0x1214ef7e0>)
def _module_inspect(self, obj):
"""
inspect objects for module dependencies
"""
worklist = []
seen = set()
mods = set()
if inspect.isfunction(obj) or (inspect.ismethod(obj) and inspect.isfunction(obj.__func__)):
# The obj is the user's function
worklist.append(obj)
elif type(obj).__name__ == 'cython_function_or_method':
for k, v in linspect.getmembers_static(obj):
if k == '__globals__':
mods.add(v['__file__'])
elif type(obj) is dict:
# the obj is the user's iterdata
for param in obj.values():
if type(param).__module__ == "__builtin__":
continue
elif inspect.isfunction(param):
# it is a user defined function
worklist.append(param)
else:
# it is a user defined class
for k, v in linspect.getmembers_static(param):
if inspect.isfunction(v) or (inspect.ismethod(v) and inspect.isfunction(v.__func__)):
worklist.append(v)
else:
# The obj is the user's function but in form of a class
found_methods = []
for k, v in linspect.getmembers_static(obj):
if inspect.isfunction(v) or (inspect.ismethod(v) and inspect.isfunction(v.__func__)):
found_methods.append(k)
worklist.append(v)
if "__call__" not in found_methods:
> raise Exception('The class you passed as the function to '
'run must contain the "__call__" method')
E Exception: The class you passed as the function to run must contain the "__call__" methodBut it definitely does have a __call__ method:
print(dir(partial_f))['__call__', '__class__', '__class_getitem__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__vectorcalloffset__', 'args', 'func', 'keywords']
I think this indicates that this line is not general enough
lithops/lithops/job/serialize.py
Line 158 in ceebd0f
| if inspect.isfunction(v) or (inspect.ismethod(v) and inspect.isfunction(v.__func__)): |
Metadata
Metadata
Assignees
Labels
No labels