Skip to content
Snippets Groups Projects
Unverified Commit 468081fd authored by Pete Peterson's avatar Pete Peterson Committed by GitHub
Browse files

Merge pull request #22111 from mantidproject/22109_add_python_3_dev_docs

Add Python3 Developer Documentation
parents 47cd8540 d4d8bada
No related merge requests found
========
Python 3
========
Python 2 has an `end-of-life date set for 2020 <http://legacy.python.org/dev/peps/pep-0373/>`_
and now that most third-party packages support both 2 and 3 we are starting to think about a
migration strategy for Mantid.
.. contents::
:local:
Building Against Python 3
#########################
This is currently only possible on a Linux system with a pre-installed version of python 3. You need
to install some additional packages as shown below:
.. code-block:: sh
apt-get install python3-sip-dev python3-pyqt4 python3-numpy python3-scipy python3-sphinx \
python3-sphinx-bootstrap-theme python3-dateutil python3-matplotlib ipython3-qtconsole \
python3-h5py python3-yaml
or on fedora, with slightly different package names
.. code-block:: sh
dnf install python3-sip-devel python3-PyQt4-devel python3-numpy python3-scipy python3-sphinx \
python3-sphinx-theme-bootstrap python3-dateutil python3-matplotlib python3-ipython-gui \
boost-python3-devel python3-h5py python3-yaml
then set ``-DPYTHON_EXECUTABLE=/usr/bin/python3`` when running cmake before building.
.. warning::
If any of these packages are installed via pip, this could cause conflicts.
Install as described here only.
Supporting Python 2 and 3
#########################
Python 3 introduces many exciting new features. For a full description see the official Python 3
changes document. For a shorter overview see
`here <https://asmeurer.github.io/python3-presentation/slides.html#1>`__ or
`here <http://python3porting.com/differences.html>`__.
Some features of Python 3 have been backported to Python 2.x within the
`__future__ <https://docs.python.org/2.7/library/__future__.html?highlight=future#module-__future__>`_
module. These make it easier to write code that is compatible with both versions.
This cheat sheet provides helpful examples of how to write code in a 2/3 compatible manner. Where an
option is given to use either the `six <https://pythonhosted.org/six/>`_ or
`future <https://pypi.python.org/pypi/future>`_ (not to be confused with ``__future__``!) modules
then ``six`` is used.
All new code should be written to be compatible with Python 2 & 3 and as a minimum the first import
line of the module should be:
.. code-block:: python
from __future__ import (absolute_import, division, print_function)
It is quite common to also see ``unicode_literals`` in the above import list, however, when running
under Python 2 ``Boost.Python`` will not automatically convert a Python ``str`` to C++ ``std::string``
automatically if the string is unicode. When running with Python 3 ``Boost.Python`` will do this
conversion automatically for unicode strings so this is in fact not a huge issue going forward.
Migrating From Python 2 to 3
############################
One way to migrate a file from python 2 to 3 is as follows...
.. warning::
| To perform the following procedure on windows:
| 1. Git Bash or similar will be required.
| 2. To run the ``2to3`` script you will need to start the command-prompt.bat in the build directory and run ``%PYTHONHOME%\Scripts\2to3``
Run the following script to run the python 2 to 3 translation tool and rename the file to ``filename.py.bak``
.. code-block:: sh
2to3 --no-diffs -w filename.py
mv filename.py{,.bak};
Run **one** of the following commands to append the import statement listed above.
.. code-block:: sh
awk '/(from|import)/ && !x {print "from __future__ import (absolute_import, division, print_function)\n"; x=1} 1' \
filename.py.bak > filename.py
**or**
.. code-block:: sh
sed -i '0,/^import\|from.*/s/^import\|from.*/from __future__ import (absolute_import, division, print_function)\n&/' filename.py
Check each changed block,
- If any change has replaced ``xrange`` with ``range`` then add ``from six.moves import range``
to the imports list
- If any change has replaced ``ifilterfalse`` with ``filterfalse`` from ``itertools`` then replace a
statement like ``from itertools import filterfalse`` with ``from six.moves import filterfalse`` in the
imports list. There are more cases like this documented `here <https://pythonhosted.org/six/#module-six.moves>`_.
- If any change has replaced ``for k, v in knights.iteritems()`` with ``for k, v in knights.items()``
then add ``from six import iteritems`` to the import list and update the replacement to
``for k, v in iteritems(knights)``.
In some cases like ``range``, pylint will complain about `Replacing builtin 'range'` or similar.
Make sure to put the proper ignore statement on that line using ``#pylint: disable=redefined-builtin``.
Check the code still runs as expected in Python 2.
.. note::
``2to3`` will try to keep the type of the objects the same. So, for example ``range(5)`` will
become ``list(range(5))``. This is not necessary if you use it just for iteration. Things like
``for i in range(5)`` will work in both versions of Python, you don't need to transform it into a
list.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment