As described by the documentation, I expect to be able to specify as a call target of Context.call_async – fn – either a:
- module-level function
- static method
- class method
However, at least in naively passing the Python object reference of either version of a method, mitogen is either unable to find or unable to process the call target.
For example, using staticmethod –
#!/usr/bin/env python
import os
import pathlib
import socket
import mitogen.utils
class MyClass:
@staticmethod
def my_first_function():
print('hostname:', socket.gethostname())
print('remote PID:', os.getpid())
print('file:', pathlib.Path(__file__))
return 123
@classmethod
def main(cls, router):
local = router.local()
result = local.call(cls.my_first_function)
print(result, socket.gethostname(), os.getpid())
if __name__ == '__main__':
mitogen.utils.log_to_file()
mitogen.utils.run_with_router(MyClass.main)
– results in the following error –
Traceback (most recent call last):
File "./fake_manage_method.py", line 27, in <module>
mitogen.utils.run_with_router(MyClass.main)
File "/home/USER/dev/repo/opt/mitogen/mitogen/utils.py", line 100, in run_with_router
return func(router, *args, **kwargs)
File "./fake_manage_method.py", line 21, in main
result = local.call(cls.my_first_function)
File "/home/USER/dev/repo/opt/mitogen/mitogen/parent.py", line 1016, in call
return receiver.get().unpickle(throw_dead=False)
File "/home/USER/dev/repo/opt/mitogen/mitogen/core.py", line 487, in unpickle
raise obj
mitogen.core.CallError: builtins.AttributeError: module '__main__' has no attribute 'my_first_function'
File "<stdin>", line 2049, in _dispatch_calls
File "<stdin>", line 2036, in _dispatch_one
Or, replacing the staticmethod with classmethod:
Traceback (most recent call last):
File "./fake_manage_method.py", line 27, in <module>
mitogen.utils.run_with_router(MyClass.main)
File "/home/USER/dev/repo/opt/mitogen/mitogen/utils.py", line 100, in run_with_router
return func(router, *args, **kwargs)
File "./fake_manage_method.py", line 21, in main
result = local.call(cls.my_first_function)
File "/home/USER/dev/repo/opt/mitogen/mitogen/parent.py", line 1015, in call
receiver = self.call_async(fn, *args, **kwargs)
File "/home/USER/dev/repo/opt/mitogen/mitogen/parent.py", line 1012, in call_async
return self.send_async(make_call_msg(fn, *args, **kwargs))
File "/home/USER/dev/repo/opt/mitogen/mitogen/parent.py", line 401, in make_call_msg
isinstance(fn.im_self, (type, types.ClassType)):
AttributeError: 'function' object has no attribute 'im_self'
In the case of the staticmethod, (unpickling), this may be worked around, for example –
def my_first_function():
print('hostname:', socket.gethostname())
print('remote PID:', os.getpid())
print('file:', pathlib.Path(__file__))
return 123
class MyClass:
my_first_function = staticmethod(my_first_function)
@classmethod
def main(cls, router):
local = router.local()
result = local.call(cls.my_first_function)
print(result, socket.gethostname(), os.getpid())
– such that mitogen can now find the call target at the module level; (however, if mitogen intends to support static methods, this is less than ideal).
As described by the documentation, I expect to be able to specify as a call target of
Context.call_async–fn– either a:However, at least in naively passing the Python object reference of either version of a method, mitogen is either unable to find or unable to process the call target.
For example, using
staticmethod–– results in the following error –
Or, replacing the
staticmethodwithclassmethod:In the case of the
staticmethod, (unpickling), this may be worked around, for example –– such that mitogen can now find the call target at the module level; (however, if mitogen intends to support static methods, this is less than ideal).