I am converting a large project I didn't write from python2 to python3. Most the conversion is working but some parts of our UI that applies configs does nothing. I think it is the way the method is being called and defined. An example is this:
There is a file StatusConfigWdg.py that sets a runFunc to a method defined in the same py file:
self.scriptRunner = RO.ScriptRunner.ScriptRunner(
master = master,
name = "%s Config" % (self.instName,),
dispatcher = tuiModel.dispatcher,
runFunc = self._runConfig,
statusBar = self.statusBar,
stateFunc = self.enableButtons,
)
Later on in the ScriptRunner class there is a method _continue that has these lines:
if not self._iterStack:
# just started; call run function,
# and if it's an iterator, put it on the stack
print("about to call run func: " + str(self.runFunc) + " type: " + str(type(self.runFunc)))
res = self.runFunc(self) #does not work in python3
print("called run func with result res " + str(res))
if not hasattr(res, "next"):
# function was a function, not a generator; all done
print("zomg all done")
self._setState(Done)
return
self._iterStack = [res]
In python2 this works all day, several different classes would use this method of getting _runConfig which was either defined in a base class or in another class for another science instrument to use.
Now in python3, only the _runConfig defined in other classes for the science instruments to use works, if it is a science instrument using it in the base StatusConfigWdg.py class, like the one above self._runConfig, it never gets called.
The output of those print statements is what I found interesting, between python2.7 and python3 they are different.
ECHELLE instrument under Python2 (works!)
script state running
set state 0
script runner continue [0]
about to call run func: <bound method StatusConfigWdg._runConfig of <TUI.Inst.Echelle.EchelleWindow.StatusConfigWdg instance at 0x116684f50>> type: <type 'instancemethod'>
called run func with result res <generator object _runConfig at 0x11aac8870>
RUNNING CONFIG!!! YAY
command list: ['calfilter Blue']
it is a wait command
waitCMD after
ECHELLE instrument under Python3 does not work. (a few more superfluous printouts was added to the code)
script state running
set state 0reason: None
really setting state to: 0
Do call backs
script runner continue [0]
in continue val: None
about to call run func: <bound method StatusConfigWdg._runConfig of <TUI.Inst.Echelle.EchelleWindow.StatusConfigWdg object .!toplevel24.!statusconfigwdg>> type: <class 'method'>
called run func with result res <generator object StatusConfigWdg._runConfig at 0x12956a190>
zomg all done
set state -1reason: None
really setting state to: -1
Do call backs
ending in the start here
So my big question is python3 not properly executing the runFunc that is assigned to _runConfig because of the difference in types that are stated in the printouts where the functioning python2 version is:
<type 'instancemethod'>
and the non functioning python3 version is:
type: <class 'method'>
And is it because of the way it is called?
res = self.runFunc(self)
the defined _runConfig in StatusConfigWdg.py:
def _runConfig(self, sr):
"""Script runner run function to modify the configuration.
Execute each command string in self.inputWdg.getStringList(). Wait for each command
to finish before starting the next and halt if any command fails.
"""
print("RUNNING CONFIG")
cmdList = self.inputWdg.getStringList()
print("command list: " + str(cmdList))
for cmdStr in cmdList:
print("waitCMD");
yield sr.waitCmd(
actor = self.getActorForCommand(cmdStr),
cmdStr = cmdStr,
)
print("waitCMD after");