From bd6663da3061e1dcc7118b36821d27d394b37b89 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 19:08:42 +0100 Subject: [PATCH 01/25] Fix implicit relative import in the PDB parser --- package/MDAnalysis/coordinates/PDB.py | 6 +++--- package/MDAnalysis/coordinates/pdb/__init__.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 3a3239a86ba..8138d3e4812 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -201,7 +201,7 @@ try: # BioPython is overkill but potentially extensible (altLoc etc) import Bio.PDB - import pdb.extensions + from . import pdb # disable PDBConstructionWarning from picky builder import warnings @@ -1114,7 +1114,7 @@ def _write_timestep(self, ts, multiframe=False): vals['element'] = guess_atom_element(atom.name.strip())[:2] vals['charge'] = 0 - # .. _ATOM: http://www.wwpdb.org/documentation/format32/sect9.html + # .. _ATOM: http://www.wwpdb.org/documentation/format32/sect9.html self.pdbfile.write(self.fmt['ATOM'].format(**vals)) if multiframe: self.ENDMDL() diff --git a/package/MDAnalysis/coordinates/pdb/__init__.py b/package/MDAnalysis/coordinates/pdb/__init__.py index 475243d3add..91c033d99c8 100644 --- a/package/MDAnalysis/coordinates/pdb/__init__.py +++ b/package/MDAnalysis/coordinates/pdb/__init__.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -17,4 +17,4 @@ """Helper module for handling PDB files.""" -import extensions +from . import extensions From 756ca76360a1e9e51dfbf4a0f99db244e1a124e7 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 19:11:08 +0100 Subject: [PATCH 02/25] Fix print for py3 in LAMMPS topology parser Why is there a print here anyway? --- package/MDAnalysis/topology/LAMMPSParser.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package/MDAnalysis/topology/LAMMPSParser.py b/package/MDAnalysis/topology/LAMMPSParser.py index c9bdb2e61df..27514afef42 100644 --- a/package/MDAnalysis/topology/LAMMPSParser.py +++ b/package/MDAnalysis/topology/LAMMPSParser.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -36,7 +36,7 @@ :members: """ -from __future__ import absolute_import +from __future__ import absolute_import, print_function from six.moves import range @@ -143,7 +143,7 @@ def iterdata(self): for line in f: line = line.partition('#')[0].strip() if line: - yield line + yield line def grab_datafile(self): """Split a data file into dict of header and sections @@ -296,7 +296,7 @@ def _parse_section(self, datalines, nentries): for line in datalines: line = line.split() # map to 0 based int - section.append(tuple(map(lambda x: int(x) - 1, + section.append(tuple(map(lambda x: int(x) - 1, line[2:2 + nentries]))) return tuple(section) @@ -530,7 +530,7 @@ def __init__(self, filename=None): data = [] for i in range(headers["atom type"]): fields = file_iter.next().strip().split() - print "help" + print("help") self.positions = positions def writePSF(self, filename, names=None): From 0f4eec11260cd9e6f3540b95405cc5111a578354 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 19:12:29 +0100 Subject: [PATCH 03/25] Make some coordinate parser optional on Py3 The DCD parser is not compatible with python 3, this commit makes it optional on that version of python. As the LAMPPS coordinate parser uses the DCD parser, it is made optional as well. The TRZ parser requires some small modifications to be compatible. It is made optional until is can be tested. --- package/MDAnalysis/coordinates/__init__.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/package/MDAnalysis/coordinates/__init__.py b/package/MDAnalysis/coordinates/__init__.py index c9f59b97546..cb844149923 100644 --- a/package/MDAnalysis/coordinates/__init__.py +++ b/package/MDAnalysis/coordinates/__init__.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -274,7 +274,7 @@ In various places, MDAnalysis tries to automatically select appropriate formats (e.g. by looking at file extensions). In order to allow it to choose the -correct format, all I/O classes must subclass either +correct format, all I/O classes must subclass either :class:`MDAnalysis.coordinates.base.ProtoReader` or :class:`MDAnalysis.coordinates.base.Writer` and set the `format` attribute with a string defining the expected suffix. @@ -678,22 +678,31 @@ _SINGLEFRAME_WRITERS = {} _MULTIFRAME_WRITERS = {} +import six + from . import base from .core import reader, writer from . import CRD -from . import DCD from . import DLPoly from . import DMS from . import GMS from . import GRO from . import INPCRD -from . import LAMMPS from . import MOL2 from . import PDB from . import PDBQT from . import PQR from . import TRJ from . import TRR -from . import TRZ from . import XTC from . import XYZ + +try: + from . import DCD + from . import LAMMPS + from . import TRZ +except ImportError as e: + # The import is expected to fail under Python 3. + # It should not fail on Python 2, however. + if six.PY2: + raise e From 36a38a518579f2f29251a76172f89a863b2da29b Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 19:47:53 +0100 Subject: [PATCH 04/25] Fix implicit relative import in test plugins --- testsuite/MDAnalysisTests/plugins/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testsuite/MDAnalysisTests/plugins/__init__.py b/testsuite/MDAnalysisTests/plugins/__init__.py index 12e620f108a..efcb2e7a5ec 100644 --- a/testsuite/MDAnalysisTests/plugins/__init__.py +++ b/testsuite/MDAnalysisTests/plugins/__init__.py @@ -76,7 +76,7 @@ def _nose_config(): """Function that exposes nose's configuration via a hack in one of our plugins - + The external plugins managed by this module are scanned for the :attr:`config` attribute, which at least one should implement upon configuration. Plugins need only to be loaded for this to work, not necessarily enabled. @@ -88,7 +88,7 @@ def _nose_config(): def _check_plugins_loaded(): """Function that checks whether external plugins were loaded. - + It can be used to ascertain whether nose tests were launched using `nosetests` from the command-line, and hence that external plugins aren't available. @@ -103,7 +103,7 @@ def _check_plugins_loaded(): loaded_plugins = dict() # ADD HERE your plugin import -import memleak, capture_err, knownfailure +from . import memleak, capture_err, knownfailure plugin_classes = [] for plugin in __all__: From 7b1fded506274a4d3fd29139346a4117a499a29b Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 19:48:26 +0100 Subject: [PATCH 05/25] Replace iteritems with six.iteritems See #632 --- package/MDAnalysis/analysis/hbonds/hbond_analysis.py | 10 +++++----- package/MDAnalysis/analysis/psa.py | 6 +++--- package/MDAnalysis/coordinates/XDR.py | 4 +++- package/MDAnalysis/topology/core.py | 9 +++++---- package/MDAnalysis/visualization/streamlines_3D.py | 8 ++++---- testsuite/MDAnalysisTests/coordinates/test_xdr.py | 12 +++++++----- testsuite/MDAnalysisTests/plugins/capture_err.py | 2 +- testsuite/MDAnalysisTests/test_streamio.py | 3 ++- testsuite/MDAnalysisTests/test_units.py | 3 ++- 9 files changed, 32 insertions(+), 25 deletions(-) diff --git a/package/MDAnalysis/analysis/hbonds/hbond_analysis.py b/package/MDAnalysis/analysis/hbonds/hbond_analysis.py index d7132d859e3..ab6d5e45427 100644 --- a/package/MDAnalysis/analysis/hbonds/hbond_analysis.py +++ b/package/MDAnalysis/analysis/hbonds/hbond_analysis.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -309,10 +309,10 @@ class HydrogenBondAnalysis_OtherFF(HydrogenBondAnalysis): .. automethod:: _get_bonded_hydrogens_list """ - +import six +from six.moves import range, zip, map from collections import defaultdict -from six.moves import range, zip, map import numpy as np import warnings import logging @@ -1050,7 +1050,7 @@ def count_by_type(self): # float because of division later tsteps = float(len(self.timesteps)) - for cursor, (key, count) in enumerate(hbonds.iteritems()): + for cursor, (key, count) in enumerate(six.iteritems(hbonds)): out[cursor] = key + (count / tsteps,) # return array as recarray @@ -1109,7 +1109,7 @@ def timesteps_by_type(self): out = np.empty((out_nrows,), dtype=dtype) out_row = 0 - for (key, times) in hbonds.iteritems(): + for (key, times) in six.iteritems(hbonds): for tstep in times: out[out_row] = key + (tstep,) out_row += 1 diff --git a/package/MDAnalysis/analysis/psa.py b/package/MDAnalysis/analysis/psa.py index f66db0ca5ae..11c188c7f60 100644 --- a/package/MDAnalysis/analysis/psa.py +++ b/package/MDAnalysis/analysis/psa.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -217,7 +217,7 @@ .. |Np| replace:: :math:`N_p` """ - +import six from six.moves import range import numpy as np @@ -1144,7 +1144,7 @@ def __init__(self, universes, reference=None, ref_select='name CA', 'paths' : '/paths', 'distance_matrices' : '/distance_matrices', 'plots' : '/plots'} - for dir_name, directory in self.datadirs.iteritems(): + for dir_name, directory in six.iteritems(self.datadirs): try: full_dir_name = os.path.join(self.targetdir, dir_name) os.makedirs(full_dir_name) diff --git a/package/MDAnalysis/coordinates/XDR.py b/package/MDAnalysis/coordinates/XDR.py index 3373ee677a2..bdc1dda60fb 100644 --- a/package/MDAnalysis/coordinates/XDR.py +++ b/package/MDAnalysis/coordinates/XDR.py @@ -13,6 +13,8 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # +import six + import errno import numpy as np from os.path import getctime, getsize, isfile, split, join @@ -92,7 +94,7 @@ def _load_offsets(self): return with open(fname) as f: - data = {k: v for k, v in np.load(f).iteritems()} + data = {k: v for k, v in six.iteritems(np.load(f))} ctime_ok = getctime(self.filename) == data['ctime'] size_ok = getsize(self.filename) == data['size'] diff --git a/package/MDAnalysis/topology/core.py b/package/MDAnalysis/topology/core.py index 29a5fea4add..40b08e8c94e 100644 --- a/package/MDAnalysis/topology/core.py +++ b/package/MDAnalysis/topology/core.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -26,6 +26,7 @@ """ from __future__ import print_function +import six # Global imports import os.path @@ -72,7 +73,7 @@ def build_segments(atoms): # We've come to a new segment # Build the Segment we just left residues = [AtomGroup.Residue(ats[0].resname, k, ats) - for k, ats in resatomlist.iteritems()] + for k, ats in six.iteritems(resatomlist)] struc.append(AtomGroup.Segment(curr_segname, residues)) # Reset things and start again @@ -82,7 +83,7 @@ def build_segments(atoms): # Add the last segment residues = [AtomGroup.Residue(ats[0].resname, k, ats) - for k, ats in resatomlist.iteritems()] + for k, ats in six.iteritems(resatomlist)] struc.append(AtomGroup.Segment(curr_segname, residues)) return struc @@ -106,7 +107,7 @@ def build_residues(atoms): resatomlist[a.resid].append(a) residues = [AtomGroup.Residue(ats[0].resname, k, ats) - for k, ats in resatomlist.iteritems()] + for k, ats in six.iteritems(resatomlist)] return residues diff --git a/package/MDAnalysis/visualization/streamlines_3D.py b/package/MDAnalysis/visualization/streamlines_3D.py index 2ce1891157f..dc633339abb 100644 --- a/package/MDAnalysis/visualization/streamlines_3D.py +++ b/package/MDAnalysis/visualization/streamlines_3D.py @@ -1,5 +1,5 @@ # -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*- -# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 +# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 # # MDAnalysis --- http://www.MDAnalysis.org # Copyright (c) 2006-2015 Naveen Michaud-Agrawal, Elizabeth J. Denning, Oliver Beckstein @@ -26,7 +26,7 @@ .. autofunction:: generate_streamlines_3d ''' - +import six from six.moves import range import MDAnalysis @@ -198,7 +198,7 @@ def update_dictionary_point_in_cube_start_frame(array_simulation_particle_coordi corresponding to the indices of the relevant particles that fall within a given cube. Also, for a given cube, store a key/value pair for the centroid of the particles that fall within the cube.''' cube_counter = 0 - for key, cube in dictionary_cube_data_this_core.iteritems(): + for key, cube in six.iteritems(dictionary_cube_data_this_core): index_list_in_cube = point_in_cube(array_simulation_particle_coordinates, cube['vertex_list'], cube['centroid']) cube['start_frame_index_list_in_cube'] = index_list_in_cube @@ -213,7 +213,7 @@ def update_dictionary_point_in_cube_start_frame(array_simulation_particle_coordi def update_dictionary_end_frame(array_simulation_particle_coordinates, dictionary_cube_data_this_core): '''Update the cube dictionary objects again as appropriate for the second and final frame.''' cube_counter = 0 - for key, cube in dictionary_cube_data_this_core.iteritems(): + for key, cube in six.iteritems(dictionary_cube_data_this_core): # if there were no particles in the cube in the first frame, then set dx,dy,dz each to 0 if cube['centroid_of_particles_first_frame'] == 'empty': cube['dx'] = 0 diff --git a/testsuite/MDAnalysisTests/coordinates/test_xdr.py b/testsuite/MDAnalysisTests/coordinates/test_xdr.py index 0b7aa050017..09898b8af1f 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_xdr.py +++ b/testsuite/MDAnalysisTests/coordinates/test_xdr.py @@ -1,10 +1,12 @@ +import six +from six.moves import zip, range + import errno import MDAnalysis as mda from MDAnalysis.coordinates.base import Timestep import numpy as np import os import shutil -from six.moves import zip, range import warnings from nose.plugins.attrib import attr @@ -727,7 +729,7 @@ def test_offsets(self): outfile_offsets = XDR.offsets_filename(self.traj) with open(outfile_offsets) as f: - saved_offsets = {k: v for k, v in np.load(f).iteritems()} + saved_offsets = {k: v for k, v in six.iteritems(np.load(f))} assert_array_almost_equal(self.trajectory._xdr.offsets, saved_offsets['offsets'], @@ -752,7 +754,7 @@ def test_persistent_offsets_size_mismatch(self): # size differs from stored size fname = XDR.offsets_filename(self.traj) with open(fname) as f: - saved_offsets = {k: v for k, v in np.load(f).iteritems()} + saved_offsets = {k: v for k, v in six.iteritems(np.load(f))} saved_offsets['size'] += 1 with open(fname, 'w') as f: np.savez(f, **saved_offsets) @@ -769,7 +771,7 @@ def test_persistent_offsets_ctime_mismatch(self): # ctime differs from stored ctime fname = XDR.offsets_filename(self.traj) with open(fname) as f: - saved_offsets = {k: v for k, v in np.load(f).iteritems()} + saved_offsets = {k: v for k, v in six.iteritems(np.load(f))} saved_offsets['ctime'] += 1 with open(fname, 'w') as f: np.savez(f, **saved_offsets) @@ -790,7 +792,7 @@ def test_persistent_offsets_ctime_mismatch(self): # # check that stored offsets are not loaded when the offsets # # themselves appear to be wrong # with open(XDR.offsets_filename(self.traj), 'rb') as f: - # saved_offsets = {k: v for k, v in np.load(f).iteritems()} + # saved_offsets = {k: v for k, v in six.iteritems(np.load(f))} # saved_offsets['offsets'] += 1 # with open(XDR.offsets_filename(self.traj), 'wb') as f: # np.savez(f, **saved_offsets) diff --git a/testsuite/MDAnalysisTests/plugins/capture_err.py b/testsuite/MDAnalysisTests/plugins/capture_err.py index 2ea850c9e21..3cc1bc9f0df 100644 --- a/testsuite/MDAnalysisTests/plugins/capture_err.py +++ b/testsuite/MDAnalysisTests/plugins/capture_err.py @@ -27,7 +27,7 @@ from nose.plugins.base import Plugin from nose.pyversion import exc_to_unicode, force_unicode from nose.util import ln -from StringIO import StringIO +from six import StringIO class CaptureStdErr(Plugin): """ diff --git a/testsuite/MDAnalysisTests/test_streamio.py b/testsuite/MDAnalysisTests/test_streamio.py index e7357741b3a..176a08e16ab 100644 --- a/testsuite/MDAnalysisTests/test_streamio.py +++ b/testsuite/MDAnalysisTests/test_streamio.py @@ -13,6 +13,7 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # +import six from six.moves import range import numpy as np @@ -262,7 +263,7 @@ class _StreamData(object): def __init__(self): self.buffers = dict( - (name, "".join(open(fn).readlines())) for name, fn in self.filenames.iteritems()) + (name, "".join(open(fn).readlines())) for name, fn in six.iteritems(self.filenames)) self.filenames['XYZ_PSF'] = "bogus/path/mini.psf" self.buffers['XYZ_PSF'] = """\ PSF CMAP diff --git a/testsuite/MDAnalysisTests/test_units.py b/testsuite/MDAnalysisTests/test_units.py index afd2bc2b1da..a9d60200f03 100644 --- a/testsuite/MDAnalysisTests/test_units.py +++ b/testsuite/MDAnalysisTests/test_units.py @@ -14,6 +14,7 @@ # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # from __future__ import unicode_literals +import six import numpy as np from numpy.testing import * @@ -62,7 +63,7 @@ class TestConstants(object): } def test_constant(self): - for name, value in self.constants_reference.iteritems(): + for name, value in six.iteritems(self.constants_reference): yield self.check_physical_constant, name, value @staticmethod From da8bfa548bf9a018141affacc082c4996624e557 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Fri, 22 Jan 2016 21:02:50 +0100 Subject: [PATCH 06/25] Fix how unicode Angstrom symbol is encoded The unicode representation for the Angstrom symbol in the dictionary used for unit conversion was wrong. While the escaping sequence was correct, it was used as a series of bytes rather than like a unicode string. Also, the same key was created twice as two escaping sequences were used (utf-16 and utf-8) and they were synonymous. The tests were passing because they were testing against the same series of bytes. This commit use a proper unicode string as key and remove the redundant definition. It also adds a test with the actual unicode symbol rather than an escaping sequence. --- package/MDAnalysis/units.py | 2 +- testsuite/MDAnalysisTests/test_units.py | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/package/MDAnalysis/units.py b/package/MDAnalysis/units.py index 06876383bba..771c0bf03ce 100644 --- a/package/MDAnalysis/units.py +++ b/package/MDAnalysis/units.py @@ -195,7 +195,7 @@ #: *x* can be *nm*/*nanometer* or *fm*. lengthUnit_factor = { 'Angstrom': 1.0, 'A': 1.0, 'angstrom': 1.0, - '\u212b': 1.0, b'\xe2\x84\xab': 1.0, # Unicode and UTF-8 encoded symbol for angstroms + u'\u212b': 1.0, # Unicode and UTF-8 encoded symbol for angstroms 'nm': 1.0 / 10, 'nanometer': 1.0 / 10, 'pm': 1e2, 'picometer': 1e2, 'fm': 1e5, 'femtometer': 1e5, diff --git a/testsuite/MDAnalysisTests/test_units.py b/testsuite/MDAnalysisTests/test_units.py index a9d60200f03..09f2465e946 100644 --- a/testsuite/MDAnalysisTests/test_units.py +++ b/testsuite/MDAnalysisTests/test_units.py @@ -26,27 +26,33 @@ class TestDefaultUnits(TestCase): def testLength(self): assert_equal(flags['length_unit'], 'Angstrom', - b"The default length unit should be Angstrom (in core.flags)") + u"The default length unit should be Angstrom (in core.flags)") def testTime(self): assert_equal(flags['time_unit'], 'ps', - b"The default length unit should be pico seconds (in core.flags)") + u"The default length unit should be pico seconds (in core.flags)") def testConvertGromacsTrajectories(self): assert_equal(flags['convert_lengths'], True, - b"The default behaviour should be to auto-convert Gromacs trajectories") + u"The default behaviour should be to auto-convert Gromacs trajectories") class TestUnitEncoding(TestCase): def testUnicode(self): try: - assert_equal(units.lengthUnit_factor["\u212b"], 1.0) + assert_equal(units.lengthUnit_factor[u"\u212b"], 1.0) except KeyError: raise AssertionError("Unicode symbol for Angtrom not supported") def testUTF8Encoding(self): try: - assert_equal(units.lengthUnit_factor[b"\xe2\x84\xab"], 1.0) + assert_equal(units.lengthUnit_factor[b'\xe2\x84\xab'.decode('utf-8')], 1.0) + except KeyError: + raise AssertionError("UTF-8-encoded symbol for Angtrom not supported") + + def testUnicodeEncodingWithSymbol(self): + try: + assert_equal(units.lengthUnit_factor[u"Å"], 1.0) except KeyError: raise AssertionError("UTF-8-encoded symbol for Angtrom not supported") From 2dc601cf4d7667ae5d1668a07a37993737bca021 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 10:31:28 +0100 Subject: [PATCH 07/25] Make topology objects hashable on Python 3 On python 2, user defined object are hashable by default unless the __hash__ method is overloaded to return None. On python 3, user objects are not hashable if the __eq__ method is overloaded. This commit defines a __hash__ method that returns a hash based on the sorted indices of the atoms involved in the topology object. This should reproduce the behavior advertised in the topology object documentation. Yet, it is different from the previous behavior. In the previous behavior, two different objects with the same atoms were equal for __eq__ but different regarding the hash. --- package/MDAnalysis/core/topologyobjects.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index c84ad1de955..c1a64cf8f9f 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -124,6 +124,15 @@ def __iter__(self): def __len__(self): return len(self.atoms) + def _cmp_key(self): + """Unique key for the object to be used to generate the object hash""" + # This key must be equal for two object considered as equal by __eq__ + return '_'.join(map(str, sorted(self.indices))) + + def __hash__(self): + """Makes the object hashable""" + return hash(self._cmp_key()) + class Bond(TopologyObject): From 23b8cddebfd6fe23da7d7a7a554242ea466a9194 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 13:28:44 +0100 Subject: [PATCH 08/25] Replace print statement by print function --- README.rst | 2 +- package/MDAnalysis/analysis/gnm.py | 9 ++- package/MDAnalysis/analysis/helanal.py | 77 ++++++++++--------- package/MDAnalysis/analysis/hole.py | 4 +- package/MDAnalysis/analysis/waterdynamics.py | 31 ++++---- package/MDAnalysis/analysis/x3dna.py | 7 +- package/MDAnalysis/coordinates/MOL2.py | 2 +- package/MDAnalysis/coordinates/__init__.py | 2 +- package/MDAnalysis/core/__init__.py | 4 +- .../fixes/fix_framenumberingzerobased2.py | 3 +- package/MDAnalysis/tests/datafiles.py | 19 ++--- .../MDAnalysisTests/formats/test_xdrlib.py | 6 +- 12 files changed, 89 insertions(+), 77 deletions(-) diff --git a/README.rst b/README.rst index eb8908317f6..ef4d2ff065e 100644 --- a/README.rst +++ b/README.rst @@ -28,7 +28,7 @@ lists of supported `trajectory formats`_ and `topology formats`_.) # Iterate through trajectories for ts in u.trajectory: - print ag.center_of_mass() + print(ag.center_of_mass()) Source code =========== diff --git a/package/MDAnalysis/analysis/gnm.py b/package/MDAnalysis/analysis/gnm.py index 5e0ab019306..5f4910b9480 100644 --- a/package/MDAnalysis/analysis/gnm.py +++ b/package/MDAnalysis/analysis/gnm.py @@ -80,6 +80,7 @@ # import copy #unused +from __future__ import print_function from six.moves import range import numpy as np @@ -113,7 +114,7 @@ def backup_file(filename): failure = False break if failure: - print "Too many backups. Clean up and try again" + print("Too many backups. Clean up and try again") exit() @@ -195,7 +196,8 @@ def generate_output(self, w, v, outputobject, time, matrix, nmodes=2, ReportVect if ReportVector: with open(ReportVector, "a") as oup: for item in enumerate(v[list_map[1]]): - print >> oup, "", counter, time, item[0] + 1, w[list_map[1]], item[1] + print("", counter, time, item[0] + 1, + w[list_map[1]], item[1], file=oup) outputobject.append((time, w[list_map[1]], v[list_map[1]])) #outputobject.append((time, [ w[list_map[i]] for i in range(nmodes) ], [ v[list_map[i]] for i in range( # nmodes) ] )) @@ -288,7 +290,8 @@ def _get_timestep(): try: [u, w, v] = linalg.svd(matrix) except linalg.LinAlgError: - print "\nFrame skip at", timestep, "(SVD failed to converge). Cutoff", self.cutoff + print("\nFrame skip at", timestep, + "(SVD failed to converge). Cutoff", self.cutoff) continue #Save the results somewhere useful in some useful format. Usefully. self.generate_output(w, v, self.results, timestep, matrix, ReportVector=self.ReportVector, counter=counter) diff --git a/package/MDAnalysis/analysis/helanal.py b/package/MDAnalysis/analysis/helanal.py index 014b685f016..8f0cb6b3987 100644 --- a/package/MDAnalysis/analysis/helanal.py +++ b/package/MDAnalysis/analysis/helanal.py @@ -109,7 +109,7 @@ .. autofunction:: helanal_main """ - +from __future__ import print_function from six.moves import range import os @@ -316,31 +316,32 @@ def helanal_trajectory(universe, selection="name CA", start=None, end=None, begi #print out rotations across the helix to a file with open(twist_filename, "a") as twist_output: - print >> twist_output, frame, + print(frame, end='', file=twist_output) for loc_twist in twist: - print >> twist_output, loc_twist, - print >> twist_output, "" + print(loc_twist, end='', file=twist_output) + print("", file=twist_output) with open(bend_filename, "a") as bend_output: - print >> bend_output, frame, + print(frame, end='', file=bend_output) for loc_bend in bending_angles: - print >> bend_output, loc_bend, - print >> bend_output, "" + print(loc_bend, end='', file=bend_output) + print("", file=bend_output) with open(screw_filename, "a") as rot_output: - print >> rot_output, frame, + print(frame, end='', file=rot_output) for rotation in local_screw_angles: - print >> rot_output, rotation, - print >> rot_output, "" + print(rotation, end='', file=rot_output) + print("", file=rot_output) with open(tilt_filename, "a") as tilt_output: - print >> tilt_output, frame, + print(frame, end='', file=tilt_output) for tilt in local_helix_axes: - print >> tilt_output, np.rad2deg(mdamath.angle(tilt, ref_axis)), - print >> tilt_output, "" + print(np.rad2deg(mdamath.angle(tilt, ref_axis)), + end='', file=tilt_output) + print("", file=tilt_output) with open(fitted_tilt_filename, "a") as tilt_output: - print >> tilt_output, frame, np.rad2deg(fit_tilt) + print(frame, np.rad2deg(fit_tilt), file=tilt_output) if len(global_bending) == 0: global_bending = [[] for item in bending_angles] @@ -360,26 +361,26 @@ def helanal_trajectory(universe, selection="name CA", start=None, end=None, begi bending_statistics_matrix = [[stats(col) for col in row] for row in global_bending_matrix] with open(matrix_filename, 'w') as mat_output: - print >> mat_output, "Mean" + print("Mean", file=mat_output) for row in bending_statistics_matrix: for col in row: formatted_angle = "{0:6.1f}".format(col[0]) - print >> mat_output, formatted_angle, - print >> mat_output, '' + print(formatted_angle, end='', file=mat_output) + print('', file=mat_output) - print >> mat_output, "\nSD" + print('\nSD', file=mat_output) for row in bending_statistics_matrix: for col in row: formatted_angle = "{0:6.1f}".format(col[1]) - print >> mat_output, formatted_angle, - print >> mat_output, '' + print(formatted_angle, end='', file=mat_output) + print('', file=mat_output) - print >> mat_output, "\nABDEV" + print("\nABDEV", file=mat_output) for row in bending_statistics_matrix: for col in row: formatted_angle = "{0:6.1f}".format(col[2]) - print >> mat_output, formatted_angle, - print >> mat_output, '' + print(formatted_angle, end='', file=mat_output) + print('', file=mat_output) logger.info("Height: %g SD: %g ABDEV: %g (Angstroem)", height_mean, height_sd, height_abdev) logger.info("Twist: %g SD: %g ABDEV: %g", twist_mean, twist_sd, twist_abdev) @@ -401,29 +402,31 @@ def helanal_trajectory(universe, selection="name CA", start=None, end=None, begi logger.info(output) with open(summary_filename, 'w') as summary_output: - print >> summary_output, "Height:", height_mean, "SD", height_sd, "ABDEV", height_abdev, '(nm)' - print >> summary_output, "Twist:", twist_mean, "SD", twist_sd, "ABDEV", twist_abdev - print >> summary_output, "Residues/turn:", rnou_mean, "SD", rnou_sd, "ABDEV", rnou_abdev - print >> summary_output, "Local bending angles:" - residue_statistics = zip(*bending_statistics) + print("Height:", height_mean, "SD", height_sd, "ABDEV", height_abdev, '(nm)', file=summary_output) + print("Twist:", twist_mean, "SD", twist_sd, "ABDEV", twist_abdev, + file=summary_output) + print("Residues/turn:", rnou_mean, "SD", rnou_sd, "ABDEV", rnou_abdev, + file=summary_output) + print("Local bending angles:", file=summary_output) + residue_statistics = list(zip(*bending_statistics)) measure_names = ["Mean ", "SD ", "ABDEV"] - print >> summary_output, "ResID", + print("ResID", end='', file=summary_output) if start is None: for item in range(4, len(residue_statistics[0]) + 4): output = "{0:8d}".format(item) - print >> summary_output, output, + print(output, end='', file=summary_output) else: for item in range(start + 3, len(residue_statistics[0]) + start + 3): output = "{0:8d}".format(item) - print >> summary_output, output, - print >> summary_output, "" + print(output, end='', file=summary_output) + print('', file=summary_output) for measure, name in zip(residue_statistics, measure_names): - print >> summary_output, name, + print(name, end='', file=summary_output) for residue in measure: output = "{0:8.1f}".format(residue) - print >> summary_output, output, - print >> summary_output, '' + print(output, end='', file=summary_output) + print('', file=summary_output) def tilt_correct(number): @@ -596,9 +599,9 @@ def origin_pdb(origins, pdbfile): i = 1 for xyz in origins: tmp = "ATOM {0:3d} CA ALA {1:3d} {2:8.3f}{3:8.3f}{4:8.3f} 1.00 0.00".format(i, i, xyz[0], xyz[1], xyz[2]) - print >> output, tmp + print(tmp, file=output) i += 1 - print >> output, "TER\nENDMDL" + print("TER\nENDMDL", file=output) def main_loop(positions, ref_axis=None): diff --git a/package/MDAnalysis/analysis/hole.py b/package/MDAnalysis/analysis/hole.py index 97528a7f52b..04fb95d831b 100644 --- a/package/MDAnalysis/analysis/hole.py +++ b/package/MDAnalysis/analysis/hole.py @@ -101,8 +101,8 @@ iterate over the sorted profiles (see :meth:`HOLEtraj.sorted_profiles_iter`) :: for q, profile in H: - print "orderparameter = %g" % q - print "min(R) = %g" % profile.radius.min() + print("orderparameter = %g" % q) + print("min(R) = %g" % profile.radius.min()) Data structures diff --git a/package/MDAnalysis/analysis/waterdynamics.py b/package/MDAnalysis/analysis/waterdynamics.py index 0d0edaf5aa1..54b13462b23 100644 --- a/package/MDAnalysis/analysis/waterdynamics.py +++ b/package/MDAnalysis/analysis/waterdynamics.py @@ -82,7 +82,7 @@ #now we print the data ready to graph. The first two columns are the HBLc vs t graph and #the second two columns are the HBLi vs t graph for HBLc, HBLi in HBL_analysis.timeseries: - print i +" "+ HBLc +" "+ i +" "+ HBLi + print(i +" "+ HBLc +" "+ i +" "+ HBLi) i+=1 where HBLc is the value for the continuos hydrogen bond lifetimes and HBLi is the value for the intermittent @@ -106,7 +106,7 @@ #now we print the data ready to graph. The first two columns are WOR_OH vs t graph, #the second two columns are WOR_HH vs t graph and the third two columns are WOR_dip vs t graph for WOR_OH, WOR_HH, WOR_dip in WOR_analysis.timeseries: - print i +" "+ WOR_OH +" "+ i +" "+ WOR_HH +" "+ i +" "+ WOR_dip + print(i +" "+ WOR_OH +" "+ i +" "+ WOR_HH +" "+ i +" "+ WOR_dip) where t0 = 0, tf = 1000 and dtmax = 20. In this way we create 20 windows timesteps (20 values in the x axis), the first window is created with 1000 timestep average (1000/1), the second window is created with 500 @@ -133,7 +133,7 @@ #the seconds two columns are P(cos(theta)) vs cos(theta) for HH vector and thirds two columns #are P(cos(theta)) vs cos(theta) for dipole vector for i in range(bins): - print AD_analysis.graph[0][i] +" "+ AD_analysis.graph[1][i] +" "+ AD_analysis.graph[2][i] + print(AD_analysis.graph[0][i] +" "+ AD_analysis.graph[1][i] +" "+ AD_analysis.graph[2][i]) where P(cos(theta)) is the angular distribution or angular probabilities. @@ -154,7 +154,7 @@ #represents MSD vs t i=0 for msd in MSD_analysis.timeseries: - print i +" "+ msd + print(i +" "+ msd) i += 1 @@ -176,7 +176,7 @@ #represents SP vs t i=0 for sp in SP_analysis.timeseries: - print i +" "+ sp + print(i +" "+ sp) i += 1 .. Output @@ -279,8 +279,9 @@ """ - +from __future__ import print_function from six.moves import range, zip_longest + import numpy as np import multiprocessing @@ -466,8 +467,8 @@ def _HBA(self, ts, conn, universe, selAtom1, selAtom2, quiet=True): h.run(quiet=quiet) break except: - print "error" - print "trying again" + print("error") + print("trying again") sys.stdout.flush() sys.stdout.flush() conn.send(h.timeseries[0]) @@ -486,7 +487,7 @@ def run(self, **kwargs): k=i for j in range(self.nproc): #start - print "ts=",i+1 + print("ts=",i+1) if i >= len(self.universe.trajectory): break conn_parent, conn_child = multiprocessing.Pipe(False) @@ -501,7 +502,7 @@ def run(self, **kwargs): conn_parent)) break except: - print "error in jobs.append" + print("error in jobs.append") jobs[j][0].start() i = i + 1 @@ -673,7 +674,7 @@ def _selection_serial(self,universe,selection_str): selection = [] for ts in universe.trajectory: selection.append(universe.select_atoms(selection_str)) - print ts.frame + print(ts.frame) return selection # Second Legendre polynomial @@ -830,7 +831,7 @@ def _selection_serial(self,universe,selection_str): selection = [] for ts in universe.trajectory: selection.append(universe.select_atoms(selection_str)) - print ts.frame + print(ts.frame) return selection @@ -928,7 +929,7 @@ def _getMeanOnePoint(self,universe,selection1,selection_str,dt,totalFrames): for j in range(totalFrames/dt-1): a = self._getOneDeltaPoint(universe,repInd,j,sumsdt,dt) - print "a=",a + print("a=",a) sumDeltaO += a valOList.append(a) sumsdt += dt @@ -951,7 +952,7 @@ def _selection_serial(self,universe,selection_str): selection = [] for ts in universe.trajectory: selection.append(universe.select_atoms(selection_str)) - print ts.frame + print(ts.frame) return selection def run(self,**kwargs): @@ -1061,7 +1062,7 @@ def _selection_serial(self,universe,selection_str): selection = [] for ts in universe.trajectory: selection.append(universe.select_atoms(selection_str)) - print ts.frame + print(ts.frame) return selection def run(self,**kwargs): diff --git a/package/MDAnalysis/analysis/x3dna.py b/package/MDAnalysis/analysis/x3dna.py index 65620960663..4d886c2b830 100644 --- a/package/MDAnalysis/analysis/x3dna.py +++ b/package/MDAnalysis/analysis/x3dna.py @@ -113,8 +113,9 @@ """ - +from __future__ import print_function from six.moves import range + import glob import os import errno @@ -695,8 +696,8 @@ def run(self, **kwargs): nucleic = self.universe.select_atoms(self.selection) for ts in self.universe.trajectory[start:stop:step]: - print ts.frame - print nucleic.atoms + print(ts.frame) + print(nucleic.atoms) logger.info("X3DNA analysis frame %4d ", ts.frame) fd, pdbfile = tempfile.mkstemp(suffix=".pdb") os.close(fd) diff --git a/package/MDAnalysis/coordinates/MOL2.py b/package/MDAnalysis/coordinates/MOL2.py index 7de6ce7facc..b9e978e0c79 100644 --- a/package/MDAnalysis/coordinates/MOL2.py +++ b/package/MDAnalysis/coordinates/MOL2.py @@ -29,7 +29,7 @@ u = Universe("MDAnalysis/testsuite/MDAnalysisTests/data/mol2/Molecule.mol2") gr = u.select_atoms("not name H*") - print len(u.atoms), len(gr) + print(len(u.atoms), len(gr)) gr.write("Molecule_noh.mol2") .. _MOL2: http://www.tripos.com/data/support/mol2.pdf diff --git a/package/MDAnalysis/coordinates/__init__.py b/package/MDAnalysis/coordinates/__init__.py index cb844149923..714cc2bc522 100644 --- a/package/MDAnalysis/coordinates/__init__.py +++ b/package/MDAnalysis/coordinates/__init__.py @@ -433,7 +433,7 @@ allow iteration from beginning to end:: for ts in trajectory: - print ts.frame + print(ts.frame) ``close()`` close the file and cease I/O diff --git a/package/MDAnalysis/core/__init__.py b/package/MDAnalysis/core/__init__.py index d20673b6348..50c3d147183 100644 --- a/package/MDAnalysis/core/__init__.py +++ b/package/MDAnalysis/core/__init__.py @@ -59,7 +59,7 @@ The entries appear as 'name'-'value' pairs. Flags check values and illegal ones raise a :exc:`ValueError`. Documentation on all flags can be obtained with :: - print MDAnalysis.core.flags.doc() + print(MDAnalysis.core.flags.doc()) List of MDAnalysis flags with default values @@ -100,7 +100,7 @@ class Flags(dict): The entries appear as 'name'-'value' pairs. Flags check values and illegal ones raise a :exc:`ValueError`. Documentation on all flags can be obtained with :: - print MDAnalysis.core.flags.__doc__ + print(MDAnalysis.core.flags.__doc__) New flags are added with the :meth:`Flags.register` method which takes a new :class:`Flag` instance as an argument. diff --git a/package/MDAnalysis/migration/fixes/fix_framenumberingzerobased2.py b/package/MDAnalysis/migration/fixes/fix_framenumberingzerobased2.py index 751da5fe1fa..668bbc9408a 100644 --- a/package/MDAnalysis/migration/fixes/fix_framenumberingzerobased2.py +++ b/package/MDAnalysis/migration/fixes/fix_framenumberingzerobased2.py @@ -2,6 +2,7 @@ run with: python ten2eleven.py -f framenumberingzerobased2 test_dummy_old_MDA_code.py Author: Tyler Reddy ''' +from __future__ import print_function from lib2to3.fixer_base import BaseFix from lib2to3.fixer_util import Name, Call, LParen, RParen, ArgList, Dot @@ -28,7 +29,7 @@ def transform(self, node, results): argstring = '' for leaf in args.leaves(): argstring += leaf.value - print 'argstring:', argstring + print('argstring:', argstring) if '.frame' in argstring: node.set_prefix(comment_string + node.prefix) node.changed() diff --git a/package/MDAnalysis/tests/datafiles.py b/package/MDAnalysis/tests/datafiles.py index eb0dfc5580f..26ad9465dd8 100644 --- a/package/MDAnalysis/tests/datafiles.py +++ b/package/MDAnalysis/tests/datafiles.py @@ -29,18 +29,19 @@ :mod:`MDAnalysisTests` package which must be downloaded from http://pypi.python.org/pypi/MDAnalysisTests and installed. """ +from __future__ import print_function try: from MDAnalysisTests.datafiles import * except ImportError: - print "*** ERROR ***" - print "In order to run the MDAnalysis test cases you must install the" - print "MDAnalysisTestData package (which has been separated from the " - print "library code itself since release 0.7.4). Go to " - print - print " http://pypi.python.org/pypi/MDAnalysisTests" - print - print "and download and install the `MDAnalysisTests-x.y.z.tar.gz'" - print "that matches your MDAnalysis release." + print("*** ERROR ***") + print("In order to run the MDAnalysis test cases you must install the") + print("MDAnalysisTestData package (which has been separated from the ") + print("library code itself since release 0.7.4). Go to ") + print() + print(" http://pypi.python.org/pypi/MDAnalysisTests") + print() + print("and download and install the `MDAnalysisTests-x.y.z.tar.gz'") + print("that matches your MDAnalysis release.") raise ImportError("MDAnalysisTests package not installed.") diff --git a/testsuite/MDAnalysisTests/formats/test_xdrlib.py b/testsuite/MDAnalysisTests/formats/test_xdrlib.py index bafd8af9f40..291f9de2354 100644 --- a/testsuite/MDAnalysisTests/formats/test_xdrlib.py +++ b/testsuite/MDAnalysisTests/formats/test_xdrlib.py @@ -13,6 +13,8 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # +from __future__ import print_function + from nose.tools import raises from numpy.testing import assert_equal, assert_array_equal from numpy.testing import assert_array_almost_equal @@ -120,7 +122,7 @@ def test_read_multi_frame_xtc(): ones = np.ones(30).reshape(10, 3) box_compare = np.eye(3) * 20 for i, frame in enumerate(f): - print i + print(i) xyz, box, step, time, prec = frame assert_array_almost_equal(xyz, ones * i, decimal=3) assert_array_almost_equal(box, box_compare, decimal=3) @@ -142,7 +144,7 @@ def test_write_xtc(): ones = np.ones(30).reshape(10, 3) box_compare = np.eye(3) * 20 for i, frame in enumerate(f): - print i + print(i) xyz, box, step, time, prec = frame assert_array_almost_equal(xyz, ones * i, decimal=3) assert_array_almost_equal(box, box_compare, decimal=3) From 9f191b63ec363e1b5d299e4cb726577e5e94ece7 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 14:15:05 +0100 Subject: [PATCH 09/25] Make tests from test_util.py pass on python 3 * The test for format guessing ignore DCD, DATA, and LAMMPS on python 3 * fix some call to the `map` function that do not return a list on python 3 * other minor fixes --- package/MDAnalysis/coordinates/GRO.py | 2 +- package/MDAnalysis/coordinates/PDB.py | 4 +++- package/MDAnalysis/lib/util.py | 4 ++-- package/MDAnalysis/topology/PSFParser.py | 21 ++++++++--------- testsuite/MDAnalysisTests/test_atomgroup.py | 11 ++++----- testsuite/MDAnalysisTests/test_util.py | 25 ++++++++++++--------- 6 files changed, 38 insertions(+), 29 deletions(-) diff --git a/package/MDAnalysis/coordinates/GRO.py b/package/MDAnalysis/coordinates/GRO.py index 2a9ef73524b..d48a9257be1 100644 --- a/package/MDAnalysis/coordinates/GRO.py +++ b/package/MDAnalysis/coordinates/GRO.py @@ -140,7 +140,7 @@ def _read_first_frame(self): for pos, line in enumerate(grofile, start=-2): # 2 header lines, 1 box line at end if pos == n_atoms: - unitcell = np.array(map(float, line.split())) + unitcell = np.array(list(map(float, line.split()))) continue if pos < 0: continue diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 8138d3e4812..4a3c223eefb 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -514,7 +514,9 @@ def __init__(self, filename, **kwargs): # on the trajectory reader if len(frames) > 1: continue - self.ts._pos[pos] = map(float, [line[30:38], line[38:46], line[46:54]]) + self.ts._pos[pos] = list(map(float, [line[30:38], + line[38:46], + line[46:54]])) try: occupancy[pos] = float(line[54:60]) except ValueError: diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index ce4893d35ef..79467106876 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -150,7 +150,7 @@ __docformat__ = "restructuredtext en" -from six.moves import range +from six.moves import range, map import six import os @@ -285,7 +285,7 @@ def anyopen(datasource, mode='r', reset=True): Only returns the ``stream`` and tries to set ``stream.name = filename`` instead of the previous behavior to return a tuple ``(stream, filename)``. """ - handlers = {'bz2': bz2.BZ2File, 'gz': gzip.open, '': file} + handlers = {'bz2': bz2.BZ2File, 'gz': gzip.open, '': open} if mode.startswith('r'): if isstream(datasource): diff --git a/package/MDAnalysis/topology/PSFParser.py b/package/MDAnalysis/topology/PSFParser.py index 4e1b5a7b67e..1a796dff174 100644 --- a/package/MDAnalysis/topology/PSFParser.py +++ b/package/MDAnalysis/topology/PSFParser.py @@ -35,10 +35,10 @@ """ from __future__ import absolute_import - from six.moves import range import logging +import functools from math import ceil from ..core.AtomGroup import Atom @@ -62,7 +62,7 @@ def parse(self): """ # Open and check psf validity with openany(self.filename, 'r') as psffile: - header = psffile.next() + header = next(psffile) if header[:3] != "PSF": err = ("{0} is not valid PSF file (header = {1})" "".format(self.filename, header)) @@ -77,15 +77,15 @@ def parse(self): else: self._format = "STANDARD" # CHARMM - psffile.next() - title = psffile.next().split() + next(psffile) + title = next(psffile).split() if not (title[1] == "!NTITLE"): err = "{0} is not a valid PSF file".format(psffile.name) logger.error(err) raise ValueError(err) # psfremarks = [psffile.next() for i in range(int(title[0]))] for _ in range(int(title[0])): - psffile.next() + next(psffile) logger.debug("PSF file {0}: format {1}" "".format(psffile.name, self._format)) @@ -103,7 +103,7 @@ def parse(self): try: for attr, info in sections: - psffile.next() + next(psffile) structure[attr] = self._parse_sec(psffile, info) except StopIteration: # Reached the end of the file before we expected @@ -118,9 +118,9 @@ def parse(self): def _parse_sec(self, psffile, section_info): desc, atoms_per, per_line, parsefunc = section_info - header = psffile.next() + header = next(psffile) while header.strip() == "": - header = psffile.next() + header = next(psffile) header = header.split() # Get the number num = float(header[0]) @@ -133,7 +133,8 @@ def _parse_sec(self, psffile, section_info): # Now figure out how many lines to read numlines = int(ceil(num/per_line)) - return parsefunc(psffile.next, atoms_per, numlines) + psffile_next = functools.partial(next, psffile) + return parsefunc(psffile_next, atoms_per, numlines) def _parseatoms(self, lines, atoms_per, numlines): """Parses atom section in a Charmm PSF file. @@ -238,7 +239,7 @@ def _parsesection(self, lines, atoms_per, numlines): for i in range(numlines): # Subtract 1 from each number to ensure zero-indexing for the atoms - fields = map(lambda x: int(x) - 1, lines().split()) + fields = list(map(lambda x: int(x) - 1, lines().split())) for j in range(0, len(fields), atoms_per): section.append(tuple(fields[j:j+atoms_per])) return section diff --git a/testsuite/MDAnalysisTests/test_atomgroup.py b/testsuite/MDAnalysisTests/test_atomgroup.py index 23cfe48158e..f6b9e585f2b 100644 --- a/testsuite/MDAnalysisTests/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/test_atomgroup.py @@ -215,11 +215,12 @@ class TestAtomGroup(TestCase): # all tests are done with the AdK system (PSF and DCD) # sequence: http://www.uniprot.org/uniprot/P69441.fasta # >sp|P69441|KAD_ECOLI Adenylate kinase OS=Escherichia coli (strain K12) GN=adk PE=1 SV=1 - ref_adk_sequence = """\ - MRIILLGAPGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSELGKQAKDIMDAGKLVT - DELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVLEFDVPDELIVDRI - VGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQEETVRKRLVEYHQMTAPLIG - YYSKEAEAGNTKYAKVDGTKPVAEVRADLEKILG""".translate(None, " \n\t") + ref_adk_sequence = ( + "MRIILLGAPGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSELGKQAKDIMDAGKLVT" + "DELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVLEFDVPDELIVDRI" + "VGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQEETVRKRLVEYHQMTAPLIG" + "YYSKEAEAGNTKYAKVDGTKPVAEVRADLEKILG" + ) def setUp(self): """Set up the standard AdK system in implicit solvent.""" diff --git a/testsuite/MDAnalysisTests/test_util.py b/testsuite/MDAnalysisTests/test_util.py index 0d01a2ebb65..1f5dbbf125f 100644 --- a/testsuite/MDAnalysisTests/test_util.py +++ b/testsuite/MDAnalysisTests/test_util.py @@ -13,9 +13,9 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # -from six.moves import range +from six.moves import range, StringIO +import six -import cStringIO import os.path import tempfile @@ -146,7 +146,7 @@ def testStringRootExtKeep(self): assert_equal(fn, self.filename2) def testNamedStream(self): - ns = util.NamedStream(cStringIO.StringIO(), self.filename) + ns = util.NamedStream(StringIO(), self.filename) fn = util.filename(ns, ext=self.ext) # assert_equal replace by this if loop to avoid segfault on some systems if fn != ns: @@ -521,11 +521,11 @@ def test_str(self): assert_equal(util.conv_float('a.b'), 'a.b') def test_map_1(self): - ret = map(util.conv_float, ['0.45', '0.56', '6.7']) + ret = list(map(util.conv_float, ['0.45', '0.56', '6.7'])) assert_equal(ret, [0.45, 0.56, 6.7]) def test_map_2(self): - ret = map(util.conv_float, ['0.45', 'a.b', '!!']) + ret = list(map(util.conv_float, ['0.45', 'a.b', '!!'])) assert_equal(ret, [0.45, 'a.b', '!!']) class TestFixedwidthBins(object): @@ -563,14 +563,11 @@ class TestGuessFormat(object): ('CHAIN', None, mda.coordinates.base.ChainReader), ('CONFIG', mda.topology.DLPolyParser.ConfigParser, mda.coordinates.DLPoly.ConfigReader), ('CRD', mda.topology.CRDParser.CRDParser, mda.coordinates.CRD.CRDReader), - ('DATA', mda.topology.LAMMPSParser.DATAParser, mda.coordinates.LAMMPS.DATAReader), - ('DCD', None, mda.coordinates.DCD.DCDReader), ('DMS', mda.topology.DMSParser.DMSParser, mda.coordinates.DMS.DMSReader), ('GMS', mda.topology.GMSParser.GMSParser, mda.coordinates.GMS.GMSReader), ('GRO', mda.topology.GROParser.GROParser, mda.coordinates.GRO.GROReader), ('HISTORY', mda.topology.DLPolyParser.HistoryParser, mda.coordinates.DLPoly.HistoryReader), ('INPCRD', None, mda.coordinates.INPCRD.INPReader), - ('LAMMPS', None, mda.coordinates.LAMMPS.DCDReader), ('MDCRD', None, mda.coordinates.TRJ.TRJReader), ('MOL2', mda.topology.MOL2Parser.MOL2Parser, mda.coordinates.MOL2.MOL2Reader), ('NC', None, mda.coordinates.TRJ.NCDFReader), @@ -585,12 +582,20 @@ class TestGuessFormat(object): ('TPR', mda.topology.TPRParser.TPRParser, None), ('TRJ', None, mda.coordinates.TRJ.TRJReader), ('TRR', None, mda.coordinates.TRR.TRRReader), - ('TRZ', None, mda.coordinates.TRZ.TRZReader), ('XML', mda.topology.HoomdXMLParser.HoomdXMLParser, None), ('XPDB', mda.topology.ExtendedPDBParser.ExtendedPDBParser, mda.coordinates.PDB.ExtendedPDBReader), ('XTC', None, mda.coordinates.XTC.XTCReader), ('XYZ', mda.topology.XYZParser.XYZParser, mda.coordinates.XYZ.XYZReader), ] + if six.PY2: + # DCD, LAMMPS, and TRZ are not supported on Python 3 yet + formats += [ + ('DATA', mda.topology.LAMMPSParser.DATAParser, + mda.coordinates.LAMMPS.DATAReader), + ('DCD', None, mda.coordinates.DCD.DCDReader), + ('LAMMPS', None, mda.coordinates.LAMMPS.DCDReader), + ('TRZ', None, mda.coordinates.TRZ.TRZReader), + ] # list of possible compressed extensions # include no extension too! compressed_extensions = ['.bz2', '.gz'] @@ -670,7 +675,7 @@ def test_format_from_filename_TE(self): def test_guess_format_stream_VE(self): # This stream has no name, so can't guess format - s = cStringIO.StringIO('this is a very fun file') + s = StringIO('this is a very fun file') assert_raises(ValueError, util.guess_format, s) From 6a5c60fdaf8348739d110e90a4b8f5b1cbe9d69b Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 14:39:09 +0100 Subject: [PATCH 10/25] Make test_altloc.py pass on Python 3 In python 3, numpy integers are not instances of int anymore. --- package/MDAnalysis/core/AtomGroup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/AtomGroup.py b/package/MDAnalysis/core/AtomGroup.py index c9a08b5227b..d6dc8c74322 100644 --- a/package/MDAnalysis/core/AtomGroup.py +++ b/package/MDAnalysis/core/AtomGroup.py @@ -1016,7 +1016,7 @@ def __getitem__(self, item): cls = self._cls # consistent with the way list indexing/slicing behaves: - if isinstance(item, int): + if isinstance(item, (int, np.integer)): try: return container[item] except IndexError: From fa990ecc345eaa7e17b51dc116770692b866718c Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 14:57:32 +0100 Subject: [PATCH 11/25] Male test_log.py pass on Python 3 * replace seek(0L) by seek(0) * use six for StringIO --- testsuite/MDAnalysisTests/test_log.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testsuite/MDAnalysisTests/test_log.py b/testsuite/MDAnalysisTests/test_log.py index 5794a607db1..84fef3324a2 100644 --- a/testsuite/MDAnalysisTests/test_log.py +++ b/testsuite/MDAnalysisTests/test_log.py @@ -15,10 +15,10 @@ # # initial simple tests for logging module +from six.moves import StringIO import sys import os -import cStringIO import tempfile import logging @@ -75,7 +75,7 @@ def __exit__(self, exc_type, exc_value, traceback): class TestProgressMeter(TestCase): def setUp(self): - self.buf = cStringIO.StringIO() + self.buf = StringIO() def tearDown(self): del self.buf @@ -92,7 +92,7 @@ def test_default_ProgressMeter(self, n=101, interval=10): pm = MDAnalysis.lib.log.ProgressMeter(n, interval=interval) for frame in range(n): pm.echo(frame) - self.buf.seek(0L) + self.buf.seek(0) output = "".join(self.buf.readlines()) self._assert_in(output, format % {'step': 1, 'numsteps': n, 'percentage': 100./n}) # last line always has \n instead of \r! @@ -107,7 +107,7 @@ def test_custom_ProgressMeter(self, n=51, interval=7): for frame in range(n): rmsd = 0.02 * frame * (n+1)/float(n) # n+1/n correction for 0-based frame vs 1-based counting pm.echo(frame, rmsd=rmsd) - self.buf.seek(0L) + self.buf.seek(0) output = "".join(self.buf.readlines()) self._assert_in(output, format % {'rmsd': 0.0, 'step': 1, 'numsteps': n, 'percentage': 100./n}) From 6fed1960d7e9a5d68184b2e64915b768d24e70dc Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 15:09:34 +0100 Subject: [PATCH 12/25] Make test_persistance.py pass on Python 3 * use six for cPickle * use the `next` builtin rather than the `next` method --- package/MDAnalysis/coordinates/base.py | 8 ++++++-- testsuite/MDAnalysisTests/test_persistence.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index 80ca349ba71..7ed7a4a7720 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -1054,6 +1054,10 @@ def next(self): """Forward one step to next frame.""" return self._read_next_timestep() + def __next__(self): + """Forward one step to next frame when using the `next` builtin.""" + return self.next() + def rewind(self): """Position at beginning of trajectory""" self._reopen() @@ -1568,14 +1572,14 @@ def _chained_iterator(self): yield ts def _read_next_timestep(self, ts=None): - self.ts = self.__chained_trajectories_iter.next() + self.ts = next(self.__chained_trajectories_iter) return self.ts def rewind(self): """Set current frame to the beginning.""" self._rewind() self.__chained_trajectories_iter = self._chained_iterator() - self.ts = self.__chained_trajectories_iter.next() # set time step to frame 1 + self.ts = next(self.__chained_trajectories_iter) # set time step to frame 1 def _rewind(self): """Internal method: Rewind trajectories themselves and trj pointer.""" diff --git a/testsuite/MDAnalysisTests/test_persistence.py b/testsuite/MDAnalysisTests/test_persistence.py index 1553a481f1a..ac6f880bce8 100644 --- a/testsuite/MDAnalysisTests/test_persistence.py +++ b/testsuite/MDAnalysisTests/test_persistence.py @@ -13,6 +13,7 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # +from six.moves import cPickle import MDAnalysis from MDAnalysis.tests.datafiles import PDB_small, GRO, XTC, TRR @@ -28,7 +29,6 @@ import os import gc import shutil -import cPickle import warnings import tempdir From 269c629939af29da8faf0571340764e8a4c7b305 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sat, 23 Jan 2016 15:59:11 +0100 Subject: [PATCH 13/25] Use six for StringIO and cPickle everywhere An odd failure about StringIO remains in test_streamio.py on Python 3. --- package/MDAnalysis/analysis/density.py | 2 -- .../analysis/hbonds/hbond_analysis.py | 4 +-- package/MDAnalysis/analysis/psa.py | 13 +++++---- testsuite/MDAnalysisTests/test_atomgroup.py | 4 +-- testsuite/MDAnalysisTests/test_selections.py | 7 ++--- testsuite/MDAnalysisTests/test_streamio.py | 27 +++++++++---------- 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/package/MDAnalysis/analysis/density.py b/package/MDAnalysis/analysis/density.py index 031445ba2b4..cac0ba1b5b5 100644 --- a/package/MDAnalysis/analysis/density.py +++ b/package/MDAnalysis/analysis/density.py @@ -82,7 +82,6 @@ """ from __future__ import print_function - from six.moves import range import numpy as np @@ -90,7 +89,6 @@ import os import os.path import errno -import cPickle import warnings try: diff --git a/package/MDAnalysis/analysis/hbonds/hbond_analysis.py b/package/MDAnalysis/analysis/hbonds/hbond_analysis.py index ab6d5e45427..97393847479 100644 --- a/package/MDAnalysis/analysis/hbonds/hbond_analysis.py +++ b/package/MDAnalysis/analysis/hbonds/hbond_analysis.py @@ -310,7 +310,7 @@ class HydrogenBondAnalysis_OtherFF(HydrogenBondAnalysis): """ import six -from six.moves import range, zip, map +from six.moves import range, zip, map, cPickle from collections import defaultdict import numpy as np @@ -984,8 +984,6 @@ def save_table(self, filename="hbond_table.pickle"): .. SeeAlso:: :mod:`cPickle` module and :class:`numpy.recarray` """ - import cPickle - if self.table is None: self.generate_table() cPickle.dump(self.table, open(filename, 'wb'), protocol=cPickle.HIGHEST_PROTOCOL) diff --git a/package/MDAnalysis/analysis/psa.py b/package/MDAnalysis/analysis/psa.py index 11c188c7f60..03e4e923781 100644 --- a/package/MDAnalysis/analysis/psa.py +++ b/package/MDAnalysis/analysis/psa.py @@ -218,7 +218,7 @@ """ import six -from six.moves import range +from six.moves import range, cPickle import numpy as np @@ -226,7 +226,6 @@ import MDAnalysis.analysis.align from MDAnalysis import NoDataError -import cPickle as pickle import os import logging @@ -1173,11 +1172,11 @@ def __init__(self, universes, reference=None, ref_select='name CA', self._labels_pkl = os.path.join(self.targetdir, "psa_labels.pkl") # Pickle topology and trajectory filenames for this analysis to curdir with open(self._top_pkl, 'wb') as output: - pickle.dump(self.top_name, output) + cPickle.dump(self.top_name, output) with open(self._trjs_pkl, 'wb') as output: - pickle.dump(self.trj_names, output) + cPickle.dump(self.trj_names, output) with open(self._labels_pkl, 'wb') as output: - pickle.dump(self.labels, output) + cPickle.dump(self.labels, output) self.natoms = None self.npaths = None @@ -1259,7 +1258,7 @@ def generate_paths(self, **kwargs): self.fit_trj_names = fit_trj_names if save: with open(self._fit_trjs_pkl, 'wb') as output: - pickle.dump(self.fit_trj_names, output) + cPickle.dump(self.fit_trj_names, output) if store: filename = kwargs.pop('filename', None) self.save_paths(filename=filename) @@ -1407,7 +1406,7 @@ def save_paths(self, filename=None): logger.info("Wrote path to file %r", current_outfile) self.path_names = path_names with open(self._paths_pkl, 'wb') as output: - pickle.dump(self.path_names, output) + cPickle.dump(self.path_names, output) return filename diff --git a/testsuite/MDAnalysisTests/test_atomgroup.py b/testsuite/MDAnalysisTests/test_atomgroup.py index f6b9e585f2b..8620899d735 100644 --- a/testsuite/MDAnalysisTests/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/test_atomgroup.py @@ -13,6 +13,7 @@ # MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations. # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # +from six.moves import zip, cPickle import MDAnalysis from MDAnalysis.tests.datafiles import PSF, DCD, PDB_small, GRO, TRR, \ @@ -24,7 +25,6 @@ from MDAnalysis import NoDataError from MDAnalysis.core.AtomGroup import _PLURAL_PROPERTIES, _SINGULAR_PROPERTIES -from six.moves import zip import numpy as np from numpy.testing import * from nose.plugins.attrib import attr @@ -1608,8 +1608,6 @@ def test_load_multiple_args(self): assert_equal(u.trajectory.n_frames, 2 * ref.trajectory.n_frames) def test_pickle_raises_NotImplementedError(self): - import cPickle - u = MDAnalysis.Universe(PSF, DCD) assert_raises(NotImplementedError, cPickle.dumps, u, protocol=cPickle.HIGHEST_PROTOCOL) diff --git a/testsuite/MDAnalysisTests/test_selections.py b/testsuite/MDAnalysisTests/test_selections.py index be8922e3c9d..2c702e08f34 100644 --- a/testsuite/MDAnalysisTests/test_selections.py +++ b/testsuite/MDAnalysisTests/test_selections.py @@ -16,8 +16,9 @@ # Test the selection exporters in MDAnalysis.selections -# use cStringIO and NamedStream to write to memory instead to temp files -import cStringIO +# use StringIO and NamedStream to write to memory instead to temp files +from six.moves import cPickle, StringIO + import re import numpy as np @@ -37,7 +38,7 @@ class _SelectionWriter(TestCase): def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) - stream = cStringIO.StringIO() + stream = StringIO() self.namedfile = NamedStream(stream, self.filename) def tearDown(self): diff --git a/testsuite/MDAnalysisTests/test_streamio.py b/testsuite/MDAnalysisTests/test_streamio.py index 176a08e16ab..9210f2212b3 100644 --- a/testsuite/MDAnalysisTests/test_streamio.py +++ b/testsuite/MDAnalysisTests/test_streamio.py @@ -14,7 +14,7 @@ # J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787 # import six -from six.moves import range +from six.moves import range, cStringIO, StringIO import numpy as np from numpy.testing import (TestCase, dec, @@ -28,8 +28,7 @@ from MDAnalysisTests.coordinates.reference import RefAdKSmall from MDAnalysisTests.plugins.knownfailure import knownfailure -import StringIO -import cStringIO +import tempfile import os import tempdir @@ -59,23 +58,23 @@ def test_file(self): def test_cStringIO_read(self): with open(datafiles.PSF, "r") as f: - obj = cStringIO.StringIO(f.read()) + obj = cStringIO(f.read()) assert_equal(util.isstream(obj), True) obj.close() def test_cStringIO_write(self): - obj = cStringIO.StringIO() + obj = cStringIO() assert_equal(util.isstream(obj), True) obj.close() def test_StringIO_read(self): with open(datafiles.PSF, "r") as f: - obj = StringIO.StringIO(f) + obj = StringIO(f) assert_equal(util.isstream(obj), True) obj.close() def test_StringIO_write(self): - obj = StringIO.StringIO() + obj = StringIO() assert_equal(util.isstream(obj), True) obj.close() @@ -92,14 +91,14 @@ def setUp(self): self.numtextlines = len(self.text) def test_closing(self): - obj = cStringIO.StringIO("".join(self.text)) + obj = cStringIO("".join(self.text)) ns = util.NamedStream(obj, self.textname, close=True) assert_equal(ns.closed, False) ns.close() assert_equal(ns.closed, True) def test_closing_force(self): - obj = cStringIO.StringIO("".join(self.text)) + obj = cStringIO("".join(self.text)) ns = util.NamedStream(obj, self.textname) assert_equal(ns.closed, False) ns.close() @@ -108,7 +107,7 @@ def test_closing_force(self): assert_equal(ns.closed, True) def test_cStringIO_read(self): - obj = cStringIO.StringIO("".join(self.text)) + obj = cStringIO("".join(self.text)) ns = util.NamedStream(obj, self.textname) assert_equal(ns.name, self.textname) assert_equal(str(ns), self.textname) @@ -128,7 +127,7 @@ def test_File_read(self): ns.close(force=True) def test_cStringIO_write(self): - obj = cStringIO.StringIO() + obj = cStringIO() ns = util.NamedStream(obj, self.textname) ns.writelines(self.text) assert_equal(ns.name, self.textname) @@ -166,7 +165,7 @@ class TestNamedStream_filename_behavior(object): def create_NamedStream(self, name=None): if name is None: name = self.textname - obj = cStringIO.StringIO() + obj = cStringIO() return util.NamedStream(obj, name) def test_ospath_funcs(self): @@ -317,10 +316,10 @@ def __init__(self): """ def as_StringIO(self, name): - return StringIO.StringIO(self.buffers[name]) + return StringIO(self.buffers[name]) def as_cStringIO(self, name): - return cStringIO.StringIO(self.buffers[name]) + return cStringIO(self.buffers[name]) def as_NamedStream(self, name): return util.NamedStream(self.as_cStringIO(name), self.filenames[name]) From b1640c3d0344b1c6165fcb0f0d23d77328ca0192 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sun, 24 Jan 2016 20:37:01 +0100 Subject: [PATCH 14/25] Make test_tprparser.py pass on Python 3 Read the TPR file as binary (mode='rb'). --- package/MDAnalysis/topology/TPRParser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/topology/TPRParser.py b/package/MDAnalysis/topology/TPRParser.py index e1928e53774..feb6c5722fa 100644 --- a/package/MDAnalysis/topology/TPRParser.py +++ b/package/MDAnalysis/topology/TPRParser.py @@ -159,7 +159,7 @@ def parse(self): #ndo_rvec = U.ndo_rvec #ndo_ivec = U.ndo_ivec - tprf = anyopen(self.filename).read() + tprf = anyopen(self.filename, mode='rb').read() data = xdrlib.Unpacker(tprf) try: th = U.read_tpxheader(data) # tpxheader From 64ad46790492e6e7db6dc247d8e6663d9dfc675c Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Sun, 24 Jan 2016 22:19:49 +0100 Subject: [PATCH 15/25] Fix some call to map that expected a list output In Python 3, map returns a generator rather than a list. Make coordinates/test_dl_poly.py pass on python 3 --- package/MDAnalysis/coordinates/DLPoly.py | 25 ++++++++++++------------ package/MDAnalysis/coordinates/XYZ.py | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/package/MDAnalysis/coordinates/DLPoly.py b/package/MDAnalysis/coordinates/DLPoly.py index bd7101ffa05..da6df0d1990 100644 --- a/package/MDAnalysis/coordinates/DLPoly.py +++ b/package/MDAnalysis/coordinates/DLPoly.py @@ -61,9 +61,9 @@ def _read_first_frame(self): self.title = inf.readline().strip() levcfg, imcon, megatm = map(int, inf.readline().split()[:3]) if not imcon == 0: - cellx = map(float, inf.readline().split()) - celly = map(float, inf.readline().split()) - cellz = map(float, inf.readline().split()) + cellx = list(map(float, inf.readline().split())) + celly = list(map(float, inf.readline().split())) + cellz = list(map(float, inf.readline().split())) ids = [] coords = [] @@ -88,13 +88,13 @@ def _read_first_frame(self): else: ids.append(idx) - xyz = map(float, inf.readline().split()) + xyz = list(map(float, inf.readline().split())) coords.append(xyz) if has_vels: - vxyz = map(float, inf.readline().split()) + vxyz = list(map(float, inf.readline().split())) velocities.append(vxyz) if has_forces: - fxyz = map(float, inf.readline().split()) + fxyz = list(map(float, inf.readline().split())) forces.append(fxyz) line = inf.readline().strip() @@ -168,9 +168,9 @@ def _read_next_timestep(self, ts=None): if not line.startswith('timestep'): raise IOError if not self._imcon == 0: - ts._unitcell[0] = map(float, self._file.readline().split()) - ts._unitcell[1] = map(float, self._file.readline().split()) - ts._unitcell[2] = map(float, self._file.readline().split()) + ts._unitcell[0] = list(map(float, self._file.readline().split())) + ts._unitcell[1] = list(map(float, self._file.readline().split())) + ts._unitcell[2] = list(map(float, self._file.readline().split())) # If ids are given, put them in here # and later sort by them @@ -186,11 +186,12 @@ def _read_next_timestep(self, ts=None): ids.append(idx) # Read in this order for now, then later reorder in place - ts._pos[i] = map(float, self._file.readline().split()) + ts._pos[i] = list(map(float, self._file.readline().split())) if self._has_vels: - ts._velocities[i] = map(float, self._file.readline().split()) + ts._velocities[i] = list(map(float, + self._file.readline().split())) if self._has_forces: - ts._forces[i] = map(float, self._file.readline().split()) + ts._forces[i] = list(map(float, self._file.readline().split())) if ids: ids = np.array(ids) diff --git a/package/MDAnalysis/coordinates/XYZ.py b/package/MDAnalysis/coordinates/XYZ.py index e47bb0beb5b..ecb13c96a78 100644 --- a/package/MDAnalysis/coordinates/XYZ.py +++ b/package/MDAnalysis/coordinates/XYZ.py @@ -360,7 +360,7 @@ def _read_next_timestep(self, ts=None): f.readline() f.readline() for i in range(self.n_atoms): - self.ts._pos[i] = map(float, f.readline().split()[1:4]) + self.ts._pos[i] = list(map(float, f.readline().split()[1:4])) ts.frame += 1 return ts except (ValueError, IndexError) as err: From 20d0ab0d39288098cad2a6ed4518a01caf8b5f01 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 10:38:16 +0100 Subject: [PATCH 16/25] Avoid import * in test_modelling.py --- testsuite/MDAnalysisTests/test_modelling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/test_modelling.py b/testsuite/MDAnalysisTests/test_modelling.py index c4ce79b6b70..0b246d3b291 100644 --- a/testsuite/MDAnalysisTests/test_modelling.py +++ b/testsuite/MDAnalysisTests/test_modelling.py @@ -24,7 +24,7 @@ from MDAnalysis import NoDataError import numpy as np -from numpy.testing import * +from numpy.testing import TestCase, assert_equal, assert_raises, assert_, assert_array_equal from nose.plugins.attrib import attr import os From d7d956289265a241b74eac68139f24ef3904d36f Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 11:03:42 +0100 Subject: [PATCH 17/25] Avoid import * in test_topology --- testsuite/MDAnalysisTests/test_topology.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/test_topology.py b/testsuite/MDAnalysisTests/test_topology.py index 9e0d9f6b217..03541a192c4 100644 --- a/testsuite/MDAnalysisTests/test_topology.py +++ b/testsuite/MDAnalysisTests/test_topology.py @@ -33,7 +33,8 @@ DLP_HISTORY, DLP_HISTORY_order, DLP_HISTORY_minimal, HoomdXMLdata) from MDAnalysisTests.plugins.knownfailure import knownfailure -from numpy.testing import * +from numpy.testing import (TestCase, assert_equal, assert_raises, assert_, + assert_array_equal, assert_almost_equal) from nose.plugins.attrib import attr import numpy as np From c739bbeca1b4ea3f4a8f09c678207afeffc1773f Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 11:23:22 +0100 Subject: [PATCH 18/25] Avoid import * in test_atomgroup.py --- testsuite/MDAnalysisTests/test_atomgroup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/test_atomgroup.py b/testsuite/MDAnalysisTests/test_atomgroup.py index 8620899d735..1105cf8c24b 100644 --- a/testsuite/MDAnalysisTests/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/test_atomgroup.py @@ -26,7 +26,10 @@ from MDAnalysis.core.AtomGroup import _PLURAL_PROPERTIES, _SINGULAR_PROPERTIES import numpy as np -from numpy.testing import * +from numpy.testing import (TestCase, dec, raises, assert_equal, + assert_almost_equal, assert_raises, assert_, + assert_array_almost_equal, assert_array_equal, + assert_allclose) from nose.plugins.attrib import attr import os From fde8735e40001845a7a92cb7ed3c4f58f69b4b96 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 11:37:28 +0100 Subject: [PATCH 19/25] On python 3 skip tests that use unsupported reader Tests that relies on DCD, LAMMPS, or TRZ test files ends with an error because the reader is not supported on python 3 yet. This creates a lot of noise in the nose report that hides the other failures. Hereby we make these tests being skipped if the parser is not loaded. Note that this reduce dramatically the test coverage on python 3! --- testsuite/MDAnalysisTests/__init__.py | 20 +++++++ .../MDAnalysisTests/analysis/test_align.py | 4 +- .../MDAnalysisTests/analysis/test_base.py | 5 +- .../MDAnalysisTests/analysis/test_contacts.py | 4 +- .../MDAnalysisTests/analysis/test_helanal.py | 5 +- .../MDAnalysisTests/analysis/test_psa.py | 6 +- .../analysis/test_waterdynamics.py | 5 +- .../coordinates/test_coordinates.py | 7 +++ .../MDAnalysisTests/coordinates/test_pdb.py | 5 ++ .../coordinates/test_timestep_api.py | 12 +++- testsuite/MDAnalysisTests/test_atomgroup.py | 59 +++++++++++++++++++ .../MDAnalysisTests/test_atomselections.py | 9 +++ testsuite/MDAnalysisTests/test_distances.py | 11 +++- testsuite/MDAnalysisTests/test_modelling.py | 6 +- testsuite/MDAnalysisTests/test_selections.py | 9 ++- testsuite/MDAnalysisTests/test_topology.py | 9 ++- 16 files changed, 163 insertions(+), 13 deletions(-) diff --git a/testsuite/MDAnalysisTests/__init__.py b/testsuite/MDAnalysisTests/__init__.py index 716fbeb7b74..0d84a0774ba 100644 --- a/testsuite/MDAnalysisTests/__init__.py +++ b/testsuite/MDAnalysisTests/__init__.py @@ -175,3 +175,23 @@ def module_not_found(module): return True else: return False + + +def parser_not_found(parser_name): + """Return ``True`` if the parser of the given name cannot be found. + + This allows to skip a test when the parser is unavailable (e.g in python 3 + when the parser is not compatible). + + To be used as the argument of:: + + @dec.skipif(parser_not_found('DCD'), + 'DCD parser is not available. Are you on python 3?') + """ + import MDAnalysis.coordinates + try: + getattr(MDAnalysis.coordinates, parser_name) + except AttributeError: + return True + else: + return False diff --git a/testsuite/MDAnalysisTests/analysis/test_align.py b/testsuite/MDAnalysisTests/analysis/test_align.py index ca23dc680fe..727ebc29971 100644 --- a/testsuite/MDAnalysisTests/analysis/test_align.py +++ b/testsuite/MDAnalysisTests/analysis/test_align.py @@ -30,9 +30,11 @@ import tempfile from MDAnalysisTests.datafiles import PSF, DCD, FASTA -from MDAnalysisTests import executable_not_found +from MDAnalysisTests import executable_not_found, parser_not_found class TestAlign(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.reference = MDAnalysis.Universe(PSF, DCD) diff --git a/testsuite/MDAnalysisTests/analysis/test_base.py b/testsuite/MDAnalysisTests/analysis/test_base.py index a501e93e585..bc9a163de46 100644 --- a/testsuite/MDAnalysisTests/analysis/test_base.py +++ b/testsuite/MDAnalysisTests/analysis/test_base.py @@ -18,13 +18,14 @@ from six.moves import range from numpy.testing import ( - assert_, + assert_, dec ) import MDAnalysis as mda from MDAnalysis.analysis.base import AnalysisBase from MDAnalysisTests.datafiles import PSF, DCD +from MDAnalysisTests import parser_not_found class FrameAnalysis(AnalysisBase): @@ -43,6 +44,8 @@ def _single_frame(self): class TestAnalysisBase(object): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): # has 98 frames self.u = mda.Universe(PSF, DCD) diff --git a/testsuite/MDAnalysisTests/analysis/test_contacts.py b/testsuite/MDAnalysisTests/analysis/test_contacts.py index 37571b4673f..dea0aa19740 100644 --- a/testsuite/MDAnalysisTests/analysis/test_contacts.py +++ b/testsuite/MDAnalysisTests/analysis/test_contacts.py @@ -29,9 +29,11 @@ import tempdir from MDAnalysisTests.datafiles import PSF, DCD -from MDAnalysisTests import executable_not_found +from MDAnalysisTests import executable_not_found, parser_not_found class TestContacts(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.trajectory = self.universe.trajectory diff --git a/testsuite/MDAnalysisTests/analysis/test_helanal.py b/testsuite/MDAnalysisTests/analysis/test_helanal.py index 083785c5bd2..523cf315c3d 100644 --- a/testsuite/MDAnalysisTests/analysis/test_helanal.py +++ b/testsuite/MDAnalysisTests/analysis/test_helanal.py @@ -18,7 +18,7 @@ import tempdir import numpy as np -from numpy.testing import (assert_raises, assert_, +from numpy.testing import (dec, assert_raises, assert_, assert_equal, assert_array_almost_equal) from six.moves import zip @@ -27,6 +27,7 @@ from MDAnalysis import FinishTimeException from MDAnalysisTests.datafiles import (GRO, XTC, PSF, DCD, PDB_small, HELANAL_BENDING_MATRIX) +from MDAnalysisTests import parser_not_found # reference data from a single PDB file: # data = MDAnalysis.analysis.helanal.helanal_main(PDB_small, @@ -104,6 +105,8 @@ def read_bending_matrix(fn): return data +@dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_helanal_trajectory(reference=HELANAL_BENDING_MATRIX, outfile="helanal_bending_matrix.dat"): u = mda.Universe(PSF, DCD) diff --git a/testsuite/MDAnalysisTests/analysis/test_psa.py b/testsuite/MDAnalysisTests/analysis/test_psa.py index 0989d32f3eb..f89045bda53 100644 --- a/testsuite/MDAnalysisTests/analysis/test_psa.py +++ b/testsuite/MDAnalysisTests/analysis/test_psa.py @@ -18,16 +18,20 @@ import MDAnalysis import MDAnalysis.analysis.psa -from numpy.testing import TestCase, assert_array_less, assert_array_almost_equal +from numpy.testing import (TestCase, dec, assert_array_less, + assert_array_almost_equal) import numpy as np import tempfile import shutil from MDAnalysisTests.datafiles import PSF, DCD, DCD2 +from MDAnalysisTests import parser_not_found class TestPSAnalysis(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.tmpdir = tempfile.mkdtemp() self.iu1 = np.triu_indices(3, k=1) diff --git a/testsuite/MDAnalysisTests/analysis/test_waterdynamics.py b/testsuite/MDAnalysisTests/analysis/test_waterdynamics.py index 098cd6aac33..326d5ce54f7 100644 --- a/testsuite/MDAnalysisTests/analysis/test_waterdynamics.py +++ b/testsuite/MDAnalysisTests/analysis/test_waterdynamics.py @@ -17,13 +17,16 @@ import MDAnalysis import MDAnalysis.analysis.waterdynamics -from numpy.testing import TestCase, assert_equal +from numpy.testing import TestCase, assert_equal, dec import numpy as np from MDAnalysisTests.datafiles import waterPSF, waterDCD +from MDAnalysisTests import parser_not_found class TestWaterdynamics(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(waterPSF, waterDCD) self.selection1 = "byres name OH2" diff --git a/testsuite/MDAnalysisTests/coordinates/test_coordinates.py b/testsuite/MDAnalysisTests/coordinates/test_coordinates.py index 5fdc2caa3d0..6daa6d5755f 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_coordinates.py +++ b/testsuite/MDAnalysisTests/coordinates/test_coordinates.py @@ -28,6 +28,7 @@ from MDAnalysisTests.datafiles import (PDB, INPCRD, XYZ_five, PSF, CRD, DCD, GRO, XTC, TRR, PDB_small, PDB_closed) from MDAnalysisTests.plugins.knownfailure import knownfailure +from MDAnalysisTests import parser_not_found class TestINPCRDReader(TestCase): @@ -63,6 +64,8 @@ def test_universe_restrt(self): class TestChainReader(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parset not available. Are you using python 3?') def setUp(self): self.universe = mda.Universe(PSF, [DCD, CRD, DCD, CRD, DCD, CRD, CRD]) @@ -155,6 +158,8 @@ def test_write_dcd(self): class TestChainReaderCommonDt(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parset not available. Are you using python 3?') def setUp(self): self.common_dt = 100.0 self.universe = mda.Universe(PSF, @@ -183,6 +188,8 @@ def test_set_all_format_tuples(self): assert_equal(universe.trajectory.n_frames, 21) @attr('issue') + @dec.skipif(parser_not_found('DCD'), + 'DCD parset not available. Are you using python 3?') def test_set_one_format_tuple(self): universe = mda.Universe(PSF, [(PDB_small, 'pdb'), DCD]) assert_equal(universe.trajectory.n_frames, 99) diff --git a/testsuite/MDAnalysisTests/coordinates/test_pdb.py b/testsuite/MDAnalysisTests/coordinates/test_pdb.py index 916e6a85321..8835663586a 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_pdb.py +++ b/testsuite/MDAnalysisTests/coordinates/test_pdb.py @@ -18,6 +18,7 @@ INC_PDB, PDB_xlserial, NUCL) from MDAnalysisTests.plugins.knownfailure import knownfailure +from MDAnalysisTests import parser_not_found class TestPDBReader(_SingleFrameReader): @@ -159,6 +160,8 @@ def test_dimensions(self): class TestPrimitivePDBWriter(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = mda.Universe(PSF, PDB_small, permissive=True) self.universe2 = mda.Universe(PSF, DCD, permissive=True) @@ -400,6 +403,8 @@ def helper(atoms, bonds): class TestMultiPDBWriter(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = mda.Universe(PSF, PDB_small, permissive=True) self.multiverse = mda.Universe(PDB_multiframe, permissive=True) diff --git a/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py b/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py index 952575f02f8..0884fee23e0 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py +++ b/testsuite/MDAnalysisTests/coordinates/test_timestep_api.py @@ -21,7 +21,7 @@ """ from numpy.testing import assert_equal, dec -from MDAnalysisTests import module_not_found +from MDAnalysisTests import module_not_found, parser_not_found import MDAnalysis as mda from MDAnalysisTests.datafiles import (PSF, XYZ_five, INPCRD, DCD, DLP_CONFIG, @@ -36,6 +36,8 @@ # Can add in custom tests for a given Timestep here! class TestBaseTimestep(BaseTimestepTest): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_other_timestep(self): # use a subclass to base.Timestep to check it works ts1 = mda.coordinates.base.Timestep(10) @@ -86,6 +88,8 @@ def setUp(self): class TestDCD(BaseTimestepInterfaceTest): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): u = self.u = mda.Universe(PSF, DCD) self.ts = u.trajectory.ts @@ -129,12 +133,16 @@ def setUp(self): class TestLAMMPS(BaseTimestepInterfaceTest): + @dec.skipif(parser_not_found('LAMMPS'), + 'LAMMPS parser not available. Are you using python 3?') def setUp(self): u = self.u = mda.Universe(LAMMPSdata) self.ts = u.trajectory.ts class TestLAMMPSDCD(BaseTimestepInterfaceTest): + @dec.skipif(parser_not_found('LAMMPS'), + 'LAMMPS parser not available. Are you using python 3?') def setUp(self): u = self.u = mda.Universe(LAMMPSdata2, LAMMPSdcd2, format='LAMMPS', topology_format='DATA', @@ -187,6 +195,8 @@ def setUp(self): class TestTRZ(BaseTimestepInterfaceTest): + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def setUp(self): u = self.u = mda.Universe(TRZ_psf, TRZ) self.ts = u.trajectory.ts diff --git a/testsuite/MDAnalysisTests/test_atomgroup.py b/testsuite/MDAnalysisTests/test_atomgroup.py index 1105cf8c24b..6c0d9db58cf 100644 --- a/testsuite/MDAnalysisTests/test_atomgroup.py +++ b/testsuite/MDAnalysisTests/test_atomgroup.py @@ -37,11 +37,14 @@ import itertools from MDAnalysisTests.plugins.knownfailure import knownfailure +from MDAnalysisTests import parser_not_found class TestAtom(TestCase): """Tests of Atom.""" + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): """Set up the standard AdK system in implicit solvent.""" self.universe = MDAnalysis.Universe(PSF, DCD) @@ -225,6 +228,8 @@ class TestAtomGroup(TestCase): "YYSKEAEAGNTKYAKVDGTKPVAEVRADLEKILG" ) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): """Set up the standard AdK system in implicit solvent.""" self.universe = MDAnalysis.Universe(PSF, DCD) @@ -890,6 +895,8 @@ def access_nonexistent_instantselector(): class TestAtomGroupNoTop(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF_notop, DCD) self.ag = self.u.atoms[:10] @@ -983,6 +990,8 @@ def test_set_dimensions(self): class TestUniverseSetTopology(TestCase): """Tests setting of bonds/angles/dihedrals/impropers from Universe.""" + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF, DCD) @@ -1080,6 +1089,8 @@ def test_impropers_delete(self): class TestResidue(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.res = self.universe.residues[100] @@ -1109,6 +1120,8 @@ def test_advanced_slicing(self): class TestResidueGroup(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): """Set up the standard AdK system in implicit solvent.""" self.universe = MDAnalysis.Universe(PSF, DCD) @@ -1254,6 +1267,8 @@ def test_set_masses(self): class TestSegment(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.universe.residues[:100].set_segids("A") # make up some segments @@ -1292,6 +1307,8 @@ def test_set_id(self): class TestSegmentGroup(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): """Set up the standard AdK system in implicit solvent.""" self.universe = MDAnalysis.Universe(PSF, DCD) @@ -1398,6 +1415,8 @@ def test_set_velocities(self): class TestAtomGroupTimestep(TestCase): """Tests the AtomGroup.ts attribute (partial timestep)""" + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(TRZ_psf, TRZ) self.prec = 6 @@ -1430,6 +1449,8 @@ class _WriteAtoms(TestCase): ext = None # override to test various output writers precision = 3 + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) suffix = '.' + self.ext @@ -1528,6 +1549,8 @@ def test_flag_convert_length(self): @attr("issue") +@dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_generated_residueselection(): """Test that a generated residue group always returns a ResidueGroup (Issue 47)""" universe = MDAnalysis.Universe(PSF, DCD) @@ -1545,6 +1568,8 @@ def test_generated_residueselection(): @attr('issue') +@dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_instantselection_termini(): """Test that instant selections work, even for residues that are also termini (Issue 70)""" universe = MDAnalysis.Universe(PSF, DCD) @@ -1558,6 +1583,8 @@ def test_load(self): u = MDAnalysis.Universe(PSF, PDB_small) assert_equal(len(u.atoms), 3341, "Loading universe failed somehow") + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_bad_topology(self): # tests that Universe builds produce the right error message def bad_load(): @@ -1566,21 +1593,29 @@ def bad_load(): assert_raises(ValueError, bad_load) @attr('issue') + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_new(self): u = MDAnalysis.Universe(PSF, DCD) u.load_new(PDB_small) assert_equal(len(u.trajectory), 1, "Failed to load_new(PDB)") + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_new_strict(self): u = MDAnalysis.Universe(PSF, DCD) u.load_new(PDB_small, permissive=False) assert_equal(len(u.trajectory), 1, "Failed to load_new(PDB, permissive=False)") + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_new_permissive(self): u = MDAnalysis.Universe(PSF, DCD) u.load_new(PDB_small, permissive=True) assert_equal(len(u.trajectory), 1, "Failed to load_new(PDB, permissive=True)") + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_new_TypeError(self): u = MDAnalysis.Universe(PSF, DCD) @@ -1596,6 +1631,8 @@ def test_load_structure(self): assert_equal(len(u.atoms), 3341, "Loading universe failed somehow") assert_almost_equal(u.atoms.positions, ref.atoms.positions) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_multiple_list(self): # Universe(top, [trj, trj, ...]) ref = MDAnalysis.Universe(PSF, DCD) @@ -1603,6 +1640,8 @@ def test_load_multiple_list(self): assert_equal(len(u.atoms), 3341, "Loading universe failed somehow") assert_equal(u.trajectory.n_frames, 2 * ref.trajectory.n_frames) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_load_multiple_args(self): # Universe(top, trj, trj, ...) ref = MDAnalysis.Universe(PSF, DCD) @@ -1610,10 +1649,14 @@ def test_load_multiple_args(self): assert_equal(len(u.atoms), 3341, "Loading universe failed somehow") assert_equal(u.trajectory.n_frames, 2 * ref.trajectory.n_frames) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_pickle_raises_NotImplementedError(self): u = MDAnalysis.Universe(PSF, DCD) assert_raises(NotImplementedError, cPickle.dumps, u, protocol=cPickle.HIGHEST_PROTOCOL) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_set_dimensions(self): u = MDAnalysis.Universe(PSF, DCD) box = np.array([10, 11, 12, 90, 90, 90]) @@ -1622,6 +1665,8 @@ def test_set_dimensions(self): class TestPBCFlag(TestCase): + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def setUp(self): self.prec = 3 self.universe = MDAnalysis.Universe(TRZ_psf, TRZ) @@ -1731,6 +1776,8 @@ def test_override_flag(self): class TestAsUniverse(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF_notop, DCD) @@ -1753,6 +1800,8 @@ def test_makeuni(self): class TestFragments(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF, DCD) # To create a fragment with only one atom in, remove a bond @@ -1881,6 +1930,8 @@ class TestCustomReaders(TestCase): """ Can pass a reader as kwarg on Universe creation """ + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def test_custom_reader(self): # check that reader passing works u = MDAnalysis.Universe(TRZ_psf, TRZ, format=MDAnalysis.coordinates.TRZ.TRZReader) @@ -1901,11 +1952,15 @@ def test_custom_reader_singleframe_2(self): topology_format=T, format=R) assert_equal(len(u.atoms), 6) + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def test_custom_parser(self): # topology reader passing works u = MDAnalysis.Universe(TRZ_psf, TRZ, topology_format=MDAnalysis.topology.PSFParser.PSFParser) assert_equal(len(u.atoms), 8184) + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def test_custom_both(self): # use custom for both u = MDAnalysis.Universe(TRZ_psf, TRZ, format=MDAnalysis.coordinates.TRZ.TRZReader, @@ -1914,6 +1969,8 @@ def test_custom_both(self): class TestWrap(TestCase): + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(TRZ_psf, TRZ) self.ag = self.u.atoms[:100] @@ -2117,6 +2174,8 @@ def _change_ag_check_atoms(self, att, vals, ag, ag_setter): assert_equal(getattr(atom, att), val, err_msg="Change to AtomGroup not reflected in Atoms for propert: {0}".format(att)) + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_attributes(self): u = MDAnalysis.Universe(PSF, DCD) u.atoms.occupancies = 1.0 diff --git a/testsuite/MDAnalysisTests/test_atomselections.py b/testsuite/MDAnalysisTests/test_atomselections.py index 7fdf629b349..6d2c43eab09 100644 --- a/testsuite/MDAnalysisTests/test_atomselections.py +++ b/testsuite/MDAnalysisTests/test_atomselections.py @@ -47,9 +47,12 @@ PDB_full, ) from MDAnalysisTests.plugins.knownfailure import knownfailure +from MDAnalysisTests import parser_not_found class TestSelectionsCHARMM(TestCase): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): """Set up the standard AdK system in implicit solvent. @@ -588,6 +591,8 @@ def test_point(self): class TestOrthogonalDistanceSelections(BaseDistanceSelection): + @dec.skipif(parser_not_found('TRZ'), + 'TRZ parser not available. Are you using python 3?') def setUp(self): self.u = mda.Universe(TRZ_psf, TRZ) @@ -740,6 +745,8 @@ def test_props(self): class TestBondedSelection(object): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = mda.Universe(PSF, DCD) @@ -759,6 +766,8 @@ def test_nobonds_warns(self): class TestSelectionErrors(object): + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = mda.Universe(PSF, DCD) diff --git a/testsuite/MDAnalysisTests/test_distances.py b/testsuite/MDAnalysisTests/test_distances.py index 89f481fd14b..fe78bb4e61e 100644 --- a/testsuite/MDAnalysisTests/test_distances.py +++ b/testsuite/MDAnalysisTests/test_distances.py @@ -17,13 +17,14 @@ import MDAnalysis.lib.distances import numpy as np -from numpy.testing import (TestCase, raises, assert_, +from numpy.testing import (TestCase, dec, raises, assert_, assert_almost_equal, assert_equal, assert_raises,) from nose.plugins.attrib import attr from MDAnalysis.tests.datafiles import PSF, DCD, TRIC from MDAnalysis.lib import mdamath +from MDAnalysisTests import parser_not_found class _TestDistanceArray(TestCase): # override backend in test classes @@ -81,6 +82,9 @@ class TestDistanceArray_OpenMP(_TestDistanceArray): class _TestDistanceArrayDCD(TestCase): backend = None + + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.trajectory = self.universe.trajectory @@ -151,6 +155,9 @@ class TestDistanceArrayDCD_OpenMP(_TestDistanceArrayDCD): class _TestSelfDistanceArrayDCD(TestCase): backend = None + + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) self.trajectory = self.universe.trajectory @@ -562,6 +569,8 @@ def setUp(self): def tearDown(self): del self.prec + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def test_ortho_PBC(self): from MDAnalysis.lib.distances import apply_PBC diff --git a/testsuite/MDAnalysisTests/test_modelling.py b/testsuite/MDAnalysisTests/test_modelling.py index 0b246d3b291..24cb6ebe530 100644 --- a/testsuite/MDAnalysisTests/test_modelling.py +++ b/testsuite/MDAnalysisTests/test_modelling.py @@ -22,9 +22,11 @@ import MDAnalysis.core.AtomGroup from MDAnalysis.core.AtomGroup import Atom, AtomGroup from MDAnalysis import NoDataError +from MDAnalysisTests import parser_not_found import numpy as np -from numpy.testing import TestCase, assert_equal, assert_raises, assert_, assert_array_equal +from numpy.testing import (TestCase, dec, assert_equal, assert_raises, assert_, + assert_array_equal) from nose.plugins.attrib import attr import os @@ -203,6 +205,8 @@ def test_emptyAG_ValueError(self): class TestMergeTopology(object): """Test that Merge correct does topology""" + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF, DCD) diff --git a/testsuite/MDAnalysisTests/test_selections.py b/testsuite/MDAnalysisTests/test_selections.py index 2c702e08f34..ca470ce7479 100644 --- a/testsuite/MDAnalysisTests/test_selections.py +++ b/testsuite/MDAnalysisTests/test_selections.py @@ -22,20 +22,23 @@ import re import numpy as np -from numpy.testing import TestCase, assert_equal, assert_array_equal +from numpy.testing import TestCase, assert_equal, assert_array_equal, dec from nose.plugins.attrib import attr from MDAnalysisTests.plugins.knownfailure import knownfailure -from MDAnalysis.lib.util import NamedStream +from MDAnalysis.tests.datafiles import PSF, DCD +from MDAnalysisTests import parser_not_found import MDAnalysis -from MDAnalysis.tests.datafiles import PSF, DCD +from MDAnalysis.lib.util import NamedStream class _SelectionWriter(TestCase): filename = None max_number = 357 # to keep fixtures smallish, only select CAs up to number 357 + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.universe = MDAnalysis.Universe(PSF, DCD) stream = StringIO() diff --git a/testsuite/MDAnalysisTests/test_topology.py b/testsuite/MDAnalysisTests/test_topology.py index 03541a192c4..1036422f9e3 100644 --- a/testsuite/MDAnalysisTests/test_topology.py +++ b/testsuite/MDAnalysisTests/test_topology.py @@ -32,8 +32,9 @@ DLP_CONFIG, DLP_CONFIG_order, DLP_CONFIG_minimal, DLP_HISTORY, DLP_HISTORY_order, DLP_HISTORY_minimal, HoomdXMLdata) from MDAnalysisTests.plugins.knownfailure import knownfailure +from MDAnalysisTests import parser_not_found -from numpy.testing import (TestCase, assert_equal, assert_raises, assert_, +from numpy.testing import (TestCase, dec, assert_equal, assert_raises, assert_, assert_array_equal, assert_almost_equal) from nose.plugins.attrib import attr import numpy as np @@ -335,6 +336,8 @@ class TestTopologyObjects(TestCase): len """ + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.precision = 3 # rather lenient but see #271 self.u = MDAnalysis.Universe(PSF, DCD) @@ -840,6 +843,8 @@ class TestTopologyGroup_Cython(TestCase): - catch errors """ + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF, DCD) self.u.build_topology() @@ -1085,6 +1090,8 @@ class TestTopologyGuessers(TestCase): guess_improper_dihedrals """ + @dec.skipif(parser_not_found('DCD'), + 'DCD parser not available. Are you using python 3?') def setUp(self): self.u = MDAnalysis.Universe(PSF, DCD) From 18beb92d40619ab86fdd71a288d40ba8e85d9e25 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 11:46:44 +0100 Subject: [PATCH 20/25] Make Travis run the tests on python 3 The python 3 tests are allowed to fail so they will not mark pull requests as broken. --- .travis.yml | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0396ec857e0..d8038370596 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,23 @@ -env: - global: - - secure: "HIj3p+p2PV8DBVg/KGUx6n83KwB0ASE5FwOn0SMB9zxnzAqe8sapwdBQdMdq0sXB7xT1spJqRxuxOMVEVn35BNLu7bxMLfa4287C8YXcomnvmv9xruxAsjsIewnNQ80vtPVbQddBPxa4jKbqgPby5QhhAP8KANAqYe44pIV70fY=" - - GH_DOC_BRANCH: develop - - GH_REPOSITORY: github.com/MDAnalysis/mdanalysis.git - - GIT_CI_USER: TravisCI - - GIT_CI_EMAIL: TravisCI@mdanalysis.org - - MDA_DOCDIR: package/doc/html - matrix: - - SETUP=full CYTHONIZE=true - - SETUP=minimal CYTHONIZE=false language: python -python: - - "2.7" +env: + global: + - secure: "HIj3p+p2PV8DBVg/KGUx6n83KwB0ASE5FwOn0SMB9zxnzAqe8sapwdBQdMdq0sXB7xT1spJqRxuxOMVEVn35BNLu7bxMLfa4287C8YXcomnvmv9xruxAsjsIewnNQ80vtPVbQddBPxa4jKbqgPby5QhhAP8KANAqYe44pIV70fY=" + - GH_DOC_BRANCH: develop + - GH_REPOSITORY: github.com/MDAnalysis/mdanalysis.git + - GIT_CI_USER: TravisCI + - GIT_CI_EMAIL: TravisCI@mdanalysis.org + - MDA_DOCDIR: package/doc/html +matrix: + allow_failures: + - python: "3.3" + env: SETUP=full CYTHONIZE=true + include: + - python: "2.7" + env: SETUP=minimal CYTHONIZE=false + - python: "2.7" + env: SETUP=full CYTHONIZE=true + - python: "3.3" + env: SETUP=full CYTHONIZE=true # command to install dependencies addons: apt: @@ -41,7 +47,7 @@ install: - chmod +x testsuite/MDAnalysisTests/mda_nosetests # command to run tests script: - - ./testsuite/MDAnalysisTests/mda_nosetests --with-coverage --cover-package MDAnalysis --processes=2 --process-timeout=300 --with-memleak + - ./testsuite/MDAnalysisTests/mda_nosetests --with-coverage --cover-package MDAnalysis --processes=2 --process-timeout=300 $( if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then echo '--with-memleak'; fi ) - | test ${TRAVIS_PULL_REQUEST} == "false" && \ test ${TRAVIS_BRANCH} == ${GH_DOC_BRANCH} && \ From c4281f3f5cfc8ed5a206de07cefc8bd8340e484c Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 13:52:53 +0100 Subject: [PATCH 21/25] Simplify the __hash__ function of `TopologyObject` Following the comment of @richardjgowers on #658 --- package/MDAnalysis/core/topologyobjects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index c1a64cf8f9f..d8cdb1173ac 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -127,7 +127,7 @@ def __len__(self): def _cmp_key(self): """Unique key for the object to be used to generate the object hash""" # This key must be equal for two object considered as equal by __eq__ - return '_'.join(map(str, sorted(self.indices))) + return self.__class__, tuple(sorted(self.indices)) def __hash__(self): """Makes the object hashable""" From 3acef5be1f328b8df3e3d53e9afcccc5e636b4dc Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 13:54:34 +0100 Subject: [PATCH 22/25] Add a warning when MDAnalysis is imported on py 3 --- package/MDAnalysis/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/package/MDAnalysis/__init__.py b/package/MDAnalysis/__init__.py index 65bbb6266b1..f7db3601edd 100644 --- a/package/MDAnalysis/__init__.py +++ b/package/MDAnalysis/__init__.py @@ -172,3 +172,12 @@ del weakref from .migration.ten2eleven import ten2eleven + +import six +if six.PY3: + warnings.warn('''\ +##### +MDAnalysis on python 3 is highly experimental! +It is mostly non functional and dramatically untested. +Use at your own risks!!! +''') From b51ba1c26b75e9dc9c9f08f1d37fdce6c77abc10 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 14:25:10 +0100 Subject: [PATCH 23/25] Make test_topology.py pass on python 3 Note however than some tests are skipped because they rely on files in unsupported formats. --- package/MDAnalysis/core/topologyobjects.py | 2 +- package/MDAnalysis/topology/TOPParser.py | 4 ++-- testsuite/MDAnalysisTests/test_topology.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index d8cdb1173ac..19b8b642e32 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -571,7 +571,7 @@ def types(self): .. versionadded 0.9.0 """ - return self.topDict.keys() + return list(self.topDict.keys()) @property @cached('dict') diff --git a/package/MDAnalysis/topology/TOPParser.py b/package/MDAnalysis/topology/TOPParser.py index ff3065a6082..c5b843c76c2 100644 --- a/package/MDAnalysis/topology/TOPParser.py +++ b/package/MDAnalysis/topology/TOPParser.py @@ -42,9 +42,9 @@ """ from __future__ import absolute_import - from six.moves import range +import functools from math import ceil from ..core.AtomGroup import Atom @@ -143,7 +143,7 @@ def parse(self): # Open and check top validity # Reading header info POINTERS with openany(self.filename) as topfile: - next_line = topfile.next + next_line = functools.partial(next, topfile) header = next_line() if header[:3] != "%VE": raise ValueError("{0} is not a valid TOP file. %VE Missing in header".format(topfile)) diff --git a/testsuite/MDAnalysisTests/test_topology.py b/testsuite/MDAnalysisTests/test_topology.py index 1036422f9e3..af35a3ff190 100644 --- a/testsuite/MDAnalysisTests/test_topology.py +++ b/testsuite/MDAnalysisTests/test_topology.py @@ -506,12 +506,12 @@ def test_angles_contains(self): assert_equal(('23', '73', '1') in self.a_td, True) def test_angles_uniqueness(self): - bondtypes = self.a_td.keys() + bondtypes = list(self.a_td.keys()) assert_equal(any(b[::-1] in bondtypes for b in bondtypes if b[::-1] != b), False) def test_angles_reversal(self): - bondtypes = self.a_td.keys() + bondtypes = list(self.a_td.keys()) b = bondtypes[1] assert_equal(all([b in self.a_td, b[::-1] in self.a_td]), True) @@ -527,12 +527,12 @@ def test_dihedrals_contains(self): assert_equal(('30', '29', '20', '70') in self.t_td, True) def test_dihedrals_uniqueness(self): - bondtypes = self.t_td.keys() + bondtypes = list(self.t_td.keys()) assert_equal(any(b[::-1] in bondtypes for b in bondtypes if b[::-1] != b), False) def test_dihedrals_reversal(self): - bondtypes = self.t_td.keys() + bondtypes = list(self.t_td.keys()) b = bondtypes[1] assert_equal(all([b in self.t_td, b[::-1] in self.t_td]), True) From b0f0364acb85428184df181cfa7f293794ec13ee Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 14:47:32 +0100 Subject: [PATCH 24/25] Skip a test that relies on the LAMMPS parser --- testsuite/MDAnalysisTests/coordinates/test_lammps.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testsuite/MDAnalysisTests/coordinates/test_lammps.py b/testsuite/MDAnalysisTests/coordinates/test_lammps.py index 79c7edc9317..e15f2b5006e 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_lammps.py +++ b/testsuite/MDAnalysisTests/coordinates/test_lammps.py @@ -210,6 +210,8 @@ def test_Writer_is_LAMMPS(self): with mda.coordinates.LAMMPS.DCDWriter(self.outfile, n_atoms=10) as W: assert_(W.flavor, self.flavor) + @dec.skipif(parser_not_found('LAMMPS'), + 'LAMMPS parser not available. Are you using python 3?') def test_open(self): def open_dcd(): try: From 187272c01bcef25b329a3fa846f84f9e25dc6a05 Mon Sep 17 00:00:00 2001 From: Jonathan Barnoud Date: Mon, 25 Jan 2016 15:18:50 +0100 Subject: [PATCH 25/25] Random fixes to improve python 3 compatibility --- package/MDAnalysis/coordinates/PDB.py | 7 ++++--- package/MDAnalysis/coordinates/TRJ.py | 8 ++++---- testsuite/MDAnalysisTests/coordinates/test_lammps.py | 2 -- testsuite/MDAnalysisTests/coordinates/test_xdr.py | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 4a3c223eefb..84417b3dd13 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -596,7 +596,7 @@ def _read_frame(self, frame): occupancy = np.ones(self._n_atoms) with util.openany(self.filename, 'r') as f: for i in range(line): - f.next() # forward to frame + next(f) # forward to frame for line in f: if line[:6] == 'ENDMDL': break @@ -611,8 +611,9 @@ def _read_frame(self, frame): continue elif line[:6] in ('ATOM ', 'HETATM'): # we only care about coordinates - self.ts._pos[pos] = map(float, [line[30:38], line[38:46], - line[46:54]]) + self.ts._pos[pos] = list(map(float, [line[30:38], + line[38:46], + line[46:54]])) # TODO import bfactors - might these change? try: occupancy[pos] = float(line[54:60]) diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index b70c7e00045..7788b6b7905 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -248,7 +248,7 @@ def _read_next_timestep(self): # Read box information if self.periodic: - line = self.trjfile.next() + line = next(self.trjfile) box = self.box_line_parser.read(line) ts._unitcell[:3] = np.array(box, dtype=np.float32) ts._unitcell[3:] = [90., 90., 90.] # assumed @@ -294,7 +294,7 @@ def _detect_amber_box(self): self._read_next_timestep() ts = self.ts # TODO: what do we do with 1-frame trajectories? Try..except EOFError? - line = self.trjfile.next() + line = next(self.trjfile) nentries = self.default_line_parser.number_of_matches(line) if nentries == 3: self.periodic = True @@ -324,7 +324,7 @@ def _read_trj_n_frames(self, filename): counter = 0 try: while True: - self.next() + next(self) counter += 1 except EOFError: self.rewind() @@ -363,7 +363,7 @@ def close(self): def rewind(self): """Reposition at the beginning of the trajectory""" self._reopen() - self.next() + next(self) class NCDFReader(base.Reader): diff --git a/testsuite/MDAnalysisTests/coordinates/test_lammps.py b/testsuite/MDAnalysisTests/coordinates/test_lammps.py index e15f2b5006e..79c7edc9317 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_lammps.py +++ b/testsuite/MDAnalysisTests/coordinates/test_lammps.py @@ -210,8 +210,6 @@ def test_Writer_is_LAMMPS(self): with mda.coordinates.LAMMPS.DCDWriter(self.outfile, n_atoms=10) as W: assert_(W.flavor, self.flavor) - @dec.skipif(parser_not_found('LAMMPS'), - 'LAMMPS parser not available. Are you using python 3?') def test_open(self): def open_dcd(): try: diff --git a/testsuite/MDAnalysisTests/coordinates/test_xdr.py b/testsuite/MDAnalysisTests/coordinates/test_xdr.py index 09898b8af1f..c080d16ebec 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_xdr.py +++ b/testsuite/MDAnalysisTests/coordinates/test_xdr.py @@ -807,7 +807,7 @@ def test_persistent_offsets_readonly(self): assert_equal(os.path.exists( XDR.offsets_filename(self.trajectory.filename)), False) - os.chmod(self.tmpdir.name, 0555) + os.chmod(self.tmpdir.name, 0o555) self.trajectory._read_offsets(store=True) assert_equal(os.path.exists( XDR.offsets_filename(self.trajectory.filename)), False)