Skip to content

Commit

Permalink
Fix PDBWriter with StringIO for invalid coordinates (#2518)
Browse files Browse the repository at this point in the history
* failing test

* check if file is StringIO

* changelog

* small change

* fix typos

* actually check exception message

* fix problem with exception catch

* use pytest match
  • Loading branch information
RMeli authored Feb 11, 2020
1 parent 121ec06 commit abc9049
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
2 changes: 2 additions & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ mm/dd/yy richardjgowers, kain88-de, lilyminium, p-j-smith, bdice, joaomcteixeira
* 0.21.0

Fixes
* Handle exception when PDBWriter is trying to remove an invalid StringIO
(Issue #2512)
* Clarifies density_from_Universe docs and adds user warning (Issue #2372)
* Fix upstream deprecation of `matplotlib.axis.Tick` attributes in
`MDAnalysis.analysis.psa`
Expand Down
12 changes: 12 additions & 0 deletions package/MDAnalysis/coordinates/PDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,10 @@ def _check_pdb_coordinates(self):
coordinates and closes the file.
Raises :exc:`ValueError` if the coordinates fail the check.
.. versionchanged: 1.0.0
Check if :attr:`filename` is `StringIO` when attempting to remove
a PDB file with invalid coordinates (Issue #2512)
"""
atoms = self.obj.atoms # make sure to use atoms (Issue 46)
# can write from selection == Universe (Issue 49)
Expand All @@ -678,6 +682,14 @@ def _check_pdb_coordinates(self):
except OSError as err:
if err.errno == errno.ENOENT:
pass
else:
raise
except TypeError:
if isinstance(self.filename, StringIO):
pass
else:
raise

raise ValueError("PDB files must have coordinate values between "
"{0:.3f} and {1:.3f} Angstroem: file writing was "
"aborted.".format(self.pdb_coor_limits["min"],
Expand Down
24 changes: 24 additions & 0 deletions testsuite/MDAnalysisTests/coordinates/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ def universe(self):
def universe2(self):
return mda.Universe(PSF, DCD)

@pytest.fixture
def universe3(self):
return mda.Universe(PDB)

@pytest.fixture
def outfile(self, tmpdir):
return str(tmpdir.mkdir("PDBWriter").join('primitive-pdb-writer' + self.ext))
Expand Down Expand Up @@ -362,6 +366,26 @@ def test_segid_chainid(self, universe2, outfile):
u_pdb = mda.Universe(outfile)
assert u_pdb.segments.chainIDs[0][0] == ref_id

def test_stringio_outofrange(self, universe3):
"""
Check that when StringIO is used, the correct out-of-range error for
coordinates is raised (instead of failing trying to remove StringIO
as a file).
"""

u = universe3

u.atoms.translate([-9999, -9999, -9999])

outstring = StringIO()

errmsg = "PDB files must have coordinate values between"

with pytest.raises(ValueError, match=errmsg):
with mda.coordinates.PDB.PDBWriter(outstring) as writer:
writer.write(u.atoms)


class TestMultiPDBReader(object):
@staticmethod
@pytest.fixture(scope='class')
Expand Down

0 comments on commit abc9049

Please sign in to comment.