PySCeS / pysces

The official PySCeS project source code repository.
https://pysces.github.io
Other
34 stars 10 forks source link

Towards Python 3: print and except #26

Closed bgoli closed 4 years ago

bgoli commented 7 years ago

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))


exceptions
------------
- update exceptions to use new style

try: import blah except ImportError, ex: print ex

try: import blah except ImportError as ex: print(ex)

jmrohwer commented 7 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:

  1. How to go about this? It is a lot of work and neither I nor Carl have time to do this on our own. We could however, chip in, or at least make a plan to try to. It is important. Maybe there are some conversion tools available that will do a chunk of this automatically? (I haven't looked at this at all).
  2. It may be a good idea at the same time to implement a pyscesprint() method, which basically calls print() but has an option to be silenced (see discussion in #23 ).
  3. If we are going to refactor, it may be useful to distinguish between informative messages (which should be able to be turned off) and error messages (which should always be displayed). Maybe making use of 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.

bgoli commented 7 years ago

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_ 2) sort out print(), Exceptions, Dictionaries (auto-convert, do manually, 2to3, whatever) but, 3) test changes to make sure they don't mess with the Python 2 functionality 4) crude test with Python 3 using 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?

jmrohwer commented 7 years ago

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.

bgoli commented 7 years ago

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

jmrohwer commented 5 years ago

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.

bgoli commented 5 years ago

Great, Python 3.6+ seems, finally, the way to go now. Let me know if I can help out.

jmrohwer commented 5 years ago

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.

jmrohwer commented 5 years ago

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?

bgoli commented 5 years ago

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

jmrohwer commented 4 years ago

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.