-
Notifications
You must be signed in to change notification settings - Fork 101
Python Compatibility
For PINT, we recommend following the writing portable code practices as specified by the Astropy project.
The target Python releases are:
-
Python 2: 2.6 or newer. This allows to make PINT function in "reasonably" old Linux machines
-
Python 3: 3.3 or newer.
This allows for easier writing of code that is portable between different Python versions. The recommended workflow is to write Python 3 code that is compatible with Python 2, rather than vice versa.
A good start for Python 2/3 compatibility is adding the following line at the very top of each Python source:
#!python
from __future__ import (print_function, division, unicode_literals,
absolute_import)
This will allow to make the new syntax introduced by Python 3 work also on Python 2, making the code automatically compatible with the two versions.
While in Python 2 the division between two integers is always the integer part of the result (4/3 = 1), in Python 3 this has changed and now division correctly returns a float if required (4/3=1.33333...). Adding division
to the __future__
imports makes division work this way also in Python 2. To execute an integer division, the operation is now a//b
.
print
is a function in Python 3. This means that while in Python 2 (without the print_function
import from 'future') we wrote
#!python
print a
we now write
#!python
print(a)
print a,
(a way not to print a newline at the end of the print) now becomes print(a, end='')
.
print >>fobj, a
now becomes print(a, file=fobj)
In Python 3, strings are by default Unicode while in Python 2 they were by default byte strings. By adding the from __future__ import unicode_literals
, one instates the Python 3 behavior in all Python versions. To specify byte strings, now one has to add a letter b
in front of the string: b'This is a byte string'
[... Add about the use of str()
, the elimination of basestring
, and so on]
Format specifications with the new mini-language are encouraged. Example:
print('Result: {0} # {1}'.format(result, comment))
From Python 2.7 on, the '0' and '1' above can be omitted (Result: {} # {}
will produce the same output). Keep in mind, however, that this will not work in Python 2.6.
Since Python 2.7, relative imports are allowed by default. PINT uses them, e.g. in models/spindown.py
:
#!python
from .parameter import Parameter, MJDParameter
from .timing_model import TimingModel, MissingParameter
This is incompatible out-of-the-box with Python 2.6, but adding the from __future__ import absolute_import
line makes it work in Python 2.5 or newer.
pickle
is called cPickle
in Python 2 and pickle
in Python 3. A workaround might be
#!python
try:
# Python 2
import cPickle as pickle
except:
# Python 3
import pickle