Describe the bug
I implemented a sub-class of yarp::Thread using YARP's Python bindings, but get a
SWIG:DirectorMethodException when executing the script. The precise error message is:
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'Thread.threadInit'
To Reproduce
Create a sub-class of yarp::Thread using the Python bindings and try to instantiate it
Expected behavior
I would expect it to instantiate the Thread as a new object
Configuration (please complete the following information):
Additional context
I noticed that none of the very few python scripts in any of the robotology sub-repositories, that make use of multi-threading use YARP's own multi-threading functionality. All of them use native Python multi-threading libraries instead. This is what I am intending to do now as well but I thought it might be useful to solve this bug or, at least, understand somewhat better what causes it.
I think yarp threads should not be used with bindings, and the native implementation should be used instead. Nonetheless yarp::Thread should either work or not be created at all...
If it doesn't work, I vote for removing it.
I kind of suspected something like that. I agree that, if it doesn't work, it's better not to see it in the bindings at all. I'm not a SWIG specialist, so I don't know how to stop it from generating those parts of the interface that deal with multi-threading.
I can replicate the error with the following code:
import yarp
class MyThread(yarp.Thread):
def run(): # or initThread(): to get the exact error
print("hi")
yarp.Network() # or yarp.Network.init()
x = MyThread()
x.start()
Edited my above comment, was missing the x.start() line.
Unordered comments:
SWIG:DirectorMethodException can appear even when issues are completely unrelated to SWIG.RFModule examples (1, 2) are still working (which is good).RateThread class (now PeriodicThread). It worked, but things were laggy, so I ended up going for a more Pythonic solution.time.sleep rather than the YARPy equivalent. After a couple of tests, I realized that this works:
import yarp
class MyThread(yarp.Thread):
def run(self):
print("hi")
yarp.Network()
x = MyThread()
x.start()
The only change is this one:
- def run():
+ def run(self):
Probably relevant:
This works:
def run(self):
yarp.delay(0.5)
This doesn't work:
def run(self):
time.sleep(0.5)
```
terminate called after throwing an instance of 'Swig::DirectorMethodException'
what(): SWIG director method error. Error detected when calling 'Thread.run'
This again works:
```python
import time
# [...]
def run(self):
time.sleep(0.5)