Fix Version/s: None
singleFrameDriver.py is only using a single process. The problem appears to be the change to use a ButlerInitializedTaskRunner, which doesn't inherit from BatchTaskRunner.
- mentioned in
My only concern is that I think you might need to modify BatchTaskRunner.__init__ to use super to ensure that TaskRunner.__init__ is invoked properly; it'd certainly be good practice to do so, even if we're skating by on an edge case. In fact, I'd feel a bit safer if all three derived classes explicitly did that, but I've got to imagine Python also handles multiple inheritance correctly if you don't define __init__ at all.
I don't think that's necessary.
- BatchTaskRunner overrides __init__, run and __call__.
- ButlerInitializedTaskRunner overrides only makeTask.
These lists are orthogonal, so the correct parent should be firing without having to worry about the MRO. Since you mentioned it explictly, take the example of __init__:
- SingleFrameTaskRunner.__init__ isn't defined, so we go looking up the MRO.
- BatchTaskRunner is next in the MRO, and it defines __init__, so that fires.
- That explicitly calls TaskRunner.__init__ (not using super).
- That doesn't call any other __init__ method.
Note that nothing is calling ButlerInitializedTaskRunner.__init__, and that's good because it doesn't override that method. So I think everything fires that needs to, and nothing fires that shouldn't. If we used super somewhere but not everywhere, that would create trouble, but I think this does the right thing now without any changes required.
Please let me know if you disagree or still have concerns. I'll wait on your final OK before merging.
I don't disagree with your analysis that the current code is safe, but I still worry that it's fragile w.r.t. the addition of new subclasses. That said, TaskRunner is perhaps not long for this world with SuperTask on the horizon, so it's probably not necessary to fix this now.
Thanks, I'll go ahead and merge now.
I'm not sure how this is any more fragile than usual, nor how super would fix it (using super in a class hierarchy that doesn't all use super is dangerous, and I thought you were against using it for that reason); perhaps you could explain that offline for me?
To be honest, while I do remember being unhappy with super in the past, I don't remember the arguments for and against anymore, and I don't think that unease extended to diamond inheritance when all classes have a nontrivial constructors; I think super is till the only way to handle that situation correctly.
I wonder what the situation is in Python 3 (or futurized Python 2), where I hear super is better - Tim Jenness?
Python 3 super docs are at https://docs.python.org/3/library/functions.html?highlight=super#super which then tells you to read https://rhettinger.wordpress.com/2011/05/26/super-considered-super/
Jim Bosch, would you please review this? Here's the patch: