Closed bgoli closed 4 years ago
I agree that Python3 compatibility is important and this is a crucial step in that direction. The whole scientific Python stack is now available in Python 3, the latest IPython only supports Python 3, and other software we are using in the lab (NMRPy) only works in Python 3. So our workflow for analysing NMR kinetics data and fitting parameters with PySCeS now involves an initial Python 3 step, pickling of intermediate data structures, and then fitting in Python 2, which is less than ideal!
Three points:
pyscesprint()
method, which basically calls print()
but has an option to be silenced (see discussion in #23 ).sys.stdout
and sys.stderr
which you can pass as arguments to the file=
parameter of the print()
function. What do you think?Coming to think of it, a separate pyscesprint()
function may not even be necessary. If we make sure that all error messages are in fact printed to stderr, then the silencing function could just kill stdout output, much like Carl's silence_print
in PySCeSToolbox.
I once tried an automatic converter and had mixed success, the general stuff is print()
, Exception as
and dictionary related irritations for a in D
replaced by for a in list(D)
if you are modifying the dictionary, getting rid of dict.has_key()
.
There are also some modules that have changed names/structure and some other things that might need specific attention as well as the whole relative import thing can be irritating. We will also have to work through the included dependencies: PLY, Scientific Python etc. Some tricky things might lurk within the eval code.
With CBMPy I write the code so it is 2 and 3 compatible as it is insane to make things Python 3 only or maintain dual code-bases (I'm not convinced about things like six but haven't tried it for a long time) using the the following restrictions:
from __future__ import division, print_function
from __future__ import absolute_import
from __future__ import unicode_literals
So with PySCeS I suggest we start with the first two and work from there. What I suggest is we do this by divide and conquer, whenever someone has time they work on a module (file) and do the following (start with the easy ones and leave core modules for last):
1) one branch per file that is being worked on until it is complete, branch as py3_Python2.7 -3 testscript.py
5) make a note of and fix any further things that need to be changed
When the file is converted and tested merge it back in fix everything that we broke and see what happens.
Do you think something like this could work?
Sounds like a plan! The only modules I have really looked at in detail are PyscesScan, PyscesParscan and PyscesParse, and of course PyscesModel (but I suppose that one will be looked at last), so I'd be prepared to give those a try. Also if we are in cleanup mode I guess we should deprecate RateChar since it's been superseded by psctb.
Sounds good. I have the feeling PyscesModel will have some strange stuff so let's wait with that, I've just downloaded the latest PLY which is also Py2/3 compatible so will push that up shortly to start with then look at the other lib/* stuff
On the current py3
branch both level 1 and level 2 tests now pass! Am busy looking at level 3 tests. This is maybe not so bit a deal as originally anticipated.
Great, Python 3.6+ seems, finally, the way to go now. Let me know if I can help out.
Okay, this now builds and installs perfectly under python3 (I have also updated setup.py), and all the tests (up to level 3) pass. You could definitely help by starting to test functionality for which no prebuilt tests are there. If you cant fix it immediately, open an issue. I will do so on my side as well, starting with the parallel stuff.
By the way, if this turns out to be really easy, I see no point in maintaining a py2 and py3 code base, as the end of life for py2 is 1/1/2020. I haven't yet tested if the py3 branch code still runs under py2. If it does (we might have to put the future imports at the start of every file), then that's fine, but I would not go out of my way to try and keep this. There is a perfectly functional current version that runs on py2.7 and can continue to be used. Your ideas?
I agree, we can maintain parallel branches for a while if it is not too much effort and any new stuff goes into the Py3 version
Cleanup, this issue is obsolete since the port to Python 3 is done and the same code base can run under 2.7 and 3.x.
While it will take quite a bit of work we can start thinking about moving towards a Python 3 PySCeS. Some very basic things that need to change (and should be used with any new code)
print
print('You are using NumPy ({}) with SciPy ({})'.format(numpy.version, scipy.version))
try: import blah except ImportError, ex: print ex
try: import blah except ImportError as ex: print(ex)