From b003118feb3a3fd8f01054f786b7f8662900a8c7 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 18:54:41 -0400 Subject: [PATCH 01/15] assigned from e --- package/MDAnalysis/analysis/align.py | 6 +- package/MDAnalysis/analysis/density.py | 22 ++--- .../analysis/hbonds/hbond_autocorrel.py | 4 +- package/MDAnalysis/analysis/hole.py | 4 +- package/MDAnalysis/analysis/nuclinfo.py | 8 +- package/MDAnalysis/analysis/polymer.py | 4 +- package/MDAnalysis/analysis/psa.py | 15 +-- package/MDAnalysis/analysis/rms.py | 8 +- package/MDAnalysis/auxiliary/XVG.py | 8 +- package/MDAnalysis/auxiliary/core.py | 9 +- package/MDAnalysis/coordinates/CRD.py | 4 +- package/MDAnalysis/coordinates/GRO.py | 4 +- package/MDAnalysis/coordinates/GSD.py | 4 +- package/MDAnalysis/coordinates/LAMMPS.py | 13 +-- package/MDAnalysis/coordinates/MOL2.py | 8 +- package/MDAnalysis/coordinates/PDB.py | 8 +- package/MDAnalysis/coordinates/TRJ.py | 24 ++--- package/MDAnalysis/coordinates/TRZ.py | 4 +- package/MDAnalysis/coordinates/TXYZ.py | 2 +- package/MDAnalysis/coordinates/XYZ.py | 6 +- package/MDAnalysis/coordinates/base.py | 27 +++--- package/MDAnalysis/coordinates/core.py | 4 +- package/MDAnalysis/coordinates/memory.py | 14 +-- package/MDAnalysis/core/__init__.py | 5 +- package/MDAnalysis/core/_get_readers.py | 17 ++-- package/MDAnalysis/core/groups.py | 96 ++++++++++--------- package/MDAnalysis/core/selection.py | 30 +++--- package/MDAnalysis/core/topologyattrs.py | 14 +-- package/MDAnalysis/core/topologyobjects.py | 12 +-- package/MDAnalysis/core/universe.py | 14 +-- package/MDAnalysis/lib/distances.py | 7 +- package/MDAnalysis/lib/util.py | 45 +++++---- package/MDAnalysis/selections/__init__.py | 4 +- package/MDAnalysis/tests/datafiles.py | 4 +- package/MDAnalysis/topology/CRDParser.py | 4 +- package/MDAnalysis/topology/DMSParser.py | 11 ++- package/MDAnalysis/topology/GROParser.py | 8 +- package/MDAnalysis/topology/LAMMPSParser.py | 7 +- package/MDAnalysis/topology/PSFParser.py | 4 +- package/MDAnalysis/topology/TOPParser.py | 4 +- package/MDAnalysis/transformations/fit.py | 24 ++--- package/MDAnalysis/transformations/rotate.py | 12 +-- .../MDAnalysis/transformations/translate.py | 6 +- package/MDAnalysis/units.py | 16 ++-- .../MDAnalysis/visualization/streamlines.py | 11 ++- 45 files changed, 297 insertions(+), 268 deletions(-) diff --git a/package/MDAnalysis/analysis/align.py b/package/MDAnalysis/analysis/align.py index 7c94a1a07cd..9129acf3d35 100644 --- a/package/MDAnalysis/analysis/align.py +++ b/package/MDAnalysis/analysis/align.py @@ -506,9 +506,9 @@ def alignto(mobile, reference, select="all", weights=None, try: # treat subselection as AtomGroup mobile_atoms = subselection.atoms - except AttributeError: + except AttributeError as e: raise TypeError("subselection must be a selection string, an" - " AtomGroup or Universe or None") + " AtomGroup or Universe or None") from e # _fit_to DOES subtract center of mass, will provide proper min_rmsd mobile_atoms, new_rmsd = _fit_to(mobile_coordinates, ref_coordinates, @@ -1167,7 +1167,7 @@ def get_atoms_byres(g, match_mask=np.logical_not(mismatch_mask)): "Try to improve your selections for mobile and reference.").format( ag1.n_atoms, ag2.n_atoms) logger.error(errmsg) - raise SelectionError(errmsg) + raise SelectionError(errmsg) from None if np.any(mass_mismatches): # Test 2 failed. diff --git a/package/MDAnalysis/analysis/density.py b/package/MDAnalysis/analysis/density.py index bd8f213d80f..28543cbde53 100644 --- a/package/MDAnalysis/analysis/density.py +++ b/package/MDAnalysis/analysis/density.py @@ -372,12 +372,12 @@ def _check_set_unit(self, u): try: units.conversion_factor[unit_type][value] self.units[unit_type] = value - except KeyError: - raise ValueError('Unit ' + str(value) + ' of type ' + str(unit_type) + ' is not recognized.') - except AttributeError: + except KeyError as e: + raise ValueError('Unit ' + str(value) + ' of type ' + str(unit_type) + ' is not recognized.') from e + except AttributeError as e: errmsg = '"unit" must be a dictionary with keys "length" and "density.' logger.fatal(errmsg) - raise ValueError(errmsg) + raise ValueError(errmsg) from e # need at least length and density (can be None) if 'length' not in self.units: raise ValueError('"unit" must contain a unit for "length".') @@ -485,8 +485,8 @@ def convert_density(self, unit='Angstrom'): try: self.grid *= units.get_conversion_factor('density', self.units['density'], unit) - except KeyError: - raise ValueError("The name of the unit ({0!r} supplied) must be one of:\n{1!r}".format(unit, units.conversion_factor['density'].keys())) + except KeyError as e: + raise ValueError("The name of the unit ({0!r} supplied) must be one of:\n{1!r}".format(unit, units.conversion_factor['density'].keys())) from e self.units['density'] = unit def __repr__(self): @@ -526,14 +526,14 @@ def _set_user_grid(gridcenter, xdim, ydim, zdim, smin, smax): # Check user inputs try: gridcenter = np.asarray(gridcenter, dtype=np.float32) - except ValueError: - raise ValueError("Non-number values assigned to gridcenter") + except ValueError as e: + raise ValueError("Non-number values assigned to gridcenter") from e if gridcenter.shape != (3,): - raise ValueError("gridcenter must be a 3D coordinate") + raise ValueError("gridcenter must be a 3D coordinate") from e try: xyzdim = np.array([xdim, ydim, zdim], dtype=np.float32) - except ValueError: - raise ValueError("xdim, ydim, and zdim must be numbers") + except ValueError as e: + raise ValueError("xdim, ydim, and zdim must be numbers") from e # Set min/max by shifting by half the edge length of each dimension umin = gridcenter - xyzdim/2 diff --git a/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py b/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py index ebb2933c317..3bfb30a0b28 100644 --- a/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py +++ b/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py @@ -300,8 +300,8 @@ def __init__(self, universe, # check that slicing is possible try: self.u.trajectory[0] - except: - raise ValueError("Trajectory must support slicing") + except Exception as e: + raise ValueError("Trajectory must support slicing") from e self.h = hydrogens self.a = acceptors diff --git a/package/MDAnalysis/analysis/hole.py b/package/MDAnalysis/analysis/hole.py index c617de56581..a53004cae15 100644 --- a/package/MDAnalysis/analysis/hole.py +++ b/package/MDAnalysis/analysis/hole.py @@ -1030,7 +1030,7 @@ def create_vmd_surface(self, filename="hole.vmd", **kwargs): except subprocess.CalledProcessError as err: os.unlink(tmp_sos) logger.fatal("sph_process failed ({0})".format(err.returncode)) - raise OSError(err.returncode, "sph_process failed") + raise OSError(err.returncode, "sph_process failed") from err except: os.unlink(tmp_sos) raise @@ -1045,7 +1045,7 @@ def create_vmd_surface(self, filename="hole.vmd", **kwargs): stderr=FNULL) except subprocess.CalledProcessError as err: logger.fatal("sos_triangle failed ({0})".format(err.returncode)) - raise OSError(err.returncode, "sos_triangle failed") + raise OSError(err.returncode, "sos_triangle failed") from err finally: os.unlink(tmp_sos) diff --git a/package/MDAnalysis/analysis/nuclinfo.py b/package/MDAnalysis/analysis/nuclinfo.py index 05b9f07c580..dd6b36d1b13 100644 --- a/package/MDAnalysis/analysis/nuclinfo.py +++ b/package/MDAnalysis/analysis/nuclinfo.py @@ -710,9 +710,11 @@ def hydroxyl(universe, seg, i): "atom {0!s} {1!s} H2'".format(seg, i)) try: hydr = h.dihedral.value() % 360 - except ValueError: - raise ValueError("Resid {0} does not contain atoms C1', C2', O2', H2' but atoms {1}" - .format(i, str(list(h.atoms)))) + except ValueError as e: + errmsg = ( + "Resid {0} does not contain atoms C1', C2', O2', H2' but atoms {1}" + ) + raise ValueError(errmsg.format(i, str(list(h.atoms)))) from e return hydr diff --git a/package/MDAnalysis/analysis/polymer.py b/package/MDAnalysis/analysis/polymer.py index 642297da2fe..62440b5f034 100644 --- a/package/MDAnalysis/analysis/polymer.py +++ b/package/MDAnalysis/analysis/polymer.py @@ -247,8 +247,8 @@ def _perform_fit(self): """Fit the results to an exponential decay""" try: self.results - except AttributeError: - raise NoDataError("Use the run method first") + except AttributeError as e: + raise NoDataError("Use the run method first") from e self.x = np.arange(len(self.results)) * self.lb self.lp = fit_exponential_decay(self.x, self.results) diff --git a/package/MDAnalysis/analysis/psa.py b/package/MDAnalysis/analysis/psa.py index d0d8d36d3d6..5b977af70f0 100644 --- a/package/MDAnalysis/analysis/psa.py +++ b/package/MDAnalysis/analysis/psa.py @@ -266,9 +266,10 @@ def get_path_metric_func(name): try: return path_metrics[name] except KeyError as key: - raise KeyError('Path metric "{}" not found. Valid selections: {}' - ''.format(key, " ".join('"{}"'.format(n) - for n in path_metrics.keys()))) + errmsg = ('Path metric "{}" not found. Valid selections: {}' + ''.format(key, " ".join('"{}"'.format(n) + for n in path_metrics.keys()))) + raise KeyError(errmsg) from key def sqnorm(v, axis=None): @@ -1864,7 +1865,7 @@ def plot_annotated_heatmap(self, filename=None, linkage='ward', \ try: import seaborn.apionly as sns - except ImportError: + except ImportError as e: raise ImportError( """ERROR --- The seaborn package cannot be found! @@ -1880,7 +1881,7 @@ def plot_annotated_heatmap(self, filename=None, linkage='ward', \ and install in the usual manner. """ - ) + ) from e if self.D is None: raise ValueError( @@ -1973,7 +1974,7 @@ def plot_nearest_neighbors(self, filename=None, idx=0, \ from matplotlib.pyplot import figure, savefig, tight_layout, clf, show try: import seaborn.apionly as sns - except ImportError: + except ImportError as e: raise ImportError( """ERROR --- The seaborn package cannot be found! @@ -1989,7 +1990,7 @@ def plot_nearest_neighbors(self, filename=None, idx=0, \ and install in the usual manner. """ - ) + ) from e colors = sns.xkcd_palette(["cherry", "windows blue"]) diff --git a/package/MDAnalysis/analysis/rms.py b/package/MDAnalysis/analysis/rms.py index aabd8ae8866..ce899911748 100644 --- a/package/MDAnalysis/analysis/rms.py +++ b/package/MDAnalysis/analysis/rms.py @@ -286,17 +286,17 @@ def process_selection(select): elif type(select) is tuple: try: select = {'mobile': select[0], 'reference': select[1]} - except IndexError: + except IndexError as e: raise IndexError("select must contain two selection strings " - "(reference, mobile)") + "(reference, mobile)") from e elif type(select) is dict: # compatability hack to use new nomenclature try: select['mobile'] select['reference'] - except KeyError: + except KeyError as e: raise KeyError("select dictionary must contain entries for keys " - "'mobile' and 'reference'.") + "'mobile' and 'reference'.") from e else: raise TypeError("'select' must be either a string, 2-tuple, or dict") select['mobile'] = asiterable(select['mobile']) diff --git a/package/MDAnalysis/auxiliary/XVG.py b/package/MDAnalysis/auxiliary/XVG.py index c1847509bdf..cc19462cd97 100644 --- a/package/MDAnalysis/auxiliary/XVG.py +++ b/package/MDAnalysis/auxiliary/XVG.py @@ -148,9 +148,9 @@ def _select_data(self, key): if isinstance(key, numbers.Integral): try: return self._data[key] - except IndexError: + except IndexError as e: raise ValueError('{} not a valid index for data with {} ' - 'columns'.format(key, len(self._data))) + 'columns'.format(key, len(self._data))) from e else: return np.array([self._select_data(i) for i in key]) @@ -318,13 +318,13 @@ def _read_next_step(self): # see if we've set n_cols yet... try: auxstep._n_cols - except AttributeError: + except AttributeError as e: # haven't set n_cols yet; set now auxstep._n_cols = len(auxstep._data) if len(auxstep._data) != auxstep._n_cols: raise ValueError('Step {0} has {1} columns instead of ' '{2}'.format(self.step, len(auxstep._data), - auxstep._n_cols)) + auxstep._n_cols)) from e return auxstep # line is comment only - move to next line = next(self.auxfile) diff --git a/package/MDAnalysis/auxiliary/core.py b/package/MDAnalysis/auxiliary/core.py index 3c3f2c918ae..de9b1a3088e 100644 --- a/package/MDAnalysis/auxiliary/core.py +++ b/package/MDAnalysis/auxiliary/core.py @@ -74,14 +74,15 @@ def get_auxreader_for(auxdata=None, format=None): format = format.upper() try: return _AUXREADERS[format] - except KeyError: + except KeyError as e: raise ValueError("Unknown auxiliary data format for auxdata: " - "{0}".format(auxdata)) + "{0}".format(auxdata)) from e else: try: return _AUXREADERS[format] - except KeyError: - raise ValueError("Unknown auxiliary data format {0}".format(format)) + except KeyError as e: + errmsg = "Unknown auxiliary data format {0}".format(format) + raise ValueError(errmsg) from e def auxreader(auxdata, format=None, **kwargs): """ Return an auxiliary reader instance for *auxdata*. diff --git a/package/MDAnalysis/coordinates/CRD.py b/package/MDAnalysis/coordinates/CRD.py index 0d3e4de5ab0..9db5a75badf 100644 --- a/package/MDAnalysis/coordinates/CRD.py +++ b/package/MDAnalysis/coordinates/CRD.py @@ -80,9 +80,9 @@ def _read_first_frame(self): coords_list.append(np.array(line[45:100].split()[0:3], dtype=float)) else: coords_list.append(np.array(line[20:50].split()[0:3], dtype=float)) - except: + except Exception as e: raise ValueError("Check CRD format at line {0}: {1}" - "".format(linenum, line.rstrip())) + "".format(linenum, line.rstrip())) from e self.n_atoms = len(coords_list) diff --git a/package/MDAnalysis/coordinates/GRO.py b/package/MDAnalysis/coordinates/GRO.py index 25f42c409f3..abb34a9320d 100644 --- a/package/MDAnalysis/coordinates/GRO.py +++ b/package/MDAnalysis/coordinates/GRO.py @@ -366,11 +366,11 @@ def write(self, obj): ag_or_ts = obj.atoms # can write from selection == Universe (Issue 49) - except AttributeError: + except AttributeError as e: if isinstance(obj, base.Timestep): ag_or_ts = obj.copy() else: - raise TypeError("No Timestep found in obj argument") + raise TypeError("No Timestep found in obj argument") from e try: velocities = ag_or_ts.velocities diff --git a/package/MDAnalysis/coordinates/GSD.py b/package/MDAnalysis/coordinates/GSD.py index efa8a3c1731..613f6d80efb 100644 --- a/package/MDAnalysis/coordinates/GSD.py +++ b/package/MDAnalysis/coordinates/GSD.py @@ -105,8 +105,8 @@ def _reopen(self): def _read_frame(self, frame): try : myframe = self._file[frame] - except IndexError : - raise IOError + except IndexError as e: + raise IOError from e # set frame number self._frame = frame diff --git a/package/MDAnalysis/coordinates/LAMMPS.py b/package/MDAnalysis/coordinates/LAMMPS.py index cd1fe002198..096d8c3c3f8 100644 --- a/package/MDAnalysis/coordinates/LAMMPS.py +++ b/package/MDAnalysis/coordinates/LAMMPS.py @@ -160,8 +160,9 @@ def __init__(self, *args, **kwargs): try: if units.unit_types[unit] != unit_type: raise TypeError("LAMMPS DCDWriter: wrong unit {0!r} for unit type {1!r}".format(unit, unit_type)) - except KeyError: - raise ValueError("LAMMPS DCDWriter: unknown unit {0!r}".format(unit)) + except KeyError as e: + errmsg = ("LAMMPS DCDWriter: unknown unit {0!r}".format(unit)) + raise ValueError(errmsg) from e super(DCDWriter, self).__init__(*args, **kwargs) @@ -340,10 +341,10 @@ def _write_bonds(self, bonds): try: self.f.write('{:d} {:d} '.format(i, int(bond.type))+\ ' '.join((bond.atoms.indices + 1).astype(str))+'\n') - except TypeError: + except TypeError as e: raise TypeError('LAMMPS DATAWriter: Trying to write bond, ' 'but bond type {} is not ' - 'numerical.'.format(bond.type)) + 'numerical.'.format(bond.type)) from e def _write_dimensions(self, dimensions): """Convert dimensions to triclinic vectors, convert lengths to native @@ -401,9 +402,9 @@ def write(self, selection, frame=None): # check that types can be converted to ints if they aren't ints already try: atoms.types.astype(np.int32) - except ValueError: + except ValueError as e: raise ValueError('LAMMPS.DATAWriter: atom types must be '+ - 'convertible to integers') + 'convertible to integers') from e try: velocities = atoms.velocities diff --git a/package/MDAnalysis/coordinates/MOL2.py b/package/MDAnalysis/coordinates/MOL2.py index 948ef58b7e2..285a4098dd8 100644 --- a/package/MDAnalysis/coordinates/MOL2.py +++ b/package/MDAnalysis/coordinates/MOL2.py @@ -218,9 +218,9 @@ def _read_frame(self, frame): unitcell = np.zeros(6, dtype=np.float32) try: block = self.frames[frame] - except IndexError: + except IndexError as e: raise IOError("Invalid frame {0} for trajectory with length {1}" - "".format(frame, len(self))) + "".format(frame, len(self))) from e sections, coords = self.parse_block(block) @@ -313,9 +313,9 @@ def encode_block(self, obj): try: molecule = ts.data['molecule'] - except KeyError: + except KeyError as e: raise NotImplementedError( - "MOL2Writer cannot currently write non MOL2 data") + "MOL2Writer cannot currently write non MOL2 data") from e # Need to remap atom indices to 1 based in this selection mapping = {a: i for i, a in enumerate(obj.atoms, start=1)} diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index ffb275ce3ec..459e8d47132 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -366,8 +366,8 @@ def _read_frame(self, frame): try: start = self._start_offsets[frame] stop = self._stop_offsets[frame] - except IndexError: # out of range of known frames - raise IOError + except IndexError as e: # out of range of known frames + raise IOError from e pos = 0 occupancy = np.ones(self.n_atoms) @@ -835,9 +835,9 @@ def write_next_timestep(self, ts=None, **kwargs): if ts is None: try: ts = self.ts - except AttributeError: + except AttributeError as e: raise NoDataError("PBDWriter: no coordinate data to write to " - "trajectory file") + "trajectory file") from e self._check_pdb_coordinates() self._write_timestep(ts, **kwargs) diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index 7ff3f15d495..223a30d6493 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -494,11 +494,11 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): "Conventions)".format(self.filename)) logger.fatal(errmsg) raise TypeError(errmsg) - except AttributeError: + except AttributeError as e: errmsg = "NCDF trajectory {0} is missing Conventions".format( self.filename) logger.fatal(errmsg) - raise ValueError(errmsg) + raise ValueError(errmsg) from e # AMBER NetCDF files should also have a ConventionVersion try: @@ -509,10 +509,10 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): ConventionVersion, self.version)) warnings.warn(wmsg) logger.warning(wmsg) - except AttributeError: + except AttributeError as e: errmsg = "NCDF trajectory {0} is missing ConventionVersion".format( self.filename) - raise ValueError(errmsg) + raise ValueError(errmsg) from e # The AMBER NetCDF standard enforces 64 bit offsets if not self.trjfile.version_byte == 2: @@ -529,9 +529,9 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): if not self.trjfile.dimensions['spatial'] == 3: errmsg = "Incorrect spatial value for NCDF trajectory file" raise TypeError(errmsg) - except KeyError: + except KeyError as e: errmsg = "NCDF trajectory does not contain spatial dimension" - raise ValueError(errmsg) + raise ValueError(errmsg) from e # AMBER NetCDF specs require program and programVersion. Warn users # if those attributes do not exist @@ -550,10 +550,10 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): "Note: n_atoms can be None and then the ncdf value " "is used!".format(n_atoms, self.n_atoms)) raise ValueError(errmsg) - except KeyError: + except KeyError as e: errmsg = ("NCDF trajectory {0} does not contain atom " "information".format(self.filename)) - raise ValueError(errmsg) + raise ValueError(errmsg) from e try: self.n_frames = self.trjfile.dimensions['frame'] @@ -564,10 +564,10 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): # the number of frames from somewhere such as the time variable: if self.n_frames is None: self.n_frames = self.trjfile.variables['time'].shape[0] - except KeyError: + except KeyError as e: errmsg = ("NCDF trajectory {0} does not contain frame " "information".format(self.filename)) - raise ValueError(errmsg) + raise ValueError(errmsg) from e try: self.remarks = self.trjfile.title @@ -708,8 +708,8 @@ def _read_next_timestep(self, ts=None): ts = self.ts try: return self._read_frame(self._current_frame + 1) - except IndexError: - raise IOError + except IndexError as e: + raise IOError from e def _get_dt(self): t1 = self.trjfile.variables['time'][1] diff --git a/package/MDAnalysis/coordinates/TRZ.py b/package/MDAnalysis/coordinates/TRZ.py index a469ee09aba..53414594f52 100644 --- a/package/MDAnalysis/coordinates/TRZ.py +++ b/package/MDAnalysis/coordinates/TRZ.py @@ -269,8 +269,8 @@ def _read_next_timestep(self, ts=None): ts._forces[:, 0] = data['fx'] ts._forces[:, 1] = data['fy'] ts._forces[:, 2] = data['fz'] - except IndexError: # Raises indexerror if data has no data (EOF) - raise IOError + except IndexError as e: # Raises indexerror if data has no data (EOF) + raise IOError from e else: # Convert things read into MDAnalysis' native formats (nm -> angstroms) if self.convert_units: diff --git a/package/MDAnalysis/coordinates/TXYZ.py b/package/MDAnalysis/coordinates/TXYZ.py index c8c7dc379a3..8b93cf7138b 100644 --- a/package/MDAnalysis/coordinates/TXYZ.py +++ b/package/MDAnalysis/coordinates/TXYZ.py @@ -154,7 +154,7 @@ def _read_next_timestep(self, ts=None): ts.frame += 1 return ts except (ValueError, IndexError) as err: - raise EOFError(err) + raise EOFError(err) from err def _reopen(self): self.close() diff --git a/package/MDAnalysis/coordinates/XYZ.py b/package/MDAnalysis/coordinates/XYZ.py index 149467f5c04..37aa8b8c3d3 100644 --- a/package/MDAnalysis/coordinates/XYZ.py +++ b/package/MDAnalysis/coordinates/XYZ.py @@ -200,11 +200,11 @@ def write(self, obj): # but this is not tested.) try: atoms = obj.atoms - except AttributeError: + except AttributeError as e: if isinstance(obj, base.Timestep): ts = obj else: - raise TypeError("No Timestep found in obj argument") + raise TypeError("No Timestep found in obj argument") from e else: if hasattr(obj, 'universe'): # For AtomGroup and children (Residue, ResidueGroup, Segment) @@ -376,7 +376,7 @@ def _read_next_timestep(self, ts=None): ts.frame += 1 return ts except (ValueError, IndexError) as err: - raise EOFError(err) + raise EOFError(err) from err def _reopen(self): self.close() diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index d29b741fd75..42f30ee8220 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -508,23 +508,23 @@ def copy_slice(self, sel): except NoDataError: # It's cool if there's no Data, we'll live pos = None - except: + except Exception as e: raise TypeError("Selection type must be compatible with slicing" - " the coordinates") + " the coordinates") from e try: vel = self.velocities[sel, :] except NoDataError: vel = None - except: + except Exception as e: raise TypeError("Selection type must be compatible with slicing" - " the coordinates") + " the coordinates") from e try: force = self.forces[sel, :] except NoDataError: force = None - except: + except Exception as e: raise TypeError("Selection type must be compatible with slicing" - " the coordinates") + " the coordinates") from e new_TS = self.__class__.from_coordinates( positions=pos, @@ -1408,7 +1408,7 @@ def next(self): ts = self._read_next_timestep() except (EOFError, IOError): self.rewind() - raise StopIteration + raise StopIteration from None else: for auxname in self.aux_list: ts = self._auxs[auxname].update_ts(ts) @@ -1591,9 +1591,9 @@ def _sliced_iter(self, start, stop, step): for i in range(start, stop, step): yield self._read_frame_with_aux(i) self.rewind() - except TypeError: # if _read_frame not implemented + except TypeError as e: # if _read_frame not implemented raise TypeError("{0} does not support slicing." - "".format(self.__class__.__name__)) + "".format(self.__class__.__name__)) from e def check_slice_indices(self, start, stop, step): """Check frame indices are valid and clip to fit trajectory. @@ -2011,8 +2011,9 @@ def add_transformations(self, *transformations): try: self.transformations = transformations - except ValueError: - raise ValueError("Can't add transformations again. Please create new Universe object") + except ValueError as e: + errmsg = "Can't add transformations again. Please create new Universe object" + raise ValueError(errmsg) from e else: self.ts = self._apply_transformations(self.ts) @@ -2175,8 +2176,8 @@ def write(self, obj): try: # special case: can supply a Universe, too... ts = obj.trajectory.ts - except AttributeError: - raise TypeError("No Timestep found in obj argument") + except AttributeError as e: + raise TypeError("No Timestep found in obj argument") from e return self.write_next_timestep(ts) def __del__(self): diff --git a/package/MDAnalysis/coordinates/core.py b/package/MDAnalysis/coordinates/core.py index 8f3c0b8aea4..ce48d768814 100644 --- a/package/MDAnalysis/coordinates/core.py +++ b/package/MDAnalysis/coordinates/core.py @@ -83,9 +83,9 @@ def reader(filename, format=None, **kwargs): Reader = get_reader_for(filename, format=format) try: return Reader(filename, **kwargs) - except ValueError: + except ValueError as e: raise TypeError('Unable to read {fn} with {r}.'.format(fn=filename, - r=Reader)) + r=Reader)) from e def writer(filename, n_atoms=None, **kwargs): diff --git a/package/MDAnalysis/coordinates/memory.py b/package/MDAnalysis/coordinates/memory.py index 2ce79adf93a..dcd97d5c32d 100644 --- a/package/MDAnalysis/coordinates/memory.py +++ b/package/MDAnalysis/coordinates/memory.py @@ -318,7 +318,7 @@ def __init__(self, coordinate_array, order='fac', except AttributeError as e: raise TypeError("The input has to be a numpy.ndarray that " "corresponds to the layout specified by the " - "'order' keyword.") + "'order' keyword.") from e self.set_array(coordinate_array, order) self.n_frames = \ @@ -329,9 +329,9 @@ def __init__(self, coordinate_array, order='fac', if velocities is not None: try: velocities = np.asarray(velocities, dtype=np.float32) - except ValueError: + except ValueError as e: raise TypeError("'velocities' must be array-like got {}" - "".format(type(velocities))) + "".format(type(velocities))) from e # if single frame, make into array of 1 frame if velocities.ndim == 2: velocities = velocities[np.newaxis, :, :] @@ -347,9 +347,9 @@ def __init__(self, coordinate_array, order='fac', if forces is not None: try: forces = np.asarray(forces, dtype=np.float32) - except ValueError: + except ValueError as e: raise TypeError("'forces' must be array like got {}" - "".format(type(forces))) + "".format(type(forces))) from e if forces.ndim == 2: forces = forces[np.newaxis, :, :] if not forces.shape == self.coordinate_array.shape: @@ -376,9 +376,9 @@ def __init__(self, coordinate_array, order='fac', else: try: dimensions = np.asarray(dimensions, dtype=np.float32) - except ValueError: + except ValueError as e: raise TypeError("'dimensions' must be array-like got {}" - "".format(type(dimensions))) + "".format(type(dimensions))) from e if dimensions.shape == (6,): # single box, tile this to trajectory length # allows modifying the box of some frames diff --git a/package/MDAnalysis/core/__init__.py b/package/MDAnalysis/core/__init__.py index e6065f9d0e6..ec94bd7e853 100644 --- a/package/MDAnalysis/core/__init__.py +++ b/package/MDAnalysis/core/__init__.py @@ -264,8 +264,9 @@ def set(self, value): if value is not None: try: self.value = self.mapping[value] - except KeyError: - raise ValueError("flag must be None or one of " + str(self.mapping.keys())) + except KeyError as e: + errmsg = "flag must be None or one of " + str(self.mapping.keys()) + raise ValueError(errmsg) from e return self.get() def prop(self): diff --git a/package/MDAnalysis/core/_get_readers.py b/package/MDAnalysis/core/_get_readers.py index ecb19739f3d..a1ded3bc14c 100644 --- a/package/MDAnalysis/core/_get_readers.py +++ b/package/MDAnalysis/core/_get_readers.py @@ -96,7 +96,7 @@ def get_reader_for(filename, format=None): format = format.upper() try: return _READERS[format] - except KeyError: + except KeyError as e: raise ValueError( "Unknown coordinate trajectory format '{0}' for '{1}'. The FORMATs \n" " {2}\n" @@ -105,7 +105,7 @@ def get_reader_for(filename, format=None): " Use the format keyword to explicitly set the format: 'Universe(...,format=FORMAT)'\n" " For missing formats, raise an issue at " "http://issues.mdanalysis.org".format( - format, filename, _READERS.keys())) + format, filename, _READERS.keys())) from e def get_writer_for(filename, format=None, multiframe=None): @@ -163,13 +163,13 @@ def get_writer_for(filename, format=None, multiframe=None): elif format is None: try: root, ext = util.get_ext(filename) - except (TypeError, AttributeError): + except (TypeError, AttributeError) as e: # An AttributeError is raised if filename cannot # be manipulated as a string. # A TypeError is raised in py3.6 # "TypeError: expected str, bytes or os.PathLike object" raise ValueError('File format could not be guessed from "{0}"' - .format(filename)) + .format(filename)) from e else: format = util.check_compressed_format(root, ext) format = format.upper() @@ -191,8 +191,8 @@ def get_writer_for(filename, format=None, multiframe=None): try: return options[format] - except KeyError: - raise TypeError(errmsg.format(format)) + except KeyError as e: + raise TypeError(errmsg.format(format)) from e def get_parser_for(filename, format=None): @@ -230,8 +230,8 @@ def get_parser_for(filename, format=None): except KeyError: try: rdr = get_reader_for(filename) - except ValueError: - raise ValueError( + except ValueError as e: + errmsg = ( "'{0}' isn't a valid topology format, nor a coordinate format\n" " from which a topology can be minimally inferred.\n" " You can use 'Universe(topology, ..., topology_format=FORMAT)'\n" @@ -241,5 +241,6 @@ def get_parser_for(filename, format=None): " See https://docs.mdanalysis.org/documentation_pages/topology/init.html#supported-topology-formats\n" " For missing formats, raise an issue at \n" " http://issues.mdanalysis.org".format(format, _PARSERS.keys())) + raise ValueError(errmsg) from e else: return _PARSERS['MINIMAL'] diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 9d916facbac..b0683afed29 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -119,14 +119,15 @@ def _unpickle(uhash, ix): try: u = _ANCHOR_UNIVERSES[uhash] - except KeyError: + except KeyError as e: # doesn't provide as nice an error message as before as only hash of universe is stored # maybe if we pickled the filename too we could do better... - raise RuntimeError( + errmsg = ( "Couldn't find a suitable Universe to unpickle AtomGroup onto " "with Universe hash '{}'. Available hashes: {}" "".format(uhash, ', '.join([str(k) for k in _ANCHOR_UNIVERSES.keys()]))) + raise RuntimeError(errmsg) from e return u.atoms[ix] def _unpickle_uag(basepickle, selections, selstrs): @@ -308,7 +309,7 @@ def __new__(cls, *args, **kwargs): try: # older AtomGroup init method.. u = args[0][0].universe - except (TypeError, IndexError, AttributeError): + except (TypeError, IndexError, AttributeError) as e: from .universe import Universe # Let's be generic and get the first argument that's either a # Universe, a Group, or a Component, and go from there. @@ -321,7 +322,7 @@ def __new__(cls, *args, **kwargs): else: raise TypeError("No universe, or universe-containing " "object passed to the initialization of " - "{}".format(cls.__name__)) + "{}".format(cls.__name__)) from e try: return object.__new__(u._classes[cls]) except KeyError: @@ -456,12 +457,12 @@ def __init__(self, *args): # current/new init method ix, u = args except (AttributeError, # couldn't find ix/universe - TypeError): # couldn't iterate the object we got + TypeError) as e: # couldn't iterate the object we got raise TypeError( "Can only initialise a Group from an iterable of Atom/Residue/" "Segment objects eg: AtomGroup([Atom1, Atom2, Atom3]) " "or an iterable of indices and a Universe reference " - "eg: AtomGroup([0, 5, 7, 8], u).") + "eg: AtomGroup([0, 5, 7, 8], u).") from e # indices for the objects I hold self._ix = np.asarray(ix, dtype=np.intp) @@ -773,15 +774,15 @@ def center(self, weights, pbc=None, compound='group', unwrap=False): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError: + except AttributeError as e: raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") + "No molecule information in topology.") from e elif comp == 'fragments': try: compound_indices = atoms.fragindices - except NoDataError: + except NoDataError as e: raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") + "No bond information in topology.") from e else: raise ValueError("Unrecognized compound definition: {}\nPlease use" " one of 'group', 'residues', 'segments', " @@ -983,15 +984,15 @@ def accumulate(self, attribute, function=np.sum, compound='group'): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError: + except AttributeError as e: raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") + "No molecule information in topology.") from e elif comp == 'fragments': try: compound_indices = atoms.fragindices - except NoDataError: + except NoDataError as e: raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") + "No bond information in topology.") from e else: raise ValueError("Unrecognized compound definition: '{}'. Please " "use one of 'group', 'residues', 'segments', " @@ -1478,15 +1479,15 @@ def wrap(self, compound="atoms", center="com", box=None, inplace=True): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError: + except AttributeError as e: raise NoDataError("Cannot use compound='molecules', " - "this requires molnums.") + "this requires molnums.") from e else: # comp == 'fragments' try: compound_indices = atoms.fragindices - except NoDataError: + except NoDataError as e: raise NoDataError("Cannot use compound='fragments', " - "this requires bonds.") + "this requires bonds.") from e # compute required shifts: if ctr == 'com': @@ -1640,9 +1641,9 @@ def unwrap(self, compound='fragments', reference='com', inplace=True): else: # comp == 'molecules' try: compound_indices = unique_atoms.molnums - except AttributeError: + except AttributeError as e: raise NoDataError("Cannot use compound='molecules', this " - "requires molnums.") + "requires molnums.") from e # Now process every compound: unique_compound_indices = unique_int_1d(compound_indices) positions = unique_atoms.positions @@ -2325,12 +2326,12 @@ def residues(self, new): else: try: r_ix = [r.resindex for r in new] - except AttributeError: + except AttributeError as e: raise TypeError("Can only set AtomGroup residues to Residue " "or ResidueGroup not {}".format( ', '.join(type(r) for r in new if not isinstance(r, Residue)) - )) + )) from e if not isinstance(r_ix, itertools.cycle) and len(r_ix) != len(self): raise ValueError("Incorrect size: {} for AtomGroup of size: {}" "".format(len(new), len(self))) @@ -2502,16 +2503,16 @@ def velocities(self): ts = self.universe.trajectory.ts try: return np.array(ts.velocities[self.ix]) - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain velocities") from e @velocities.setter def velocities(self, values): ts = self.universe.trajectory.ts try: ts.velocities[self.ix, :] = values - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain velocities") from e @property def forces(self): @@ -2536,16 +2537,16 @@ def forces(self): ts = self.universe.trajectory.ts try: return ts.forces[self.ix] - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain forces") from e @forces.setter def forces(self, values): ts = self.universe.trajectory.ts try: ts.forces[self.ix, :] = values - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain forces") from e @property def ts(self): @@ -2882,14 +2883,16 @@ def split(self, level): # higher level groupings try: levelindices = getattr(self, accessors[level]) - except AttributeError: + except AttributeError as e: raise AttributeError('This universe does not have {} ' 'information. Maybe it is not provided in the ' - 'topology format in use.'.format(level)) - except KeyError: - raise ValueError("level = '{0}' not supported, " - "must be one of {1}".format(level, - accessors.keys())) + 'topology format in use.'.format(level)) from e + except KeyError as e: + errmsg = ( + "level = '{0}' not supported, " + "must be one of {1}".format(level, accessors.keys()) + ) + raise ValueError(errmsg) from e return [self[levelindices == index] for index in unique_int_1d(levelindices)] @@ -3239,12 +3242,13 @@ def segments(self, new): else: try: s_ix = [s.segindex for s in new] - except AttributeError: - raise TypeError("Can only set ResidueGroup segments to Segment " + except AttributeError as e: + errmsg = ("Can only set ResidueGroup segments to Segment " "or SegmentGroup, not {}".format( ', '.join(type(r) for r in new if not isinstance(r, Segment)) )) + raise TypeError(errmsg) from e if not isinstance(s_ix, itertools.cycle) and len(s_ix) != len(self): raise ValueError("Incorrect size: {} for ResidueGroup of size: {}" "".format(len(new), len(self))) @@ -3644,16 +3648,16 @@ def velocity(self): ts = self.universe.trajectory.ts try: return ts.velocities[self.ix].copy() - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain velocities") from e @velocity.setter def velocity(self, values): ts = self.universe.trajectory.ts try: ts.velocities[self.ix, :] = values - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain velocities") from e @property def force(self): @@ -3675,16 +3679,16 @@ def force(self): ts = self.universe.trajectory.ts try: return ts.forces[self.ix].copy() - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain forces") from e @force.setter def force(self, values): ts = self.universe.trajectory.ts try: ts.forces[self.ix, :] = values - except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") + except (AttributeError, NoDataError) as e: + raise NoDataError("Timestep does not contain forces") from e class Residue(ComponentBase): diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index 2311b9f8c2d..9756e3282e1 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -488,8 +488,8 @@ def __init__(self, parser, tokens): .format(grpname)) try: self.grp = parser.selgroups[grpname] - except KeyError: - raise ValueError("Failed to find group: {0}".format(grpname)) + except KeyError as e: + raise ValueError("Failed to find group: {0}".format(grpname)) from e def apply(self, group): mask = np.in1d(group.indices, self.grp.indices) @@ -503,8 +503,8 @@ def __init__(self, parser, tokens): grpname = tokens.popleft() try: self.grp = parser.selgroups[grpname] - except KeyError: - raise ValueError("Failed to find group: {0}".format(grpname)) + except KeyError as e: + raise ValueError("Failed to find group: {0}".format(grpname)) from e @deprecate(old_name='fullgroup', new_name='global group', message=' This will be removed in v0.15.0') @@ -632,13 +632,13 @@ def apply(self, group): vals = group.resids try: # optional attribute icodes = group.icodes - except (AttributeError, NoDataError): + except (AttributeError, NoDataError) as e: icodes = None # if no icodes and icodes are part of selection, cause a fuss if (any(v[1] for v in self.uppers) or any(v[1] for v in self.lowers)): raise ValueError("Selection specified icodes, while the " - "topology doesn't have any.") + "topology doesn't have any.") from e if not icodes is None: mask = self._sel_with_icodes(vals, icodes) @@ -722,12 +722,12 @@ def __init__(self, parser, tokens): try: lower = int(val) upper = None - except ValueError: + except ValueError from e: # check if in appropriate format 'lower:upper' or 'lower-upper' selrange = re.match("(\d+)[:-](\d+)", val) if not selrange: raise ValueError( - "Failed to parse number: {0}".format(val)) + "Failed to parse number: {0}".format(val)) from e lower, upper = np.int64(selrange.groups()) lowers.append(lower) @@ -996,16 +996,16 @@ def __init__(self, parser, tokens): self.prop = prop try: self.operator = self.ops[oper] - except KeyError: + except KeyError as e: raise ValueError( "Invalid operator : '{0}' Use one of : '{1}'" - "".format(oper, self.ops.keys())) + "".format(oper, self.ops.keys())) from e self.value = float(value) def apply(self, group): try: col = {'x': 0, 'y': 1, 'z': 2}[self.prop] - except KeyError: + except KeyError as e: if self.prop == 'mass': values = group.masses elif self.prop == 'charge': @@ -1013,7 +1013,7 @@ def apply(self, group): else: raise SelectionError( "Expected one of : {0}" - "".format(['x', 'y', 'z', 'mass', 'charge'])) + "".format(['x', 'y', 'z', 'mass', 'charge'])) from e else: values = group.positions[:, col] @@ -1185,10 +1185,10 @@ def _parse_subexp(self): try: return _SELECTIONDICT[op](self, self.tokens) - except KeyError: - raise SelectionError("Unknown selection token: '{0}'".format(op)) + except KeyError as e: + raise SelectionError("Unknown selection token: '{0}'".format(op)) from e except ValueError as e: - raise SelectionError("Selection failed: '{0}'".format(e)) + raise SelectionError("Selection failed: '{0}'".format(e)) from e # The module level instance diff --git a/package/MDAnalysis/core/topologyattrs.py b/package/MDAnalysis/core/topologyattrs.py index 5366bca67c8..acbb6cdb833 100644 --- a/package/MDAnalysis/core/topologyattrs.py +++ b/package/MDAnalysis/core/topologyattrs.py @@ -486,9 +486,9 @@ def _gen_initial_values(na, nr, ns): def getattr__(atomgroup, name): try: return atomgroup._get_named_atom(name) - except selection.SelectionError: + except selection.SelectionError as e: raise AttributeError("'{0}' object has no attribute '{1}'".format( - atomgroup.__class__.__name__, name)) + atomgroup.__class__.__name__, name)) from e def _get_named_atom(group, name): """Get all atoms with name *name* in the current AtomGroup. @@ -1346,9 +1346,9 @@ def _gen_initial_values(na, nr, ns): def getattr__(residuegroup, resname): try: return residuegroup._get_named_residue(resname) - except selection.SelectionError: + except selection.SelectionError as e: raise AttributeError("'{0}' object has no attribute '{1}'".format( - residuegroup.__class__.__name__, resname)) + residuegroup.__class__.__name__, resname)) from e transplants[ResidueGroup].append(('__getattr__', getattr__)) # This transplant is hardcoded for now to allow for multiple getattr things @@ -1483,7 +1483,7 @@ def sequence(self, **kwargs): except KeyError as err: raise ValueError("AtomGroup contains a residue name '{0}' that " "does not have a IUPAC protein 1-letter " - "character".format(err.message)) + "character".format(err.message)) from err if format == "string": return sequence seq = Bio.Seq.Seq(sequence, alphabet=Bio.Alphabet.IUPAC.protein) @@ -1588,9 +1588,9 @@ def _gen_initial_values(na, nr, ns): def getattr__(segmentgroup, segid): try: return segmentgroup._get_named_segment(segid) - except selection.SelectionError: + except selection.SelectionError as e: raise AttributeError("'{0}' object has no attribute '{1}'".format( - segmentgroup.__class__.__name__, segid)) + segmentgroup.__class__.__name__, segid)) from e transplants[SegmentGroup].append( ('__getattr__', getattr__)) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index 0475cf432f6..b9700a9aa27 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -810,20 +810,20 @@ def atom3(self): """The third atom in each TopologyObject in this Group""" try: return self._ags[2] - except IndexError: + except IndexError as e: nvert = _BTYPE_TO_SHAPE[self.btype] - raise IndexError("TopologyGroup of {}s only has {} vertical AtomGroups" - "".format(self.btype, nvert)) + errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" + raise IndexError(errmsg.format(self.btype, nvert)) from e @property def atom4(self): """The fourth atom in each TopologyObject in this Group""" try: return self._ags[3] - except IndexError: + except IndexError as e: nvert = _BTYPE_TO_SHAPE[self.btype] - raise IndexError("TopologyGroup of {}s only has {} vertical AtomGroups" - "".format(self.btype, nvert)) + errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" + raise IndexError(errmsg.format(self.btype, nvert)) from e # Distance calculation methods below # "Slow" versions exist as a way of testing the Cython implementations diff --git a/package/MDAnalysis/core/universe.py b/package/MDAnalysis/core/universe.py index 5594ce4a209..39d4a3d1c03 100644 --- a/package/MDAnalysis/core/universe.py +++ b/package/MDAnalysis/core/universe.py @@ -300,15 +300,16 @@ def __init__(self, *args, **kwargs): six.reraise(*sys.exc_info()) else: # Runs when the parser fails - raise IOError( + errmsg = ( "Failed to load from the topology file {0}" " with parser {1}.\n" "Error: {2}".format(self.filename, parser, err)) + raise IOError(errmsg) from err except (ValueError, NotImplementedError) as err: raise ValueError( "Failed to construct topology from file {0}" " with parser {1}.\n" - "Error: {2}".format(self.filename, parser, err)) + "Error: {2}".format(self.filename, parser, err)) from e # generate and populate Universe version of each class self._generate_from_topology() @@ -508,8 +509,8 @@ def __getattr__(self, key): # created at the beginning of __init__. try: segment = self._instant_selectors[key] - except KeyError: - raise AttributeError('No attribute "{}".'.format(key)) + except KeyError as e: + raise AttributeError('No attribute "{}".'.format(key)) from e else: warnings.warn("Instant selector Universe. " "is deprecated and will be removed in 1.0. " @@ -859,14 +860,15 @@ def add_TopologyAttr(self, topologyattr, values=None): if isinstance(topologyattr, six.string_types): try: tcls = _TOPOLOGY_ATTRS[topologyattr] - except KeyError: - raise ValueError( + except KeyError as e: + errmsg = ( "Unrecognised topology attribute name: '{}'." " Possible values: '{}'\n" "To raise an issue go to: http://issues.mdanalysis.org" "".format( topologyattr, ', '.join(sorted(_TOPOLOGY_ATTRS.keys()))) ) + raise ValueError(errmsg) from e else: topologyattr = tcls.from_blank( n_atoms=self._topology.n_atoms, diff --git a/package/MDAnalysis/lib/distances.py b/package/MDAnalysis/lib/distances.py index 5a3ba55fb30..8fac61fd1b0 100644 --- a/package/MDAnalysis/lib/distances.py +++ b/package/MDAnalysis/lib/distances.py @@ -98,9 +98,10 @@ def _run(funcname, args=None, kwargs=None, backend="serial"): backend = backend.lower() try: func = getattr(_distances[backend], funcname) - except KeyError: - raise ValueError("Function {0} not available with backend {1}; try one " - "of: {2}".format(funcname, backend, _distances.keys())) + except KeyError as e: + errmsg = ("Function {0} not available with backend {1}; try one " + "of: {2}".format(funcname, backend, _distances.keys())) + raise ValueError(errmsg) from e return func(*args, **kwargs) # serial versions are always available (and are typically used within diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index 18627e859d1..899afcae2c3 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -850,9 +850,9 @@ def fileno(self): """ try: return self.stream.fileno() - except AttributeError: + except AttributeError as e: # IOBase.fileno does not raise IOError as advertised so we do this here - raise IOError("This NamedStream does not use a file descriptor.") + raise IOError("This NamedStream does not use a file descriptor.") from e def readline(self): try: @@ -955,9 +955,9 @@ def check_compressed_format(root, ext): if ext.lower() in ("bz2", "gz"): try: root, ext = get_ext(root) - except: + except Exception as e: raise TypeError("Cannot determine coordinate format for '{0}.{1}'" - "".format(root, ext)) + "".format(root, ext)) from e return ext.upper() @@ -980,11 +980,11 @@ def format_from_filename_extension(filename): """ try: root, ext = get_ext(filename) - except: + except Exception as e: raise TypeError( "Cannot determine file format for file '{0}'.\n" " You can set the format explicitly with " - "'Universe(..., format=FORMAT)'.".format(filename)) + "'Universe(..., format=FORMAT)'.".format(filename)) from e format = check_compressed_format(root, ext) return format @@ -1020,10 +1020,10 @@ def guess_format(filename): # perhaps StringIO or open stream try: format = format_from_filename_extension(filename.name) - except AttributeError: + except AttributeError as e: # format is None so we need to complain: raise ValueError("guess_format requires an explicit format specifier " - "for stream {0}".format(filename)) + "for stream {0}".format(filename)) from e else: # iterator, list, filename: simple extension checking... something more # complicated is left for the ambitious. @@ -1109,8 +1109,9 @@ def read(self, line): """Read the entry from `line` and convert to appropriate type.""" try: return self.convertor(line[self.start:self.stop]) - except ValueError: - raise ValueError("{0!r}: Failed to read&convert {1!r}".format(self, line[self.start:self.stop])) + except ValueError as e: + errmsg = "{0!r}: Failed to read&convert {1!r}".format(self, line[self.start:self.stop]) + raise ValueError(errmsg) from e def __len__(self): """Length of the field in columns (stop - start)""" @@ -1343,8 +1344,8 @@ def get_weights(atoms, weights): if not iterable(weights) and weights == "mass": try: weights = atoms.masses - except AttributeError: - raise TypeError("weights='mass' selected but atoms.masses is missing") + except AttributeError as e: + raise TypeError("weights='mass' selected but atoms.masses is missing") from e if iterable(weights): if len(np.asarray(weights).shape) != 1: @@ -1423,8 +1424,9 @@ def convert_aa_code(x): try: return d[x.upper()] - except KeyError: - raise ValueError("No conversion for {0} found (1 letter -> 3 letter or 3/4 letter -> 1 letter)".format(x)) + except KeyError as e: + errmsg = "No conversion for {0} found (1 letter -> 3 letter or 3/4 letter -> 1 letter)".format(x) + raise ValueError(errmsg) from e #: Regular expression to match and parse a residue-atom selection; will match @@ -1673,9 +1675,9 @@ def __getattr__(self, key): # a.this causes a __getattr__ call for key = 'this' try: return dict.__getitem__(self, key) - except KeyError: + except KeyError as e: raise AttributeError('"{}" is not known in the namespace.' - .format(key)) + .format(key)) from e def __setattr__(self, key, value): dict.__setitem__(self, key, value) @@ -1683,9 +1685,9 @@ def __setattr__(self, key, value): def __delattr__(self, key): try: dict.__delitem__(self, key) - except KeyError: + except KeyError as e: raise AttributeError('"{}" is not known in the namespace.' - .format(key)) + .format(key)) from e def __eq__(self, other): try: @@ -1990,9 +1992,10 @@ def _check_coords(coords, argname): "".format(fname, argname, coords.shape)) try: coords = coords.astype(np.float32, order='C', copy=enforce_copy) - except ValueError: - raise TypeError("{}(): {}.dtype must be convertible to float32," - " got {}.".format(fname, argname, coords.dtype)) + except ValueError as e: + errmsg = ("{}(): {}.dtype must be convertible to float32," + " got {}.".format(fname, argname, coords.dtype)) + raise TypeError(errmsg) from e return coords, is_single @wraps(func) diff --git a/package/MDAnalysis/selections/__init__.py b/package/MDAnalysis/selections/__init__.py index 1ac7c2630a8..eb80751bfe0 100644 --- a/package/MDAnalysis/selections/__init__.py +++ b/package/MDAnalysis/selections/__init__.py @@ -84,7 +84,7 @@ def get_writer(filename, defaultformat): format = format.strip().upper() # canonical for lookup try: return _SELECTION_WRITERS[format] - except KeyError: + except KeyError as e: raise NotImplementedError( "Writing as {0!r} is not implemented;" - " only {1!r} will work.".format(format, _SELECTION_WRITERS.keys())) + " only {1!r} will work.".format(format, _SELECTION_WRITERS.keys())) from e diff --git a/package/MDAnalysis/tests/datafiles.py b/package/MDAnalysis/tests/datafiles.py index a24be633838..71b07737741 100644 --- a/package/MDAnalysis/tests/datafiles.py +++ b/package/MDAnalysis/tests/datafiles.py @@ -40,7 +40,7 @@ try: from MDAnalysisTests.datafiles import * -except ImportError: +except ImportError as e: print("*** ERROR ***") print("In order to run the MDAnalysis test cases you must install the") print("MDAnalysisTestData package (which has been separated from the ") @@ -50,4 +50,4 @@ 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.") + raise ImportError("MDAnalysisTests package not installed.") from e diff --git a/package/MDAnalysis/topology/CRDParser.py b/package/MDAnalysis/topology/CRDParser.py index c841d2bba65..5e5d90a3b37 100644 --- a/package/MDAnalysis/topology/CRDParser.py +++ b/package/MDAnalysis/topology/CRDParser.py @@ -121,9 +121,9 @@ def parse(self, **kwargs): try: (serial, resnum, resName, name, x, y, z, segid, resid, tempFactor) = r.read(line) - except: + except Exception as e: raise ValueError("Check CRD format at line {0}: {1}" - "".format(linenum + 1, line.rstrip())) + "".format(linenum + 1, line.rstrip())) from e atomids.append(serial) atomnames.append(name) diff --git a/package/MDAnalysis/topology/DMSParser.py b/package/MDAnalysis/topology/DMSParser.py index 93715a920cb..657c429bb97 100644 --- a/package/MDAnalysis/topology/DMSParser.py +++ b/package/MDAnalysis/topology/DMSParser.py @@ -140,9 +140,9 @@ def dict_factory(cursor, row): cur.execute('SELECT {} FROM particle' ''.format(attrname)) vals = cur.fetchall() - except sqlite3.DatabaseError: - raise IOError( - "Failed reading the atoms from DMS Database") + except sqlite3.DatabaseError as e: + errmsg = "Failed reading the atoms from DMS Database" + raise IOError(errmsg) from e else: attrs[attrname] = np.array(vals, dtype=dt) @@ -150,8 +150,9 @@ def dict_factory(cursor, row): cur.row_factory = dict_factory cur.execute('SELECT * FROM bond') bonds = cur.fetchall() - except sqlite3.DatabaseError: - raise IOError("Failed reading the bonds from DMS Database") + except sqlite3.DatabaseError as e: + errmsg = "Failed reading the bonds from DMS Database" + raise IOError(errmsg) from e else: bondlist = [] bondorder = {} diff --git a/package/MDAnalysis/topology/GROParser.py b/package/MDAnalysis/topology/GROParser.py index 3bfaf930449..ec1e0cf546a 100644 --- a/package/MDAnalysis/topology/GROParser.py +++ b/package/MDAnalysis/topology/GROParser.py @@ -102,10 +102,12 @@ def parse(self, **kwargs): resnames[i] = line[5:10].strip() names[i] = line[10:15].strip() indices[i] = int(line[15:20]) - except (ValueError, TypeError): - raise IOError( + except (ValueError, TypeError) as e: + errmsg = ( "Couldn't read the following line of the .gro file:\n" - "{0}".format(line)) + "{0}" + ) + raise IOError(errmsg.format(line)) from e # Check all lines had names if not np.all(names): missing = np.where(names == '') diff --git a/package/MDAnalysis/topology/LAMMPSParser.py b/package/MDAnalysis/topology/LAMMPSParser.py index 0ecb42f27d5..8684a35ff3c 100644 --- a/package/MDAnalysis/topology/LAMMPSParser.py +++ b/package/MDAnalysis/topology/LAMMPSParser.py @@ -285,12 +285,12 @@ def parse(self, **kwargs): try: top = self._parse_atoms(sects['Atoms'], masses) - except: + except Exception as e: raise ValueError( "Failed to parse atoms section. You can supply a description " "of the atom_style as a keyword argument, " "eg mda.Universe(..., atom_style='id resid x y z')" - ) + ) from e # create mapping of id to index (ie atom id 10 might be the 0th atom) mapping = {atom_id: i for i, atom_id in enumerate(top.ids.values)} @@ -336,7 +336,8 @@ def read_DATA_timestep(self, n_atoms, TS_class, TS_kwargs, try: positions, ordering = self._parse_pos(sects['Atoms']) except KeyError as err: - raise IOError("Position information not found: {}".format(err)) + errmsg = "Position information not found: {}".format(err) + raise IOError(errmsg) from err if 'Velocities' in sects: velocities = self._parse_vel(sects['Velocities'], ordering) diff --git a/package/MDAnalysis/topology/PSFParser.py b/package/MDAnalysis/topology/PSFParser.py index 798c5f22591..0289f23a898 100644 --- a/package/MDAnalysis/topology/PSFParser.py +++ b/package/MDAnalysis/topology/PSFParser.py @@ -276,11 +276,11 @@ def _parseatoms(self, lines, atoms_per, numlines): for i in range(numlines): try: line = lines() - except StopIteration: + except StopIteration as e: err = ("{0} is not valid PSF file" "".format(self.filename)) logger.error(err) - raise ValueError(err) + raise ValueError(err) from e try: vals = set_type(atom_parser(line)) except ValueError: diff --git a/package/MDAnalysis/topology/TOPParser.py b/package/MDAnalysis/topology/TOPParser.py index 10968b9850c..25cc8b8c24e 100644 --- a/package/MDAnalysis/topology/TOPParser.py +++ b/package/MDAnalysis/topology/TOPParser.py @@ -233,10 +233,10 @@ def next_getter(): else: try: next_section = line.split("%FLAG")[1].strip() - except IndexError: + except IndexError as e: msg = ("%FLAG section not found, formatting error " "for PARM7 file {0} ".format(self.filename)) - raise IndexError(msg) + raise IndexError(msg) from e # strip out a few values to play with them n_atoms = len(attrs['name']) diff --git a/package/MDAnalysis/transformations/fit.py b/package/MDAnalysis/transformations/fit.py index 63ee6213544..2db1579fd8d 100644 --- a/package/MDAnalysis/transformations/fit.py +++ b/package/MDAnalysis/transformations/fit.py @@ -89,19 +89,19 @@ def fit_translation(ag, reference, plane=None, weights=None): axes = {'yz' : 0, 'xz' : 1, 'xy' : 2} try: plane = axes[plane] - except (TypeError, KeyError): - raise ValueError('{} is not a valid plane'.format(plane)) + except (TypeError, KeyError) as e: + raise ValueError('{} is not a valid plane'.format(plane)) from e try: if ag.atoms.n_residues != reference.atoms.n_residues: raise ValueError("{} and {} have mismatched number of residues".format(ag,reference)) - except AttributeError: - raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) + except AttributeError as e: + raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) from e ref, mobile = align.get_matching_atoms(reference.atoms, ag.atoms) try: weights = align.get_weights(ref.atoms, weights=weights) - except (ValueError, TypeError): + except (ValueError, TypeError) as e: raise ValueError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") + "same size as the atomgroup.") from e ref_com = np.asarray(ref.center(weights), np.float32) @@ -168,19 +168,19 @@ def fit_rot_trans(ag, reference, plane=None, weights=None): axes = {'yz' : 0, 'xz' : 1, 'xy' : 2} try: plane = axes[plane] - except (TypeError, KeyError): - raise ValueError('{} is not a valid plane'.format(plane)) + except (TypeError, KeyError) as e: + raise ValueError('{} is not a valid plane'.format(plane)) from e try: if ag.atoms.n_residues != reference.atoms.n_residues: raise ValueError("{} and {} have mismatched number of residues".format(ag,reference)) - except AttributeError: - raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) + except AttributeError as e: + raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) from e ref, mobile = align.get_matching_atoms(reference.atoms, ag.atoms) try: weights = align.get_weights(ref.atoms, weights=weights) - except (ValueError, TypeError): + except (ValueError, TypeError) as e: raise ValueError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") + "same size as the atomgroup.") from e ref_com = ref.center(weights) ref_coordinates = ref.atoms.positions - ref_com diff --git a/package/MDAnalysis/transformations/rotate.py b/package/MDAnalysis/transformations/rotate.py index 4d0cb29cc08..49285ea7cd5 100644 --- a/package/MDAnalysis/transformations/rotate.py +++ b/package/MDAnalysis/transformations/rotate.py @@ -112,8 +112,8 @@ def rotateby(angle, direction, point=None, ag=None, weights=None, wrap=False): if direction.shape != (3, ) and direction.shape != (1, 3): raise ValueError('{} is not a valid direction'.format(direction)) direction = direction.reshape(3, ) - except ValueError: - raise ValueError('{} is not a valid direction'.format(direction)) + except ValueError as e: + raise ValueError('{} is not a valid direction'.format(direction)) from e if point is not None: point = np.asarray(point, np.float32) if point.shape != (3, ) and point.shape != (1, 3): @@ -122,14 +122,14 @@ def rotateby(angle, direction, point=None, ag=None, weights=None, wrap=False): elif ag: try: atoms = ag.atoms - except AttributeError: - raise ValueError('{} is not an AtomGroup object'.format(ag)) + except AttributeError as e: + raise ValueError('{} is not an AtomGroup object'.format(ag)) from e else: try: weights = get_weights(atoms, weights=weights) - except (ValueError, TypeError): + except (ValueError, TypeError) as e: raise TypeError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") + "same size as the atomgroup.") from e center_method = partial(atoms.center, weights, pbc=wrap) else: raise ValueError('A point or an AtomGroup must be specified') diff --git a/package/MDAnalysis/transformations/translate.py b/package/MDAnalysis/transformations/translate.py index bdcc16870f0..97a8b942893 100644 --- a/package/MDAnalysis/transformations/translate.py +++ b/package/MDAnalysis/transformations/translate.py @@ -124,11 +124,11 @@ def center_in_box(ag, center='geometry', point=None, wrap=False): center_method = partial(ag.center_of_mass, pbc=pbc_arg) else: raise ValueError('{} is not a valid argument for center'.format(center)) - except AttributeError: + except AttributeError as e: if center == 'mass': - raise AttributeError('{} is not an AtomGroup object with masses'.format(ag)) + raise AttributeError('{} is not an AtomGroup object with masses'.format(ag)) from e else: - raise ValueError('{} is not an AtomGroup object'.format(ag)) + raise ValueError('{} is not an AtomGroup object'.format(ag)) from e def wrapped(ts): if point is None: diff --git a/package/MDAnalysis/units.py b/package/MDAnalysis/units.py index ab317c568ce..cdbf2b84377 100644 --- a/package/MDAnalysis/units.py +++ b/package/MDAnalysis/units.py @@ -363,14 +363,18 @@ def convert(x, u1, u2): """ try: ut1 = unit_types[u1] - except KeyError: - raise ValueError("unit '{0}' not recognized.\n" - "It must be one of {1}.".format(u1, ", ".join(unit_types))) + except KeyError as e: + errmsg = ("unit '{0}' not recognized.\n" + "It must be one of {1}.".format(u1, ", ".join(unit_types)) + ) + raise ValueError(errmsg) from e try: ut2 = unit_types[u2] - except KeyError: - raise ValueError("unit '{0}' not recognized.\n" - "It must be one of {1}.".format(u2, ", ".join(unit_types))) + except KeyError as e: + errmsg = ("unit '{0}' not recognized.\n" + "It must be one of {1}.".format(u2, ", ".join(unit_types)) + ) + raise ValueError(errmsg) from e if ut1 != ut2: raise ValueError("Cannot convert between unit types " "{0} --> {1}".format(u1, u2)) diff --git a/package/MDAnalysis/visualization/streamlines.py b/package/MDAnalysis/visualization/streamlines.py index 23f91575200..e7e2c4be8fa 100644 --- a/package/MDAnalysis/visualization/streamlines.py +++ b/package/MDAnalysis/visualization/streamlines.py @@ -53,11 +53,14 @@ try: import matplotlib import matplotlib.path -except ImportError: - raise ImportError( - '2d streamplot module requires: matplotlib.path for its path.Path.contains_points method. The installation ' +except ImportError as e: + errmsg = ( + '2d streamplot module requires: matplotlib.path for its ' + 'path.Path.contains_points method. The installation ' 'instructions for the matplotlib module can be found here: ' - 'http://matplotlib.org/faq/installing_faq.html?highlight=install') + 'http://matplotlib.org/faq/installing_faq.html?highlight=install' + ) + raise ImportError(errmsg) from e import MDAnalysis From 502cda611678d1a10624c169989acf7b9ab07205 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 19:30:54 -0400 Subject: [PATCH 02/15] from None in custom exceptions --- package/MDAnalysis/analysis/polymer.py | 4 +- package/MDAnalysis/coordinates/PDB.py | 4 +- package/MDAnalysis/core/groups.py | 60 +++++++++++++------------- package/MDAnalysis/core/selection.py | 12 +++--- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/package/MDAnalysis/analysis/polymer.py b/package/MDAnalysis/analysis/polymer.py index 62440b5f034..1821fe86596 100644 --- a/package/MDAnalysis/analysis/polymer.py +++ b/package/MDAnalysis/analysis/polymer.py @@ -247,8 +247,8 @@ def _perform_fit(self): """Fit the results to an exponential decay""" try: self.results - except AttributeError as e: - raise NoDataError("Use the run method first") from e + except AttributeError: + raise NoDataError("Use the run method first") from None self.x = np.arange(len(self.results)) * self.lb self.lp = fit_exponential_decay(self.x, self.results) diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 459e8d47132..592f4677e98 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -835,9 +835,9 @@ def write_next_timestep(self, ts=None, **kwargs): if ts is None: try: ts = self.ts - except AttributeError as e: + except AttributeError: raise NoDataError("PBDWriter: no coordinate data to write to " - "trajectory file") from e + "trajectory file") from None self._check_pdb_coordinates() self._write_timestep(ts, **kwargs) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index b0683afed29..47e42f73a26 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -774,15 +774,15 @@ def center(self, weights, pbc=None, compound='group', unwrap=False): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError as e: + except AttributeError: raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") from e + "No molecule information in topology.") from None elif comp == 'fragments': try: compound_indices = atoms.fragindices - except NoDataError as e: + except NoDataError: raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") from e + "No bond information in topology.") from None else: raise ValueError("Unrecognized compound definition: {}\nPlease use" " one of 'group', 'residues', 'segments', " @@ -984,15 +984,15 @@ def accumulate(self, attribute, function=np.sum, compound='group'): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError as e: + except AttributeError: raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") from e + "No molecule information in topology.") from None elif comp == 'fragments': try: compound_indices = atoms.fragindices - except NoDataError as e: + except NoDataError: raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") from e + "No bond information in topology.") from None else: raise ValueError("Unrecognized compound definition: '{}'. Please " "use one of 'group', 'residues', 'segments', " @@ -1479,15 +1479,15 @@ def wrap(self, compound="atoms", center="com", box=None, inplace=True): elif comp == 'molecules': try: compound_indices = atoms.molnums - except AttributeError as e: + except AttributeError: raise NoDataError("Cannot use compound='molecules', " - "this requires molnums.") from e + "this requires molnums.") from None else: # comp == 'fragments' try: compound_indices = atoms.fragindices - except NoDataError as e: + except NoDataError: raise NoDataError("Cannot use compound='fragments', " - "this requires bonds.") from e + "this requires bonds.") from None # compute required shifts: if ctr == 'com': @@ -1641,9 +1641,9 @@ def unwrap(self, compound='fragments', reference='com', inplace=True): else: # comp == 'molecules' try: compound_indices = unique_atoms.molnums - except AttributeError as e: + except AttributeError: raise NoDataError("Cannot use compound='molecules', this " - "requires molnums.") from e + "requires molnums.") from None # Now process every compound: unique_compound_indices = unique_int_1d(compound_indices) positions = unique_atoms.positions @@ -2503,16 +2503,16 @@ def velocities(self): ts = self.universe.trajectory.ts try: return np.array(ts.velocities[self.ix]) - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain velocities") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain velocities") from None @velocities.setter def velocities(self, values): ts = self.universe.trajectory.ts try: ts.velocities[self.ix, :] = values - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain velocities") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain velocities") from None @property def forces(self): @@ -2537,16 +2537,16 @@ def forces(self): ts = self.universe.trajectory.ts try: return ts.forces[self.ix] - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain forces") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain forces") from None @forces.setter def forces(self, values): ts = self.universe.trajectory.ts try: ts.forces[self.ix, :] = values - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain forces") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain forces") from None @property def ts(self): @@ -3648,16 +3648,16 @@ def velocity(self): ts = self.universe.trajectory.ts try: return ts.velocities[self.ix].copy() - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain velocities") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain velocities") from None @velocity.setter def velocity(self, values): ts = self.universe.trajectory.ts try: ts.velocities[self.ix, :] = values - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain velocities") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain velocities") from None @property def force(self): @@ -3679,16 +3679,16 @@ def force(self): ts = self.universe.trajectory.ts try: return ts.forces[self.ix].copy() - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain forces") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain forces") from None @force.setter def force(self, values): ts = self.universe.trajectory.ts try: ts.forces[self.ix, :] = values - except (AttributeError, NoDataError) as e: - raise NoDataError("Timestep does not contain forces") from e + except (AttributeError, NoDataError): + raise NoDataError("Timestep does not contain forces") from None class Residue(ComponentBase): diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index 9756e3282e1..7f0cacb6c36 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -1005,7 +1005,7 @@ def __init__(self, parser, tokens): def apply(self, group): try: col = {'x': 0, 'y': 1, 'z': 2}[self.prop] - except KeyError as e: + except KeyError: if self.prop == 'mass': values = group.masses elif self.prop == 'charge': @@ -1013,7 +1013,7 @@ def apply(self, group): else: raise SelectionError( "Expected one of : {0}" - "".format(['x', 'y', 'z', 'mass', 'charge'])) from e + "".format(['x', 'y', 'z', 'mass', 'charge'])) from None else: values = group.positions[:, col] @@ -1185,10 +1185,10 @@ def _parse_subexp(self): try: return _SELECTIONDICT[op](self, self.tokens) - except KeyError as e: - raise SelectionError("Unknown selection token: '{0}'".format(op)) from e - except ValueError as e: - raise SelectionError("Selection failed: '{0}'".format(e)) from e + except KeyError: + raise SelectionError("Unknown selection token: '{0}'".format(op)) from None + except ValueError: + raise SelectionError("Selection failed: '{0}'".format(e)) from None # The module level instance From 95d61e4254abe95469379d570601b73043d13243 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 19:55:02 -0400 Subject: [PATCH 03/15] corrected syntax --- package/MDAnalysis/core/selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index 7f0cacb6c36..840aa23e8eb 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -722,7 +722,7 @@ def __init__(self, parser, tokens): try: lower = int(val) upper = None - except ValueError from e: + except ValueError as e: # check if in appropriate format 'lower:upper' or 'lower-upper' selrange = re.match("(\d+)[:-](\d+)", val) if not selrange: From aafc6a3d975a0c9e66270b280249ba8a46d3b020 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 20:32:07 -0400 Subject: [PATCH 04/15] assign error to var --- package/MDAnalysis/core/selection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index 840aa23e8eb..a211ce21f2e 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -1187,7 +1187,7 @@ def _parse_subexp(self): return _SELECTIONDICT[op](self, self.tokens) except KeyError: raise SelectionError("Unknown selection token: '{0}'".format(op)) from None - except ValueError: + except ValueError as e: raise SelectionError("Selection failed: '{0}'".format(e)) from None From 65a83c27d091eabf8d1f46f25e7fd62db490711e Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 20:34:50 -0400 Subject: [PATCH 05/15] correct after tests --- package/MDAnalysis/core/universe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/core/universe.py b/package/MDAnalysis/core/universe.py index 39d4a3d1c03..dd63a7b0a14 100644 --- a/package/MDAnalysis/core/universe.py +++ b/package/MDAnalysis/core/universe.py @@ -309,7 +309,7 @@ def __init__(self, *args, **kwargs): raise ValueError( "Failed to construct topology from file {0}" " with parser {1}.\n" - "Error: {2}".format(self.filename, parser, err)) from e + "Error: {2}".format(self.filename, parser, err)) from err # generate and populate Universe version of each class self._generate_from_topology() From 9a85e89cffc9d53f961519d044a0b5b1c79a7a3a Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 20:58:53 -0400 Subject: [PATCH 06/15] correcting after tests in server --- package/MDAnalysis/analysis/density.py | 2 +- package/MDAnalysis/auxiliary/XVG.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package/MDAnalysis/analysis/density.py b/package/MDAnalysis/analysis/density.py index 28543cbde53..fb5757331c4 100644 --- a/package/MDAnalysis/analysis/density.py +++ b/package/MDAnalysis/analysis/density.py @@ -529,7 +529,7 @@ def _set_user_grid(gridcenter, xdim, ydim, zdim, smin, smax): except ValueError as e: raise ValueError("Non-number values assigned to gridcenter") from e if gridcenter.shape != (3,): - raise ValueError("gridcenter must be a 3D coordinate") from e + raise ValueError("gridcenter must be a 3D coordinate") try: xyzdim = np.array([xdim, ydim, zdim], dtype=np.float32) except ValueError as e: diff --git a/package/MDAnalysis/auxiliary/XVG.py b/package/MDAnalysis/auxiliary/XVG.py index cc19462cd97..2c3f8a5c824 100644 --- a/package/MDAnalysis/auxiliary/XVG.py +++ b/package/MDAnalysis/auxiliary/XVG.py @@ -318,13 +318,13 @@ def _read_next_step(self): # see if we've set n_cols yet... try: auxstep._n_cols - except AttributeError as e: + except AttributeError: # haven't set n_cols yet; set now auxstep._n_cols = len(auxstep._data) if len(auxstep._data) != auxstep._n_cols: raise ValueError('Step {0} has {1} columns instead of ' '{2}'.format(self.step, len(auxstep._data), - auxstep._n_cols)) from e + auxstep._n_cols)) return auxstep # line is comment only - move to next line = next(self.auxfile) From f0e2d719295d48bac3d908e8c25af158c749d87f Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 21:32:38 -0400 Subject: [PATCH 07/15] updated CHANGELOG --- package/CHANGELOG | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index 132976d1bc9..d8d17d70f13 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -13,14 +13,18 @@ The rules for this file: * release numbers follow "Semantic Versioning" http://semver.org ------------------------------------------------------------------------------ -mm/dd/yy ??? + +mm/dd/yy joaomcteixeira, * 0.20.2 Fixes Enhancements - + * Exception handling: exception that derive from other exceptions are now + raise `from` catched Exception. + * Custom Exceptions are `raise`ed `from None` instead of from catched + Exception. 09/05/19 IAlibay, richardjgowers From 9e5ebe0dda41fe20cbdb87c1ad48ef70b4796238 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 28 Sep 2019 21:41:44 -0400 Subject: [PATCH 08/15] corrects irregular verb --- package/CHANGELOG | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index d8d17d70f13..e96aa3539d5 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -22,9 +22,8 @@ Fixes Enhancements * Exception handling: exception that derive from other exceptions are now - raise `from` catched Exception. - * Custom Exceptions are `raise`ed `from None` instead of from catched - Exception. + raise `from` caught Exception + * Custom Exceptions are `raise`ed `from None` 09/05/19 IAlibay, richardjgowers From a0a13da267a3effe4a9a4d7f4d101b6eb1d80b30 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 2 Nov 2019 23:13:55 -0400 Subject: [PATCH 09/15] implemented six.raise_from. Passes tests for py37 --- .gitignore | 2 + package/MDAnalysis/analysis/align.py | 13 +-- package/MDAnalysis/analysis/density.py | 28 ++++--- .../analysis/hbonds/hbond_autocorrel.py | 5 +- package/MDAnalysis/analysis/hole.py | 4 +- package/MDAnalysis/analysis/nuclinfo.py | 5 +- package/MDAnalysis/analysis/polymer.py | 3 +- package/MDAnalysis/analysis/psa.py | 20 +++-- package/MDAnalysis/analysis/rms.py | 22 +++-- package/MDAnalysis/auxiliary/XVG.py | 12 ++- package/MDAnalysis/auxiliary/core.py | 16 ++-- package/MDAnalysis/coordinates/CRD.py | 11 ++- package/MDAnalysis/coordinates/GRO.py | 6 +- package/MDAnalysis/coordinates/GSD.py | 5 +- package/MDAnalysis/coordinates/LAMMPS.py | 12 +-- package/MDAnalysis/coordinates/MOL2.py | 15 ++-- package/MDAnalysis/coordinates/PDB.py | 14 ++-- package/MDAnalysis/coordinates/TRJ.py | 22 ++--- package/MDAnalysis/coordinates/TRZ.py | 4 +- package/MDAnalysis/coordinates/TXYZ.py | 5 +- package/MDAnalysis/coordinates/XYZ.py | 6 +- package/MDAnalysis/coordinates/base.py | 35 +++++--- package/MDAnalysis/coordinates/core.py | 12 ++- package/MDAnalysis/coordinates/memory.py | 30 ++++--- package/MDAnalysis/core/__init__.py | 4 +- package/MDAnalysis/core/_get_readers.py | 24 +++--- package/MDAnalysis/core/groups.py | 81 ++++++++++--------- package/MDAnalysis/core/selection.py | 39 +++++---- package/MDAnalysis/core/topologyattrs.py | 28 ++++--- package/MDAnalysis/core/topologyobjects.py | 9 ++- package/MDAnalysis/core/universe.py | 14 ++-- package/MDAnalysis/lib/distances.py | 5 +- package/MDAnalysis/lib/util.py | 53 +++++++----- package/MDAnalysis/selections/__init__.py | 8 +- package/MDAnalysis/tests/datafiles.py | 5 +- package/MDAnalysis/topology/CRDParser.py | 8 +- package/MDAnalysis/topology/DMSParser.py | 9 ++- package/MDAnalysis/topology/GROParser.py | 5 +- package/MDAnalysis/topology/LAMMPSParser.py | 12 +-- package/MDAnalysis/topology/PSFParser.py | 5 +- package/MDAnalysis/topology/TOPParser.py | 5 +- package/MDAnalysis/transformations/fit.py | 31 +++---- package/MDAnalysis/transformations/rotate.py | 19 +++-- .../MDAnalysis/transformations/translate.py | 9 ++- package/MDAnalysis/units.py | 9 ++- .../MDAnalysis/visualization/streamlines.py | 7 +- 46 files changed, 419 insertions(+), 277 deletions(-) diff --git a/.gitignore b/.gitignore index 67f2bf4528e..41890f3f8a1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ MDAnalysis.log authors.py # Ignore the .DS_Store file in the osx file system *.DS_Store +# ignore files from tests +.hypothesis/ diff --git a/package/MDAnalysis/analysis/align.py b/package/MDAnalysis/analysis/align.py index 9129acf3d35..7d0e71c937e 100644 --- a/package/MDAnalysis/analysis/align.py +++ b/package/MDAnalysis/analysis/align.py @@ -190,7 +190,7 @@ import logging from six.moves import range, zip, zip_longest -from six import string_types +from six import raise_from, string_types import numpy as np @@ -506,9 +506,12 @@ def alignto(mobile, reference, select="all", weights=None, try: # treat subselection as AtomGroup mobile_atoms = subselection.atoms - except AttributeError as e: - raise TypeError("subselection must be a selection string, an" - " AtomGroup or Universe or None") from e + except AttributeError: + error_ = TypeError( + "subselection must be a selection string, an" + " AtomGroup or Universe or None" + ) + raise_from(error_, None) # _fit_to DOES subtract center of mass, will provide proper min_rmsd mobile_atoms, new_rmsd = _fit_to(mobile_coordinates, ref_coordinates, @@ -1167,7 +1170,7 @@ def get_atoms_byres(g, match_mask=np.logical_not(mismatch_mask)): "Try to improve your selections for mobile and reference.").format( ag1.n_atoms, ag2.n_atoms) logger.error(errmsg) - raise SelectionError(errmsg) from None + raise_from(SelectionError(errmsg), None) if np.any(mass_mismatches): # Test 2 failed. diff --git a/package/MDAnalysis/analysis/density.py b/package/MDAnalysis/analysis/density.py index fb5757331c4..b9fc724a6f2 100644 --- a/package/MDAnalysis/analysis/density.py +++ b/package/MDAnalysis/analysis/density.py @@ -161,7 +161,7 @@ from __future__ import print_function, division, absolute_import from six.moves import range, zip -from six import string_types +from six import raise_from, string_types import numpy as np import sys @@ -372,12 +372,15 @@ def _check_set_unit(self, u): try: units.conversion_factor[unit_type][value] self.units[unit_type] = value - except KeyError as e: - raise ValueError('Unit ' + str(value) + ' of type ' + str(unit_type) + ' is not recognized.') from e - except AttributeError as e: + except KeyError: + raise_from( + ValueError('Unit ' + str(value) + ' of type ' + str(unit_type) + ' is not recognized.'), + None, + ) + except AttributeError: errmsg = '"unit" must be a dictionary with keys "length" and "density.' logger.fatal(errmsg) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) # need at least length and density (can be None) if 'length' not in self.units: raise ValueError('"unit" must contain a unit for "length".') @@ -485,8 +488,11 @@ def convert_density(self, unit='Angstrom'): try: self.grid *= units.get_conversion_factor('density', self.units['density'], unit) - except KeyError as e: - raise ValueError("The name of the unit ({0!r} supplied) must be one of:\n{1!r}".format(unit, units.conversion_factor['density'].keys())) from e + except KeyError: + raise_from( + ValueError("The name of the unit ({0!r} supplied) must be one of:\n{1!r}".format(unit, units.conversion_factor['density'].keys())), + None, + ) self.units['density'] = unit def __repr__(self): @@ -526,14 +532,14 @@ def _set_user_grid(gridcenter, xdim, ydim, zdim, smin, smax): # Check user inputs try: gridcenter = np.asarray(gridcenter, dtype=np.float32) - except ValueError as e: - raise ValueError("Non-number values assigned to gridcenter") from e + except ValueError: + raise_from(ValueError("Non-number values assigned to gridcenter"), None) if gridcenter.shape != (3,): raise ValueError("gridcenter must be a 3D coordinate") try: xyzdim = np.array([xdim, ydim, zdim], dtype=np.float32) - except ValueError as e: - raise ValueError("xdim, ydim, and zdim must be numbers") from e + except ValueError: + raise_from(ValueError("xdim, ydim, and zdim must be numbers"), None) # Set min/max by shifting by half the edge length of each dimension umin = gridcenter - xyzdim/2 diff --git a/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py b/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py index 3bfb30a0b28..63579f8183c 100644 --- a/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py +++ b/package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py @@ -206,6 +206,7 @@ """ from __future__ import division, absolute_import from six.moves import zip +from six import raise_from import numpy as np import scipy.optimize @@ -300,8 +301,8 @@ def __init__(self, universe, # check that slicing is possible try: self.u.trajectory[0] - except Exception as e: - raise ValueError("Trajectory must support slicing") from e + except Exception: + raise_from(ValueError("Trajectory must support slicing"), None) self.h = hydrogens self.a = acceptors diff --git a/package/MDAnalysis/analysis/hole.py b/package/MDAnalysis/analysis/hole.py index a53004cae15..baca0f723eb 100644 --- a/package/MDAnalysis/analysis/hole.py +++ b/package/MDAnalysis/analysis/hole.py @@ -1030,7 +1030,7 @@ def create_vmd_surface(self, filename="hole.vmd", **kwargs): except subprocess.CalledProcessError as err: os.unlink(tmp_sos) logger.fatal("sph_process failed ({0})".format(err.returncode)) - raise OSError(err.returncode, "sph_process failed") from err + six.raise_from(OSError(err.returncode, "sph_process failed"), None) except: os.unlink(tmp_sos) raise @@ -1045,7 +1045,7 @@ def create_vmd_surface(self, filename="hole.vmd", **kwargs): stderr=FNULL) except subprocess.CalledProcessError as err: logger.fatal("sos_triangle failed ({0})".format(err.returncode)) - raise OSError(err.returncode, "sos_triangle failed") from err + six.raise_from(OSError(err.returncode, "sos_triangle failed"), None) finally: os.unlink(tmp_sos) diff --git a/package/MDAnalysis/analysis/nuclinfo.py b/package/MDAnalysis/analysis/nuclinfo.py index dd6b36d1b13..8432b0fee03 100644 --- a/package/MDAnalysis/analysis/nuclinfo.py +++ b/package/MDAnalysis/analysis/nuclinfo.py @@ -107,6 +107,7 @@ import numpy as np from math import pi, sin, cos, atan2, sqrt, pow +from six import raise_from from MDAnalysis.lib import mdamath @@ -710,11 +711,11 @@ def hydroxyl(universe, seg, i): "atom {0!s} {1!s} H2'".format(seg, i)) try: hydr = h.dihedral.value() % 360 - except ValueError as e: + except ValueError: errmsg = ( "Resid {0} does not contain atoms C1', C2', O2', H2' but atoms {1}" ) - raise ValueError(errmsg.format(i, str(list(h.atoms)))) from e + raise_from(ValueError(errmsg.format(i, str(list(h.atoms)))), None) return hydr diff --git a/package/MDAnalysis/analysis/polymer.py b/package/MDAnalysis/analysis/polymer.py index 1821fe86596..e699628c38b 100644 --- a/package/MDAnalysis/analysis/polymer.py +++ b/package/MDAnalysis/analysis/polymer.py @@ -62,6 +62,7 @@ """ from __future__ import division, absolute_import from six.moves import range +from six import raise_from import numpy as np import scipy.optimize @@ -248,7 +249,7 @@ def _perform_fit(self): try: self.results except AttributeError: - raise NoDataError("Use the run method first") from None + raise_from(NoDataError("Use the run method first"), None) self.x = np.arange(len(self.results)) * self.lb self.lp = fit_exponential_decay(self.x, self.results) diff --git a/package/MDAnalysis/analysis/psa.py b/package/MDAnalysis/analysis/psa.py index 5b977af70f0..f52d7e01df5 100644 --- a/package/MDAnalysis/analysis/psa.py +++ b/package/MDAnalysis/analysis/psa.py @@ -215,7 +215,7 @@ import six from six.moves import range, cPickle, zip -from six import string_types +from six import raise_from, string_types import os import warnings @@ -269,7 +269,7 @@ def get_path_metric_func(name): errmsg = ('Path metric "{}" not found. Valid selections: {}' ''.format(key, " ".join('"{}"'.format(n) for n in path_metrics.keys()))) - raise KeyError(errmsg) from key + raise_from(KeyError(errmsg), None) def sqnorm(v, axis=None): @@ -1865,8 +1865,8 @@ def plot_annotated_heatmap(self, filename=None, linkage='ward', \ try: import seaborn.apionly as sns - except ImportError as e: - raise ImportError( + except ImportError: + raise_from(ImportError( """ERROR --- The seaborn package cannot be found! The seaborn API could not be imported. Please install it first. @@ -1881,7 +1881,9 @@ def plot_annotated_heatmap(self, filename=None, linkage='ward', \ and install in the usual manner. """ - ) from e + ), + None, + ) if self.D is None: raise ValueError( @@ -1974,8 +1976,8 @@ def plot_nearest_neighbors(self, filename=None, idx=0, \ from matplotlib.pyplot import figure, savefig, tight_layout, clf, show try: import seaborn.apionly as sns - except ImportError as e: - raise ImportError( + except ImportError: + raise_from(ImportError( """ERROR --- The seaborn package cannot be found! The seaborn API could not be imported. Please install it first. @@ -1990,7 +1992,9 @@ def plot_nearest_neighbors(self, filename=None, idx=0, \ and install in the usual manner. """ - ) from e + ), + None, + ) colors = sns.xkcd_palette(["cherry", "windows blue"]) diff --git a/package/MDAnalysis/analysis/rms.py b/package/MDAnalysis/analysis/rms.py index ce899911748..049f242a08a 100644 --- a/package/MDAnalysis/analysis/rms.py +++ b/package/MDAnalysis/analysis/rms.py @@ -136,7 +136,7 @@ from __future__ import division, absolute_import from six.moves import zip -from six import string_types +from six import raise_from, string_types import numpy as np @@ -286,17 +286,25 @@ def process_selection(select): elif type(select) is tuple: try: select = {'mobile': select[0], 'reference': select[1]} - except IndexError as e: - raise IndexError("select must contain two selection strings " - "(reference, mobile)") from e + except IndexError: + raise_from(IndexError( + "select must contain two selection strings " + "(reference, mobile)"), + None, + ) elif type(select) is dict: # compatability hack to use new nomenclature try: select['mobile'] select['reference'] - except KeyError as e: - raise KeyError("select dictionary must contain entries for keys " - "'mobile' and 'reference'.") from e + except KeyError: + raise_from( + KeyError( + "select dictionary must contain entries for keys " + "'mobile' and 'reference'." + ), + None, + ) else: raise TypeError("'select' must be either a string, 2-tuple, or dict") select['mobile'] = asiterable(select['mobile']) diff --git a/package/MDAnalysis/auxiliary/XVG.py b/package/MDAnalysis/auxiliary/XVG.py index 2c3f8a5c824..c99ef1e635b 100644 --- a/package/MDAnalysis/auxiliary/XVG.py +++ b/package/MDAnalysis/auxiliary/XVG.py @@ -69,6 +69,7 @@ from __future__ import absolute_import from six.moves import range +from six import raise_from import numbers import os @@ -148,9 +149,14 @@ def _select_data(self, key): if isinstance(key, numbers.Integral): try: return self._data[key] - except IndexError as e: - raise ValueError('{} not a valid index for data with {} ' - 'columns'.format(key, len(self._data))) from e + except IndexError: + raise_from( + ValueError( + '{} not a valid index for data with {} ' + 'columns'.format(key, len(self._data)) + ), + None + ) else: return np.array([self._select_data(i) for i in key]) diff --git a/package/MDAnalysis/auxiliary/core.py b/package/MDAnalysis/auxiliary/core.py index de9b1a3088e..bd074640960 100644 --- a/package/MDAnalysis/auxiliary/core.py +++ b/package/MDAnalysis/auxiliary/core.py @@ -30,7 +30,7 @@ """ from __future__ import absolute_import -from six import string_types +from six import raise_from, string_types from . import _AUXREADERS from ..lib import util @@ -74,15 +74,19 @@ def get_auxreader_for(auxdata=None, format=None): format = format.upper() try: return _AUXREADERS[format] - except KeyError as e: - raise ValueError("Unknown auxiliary data format for auxdata: " - "{0}".format(auxdata)) from e + except KeyError: + raise_from( + ValueError( + "Unknown auxiliary data format for auxdata: " + "{0}".format(auxdata)), + None + ) else: try: return _AUXREADERS[format] - except KeyError as e: + except KeyError: errmsg = "Unknown auxiliary data format {0}".format(format) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) def auxreader(auxdata, format=None, **kwargs): """ Return an auxiliary reader instance for *auxdata*. diff --git a/package/MDAnalysis/coordinates/CRD.py b/package/MDAnalysis/coordinates/CRD.py index 9db5a75badf..cbcdf69057c 100644 --- a/package/MDAnalysis/coordinates/CRD.py +++ b/package/MDAnalysis/coordinates/CRD.py @@ -32,6 +32,7 @@ from __future__ import absolute_import from six.moves import zip, range +from six import raise_from import itertools import numpy as np @@ -80,9 +81,13 @@ def _read_first_frame(self): coords_list.append(np.array(line[45:100].split()[0:3], dtype=float)) else: coords_list.append(np.array(line[20:50].split()[0:3], dtype=float)) - except Exception as e: - raise ValueError("Check CRD format at line {0}: {1}" - "".format(linenum, line.rstrip())) from e + except Exception: + raise_from( + ValueError( + "Check CRD format at line {0}: {1}" + "".format(linenum, line.rstrip())), + None + ) self.n_atoms = len(coords_list) diff --git a/package/MDAnalysis/coordinates/GRO.py b/package/MDAnalysis/coordinates/GRO.py index abb34a9320d..723da8927ed 100644 --- a/package/MDAnalysis/coordinates/GRO.py +++ b/package/MDAnalysis/coordinates/GRO.py @@ -106,6 +106,8 @@ from __future__ import absolute_import from six.moves import range, zip +from six import raise_from + import itertools import warnings @@ -366,11 +368,11 @@ def write(self, obj): ag_or_ts = obj.atoms # can write from selection == Universe (Issue 49) - except AttributeError as e: + except AttributeError: if isinstance(obj, base.Timestep): ag_or_ts = obj.copy() else: - raise TypeError("No Timestep found in obj argument") from e + raise_from(TypeError("No Timestep found in obj argument"), None) try: velocities = ag_or_ts.velocities diff --git a/package/MDAnalysis/coordinates/GSD.py b/package/MDAnalysis/coordinates/GSD.py index 3c9c37afcd0..e5968e32d34 100644 --- a/package/MDAnalysis/coordinates/GSD.py +++ b/package/MDAnalysis/coordinates/GSD.py @@ -46,6 +46,7 @@ """ from __future__ import absolute_import, division +from six import raise_from import numpy as np import os @@ -101,8 +102,8 @@ def _reopen(self): def _read_frame(self, frame): try : myframe = self._file[frame] - except IndexError as e: - raise IOError from e + except IndexError: + raise_from(IOError, None) # set frame number self._frame = frame diff --git a/package/MDAnalysis/coordinates/LAMMPS.py b/package/MDAnalysis/coordinates/LAMMPS.py index 096d8c3c3f8..e4ce746e1fe 100644 --- a/package/MDAnalysis/coordinates/LAMMPS.py +++ b/package/MDAnalysis/coordinates/LAMMPS.py @@ -124,6 +124,7 @@ from __future__ import absolute_import from six.moves import zip, range, map +from six import raise_from import os import numpy as np @@ -160,9 +161,9 @@ def __init__(self, *args, **kwargs): try: if units.unit_types[unit] != unit_type: raise TypeError("LAMMPS DCDWriter: wrong unit {0!r} for unit type {1!r}".format(unit, unit_type)) - except KeyError as e: + except KeyError: errmsg = ("LAMMPS DCDWriter: unknown unit {0!r}".format(unit)) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) super(DCDWriter, self).__init__(*args, **kwargs) @@ -341,10 +342,11 @@ def _write_bonds(self, bonds): try: self.f.write('{:d} {:d} '.format(i, int(bond.type))+\ ' '.join((bond.atoms.indices + 1).astype(str))+'\n') - except TypeError as e: - raise TypeError('LAMMPS DATAWriter: Trying to write bond, ' + except TypeError: + raise_from(TypeError('LAMMPS DATAWriter: Trying to write bond, ' 'but bond type {} is not ' - 'numerical.'.format(bond.type)) from e + 'numerical.'.format(bond.type)), + None) def _write_dimensions(self, dimensions): """Convert dimensions to triclinic vectors, convert lengths to native diff --git a/package/MDAnalysis/coordinates/MOL2.py b/package/MDAnalysis/coordinates/MOL2.py index 285a4098dd8..67d9fa67b71 100644 --- a/package/MDAnalysis/coordinates/MOL2.py +++ b/package/MDAnalysis/coordinates/MOL2.py @@ -112,6 +112,7 @@ """ from __future__ import absolute_import +from six import raise_from import numpy as np @@ -218,9 +219,10 @@ def _read_frame(self, frame): unitcell = np.zeros(6, dtype=np.float32) try: block = self.frames[frame] - except IndexError as e: - raise IOError("Invalid frame {0} for trajectory with length {1}" - "".format(frame, len(self))) from e + except IndexError: + raise_from(IOError("Invalid frame {0} for trajectory with length {1}" + "".format(frame, len(self))), + None) sections, coords = self.parse_block(block) @@ -313,9 +315,10 @@ def encode_block(self, obj): try: molecule = ts.data['molecule'] - except KeyError as e: - raise NotImplementedError( - "MOL2Writer cannot currently write non MOL2 data") from e + except KeyError: + raise_from(NotImplementedError( + "MOL2Writer cannot currently write non MOL2 data"), + None) # Need to remap atom indices to 1 based in this selection mapping = {a: i for i, a in enumerate(obj.atoms, start=1)} diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 592f4677e98..ef530e8b4f7 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -143,7 +143,7 @@ from __future__ import absolute_import from six.moves import range, zip -from six import StringIO, BytesIO +from six import raise_from, StringIO, BytesIO import io import os @@ -366,8 +366,8 @@ def _read_frame(self, frame): try: start = self._start_offsets[frame] stop = self._stop_offsets[frame] - except IndexError as e: # out of range of known frames - raise IOError from e + except IndexError: # out of range of known frames + raise_from(IOError, None) pos = 0 occupancy = np.ones(self.n_atoms) @@ -836,8 +836,12 @@ def write_next_timestep(self, ts=None, **kwargs): try: ts = self.ts except AttributeError: - raise NoDataError("PBDWriter: no coordinate data to write to " - "trajectory file") from None + raise_from( + NoDataError( + "PBDWriter: no coordinate data to write to " + "trajectory file" + ), + None) self._check_pdb_coordinates() self._write_timestep(ts, **kwargs) diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index 223a30d6493..f7db1a5afb1 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -154,6 +154,8 @@ """ from __future__ import (absolute_import, division, print_function, unicode_literals) +from six import raise_from + import scipy.io.netcdf import numpy as np import warnings @@ -494,11 +496,11 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): "Conventions)".format(self.filename)) logger.fatal(errmsg) raise TypeError(errmsg) - except AttributeError as e: + except AttributeError: errmsg = "NCDF trajectory {0} is missing Conventions".format( self.filename) logger.fatal(errmsg) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) # AMBER NetCDF files should also have a ConventionVersion try: @@ -509,10 +511,10 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): ConventionVersion, self.version)) warnings.warn(wmsg) logger.warning(wmsg) - except AttributeError as e: + except AttributeError: errmsg = "NCDF trajectory {0} is missing ConventionVersion".format( self.filename) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) # The AMBER NetCDF standard enforces 64 bit offsets if not self.trjfile.version_byte == 2: @@ -529,9 +531,9 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): if not self.trjfile.dimensions['spatial'] == 3: errmsg = "Incorrect spatial value for NCDF trajectory file" raise TypeError(errmsg) - except KeyError as e: + except KeyError: errmsg = "NCDF trajectory does not contain spatial dimension" - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) # AMBER NetCDF specs require program and programVersion. Warn users # if those attributes do not exist @@ -550,10 +552,10 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): "Note: n_atoms can be None and then the ncdf value " "is used!".format(n_atoms, self.n_atoms)) raise ValueError(errmsg) - except KeyError as e: + except KeyError: errmsg = ("NCDF trajectory {0} does not contain atom " "information".format(self.filename)) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) try: self.n_frames = self.trjfile.dimensions['frame'] @@ -708,8 +710,8 @@ def _read_next_timestep(self, ts=None): ts = self.ts try: return self._read_frame(self._current_frame + 1) - except IndexError as e: - raise IOError from e + except IndexError: + raise_from(IOError, None) def _get_dt(self): t1 = self.trjfile.variables['time'][1] diff --git a/package/MDAnalysis/coordinates/TRZ.py b/package/MDAnalysis/coordinates/TRZ.py index 53414594f52..752fdf60dcf 100644 --- a/package/MDAnalysis/coordinates/TRZ.py +++ b/package/MDAnalysis/coordinates/TRZ.py @@ -269,8 +269,8 @@ def _read_next_timestep(self, ts=None): ts._forces[:, 0] = data['fx'] ts._forces[:, 1] = data['fy'] ts._forces[:, 2] = data['fz'] - except IndexError as e: # Raises indexerror if data has no data (EOF) - raise IOError from e + except IndexError: # Raises indexerror if data has no data (EOF) + six.raise_from(IOError, None) else: # Convert things read into MDAnalysis' native formats (nm -> angstroms) if self.convert_units: diff --git a/package/MDAnalysis/coordinates/TXYZ.py b/package/MDAnalysis/coordinates/TXYZ.py index 8b93cf7138b..14edee62594 100644 --- a/package/MDAnalysis/coordinates/TXYZ.py +++ b/package/MDAnalysis/coordinates/TXYZ.py @@ -47,6 +47,7 @@ """ from __future__ import absolute_import, division from six.moves import range +from six import raise_from import numpy as np import os @@ -153,8 +154,8 @@ def _read_next_timestep(self, ts=None): ts.positions = tmp_buf ts.frame += 1 return ts - except (ValueError, IndexError) as err: - raise EOFError(err) from err + except (ValueError, IndexError): + raise_from(EOFError(err), None) def _reopen(self): self.close() diff --git a/package/MDAnalysis/coordinates/XYZ.py b/package/MDAnalysis/coordinates/XYZ.py index 37aa8b8c3d3..470f8fecb3b 100644 --- a/package/MDAnalysis/coordinates/XYZ.py +++ b/package/MDAnalysis/coordinates/XYZ.py @@ -200,11 +200,11 @@ def write(self, obj): # but this is not tested.) try: atoms = obj.atoms - except AttributeError as e: + except AttributeError: if isinstance(obj, base.Timestep): ts = obj else: - raise TypeError("No Timestep found in obj argument") from e + six.raise_from(TypeError("No Timestep found in obj argument"), None) else: if hasattr(obj, 'universe'): # For AtomGroup and children (Residue, ResidueGroup, Segment) @@ -376,7 +376,7 @@ def _read_next_timestep(self, ts=None): ts.frame += 1 return ts except (ValueError, IndexError) as err: - raise EOFError(err) from err + six.raise_from(EOFError(err), None) def _reopen(self): self.close() diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index 42f30ee8220..28ebc50741c 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -508,9 +508,13 @@ def copy_slice(self, sel): except NoDataError: # It's cool if there's no Data, we'll live pos = None - except Exception as e: - raise TypeError("Selection type must be compatible with slicing" - " the coordinates") from e + except Exception: + six.raise_from( + TypeError( + "Selection type must be compatible with slicing" + " the coordinates" + ), + None) try: vel = self.velocities[sel, :] except NoDataError: @@ -522,9 +526,13 @@ def copy_slice(self, sel): force = self.forces[sel, :] except NoDataError: force = None - except Exception as e: - raise TypeError("Selection type must be compatible with slicing" - " the coordinates") from e + except Exception: + six.raise_from( + TypeError( + "Selection type must be compatible with slicing" + " the coordinates" + ), + None) new_TS = self.__class__.from_coordinates( positions=pos, @@ -1408,7 +1416,7 @@ def next(self): ts = self._read_next_timestep() except (EOFError, IOError): self.rewind() - raise StopIteration from None + six.raise_from(StopIteration, None) else: for auxname in self.aux_list: ts = self._auxs[auxname].update_ts(ts) @@ -1591,9 +1599,12 @@ def _sliced_iter(self, start, stop, step): for i in range(start, stop, step): yield self._read_frame_with_aux(i) self.rewind() - except TypeError as e: # if _read_frame not implemented - raise TypeError("{0} does not support slicing." - "".format(self.__class__.__name__)) from e + except TypeError: # if _read_frame not implemented + six.raise_from( + TypeError( + "{0} does not support slicing." + "".format(self.__class__.__name__)), + None) def check_slice_indices(self, start, stop, step): """Check frame indices are valid and clip to fit trajectory. @@ -2176,8 +2187,8 @@ def write(self, obj): try: # special case: can supply a Universe, too... ts = obj.trajectory.ts - except AttributeError as e: - raise TypeError("No Timestep found in obj argument") from e + except AttributeError: + six.raise_from(TypeError("No Timestep found in obj argument"), None) return self.write_next_timestep(ts) def __del__(self): diff --git a/package/MDAnalysis/coordinates/core.py b/package/MDAnalysis/coordinates/core.py index ce48d768814..47d05b110bb 100644 --- a/package/MDAnalysis/coordinates/core.py +++ b/package/MDAnalysis/coordinates/core.py @@ -83,9 +83,15 @@ def reader(filename, format=None, **kwargs): Reader = get_reader_for(filename, format=format) try: return Reader(filename, **kwargs) - except ValueError as e: - raise TypeError('Unable to read {fn} with {r}.'.format(fn=filename, - r=Reader)) from e + except ValueError: + six.raise_from( + TypeError( + 'Unable to read {fn} with {r}.'.format( + fn=filename, + r=Reader + ) + ), + None) def writer(filename, n_atoms=None, **kwargs): diff --git a/package/MDAnalysis/coordinates/memory.py b/package/MDAnalysis/coordinates/memory.py index dcd97d5c32d..75add35f419 100644 --- a/package/MDAnalysis/coordinates/memory.py +++ b/package/MDAnalysis/coordinates/memory.py @@ -185,6 +185,7 @@ """ from __future__ import absolute_import +from six import raise_from import logging import errno import numpy as np @@ -315,10 +316,11 @@ def __init__(self, coordinate_array, order='fac', try: if coordinate_array.ndim == 2 and coordinate_array.shape[1] == 3: coordinate_array = coordinate_array[np.newaxis, :, :] - except AttributeError as e: - raise TypeError("The input has to be a numpy.ndarray that " + except AttributeError: + raise_from(TypeError("The input has to be a numpy.ndarray that " "corresponds to the layout specified by the " - "'order' keyword.") from e + "'order' keyword."), + None) self.set_array(coordinate_array, order) self.n_frames = \ @@ -329,9 +331,11 @@ def __init__(self, coordinate_array, order='fac', if velocities is not None: try: velocities = np.asarray(velocities, dtype=np.float32) - except ValueError as e: - raise TypeError("'velocities' must be array-like got {}" - "".format(type(velocities))) from e + except ValueError: + raise_from( + TypeError("'velocities' must be array-like got {}" + "".format(type(velocities))), + None) # if single frame, make into array of 1 frame if velocities.ndim == 2: velocities = velocities[np.newaxis, :, :] @@ -347,9 +351,10 @@ def __init__(self, coordinate_array, order='fac', if forces is not None: try: forces = np.asarray(forces, dtype=np.float32) - except ValueError as e: - raise TypeError("'forces' must be array like got {}" - "".format(type(forces))) from e + except ValueError: + raise_from(TypeError("'forces' must be array like got {}" + "".format(type(forces))), + None) if forces.ndim == 2: forces = forces[np.newaxis, :, :] if not forces.shape == self.coordinate_array.shape: @@ -376,9 +381,10 @@ def __init__(self, coordinate_array, order='fac', else: try: dimensions = np.asarray(dimensions, dtype=np.float32) - except ValueError as e: - raise TypeError("'dimensions' must be array-like got {}" - "".format(type(dimensions))) from e + except ValueError: + raise_from(TypeError("'dimensions' must be array-like got {}" + "".format(type(dimensions))), + None) if dimensions.shape == (6,): # single box, tile this to trajectory length # allows modifying the box of some frames diff --git a/package/MDAnalysis/core/__init__.py b/package/MDAnalysis/core/__init__.py index ec94bd7e853..4e34f65c48d 100644 --- a/package/MDAnalysis/core/__init__.py +++ b/package/MDAnalysis/core/__init__.py @@ -264,9 +264,9 @@ def set(self, value): if value is not None: try: self.value = self.mapping[value] - except KeyError as e: + except KeyError: errmsg = "flag must be None or one of " + str(self.mapping.keys()) - raise ValueError(errmsg) from e + six.raise_from(ValueError(errmsg), None) return self.get() def prop(self): diff --git a/package/MDAnalysis/core/_get_readers.py b/package/MDAnalysis/core/_get_readers.py index a1ded3bc14c..c186b18b455 100644 --- a/package/MDAnalysis/core/_get_readers.py +++ b/package/MDAnalysis/core/_get_readers.py @@ -20,6 +20,7 @@ """ from __future__ import absolute_import +from six import raise_from import copy import inspect @@ -96,8 +97,8 @@ def get_reader_for(filename, format=None): format = format.upper() try: return _READERS[format] - except KeyError as e: - raise ValueError( + except KeyError: + raise_from(ValueError( "Unknown coordinate trajectory format '{0}' for '{1}'. The FORMATs \n" " {2}\n" " are implemented in MDAnalysis.\n" @@ -105,7 +106,8 @@ def get_reader_for(filename, format=None): " Use the format keyword to explicitly set the format: 'Universe(...,format=FORMAT)'\n" " For missing formats, raise an issue at " "http://issues.mdanalysis.org".format( - format, filename, _READERS.keys())) from e + format, filename, _READERS.keys())), + None) def get_writer_for(filename, format=None, multiframe=None): @@ -163,13 +165,15 @@ def get_writer_for(filename, format=None, multiframe=None): elif format is None: try: root, ext = util.get_ext(filename) - except (TypeError, AttributeError) as e: + except (TypeError, AttributeError): # An AttributeError is raised if filename cannot # be manipulated as a string. # A TypeError is raised in py3.6 # "TypeError: expected str, bytes or os.PathLike object" - raise ValueError('File format could not be guessed from "{0}"' - .format(filename)) from e + raise_from( + ValueError('File format could not be guessed from "{0}"' + .format(filename)), + None) else: format = util.check_compressed_format(root, ext) format = format.upper() @@ -191,8 +195,8 @@ def get_writer_for(filename, format=None, multiframe=None): try: return options[format] - except KeyError as e: - raise TypeError(errmsg.format(format)) from e + except KeyError: + raise_from(TypeError(errmsg.format(format)), None) def get_parser_for(filename, format=None): @@ -230,7 +234,7 @@ def get_parser_for(filename, format=None): except KeyError: try: rdr = get_reader_for(filename) - except ValueError as e: + except ValueError: errmsg = ( "'{0}' isn't a valid topology format, nor a coordinate format\n" " from which a topology can be minimally inferred.\n" @@ -241,6 +245,6 @@ def get_parser_for(filename, format=None): " See https://docs.mdanalysis.org/documentation_pages/topology/init.html#supported-topology-formats\n" " For missing formats, raise an issue at \n" " http://issues.mdanalysis.org".format(format, _PARSERS.keys())) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) else: return _PARSERS['MINIMAL'] diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 8aa811209a9..bbefce8e127 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -90,7 +90,7 @@ """ from __future__ import absolute_import, division from six.moves import zip -from six import string_types +from six import raise_from, string_types from collections import namedtuple import numpy as np @@ -119,7 +119,7 @@ def _unpickle(uhash, ix): try: u = _ANCHOR_UNIVERSES[uhash] - except KeyError as e: + except KeyError: # doesn't provide as nice an error message as before as only hash of universe is stored # maybe if we pickled the filename too we could do better... errmsg = ( @@ -127,7 +127,7 @@ def _unpickle(uhash, ix): "with Universe hash '{}'. Available hashes: {}" "".format(uhash, ', '.join([str(k) for k in _ANCHOR_UNIVERSES.keys()]))) - raise RuntimeError(errmsg) from e + raise_from(RuntimeError(errmsg), None) return u.atoms[ix] def _unpickle_uag(basepickle, selections, selstrs): @@ -309,7 +309,7 @@ def __new__(cls, *args, **kwargs): try: # older AtomGroup init method.. u = args[0][0].universe - except (TypeError, IndexError, AttributeError) as e: + except (TypeError, IndexError, AttributeError): from .universe import Universe # Let's be generic and get the first argument that's either a # Universe, a Group, or a Component, and go from there. @@ -320,9 +320,12 @@ def __new__(cls, *args, **kwargs): u = arg.universe break else: - raise TypeError("No universe, or universe-containing " - "object passed to the initialization of " - "{}".format(cls.__name__)) from e + raise_from( + TypeError( + "No universe, or universe-containing " + "object passed to the initialization of " + "{}".format(cls.__name__)), + None) try: return object.__new__(u._classes[cls]) except KeyError: @@ -457,12 +460,13 @@ def __init__(self, *args): # current/new init method ix, u = args except (AttributeError, # couldn't find ix/universe - TypeError) as e: # couldn't iterate the object we got - raise TypeError( + TypeError): # couldn't iterate the object we got + raise_from(TypeError( "Can only initialise a Group from an iterable of Atom/Residue/" "Segment objects eg: AtomGroup([Atom1, Atom2, Atom3]) " "or an iterable of indices and a Universe reference " - "eg: AtomGroup([0, 5, 7, 8], u).") from e + "eg: AtomGroup([0, 5, 7, 8], u)."), + None) # indices for the objects I hold self._ix = np.asarray(ix, dtype=np.intp) @@ -775,14 +779,14 @@ def center(self, weights, pbc=None, compound='group', unwrap=False): try: compound_indices = atoms.molnums except AttributeError: - raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") from None + raise_from(NoDataError("Cannot use compound='molecules': " + "No molecule information in topology."), None) elif comp == 'fragments': try: compound_indices = atoms.fragindices except NoDataError: - raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") from None + raise_from(NoDataError("Cannot use compound='fragments': " + "No bond information in topology."), None) else: raise ValueError("Unrecognized compound definition: {}\nPlease use" " one of 'group', 'residues', 'segments', " @@ -985,14 +989,18 @@ def accumulate(self, attribute, function=np.sum, compound='group'): try: compound_indices = atoms.molnums except AttributeError: - raise NoDataError("Cannot use compound='molecules': " - "No molecule information in topology.") from None + raise_from( + NoDataError("Cannot use compound='molecules': " + "No molecule information in topology."), + None) elif comp == 'fragments': try: compound_indices = atoms.fragindices except NoDataError: - raise NoDataError("Cannot use compound='fragments': " - "No bond information in topology.") from None + raise_from( + NoDataError("Cannot use compound='fragments': " + "No bond information in topology."), + None) else: raise ValueError("Unrecognized compound definition: '{}'. Please " "use one of 'group', 'residues', 'segments', " @@ -1480,8 +1488,8 @@ def wrap(self, compound="atoms", center="com", box=None, inplace=True): try: compound_indices = atoms.molnums except AttributeError: - raise NoDataError("Cannot use compound='molecules', " - "this requires molnums.") from None + raise_from(NoDataError("Cannot use compound='molecules', " + "this requires molnums."), None) else: # comp == 'fragments' try: compound_indices = atoms.fragindices @@ -1642,8 +1650,8 @@ def unwrap(self, compound='fragments', reference='com', inplace=True): try: compound_indices = unique_atoms.molnums except AttributeError: - raise NoDataError("Cannot use compound='molecules', this " - "requires molnums.") from None + raise_from(NoDataError("Cannot use compound='molecules', this " + "requires molnums."), None) # Now process every compound: unique_compound_indices = unique_int_1d(compound_indices) positions = unique_atoms.positions @@ -2326,12 +2334,12 @@ def residues(self, new): else: try: r_ix = [r.resindex for r in new] - except AttributeError as e: - raise TypeError("Can only set AtomGroup residues to Residue " + except AttributeError: + raise_from(TypeError("Can only set AtomGroup residues to Residue " "or ResidueGroup not {}".format( ', '.join(type(r) for r in new if not isinstance(r, Residue)) - )) from e + )), None) if not isinstance(r_ix, itertools.cycle) and len(r_ix) != len(self): raise ValueError("Incorrect size: {} for AtomGroup of size: {}" "".format(len(new), len(self))) @@ -2504,7 +2512,7 @@ def velocities(self): try: return np.array(ts.velocities[self.ix]) except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") from None + raise_from(NoDataError("Timestep does not contain velocities"), None) @velocities.setter def velocities(self, values): @@ -2512,7 +2520,7 @@ def velocities(self, values): try: ts.velocities[self.ix, :] = values except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") from None + raise_from(NoDataError("Timestep does not contain velocities"), None) @property def forces(self): @@ -2883,16 +2891,17 @@ def split(self, level): # higher level groupings try: levelindices = getattr(self, accessors[level]) - except AttributeError as e: - raise AttributeError('This universe does not have {} ' + except AttributeError: + raise_from(AttributeError('This universe does not have {} ' 'information. Maybe it is not provided in the ' - 'topology format in use.'.format(level)) from e - except KeyError as e: + 'topology format in use.'.format(level)), + None) + except KeyError: errmsg = ( "level = '{0}' not supported, " "must be one of {1}".format(level, accessors.keys()) ) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) return [self[levelindices == index] for index in unique_int_1d(levelindices)] @@ -3245,13 +3254,13 @@ def segments(self, new): else: try: s_ix = [s.segindex for s in new] - except AttributeError as e: + except AttributeError: errmsg = ("Can only set ResidueGroup segments to Segment " "or SegmentGroup, not {}".format( ', '.join(type(r) for r in new if not isinstance(r, Segment)) )) - raise TypeError(errmsg) from e + raise_from(TypeError(errmsg), None) if not isinstance(s_ix, itertools.cycle) and len(s_ix) != len(self): raise ValueError("Incorrect size: {} for ResidueGroup of size: {}" "".format(len(new), len(self))) @@ -3652,7 +3661,7 @@ def velocity(self): try: return ts.velocities[self.ix].copy() except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") from None + raise_from(NoDataError("Timestep does not contain velocities"), None) @velocity.setter def velocity(self, values): @@ -3683,7 +3692,7 @@ def force(self): try: return ts.forces[self.ix].copy() except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") from None + raise_from(NoDataError("Timestep does not contain forces"), None) @force.setter def force(self, values): diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index b137fab0eb9..0cefb32c652 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -488,8 +488,10 @@ def __init__(self, parser, tokens): .format(grpname)) try: self.grp = parser.selgroups[grpname] - except KeyError as e: - raise ValueError("Failed to find group: {0}".format(grpname)) from e + except KeyError: + six.raise_from( + ValueError("Failed to find group: {0}".format(grpname)), + None) def apply(self, group): mask = np.in1d(group.indices, self.grp.indices) @@ -503,8 +505,10 @@ def __init__(self, parser, tokens): grpname = tokens.popleft() try: self.grp = parser.selgroups[grpname] - except KeyError as e: - raise ValueError("Failed to find group: {0}".format(grpname)) from e + except KeyError: + six.raise_from( + ValueError("Failed to find group: {0}".format(grpname)), + None) @deprecate(old_name='fullgroup', new_name='global group', message=' This will be removed in v0.15.0') @@ -641,8 +645,8 @@ def apply(self, group): # if no icodes and icodes are part of selection, cause a fuss if (any(v[1] for v in self.uppers) or any(v[1] for v in self.lowers)): - raise ValueError("Selection specified icodes, while the " - "topology doesn't have any.") from e + six.raise_from(ValueError("Selection specified icodes, while the " + "topology doesn't have any."), None) if not icodes is None: mask = self._sel_with_icodes(vals, icodes) @@ -730,8 +734,8 @@ def __init__(self, parser, tokens): # check if in appropriate format 'lower:upper' or 'lower-upper' selrange = re.match("(\d+)[:-](\d+)", val) if not selrange: - raise ValueError( - "Failed to parse number: {0}".format(val)) from e + six.raise_from(ValueError( + "Failed to parse number: {0}".format(val)), None) lower, upper = np.int64(selrange.groups()) lowers.append(lower) @@ -1000,10 +1004,11 @@ def __init__(self, parser, tokens): self.prop = prop try: self.operator = self.ops[oper] - except KeyError as e: - raise ValueError( + except KeyError: + six.raise_from(ValueError( "Invalid operator : '{0}' Use one of : '{1}'" - "".format(oper, self.ops.keys())) from e + "".format(oper, self.ops.keys())), + None) self.value = float(value) def apply(self, group): @@ -1015,9 +1020,9 @@ def apply(self, group): elif self.prop == 'charge': values = group.charges else: - raise SelectionError( + six.raise_from(SelectionError( "Expected one of : {0}" - "".format(['x', 'y', 'z', 'mass', 'charge'])) from None + "".format(['x', 'y', 'z', 'mass', 'charge'])), None) else: values = group.positions[:, col] @@ -1190,9 +1195,13 @@ def _parse_subexp(self): try: return _SELECTIONDICT[op](self, self.tokens) except KeyError: - raise SelectionError("Unknown selection token: '{0}'".format(op)) from None + six.raise_from( + SelectionError("Unknown selection token: '{0}'".format(op)), + None) except ValueError as e: - raise SelectionError("Selection failed: '{0}'".format(e)) from None + six.raise_from( + SelectionError("Selection failed: '{0}'".format(e)), + None) # The module level instance diff --git a/package/MDAnalysis/core/topologyattrs.py b/package/MDAnalysis/core/topologyattrs.py index 9f61a5fe4f3..60b49998df7 100644 --- a/package/MDAnalysis/core/topologyattrs.py +++ b/package/MDAnalysis/core/topologyattrs.py @@ -486,9 +486,11 @@ def _gen_initial_values(na, nr, ns): def getattr__(atomgroup, name): try: return atomgroup._get_named_atom(name) - except selection.SelectionError as e: - raise AttributeError("'{0}' object has no attribute '{1}'".format( - atomgroup.__class__.__name__, name)) from e + except selection.SelectionError: + six.raise_from( + AttributeError("'{0}' object has no attribute '{1}'".format( + atomgroup.__class__.__name__, name)), + None) def _get_named_atom(group, name): """Get all atoms with name *name* in the current AtomGroup. @@ -1346,9 +1348,11 @@ def _gen_initial_values(na, nr, ns): def getattr__(residuegroup, resname): try: return residuegroup._get_named_residue(resname) - except selection.SelectionError as e: - raise AttributeError("'{0}' object has no attribute '{1}'".format( - residuegroup.__class__.__name__, resname)) from e + except selection.SelectionError: + six.raise_from( + AttributeError("'{0}' object has no attribute '{1}'".format( + residuegroup.__class__.__name__, resname)), + None) transplants[ResidueGroup].append(('__getattr__', getattr__)) # This transplant is hardcoded for now to allow for multiple getattr things @@ -1481,9 +1485,9 @@ def sequence(self, **kwargs): try: sequence = "".join([convert_aa_code(r) for r in self.residues.resnames]) except KeyError as err: - raise ValueError("AtomGroup contains a residue name '{0}' that " + six.raise_from(ValueError("AtomGroup contains a residue name '{0}' that " "does not have a IUPAC protein 1-letter " - "character".format(err.message)) from err + "character".format(err.message)), None) if format == "string": return sequence seq = Bio.Seq.Seq(sequence, alphabet=Bio.Alphabet.IUPAC.protein) @@ -1588,9 +1592,11 @@ def _gen_initial_values(na, nr, ns): def getattr__(segmentgroup, segid): try: return segmentgroup._get_named_segment(segid) - except selection.SelectionError as e: - raise AttributeError("'{0}' object has no attribute '{1}'".format( - segmentgroup.__class__.__name__, segid)) from e + except selection.SelectionError: + six.raise_from( + AttributeError("'{0}' object has no attribute '{1}'".format( + segmentgroup.__class__.__name__, segid)), + None) transplants[SegmentGroup].append( ('__getattr__', getattr__)) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index b9700a9aa27..0ae90bf7ba2 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -31,6 +31,7 @@ from __future__ import print_function, absolute_import, division from six.moves import zip +from six import raise_from import numbers import numpy as np import functools @@ -810,20 +811,20 @@ def atom3(self): """The third atom in each TopologyObject in this Group""" try: return self._ags[2] - except IndexError as e: + except IndexError: nvert = _BTYPE_TO_SHAPE[self.btype] errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" - raise IndexError(errmsg.format(self.btype, nvert)) from e + raise_from(IndexError(errmsg.format(self.btype, nvert)), None) @property def atom4(self): """The fourth atom in each TopologyObject in this Group""" try: return self._ags[3] - except IndexError as e: + except IndexError: nvert = _BTYPE_TO_SHAPE[self.btype] errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" - raise IndexError(errmsg.format(self.btype, nvert)) from e + raise_from(IndexError(errmsg.format(self.btype, nvert)), None) # Distance calculation methods below # "Slow" versions exist as a way of testing the Cython implementations diff --git a/package/MDAnalysis/core/universe.py b/package/MDAnalysis/core/universe.py index dd63a7b0a14..afcb4b4fb4a 100644 --- a/package/MDAnalysis/core/universe.py +++ b/package/MDAnalysis/core/universe.py @@ -304,12 +304,12 @@ def __init__(self, *args, **kwargs): "Failed to load from the topology file {0}" " with parser {1}.\n" "Error: {2}".format(self.filename, parser, err)) - raise IOError(errmsg) from err + six.raise_from(IOError(errmsg), None) except (ValueError, NotImplementedError) as err: - raise ValueError( + six.raise_from(ValueError( "Failed to construct topology from file {0}" " with parser {1}.\n" - "Error: {2}".format(self.filename, parser, err)) from err + "Error: {2}".format(self.filename, parser, err)), None) # generate and populate Universe version of each class self._generate_from_topology() @@ -509,8 +509,8 @@ def __getattr__(self, key): # created at the beginning of __init__. try: segment = self._instant_selectors[key] - except KeyError as e: - raise AttributeError('No attribute "{}".'.format(key)) from e + except KeyError: + six.raise_from(AttributeError('No attribute "{}".'.format(key)), None) else: warnings.warn("Instant selector Universe. " "is deprecated and will be removed in 1.0. " @@ -860,7 +860,7 @@ def add_TopologyAttr(self, topologyattr, values=None): if isinstance(topologyattr, six.string_types): try: tcls = _TOPOLOGY_ATTRS[topologyattr] - except KeyError as e: + except KeyError: errmsg = ( "Unrecognised topology attribute name: '{}'." " Possible values: '{}'\n" @@ -868,7 +868,7 @@ def add_TopologyAttr(self, topologyattr, values=None): "".format( topologyattr, ', '.join(sorted(_TOPOLOGY_ATTRS.keys()))) ) - raise ValueError(errmsg) from e + six.raise_from(ValueError(errmsg), None) else: topologyattr = tcls.from_blank( n_atoms=self._topology.n_atoms, diff --git a/package/MDAnalysis/lib/distances.py b/package/MDAnalysis/lib/distances.py index 8fac61fd1b0..1e30fb423c2 100644 --- a/package/MDAnalysis/lib/distances.py +++ b/package/MDAnalysis/lib/distances.py @@ -68,6 +68,7 @@ """ from __future__ import division, absolute_import from six.moves import range +from six import raise_from import numpy as np from numpy.lib.utils import deprecate @@ -98,10 +99,10 @@ def _run(funcname, args=None, kwargs=None, backend="serial"): backend = backend.lower() try: func = getattr(_distances[backend], funcname) - except KeyError as e: + except KeyError: errmsg = ("Function {0} not available with backend {1}; try one " "of: {2}".format(funcname, backend, _distances.keys())) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) return func(*args, **kwargs) # serial versions are always available (and are typically used within diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index 899afcae2c3..8948f379fb3 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -850,9 +850,11 @@ def fileno(self): """ try: return self.stream.fileno() - except AttributeError as e: + except AttributeError: # IOBase.fileno does not raise IOError as advertised so we do this here - raise IOError("This NamedStream does not use a file descriptor.") from e + six.raise_from( + IOError("This NamedStream does not use a file descriptor."), + None) def readline(self): try: @@ -955,9 +957,11 @@ def check_compressed_format(root, ext): if ext.lower() in ("bz2", "gz"): try: root, ext = get_ext(root) - except Exception as e: - raise TypeError("Cannot determine coordinate format for '{0}.{1}'" - "".format(root, ext)) from e + except Exception: + six.raise_from( + TypeError("Cannot determine coordinate format for '{0}.{1}'" + "".format(root, ext)), + None) return ext.upper() @@ -980,11 +984,12 @@ def format_from_filename_extension(filename): """ try: root, ext = get_ext(filename) - except Exception as e: - raise TypeError( + except Exception: + six.raise_from(TypeError( "Cannot determine file format for file '{0}'.\n" " You can set the format explicitly with " - "'Universe(..., format=FORMAT)'.".format(filename)) from e + "'Universe(..., format=FORMAT)'.".format(filename)), + None) format = check_compressed_format(root, ext) return format @@ -1020,10 +1025,12 @@ def guess_format(filename): # perhaps StringIO or open stream try: format = format_from_filename_extension(filename.name) - except AttributeError as e: + except AttributeError: # format is None so we need to complain: - raise ValueError("guess_format requires an explicit format specifier " - "for stream {0}".format(filename)) from e + six.raise_from( + ValueError("guess_format requires an explicit format specifier " + "for stream {0}".format(filename)), + None) else: # iterator, list, filename: simple extension checking... something more # complicated is left for the ambitious. @@ -1109,9 +1116,9 @@ def read(self, line): """Read the entry from `line` and convert to appropriate type.""" try: return self.convertor(line[self.start:self.stop]) - except ValueError as e: + except ValueError: errmsg = "{0!r}: Failed to read&convert {1!r}".format(self, line[self.start:self.stop]) - raise ValueError(errmsg) from e + six.raise_from(ValueError(errmsg), None) def __len__(self): """Length of the field in columns (stop - start)""" @@ -1344,8 +1351,10 @@ def get_weights(atoms, weights): if not iterable(weights) and weights == "mass": try: weights = atoms.masses - except AttributeError as e: - raise TypeError("weights='mass' selected but atoms.masses is missing") from e + except AttributeError: + six.raise_from( + TypeError("weights='mass' selected but atoms.masses is missing"), + None) if iterable(weights): if len(np.asarray(weights).shape) != 1: @@ -1424,9 +1433,9 @@ def convert_aa_code(x): try: return d[x.upper()] - except KeyError as e: + except KeyError: errmsg = "No conversion for {0} found (1 letter -> 3 letter or 3/4 letter -> 1 letter)".format(x) - raise ValueError(errmsg) from e + six.raise_from(ValueError(errmsg), None) #: Regular expression to match and parse a residue-atom selection; will match @@ -1675,9 +1684,9 @@ def __getattr__(self, key): # a.this causes a __getattr__ call for key = 'this' try: return dict.__getitem__(self, key) - except KeyError as e: - raise AttributeError('"{}" is not known in the namespace.' - .format(key)) from e + except KeyError: + six.raise_from(AttributeError('"{}" is not known in the namespace.' + .format(key)), None) def __setattr__(self, key, value): dict.__setitem__(self, key, value) @@ -1992,10 +2001,10 @@ def _check_coords(coords, argname): "".format(fname, argname, coords.shape)) try: coords = coords.astype(np.float32, order='C', copy=enforce_copy) - except ValueError as e: + except ValueError: errmsg = ("{}(): {}.dtype must be convertible to float32," " got {}.".format(fname, argname, coords.dtype)) - raise TypeError(errmsg) from e + six.raise_from(TypeError(errmsg), None) return coords, is_single @wraps(func) diff --git a/package/MDAnalysis/selections/__init__.py b/package/MDAnalysis/selections/__init__.py index eb80751bfe0..146252a9963 100644 --- a/package/MDAnalysis/selections/__init__.py +++ b/package/MDAnalysis/selections/__init__.py @@ -45,6 +45,7 @@ .. autofunction:: get_writer """ from __future__ import absolute_import +from six import raise_from import os.path @@ -84,7 +85,8 @@ def get_writer(filename, defaultformat): format = format.strip().upper() # canonical for lookup try: return _SELECTION_WRITERS[format] - except KeyError as e: - raise NotImplementedError( + except KeyError: + raise_from(NotImplementedError( "Writing as {0!r} is not implemented;" - " only {1!r} will work.".format(format, _SELECTION_WRITERS.keys())) from e + " only {1!r} will work.".format(format, _SELECTION_WRITERS.keys())), + None) diff --git a/package/MDAnalysis/tests/datafiles.py b/package/MDAnalysis/tests/datafiles.py index 71b07737741..68f2af8000e 100644 --- a/package/MDAnalysis/tests/datafiles.py +++ b/package/MDAnalysis/tests/datafiles.py @@ -37,10 +37,11 @@ http://pypi.python.org/pypi/MDAnalysisTests and installed. """ from __future__ import print_function, absolute_import +from six import raise_from try: from MDAnalysisTests.datafiles import * -except ImportError as e: +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 ") @@ -50,4 +51,4 @@ 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.") from e + raise_from(ImportError("MDAnalysisTests package not installed."), None) diff --git a/package/MDAnalysis/topology/CRDParser.py b/package/MDAnalysis/topology/CRDParser.py index 5e5d90a3b37..fa2e287a0e0 100644 --- a/package/MDAnalysis/topology/CRDParser.py +++ b/package/MDAnalysis/topology/CRDParser.py @@ -46,6 +46,7 @@ """ from __future__ import absolute_import +from six import raise_from import numpy as np @@ -121,9 +122,10 @@ def parse(self, **kwargs): try: (serial, resnum, resName, name, x, y, z, segid, resid, tempFactor) = r.read(line) - except Exception as e: - raise ValueError("Check CRD format at line {0}: {1}" - "".format(linenum + 1, line.rstrip())) from e + except Exception: + raise_from(ValueError("Check CRD format at line {0}: {1}" + "".format(linenum + 1, line.rstrip())), + None) atomids.append(serial) atomnames.append(name) diff --git a/package/MDAnalysis/topology/DMSParser.py b/package/MDAnalysis/topology/DMSParser.py index 657c429bb97..8294ef034d7 100644 --- a/package/MDAnalysis/topology/DMSParser.py +++ b/package/MDAnalysis/topology/DMSParser.py @@ -41,6 +41,7 @@ """ from __future__ import absolute_import +from six import raise_from import numpy as np import sqlite3 @@ -140,9 +141,9 @@ def dict_factory(cursor, row): cur.execute('SELECT {} FROM particle' ''.format(attrname)) vals = cur.fetchall() - except sqlite3.DatabaseError as e: + except sqlite3.DatabaseError: errmsg = "Failed reading the atoms from DMS Database" - raise IOError(errmsg) from e + raise_from(IOError(errmsg), None) else: attrs[attrname] = np.array(vals, dtype=dt) @@ -150,9 +151,9 @@ def dict_factory(cursor, row): cur.row_factory = dict_factory cur.execute('SELECT * FROM bond') bonds = cur.fetchall() - except sqlite3.DatabaseError as e: + except sqlite3.DatabaseError: errmsg = "Failed reading the bonds from DMS Database" - raise IOError(errmsg) from e + raise_from(IOError(errmsg), None) else: bondlist = [] bondorder = {} diff --git a/package/MDAnalysis/topology/GROParser.py b/package/MDAnalysis/topology/GROParser.py index ec1e0cf546a..53e4a35c68b 100644 --- a/package/MDAnalysis/topology/GROParser.py +++ b/package/MDAnalysis/topology/GROParser.py @@ -48,6 +48,7 @@ import numpy as np from six.moves import range +from six import raise_from from ..lib.util import openany from ..core.topologyattrs import ( @@ -102,12 +103,12 @@ def parse(self, **kwargs): resnames[i] = line[5:10].strip() names[i] = line[10:15].strip() indices[i] = int(line[15:20]) - except (ValueError, TypeError) as e: + except (ValueError, TypeError): errmsg = ( "Couldn't read the following line of the .gro file:\n" "{0}" ) - raise IOError(errmsg.format(line)) from e + raise_from(IOError(errmsg.format(line)), None) # Check all lines had names if not np.all(names): missing = np.where(names == '') diff --git a/package/MDAnalysis/topology/LAMMPSParser.py b/package/MDAnalysis/topology/LAMMPSParser.py index 8684a35ff3c..07efde717dd 100644 --- a/package/MDAnalysis/topology/LAMMPSParser.py +++ b/package/MDAnalysis/topology/LAMMPSParser.py @@ -80,6 +80,7 @@ from __future__ import absolute_import, print_function from six.moves import range +from six import raise_from import numpy as np import logging @@ -285,12 +286,13 @@ def parse(self, **kwargs): try: top = self._parse_atoms(sects['Atoms'], masses) - except Exception as e: - raise ValueError( + except Exception: + raise_from(ValueError( "Failed to parse atoms section. You can supply a description " "of the atom_style as a keyword argument, " "eg mda.Universe(..., atom_style='id resid x y z')" - ) from e + ), + None) # create mapping of id to index (ie atom id 10 might be the 0th atom) mapping = {atom_id: i for i, atom_id in enumerate(top.ids.values)} @@ -335,9 +337,9 @@ def read_DATA_timestep(self, n_atoms, TS_class, TS_kwargs, try: positions, ordering = self._parse_pos(sects['Atoms']) - except KeyError as err: + except KeyError: errmsg = "Position information not found: {}".format(err) - raise IOError(errmsg) from err + raise_from(IOError(errmsg), None) if 'Velocities' in sects: velocities = self._parse_vel(sects['Velocities'], ordering) diff --git a/package/MDAnalysis/topology/PSFParser.py b/package/MDAnalysis/topology/PSFParser.py index 0289f23a898..92b74f62735 100644 --- a/package/MDAnalysis/topology/PSFParser.py +++ b/package/MDAnalysis/topology/PSFParser.py @@ -45,6 +45,7 @@ """ from __future__ import absolute_import, division from six.moves import range +from six import raise_from import logging import functools @@ -276,11 +277,11 @@ def _parseatoms(self, lines, atoms_per, numlines): for i in range(numlines): try: line = lines() - except StopIteration as e: + except StopIteration: err = ("{0} is not valid PSF file" "".format(self.filename)) logger.error(err) - raise ValueError(err) from e + raise_from(ValueError(err), None) try: vals = set_type(atom_parser(line)) except ValueError: diff --git a/package/MDAnalysis/topology/TOPParser.py b/package/MDAnalysis/topology/TOPParser.py index 25cc8b8c24e..7124041ba0b 100644 --- a/package/MDAnalysis/topology/TOPParser.py +++ b/package/MDAnalysis/topology/TOPParser.py @@ -81,6 +81,7 @@ from __future__ import absolute_import, division from six.moves import range, zip +from six import raise_from import numpy as np import functools from math import ceil @@ -233,10 +234,10 @@ def next_getter(): else: try: next_section = line.split("%FLAG")[1].strip() - except IndexError as e: + except IndexError: msg = ("%FLAG section not found, formatting error " "for PARM7 file {0} ".format(self.filename)) - raise IndexError(msg) from e + raise_from(IndexError(msg), None) # strip out a few values to play with them n_atoms = len(attrs['name']) diff --git a/package/MDAnalysis/transformations/fit.py b/package/MDAnalysis/transformations/fit.py index 2db1579fd8d..53dd142d139 100644 --- a/package/MDAnalysis/transformations/fit.py +++ b/package/MDAnalysis/transformations/fit.py @@ -33,6 +33,7 @@ """ from __future__ import absolute_import +from six import raise_from import numpy as np from functools import partial @@ -89,19 +90,21 @@ def fit_translation(ag, reference, plane=None, weights=None): axes = {'yz' : 0, 'xz' : 1, 'xy' : 2} try: plane = axes[plane] - except (TypeError, KeyError) as e: - raise ValueError('{} is not a valid plane'.format(plane)) from e + except (TypeError, KeyError): + raise_from(ValueError('{} is not a valid plane'.format(plane)), None) try: if ag.atoms.n_residues != reference.atoms.n_residues: raise ValueError("{} and {} have mismatched number of residues".format(ag,reference)) - except AttributeError as e: - raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) from e + except AttributeError: + raise_from( + AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)), + None) ref, mobile = align.get_matching_atoms(reference.atoms, ag.atoms) try: weights = align.get_weights(ref.atoms, weights=weights) - except (ValueError, TypeError) as e: - raise ValueError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") from e + except (ValueError, TypeError): + raise_from(ValueError("weights must be {'mass', None} or an iterable of the " + "same size as the atomgroup."), None) ref_com = np.asarray(ref.center(weights), np.float32) @@ -168,19 +171,19 @@ def fit_rot_trans(ag, reference, plane=None, weights=None): axes = {'yz' : 0, 'xz' : 1, 'xy' : 2} try: plane = axes[plane] - except (TypeError, KeyError) as e: - raise ValueError('{} is not a valid plane'.format(plane)) from e + except (TypeError, KeyError): + raise_from(ValueError('{} is not a valid plane'.format(plane)), None) try: if ag.atoms.n_residues != reference.atoms.n_residues: raise ValueError("{} and {} have mismatched number of residues".format(ag,reference)) - except AttributeError as e: - raise AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)) from e + except AttributeError: + raise_from(AttributeError("{} or {} is not valid Universe/AtomGroup".format(ag,reference)), None) ref, mobile = align.get_matching_atoms(reference.atoms, ag.atoms) try: weights = align.get_weights(ref.atoms, weights=weights) - except (ValueError, TypeError) as e: - raise ValueError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") from e + except (ValueError, TypeError): + raise_from(ValueError("weights must be {'mass', None} or an iterable of the " + "same size as the atomgroup."), None) ref_com = ref.center(weights) ref_coordinates = ref.atoms.positions - ref_com diff --git a/package/MDAnalysis/transformations/rotate.py b/package/MDAnalysis/transformations/rotate.py index 49285ea7cd5..694aec606e2 100644 --- a/package/MDAnalysis/transformations/rotate.py +++ b/package/MDAnalysis/transformations/rotate.py @@ -32,6 +32,7 @@ """ from __future__ import absolute_import +from six import raise_from import math import numpy as np @@ -112,8 +113,10 @@ def rotateby(angle, direction, point=None, ag=None, weights=None, wrap=False): if direction.shape != (3, ) and direction.shape != (1, 3): raise ValueError('{} is not a valid direction'.format(direction)) direction = direction.reshape(3, ) - except ValueError as e: - raise ValueError('{} is not a valid direction'.format(direction)) from e + except ValueError: + raise_from( + ValueError('{} is not a valid direction'.format(direction)), + None) if point is not None: point = np.asarray(point, np.float32) if point.shape != (3, ) and point.shape != (1, 3): @@ -122,14 +125,16 @@ def rotateby(angle, direction, point=None, ag=None, weights=None, wrap=False): elif ag: try: atoms = ag.atoms - except AttributeError as e: - raise ValueError('{} is not an AtomGroup object'.format(ag)) from e + except AttributeError: + raise_from(ValueError('{} is not an AtomGroup object'.format(ag)), None) else: try: weights = get_weights(atoms, weights=weights) - except (ValueError, TypeError) as e: - raise TypeError("weights must be {'mass', None} or an iterable of the " - "same size as the atomgroup.") from e + except (ValueError, TypeError): + raise_from( + TypeError("weights must be {'mass', None} or an iterable of the " + "same size as the atomgroup."), + None) center_method = partial(atoms.center, weights, pbc=wrap) else: raise ValueError('A point or an AtomGroup must be specified') diff --git a/package/MDAnalysis/transformations/translate.py b/package/MDAnalysis/transformations/translate.py index 97a8b942893..77950d4bab3 100644 --- a/package/MDAnalysis/transformations/translate.py +++ b/package/MDAnalysis/transformations/translate.py @@ -37,6 +37,7 @@ """ from __future__ import absolute_import, division +from six import raise_from import numpy as np from functools import partial @@ -124,11 +125,13 @@ def center_in_box(ag, center='geometry', point=None, wrap=False): center_method = partial(ag.center_of_mass, pbc=pbc_arg) else: raise ValueError('{} is not a valid argument for center'.format(center)) - except AttributeError as e: + except AttributeError: if center == 'mass': - raise AttributeError('{} is not an AtomGroup object with masses'.format(ag)) from e + raise_from( + AttributeError('{} is not an AtomGroup object with masses'.format(ag)), + None) else: - raise ValueError('{} is not an AtomGroup object'.format(ag)) from e + raise_from(ValueError('{} is not an AtomGroup object'.format(ag)), None) def wrapped(ts): if point is None: diff --git a/package/MDAnalysis/units.py b/package/MDAnalysis/units.py index cdbf2b84377..e651e2ee93e 100644 --- a/package/MDAnalysis/units.py +++ b/package/MDAnalysis/units.py @@ -167,6 +167,7 @@ """ from __future__ import unicode_literals, division +from six import raise_from #: `Avogadro's constant`_ in mol**-1. #: @@ -363,18 +364,18 @@ def convert(x, u1, u2): """ try: ut1 = unit_types[u1] - except KeyError as e: + except KeyError: errmsg = ("unit '{0}' not recognized.\n" "It must be one of {1}.".format(u1, ", ".join(unit_types)) ) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) try: ut2 = unit_types[u2] - except KeyError as e: + except KeyError: errmsg = ("unit '{0}' not recognized.\n" "It must be one of {1}.".format(u2, ", ".join(unit_types)) ) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) if ut1 != ut2: raise ValueError("Cannot convert between unit types " "{0} --> {1}".format(u1, u2)) diff --git a/package/MDAnalysis/visualization/streamlines.py b/package/MDAnalysis/visualization/streamlines.py index e7e2c4be8fa..1b8a4e71322 100644 --- a/package/MDAnalysis/visualization/streamlines.py +++ b/package/MDAnalysis/visualization/streamlines.py @@ -44,6 +44,7 @@ """ from __future__ import absolute_import from six.moves import zip +from six import raise_from import multiprocessing @@ -53,14 +54,14 @@ try: import matplotlib import matplotlib.path -except ImportError as e: - errmsg = ( +except ImportError: + errmsg = ( '2d streamplot module requires: matplotlib.path for its ' 'path.Path.contains_points method. The installation ' 'instructions for the matplotlib module can be found here: ' 'http://matplotlib.org/faq/installing_faq.html?highlight=install' ) - raise ImportError(errmsg) from e + raise_from(ImportError(errmsg), None) import MDAnalysis From 2d6f16dcd45c6f8d5111a56637e448632534f0b2 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sat, 2 Nov 2019 23:48:10 -0400 Subject: [PATCH 10/15] added to AUTHORS --- package/AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/package/AUTHORS b/package/AUTHORS index d5518c72874..04aceff1398 100644 --- a/package/AUTHORS +++ b/package/AUTHORS @@ -124,6 +124,7 @@ Chronological list of authors - Rocco Meli - Lily Wang - Matthijs Tadema + - Joao Miguel Correia Teixeira External code ------------- From 695b2ae71a4278c0174d454d8f14d05b7b168298 Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sun, 3 Nov 2019 00:49:57 -0400 Subject: [PATCH 11/15] Completes details updates some missing lines from previous commit corrects deleted vars passes tests py37, lookforward towards Travis results --- package/MDAnalysis/coordinates/LAMMPS.py | 9 ++++++--- package/MDAnalysis/coordinates/TRJ.py | 2 +- package/MDAnalysis/coordinates/TXYZ.py | 2 +- package/MDAnalysis/coordinates/base.py | 12 +++++++----- package/MDAnalysis/core/groups.py | 19 +++++++++++-------- package/MDAnalysis/core/selection.py | 4 ++-- package/MDAnalysis/lib/util.py | 8 +++++--- package/MDAnalysis/topology/LAMMPSParser.py | 2 +- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/package/MDAnalysis/coordinates/LAMMPS.py b/package/MDAnalysis/coordinates/LAMMPS.py index e4ce746e1fe..40e9e64e86e 100644 --- a/package/MDAnalysis/coordinates/LAMMPS.py +++ b/package/MDAnalysis/coordinates/LAMMPS.py @@ -404,9 +404,12 @@ def write(self, selection, frame=None): # check that types can be converted to ints if they aren't ints already try: atoms.types.astype(np.int32) - except ValueError as e: - raise ValueError('LAMMPS.DATAWriter: atom types must be '+ - 'convertible to integers') from e + except ValueError: + raise_from( + ValueError( + 'LAMMPS.DATAWriter: atom types must be ' + 'convertible to integers'), + None) try: velocities = atoms.velocities diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index f7db1a5afb1..44a6d5056ff 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -569,7 +569,7 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): except KeyError as e: errmsg = ("NCDF trajectory {0} does not contain frame " "information".format(self.filename)) - raise ValueError(errmsg) from e + raise_from(ValueError(errmsg), None) try: self.remarks = self.trjfile.title diff --git a/package/MDAnalysis/coordinates/TXYZ.py b/package/MDAnalysis/coordinates/TXYZ.py index 14edee62594..7103fe9210b 100644 --- a/package/MDAnalysis/coordinates/TXYZ.py +++ b/package/MDAnalysis/coordinates/TXYZ.py @@ -154,7 +154,7 @@ def _read_next_timestep(self, ts=None): ts.positions = tmp_buf ts.frame += 1 return ts - except (ValueError, IndexError): + except (ValueError, IndexError) as err: raise_from(EOFError(err), None) def _reopen(self): diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index 28ebc50741c..60328a837b0 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -519,9 +519,11 @@ def copy_slice(self, sel): vel = self.velocities[sel, :] except NoDataError: vel = None - except Exception as e: - raise TypeError("Selection type must be compatible with slicing" - " the coordinates") from e + except Exception: + six.raise_from( + TypeError("Selection type must be compatible with slicing" + " the coordinates"), + None) try: force = self.forces[sel, :] except NoDataError: @@ -2022,9 +2024,9 @@ def add_transformations(self, *transformations): try: self.transformations = transformations - except ValueError as e: + except ValueError: errmsg = "Can't add transformations again. Please create new Universe object" - raise ValueError(errmsg) from e + six.raise_from(ValueError(errmsg), None) else: self.ts = self._apply_transformations(self.ts) diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index bbefce8e127..577c48d8e9f 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -335,11 +335,12 @@ def __new__(cls, *args, **kwargs): for parent in cls.mro() if parent in u._class_bases) except StopIteration: - raise TypeError("Attempted to instantiate class '{}' but " + raise_from(TypeError("Attempted to instantiate class '{}' but " "none of its parents are known to the " "universe. Currently possible parent " "classes are: {}".format(cls.__name__, - str(sorted(u._class_bases.keys())))) + str(sorted(u._class_bases.keys())))), + None) newcls = u._classes[cls] = parent_cls._mix(cls) return object.__new__(newcls) @@ -1494,8 +1495,10 @@ def wrap(self, compound="atoms", center="com", box=None, inplace=True): try: compound_indices = atoms.fragindices except NoDataError: - raise NoDataError("Cannot use compound='fragments', " - "this requires bonds.") from None + raise_from( + NoDataError("Cannot use compound='fragments', " + "this requires bonds."), + None) # compute required shifts: if ctr == 'com': @@ -2546,7 +2549,7 @@ def forces(self): try: return ts.forces[self.ix] except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") from None + raise_from(NoDataError("Timestep does not contain forces"), None) @forces.setter def forces(self, values): @@ -2554,7 +2557,7 @@ def forces(self, values): try: ts.forces[self.ix, :] = values except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") from None + raise_from(NoDataError("Timestep does not contain forces"), None) @property def ts(self): @@ -3669,7 +3672,7 @@ def velocity(self, values): try: ts.velocities[self.ix, :] = values except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain velocities") from None + raise_from(NoDataError("Timestep does not contain velocities"), None) @property def force(self): @@ -3700,7 +3703,7 @@ def force(self, values): try: ts.forces[self.ix, :] = values except (AttributeError, NoDataError): - raise NoDataError("Timestep does not contain forces") from None + raise_from(NoDataError("Timestep does not contain forces"), None) class Residue(ComponentBase): diff --git a/package/MDAnalysis/core/selection.py b/package/MDAnalysis/core/selection.py index 0cefb32c652..34f0b748e48 100644 --- a/package/MDAnalysis/core/selection.py +++ b/package/MDAnalysis/core/selection.py @@ -640,7 +640,7 @@ def apply(self, group): vals = group.resids try: # optional attribute icodes = group.icodes - except (AttributeError, NoDataError) as e: + except (AttributeError, NoDataError): icodes = None # if no icodes and icodes are part of selection, cause a fuss if (any(v[1] for v in self.uppers) or @@ -730,7 +730,7 @@ def __init__(self, parser, tokens): try: lower = int(val) upper = None - except ValueError as e: + except ValueError: # check if in appropriate format 'lower:upper' or 'lower-upper' selrange = re.match("(\d+)[:-](\d+)", val) if not selrange: diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index 8948f379fb3..c64f3ff028b 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -1694,9 +1694,11 @@ def __setattr__(self, key, value): def __delattr__(self, key): try: dict.__delitem__(self, key) - except KeyError as e: - raise AttributeError('"{}" is not known in the namespace.' - .format(key)) from e + except KeyError: + six.raise_from( + AttributeError('"{}" is not known in the namespace.' + .format(key)), + None) def __eq__(self, other): try: diff --git a/package/MDAnalysis/topology/LAMMPSParser.py b/package/MDAnalysis/topology/LAMMPSParser.py index 07efde717dd..1629545cc45 100644 --- a/package/MDAnalysis/topology/LAMMPSParser.py +++ b/package/MDAnalysis/topology/LAMMPSParser.py @@ -337,7 +337,7 @@ def read_DATA_timestep(self, n_atoms, TS_class, TS_kwargs, try: positions, ordering = self._parse_pos(sects['Atoms']) - except KeyError: + except KeyError as err: errmsg = "Position information not found: {}".format(err) raise_from(IOError(errmsg), None) From 5106053cee5cec8a229d7f49d3895e43d2af308e Mon Sep 17 00:00:00 2001 From: joaomcteixeira Date: Sun, 3 Nov 2019 19:52:54 -0500 Subject: [PATCH 12/15] added from __future__ --- package/MDAnalysis/units.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/MDAnalysis/units.py b/package/MDAnalysis/units.py index e651e2ee93e..513ae9a8c71 100644 --- a/package/MDAnalysis/units.py +++ b/package/MDAnalysis/units.py @@ -166,7 +166,7 @@ """ -from __future__ import unicode_literals, division +from __future__ import absolute_import, unicode_literals, division from six import raise_from #: `Avogadro's constant`_ in mol**-1. From 8b0582ac0cadfcdf470b8c820fe9313fdc071eb2 Mon Sep 17 00:00:00 2001 From: Joao MC Teixeira Date: Mon, 4 Nov 2019 16:39:50 -0500 Subject: [PATCH 13/15] Addressing Coverage Coverage might have decreased in previous commits because errmsg were being defined before raise the errors. Error messages are no longer defined beforehand and strings are passed directed to Error calls. I have not tested locally this commit and will rely only on CI online tests. --- package/MDAnalysis/analysis/nuclinfo.py | 13 ++++++--- package/MDAnalysis/analysis/psa.py | 12 +++++--- package/MDAnalysis/auxiliary/core.py | 5 ++-- package/MDAnalysis/coordinates/LAMMPS.py | 5 ++-- package/MDAnalysis/coordinates/base.py | 7 +++-- package/MDAnalysis/core/__init__.py | 6 ++-- package/MDAnalysis/core/_get_readers.py | 7 +++-- package/MDAnalysis/core/groups.py | 29 ++++++++++++------- package/MDAnalysis/core/topologyobjects.py | 14 ++++++--- package/MDAnalysis/core/universe.py | 13 ++++----- package/MDAnalysis/lib/distances.py | 8 +++-- package/MDAnalysis/lib/util.py | 22 +++++++++----- package/MDAnalysis/topology/DMSParser.py | 10 ++++--- package/MDAnalysis/topology/GROParser.py | 8 ++--- package/MDAnalysis/topology/LAMMPSParser.py | 5 ++-- package/MDAnalysis/units.py | 21 +++++++++----- .../MDAnalysis/visualization/streamlines.py | 15 +++++----- 17 files changed, 124 insertions(+), 76 deletions(-) diff --git a/package/MDAnalysis/analysis/nuclinfo.py b/package/MDAnalysis/analysis/nuclinfo.py index 8432b0fee03..72ba4f5da90 100644 --- a/package/MDAnalysis/analysis/nuclinfo.py +++ b/package/MDAnalysis/analysis/nuclinfo.py @@ -712,10 +712,15 @@ def hydroxyl(universe, seg, i): try: hydr = h.dihedral.value() % 360 except ValueError: - errmsg = ( - "Resid {0} does not contain atoms C1', C2', O2', H2' but atoms {1}" - ) - raise_from(ValueError(errmsg.format(i, str(list(h.atoms)))), None) + raise_from( + ValueError( + ( + "Resid {0} does not contain atoms C1', C2', O2', H2' " + "but atoms {1}" + ).format(i, str(list(h.atoms))) + ), + None) + return hydr diff --git a/package/MDAnalysis/analysis/psa.py b/package/MDAnalysis/analysis/psa.py index f52d7e01df5..9cb45008b5d 100644 --- a/package/MDAnalysis/analysis/psa.py +++ b/package/MDAnalysis/analysis/psa.py @@ -266,10 +266,14 @@ def get_path_metric_func(name): try: return path_metrics[name] except KeyError as key: - errmsg = ('Path metric "{}" not found. Valid selections: {}' - ''.format(key, " ".join('"{}"'.format(n) - for n in path_metrics.keys()))) - raise_from(KeyError(errmsg), None) + raise_from( + KeyError( + 'Path metric "{}" not found. Valid selections: {}'.format( + key, + " ".join('"{}"'.format(n) for n in path_metrics.keys()) + ) + ), + None) def sqnorm(v, axis=None): diff --git a/package/MDAnalysis/auxiliary/core.py b/package/MDAnalysis/auxiliary/core.py index bd074640960..2f05a8c1d59 100644 --- a/package/MDAnalysis/auxiliary/core.py +++ b/package/MDAnalysis/auxiliary/core.py @@ -85,8 +85,9 @@ def get_auxreader_for(auxdata=None, format=None): try: return _AUXREADERS[format] except KeyError: - errmsg = "Unknown auxiliary data format {0}".format(format) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError("Unknown auxiliary data format {0}".format(format)), + None) def auxreader(auxdata, format=None, **kwargs): """ Return an auxiliary reader instance for *auxdata*. diff --git a/package/MDAnalysis/coordinates/LAMMPS.py b/package/MDAnalysis/coordinates/LAMMPS.py index 40e9e64e86e..5f152b9902e 100644 --- a/package/MDAnalysis/coordinates/LAMMPS.py +++ b/package/MDAnalysis/coordinates/LAMMPS.py @@ -162,8 +162,9 @@ def __init__(self, *args, **kwargs): if units.unit_types[unit] != unit_type: raise TypeError("LAMMPS DCDWriter: wrong unit {0!r} for unit type {1!r}".format(unit, unit_type)) except KeyError: - errmsg = ("LAMMPS DCDWriter: unknown unit {0!r}".format(unit)) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError("LAMMPS DCDWriter: unknown unit {0!r}".format(unit)), + None) super(DCDWriter, self).__init__(*args, **kwargs) diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index 60328a837b0..4a5023d311f 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -2025,8 +2025,11 @@ def add_transformations(self, *transformations): try: self.transformations = transformations except ValueError: - errmsg = "Can't add transformations again. Please create new Universe object" - six.raise_from(ValueError(errmsg), None) + six.raise_from( + ValueError( + "Can't add transformations again. " + "Please create new Universe object"), + None) else: self.ts = self._apply_transformations(self.ts) diff --git a/package/MDAnalysis/core/__init__.py b/package/MDAnalysis/core/__init__.py index 4e34f65c48d..5c4f114c0d1 100644 --- a/package/MDAnalysis/core/__init__.py +++ b/package/MDAnalysis/core/__init__.py @@ -265,8 +265,10 @@ def set(self, value): try: self.value = self.mapping[value] except KeyError: - errmsg = "flag must be None or one of " + str(self.mapping.keys()) - six.raise_from(ValueError(errmsg), None) + six.raise_from( + ValueError("flag must be None or one of " + str(self.mapping.keys()), + None) + return self.get() def prop(self): diff --git a/package/MDAnalysis/core/_get_readers.py b/package/MDAnalysis/core/_get_readers.py index c186b18b455..971a9d98a66 100644 --- a/package/MDAnalysis/core/_get_readers.py +++ b/package/MDAnalysis/core/_get_readers.py @@ -235,7 +235,8 @@ def get_parser_for(filename, format=None): try: rdr = get_reader_for(filename) except ValueError: - errmsg = ( + raise_from( + ValueError( "'{0}' isn't a valid topology format, nor a coordinate format\n" " from which a topology can be minimally inferred.\n" " You can use 'Universe(topology, ..., topology_format=FORMAT)'\n" @@ -244,7 +245,7 @@ def get_parser_for(filename, format=None): " {1}\n" " See https://docs.mdanalysis.org/documentation_pages/topology/init.html#supported-topology-formats\n" " For missing formats, raise an issue at \n" - " http://issues.mdanalysis.org".format(format, _PARSERS.keys())) - raise_from(ValueError(errmsg), None) + " http://issues.mdanalysis.org".format(format, _PARSERS.keys())), + None) else: return _PARSERS['MINIMAL'] diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 577c48d8e9f..7d781638586 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -122,12 +122,16 @@ def _unpickle(uhash, ix): except KeyError: # doesn't provide as nice an error message as before as only hash of universe is stored # maybe if we pickled the filename too we could do better... - errmsg = ( - "Couldn't find a suitable Universe to unpickle AtomGroup onto " - "with Universe hash '{}'. Available hashes: {}" - "".format(uhash, ', '.join([str(k) - for k in _ANCHOR_UNIVERSES.keys()]))) - raise_from(RuntimeError(errmsg), None) + raise_from( + RuntimeError( + "Couldn't find a suitable Universe to unpickle AtomGroup onto " + "with Universe hash '{}'. Available hashes: {}" + "".format( + uhash, + ', '.join([str(k) for k in _ANCHOR_UNIVERSES.keys()]) + ) + ), + None) return u.atoms[ix] def _unpickle_uag(basepickle, selections, selstrs): @@ -3258,12 +3262,15 @@ def segments(self, new): try: s_ix = [s.segindex for s in new] except AttributeError: - errmsg = ("Can only set ResidueGroup segments to Segment " - "or SegmentGroup, not {}".format( - ', '.join(type(r) for r in new + raise_from( + TypeError( + "Can only set ResidueGroup segments to Segment " + "or SegmentGroup, not {}".format( + ', '.join(type(r) for r in new if not isinstance(r, Segment)) - )) - raise_from(TypeError(errmsg), None) + ) + ), + None) if not isinstance(s_ix, itertools.cycle) and len(s_ix) != len(self): raise ValueError("Incorrect size: {} for ResidueGroup of size: {}" "".format(len(new), len(self))) diff --git a/package/MDAnalysis/core/topologyobjects.py b/package/MDAnalysis/core/topologyobjects.py index 0ae90bf7ba2..d41c0b30cc0 100644 --- a/package/MDAnalysis/core/topologyobjects.py +++ b/package/MDAnalysis/core/topologyobjects.py @@ -813,8 +813,11 @@ def atom3(self): return self._ags[2] except IndexError: nvert = _BTYPE_TO_SHAPE[self.btype] - errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" - raise_from(IndexError(errmsg.format(self.btype, nvert)), None) + raise_from( + IndexError( + "TopologyGroup of {}s only has {} vertical AtomGroups".format( + self.btype, nvert)), + None) @property def atom4(self): @@ -823,8 +826,11 @@ def atom4(self): return self._ags[3] except IndexError: nvert = _BTYPE_TO_SHAPE[self.btype] - errmsg = "TopologyGroup of {}s only has {} vertical AtomGroups" - raise_from(IndexError(errmsg.format(self.btype, nvert)), None) + raise_from( + IndexError( + "TopologyGroup of {}s only has {} vertical AtomGroups".format( + self.btype, nvert)), + None) # Distance calculation methods below # "Slow" versions exist as a way of testing the Cython implementations diff --git a/package/MDAnalysis/core/universe.py b/package/MDAnalysis/core/universe.py index afcb4b4fb4a..b631d75a41a 100644 --- a/package/MDAnalysis/core/universe.py +++ b/package/MDAnalysis/core/universe.py @@ -300,11 +300,11 @@ def __init__(self, *args, **kwargs): six.reraise(*sys.exc_info()) else: # Runs when the parser fails - errmsg = ( + six.raise_from(IOError( "Failed to load from the topology file {0}" " with parser {1}.\n" - "Error: {2}".format(self.filename, parser, err)) - six.raise_from(IOError(errmsg), None) + "Error: {2}".format(self.filename, parser, err)), + None) except (ValueError, NotImplementedError) as err: six.raise_from(ValueError( "Failed to construct topology from file {0}" @@ -861,14 +861,13 @@ def add_TopologyAttr(self, topologyattr, values=None): try: tcls = _TOPOLOGY_ATTRS[topologyattr] except KeyError: - errmsg = ( + six.raise_from(ValueError( "Unrecognised topology attribute name: '{}'." " Possible values: '{}'\n" "To raise an issue go to: http://issues.mdanalysis.org" "".format( - topologyattr, ', '.join(sorted(_TOPOLOGY_ATTRS.keys()))) - ) - six.raise_from(ValueError(errmsg), None) + topologyattr, ', '.join(sorted(_TOPOLOGY_ATTRS.keys())))), + None) else: topologyattr = tcls.from_blank( n_atoms=self._topology.n_atoms, diff --git a/package/MDAnalysis/lib/distances.py b/package/MDAnalysis/lib/distances.py index 1e30fb423c2..df599be5810 100644 --- a/package/MDAnalysis/lib/distances.py +++ b/package/MDAnalysis/lib/distances.py @@ -100,9 +100,11 @@ def _run(funcname, args=None, kwargs=None, backend="serial"): try: func = getattr(_distances[backend], funcname) except KeyError: - errmsg = ("Function {0} not available with backend {1}; try one " - "of: {2}".format(funcname, backend, _distances.keys())) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError( + "Function {0} not available with backend {1}; try one " + "of: {2}".format(funcname, backend, _distances.keys())), + None) return func(*args, **kwargs) # serial versions are always available (and are typically used within diff --git a/package/MDAnalysis/lib/util.py b/package/MDAnalysis/lib/util.py index c64f3ff028b..8103457de84 100644 --- a/package/MDAnalysis/lib/util.py +++ b/package/MDAnalysis/lib/util.py @@ -1117,8 +1117,11 @@ def read(self, line): try: return self.convertor(line[self.start:self.stop]) except ValueError: - errmsg = "{0!r}: Failed to read&convert {1!r}".format(self, line[self.start:self.stop]) - six.raise_from(ValueError(errmsg), None) + six.raise_from( + ValueError( + "{0!r}: Failed to read&convert {1!r}".format( + self, line[self.start:self.stop])), + None) def __len__(self): """Length of the field in columns (stop - start)""" @@ -1434,8 +1437,11 @@ def convert_aa_code(x): try: return d[x.upper()] except KeyError: - errmsg = "No conversion for {0} found (1 letter -> 3 letter or 3/4 letter -> 1 letter)".format(x) - six.raise_from(ValueError(errmsg), None) + six.raise_from( + ValueError( + "No conversion for {0} found (1 letter -> 3 letter or 3/4 letter -> 1 letter)".format(x) + ), + None) #: Regular expression to match and parse a residue-atom selection; will match @@ -2004,9 +2010,11 @@ def _check_coords(coords, argname): try: coords = coords.astype(np.float32, order='C', copy=enforce_copy) except ValueError: - errmsg = ("{}(): {}.dtype must be convertible to float32," - " got {}.".format(fname, argname, coords.dtype)) - six.raise_from(TypeError(errmsg), None) + six.raise_from( + TypeError( + "{}(): {}.dtype must be convertible to float32," + " got {}.".format(fname, argname, coords.dtype)), + None) return coords, is_single @wraps(func) diff --git a/package/MDAnalysis/topology/DMSParser.py b/package/MDAnalysis/topology/DMSParser.py index 8294ef034d7..ef5f2b99aba 100644 --- a/package/MDAnalysis/topology/DMSParser.py +++ b/package/MDAnalysis/topology/DMSParser.py @@ -142,8 +142,9 @@ def dict_factory(cursor, row): ''.format(attrname)) vals = cur.fetchall() except sqlite3.DatabaseError: - errmsg = "Failed reading the atoms from DMS Database" - raise_from(IOError(errmsg), None) + raise_from( + IOError("Failed reading the atoms from DMS Database"), + None) else: attrs[attrname] = np.array(vals, dtype=dt) @@ -152,8 +153,9 @@ def dict_factory(cursor, row): cur.execute('SELECT * FROM bond') bonds = cur.fetchall() except sqlite3.DatabaseError: - errmsg = "Failed reading the bonds from DMS Database" - raise_from(IOError(errmsg), None) + raise_from( + IOError("Failed reading the bonds from DMS Database"), + None) else: bondlist = [] bondorder = {} diff --git a/package/MDAnalysis/topology/GROParser.py b/package/MDAnalysis/topology/GROParser.py index 53e4a35c68b..3cddcdc114e 100644 --- a/package/MDAnalysis/topology/GROParser.py +++ b/package/MDAnalysis/topology/GROParser.py @@ -104,11 +104,11 @@ def parse(self, **kwargs): names[i] = line[10:15].strip() indices[i] = int(line[15:20]) except (ValueError, TypeError): - errmsg = ( + raise_from( + IOError(( "Couldn't read the following line of the .gro file:\n" - "{0}" - ) - raise_from(IOError(errmsg.format(line)), None) + "{0}").format(line)), + None) # Check all lines had names if not np.all(names): missing = np.where(names == '') diff --git a/package/MDAnalysis/topology/LAMMPSParser.py b/package/MDAnalysis/topology/LAMMPSParser.py index 1629545cc45..4f36621e7d2 100644 --- a/package/MDAnalysis/topology/LAMMPSParser.py +++ b/package/MDAnalysis/topology/LAMMPSParser.py @@ -338,8 +338,9 @@ def read_DATA_timestep(self, n_atoms, TS_class, TS_kwargs, try: positions, ordering = self._parse_pos(sects['Atoms']) except KeyError as err: - errmsg = "Position information not found: {}".format(err) - raise_from(IOError(errmsg), None) + raise_from( + IOError("Position information not found: {}".format(err)), + None) if 'Velocities' in sects: velocities = self._parse_vel(sects['Velocities'], ordering) diff --git a/package/MDAnalysis/units.py b/package/MDAnalysis/units.py index 513ae9a8c71..40e7f24ec47 100644 --- a/package/MDAnalysis/units.py +++ b/package/MDAnalysis/units.py @@ -365,17 +365,22 @@ def convert(x, u1, u2): try: ut1 = unit_types[u1] except KeyError: - errmsg = ("unit '{0}' not recognized.\n" - "It must be one of {1}.".format(u1, ", ".join(unit_types)) - ) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError( + ("unit '{0}' not recognized.\n" + "It must be one of {1}.").format(u1, ", ".join(unit_types)) + ), + None) + try: ut2 = unit_types[u2] except KeyError: - errmsg = ("unit '{0}' not recognized.\n" - "It must be one of {1}.".format(u2, ", ".join(unit_types)) - ) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError( + ("unit '{0}' not recognized.\n" + "It must be one of {1}.").format(u2, ", ".join(unit_types)) + ), + None) if ut1 != ut2: raise ValueError("Cannot convert between unit types " "{0} --> {1}".format(u1, u2)) diff --git a/package/MDAnalysis/visualization/streamlines.py b/package/MDAnalysis/visualization/streamlines.py index 1b8a4e71322..70dbe78ecbf 100644 --- a/package/MDAnalysis/visualization/streamlines.py +++ b/package/MDAnalysis/visualization/streamlines.py @@ -55,13 +55,14 @@ import matplotlib import matplotlib.path except ImportError: - errmsg = ( - '2d streamplot module requires: matplotlib.path for its ' - 'path.Path.contains_points method. The installation ' - 'instructions for the matplotlib module can be found here: ' - 'http://matplotlib.org/faq/installing_faq.html?highlight=install' - ) - raise_from(ImportError(errmsg), None) + raise_from( + ImportError(( + '2d streamplot module requires: matplotlib.path for its ' + 'path.Path.contains_points method. The installation ' + 'instructions for the matplotlib module can be found here: ' + 'http://matplotlib.org/faq/installing_faq.html?highlight=install' + )), + None) import MDAnalysis From 3c2f3e4d8a96c6a4d7dbd0b62433bd9cc611156c Mon Sep 17 00:00:00 2001 From: Joao MC Teixeira Date: Tue, 5 Nov 2019 10:15:21 -0500 Subject: [PATCH 14/15] Completed correction Solves syntax error from 8b0582a addresses https://github.com/MDAnalysis/mdanalysis/pull/2357#issuecomment-549416295 Tests pass for python3.7 on my computer. --- package/MDAnalysis/analysis/align.py | 11 ++++++----- package/MDAnalysis/coordinates/TRJ.py | 11 +++++++---- package/MDAnalysis/core/__init__.py | 2 +- package/MDAnalysis/core/groups.py | 12 +++++++----- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/package/MDAnalysis/analysis/align.py b/package/MDAnalysis/analysis/align.py index 7d0e71c937e..0c75d925ce9 100644 --- a/package/MDAnalysis/analysis/align.py +++ b/package/MDAnalysis/analysis/align.py @@ -507,11 +507,12 @@ def alignto(mobile, reference, select="all", weights=None, # treat subselection as AtomGroup mobile_atoms = subselection.atoms except AttributeError: - error_ = TypeError( - "subselection must be a selection string, an" - " AtomGroup or Universe or None" - ) - raise_from(error_, None) + raise_from( + TypeError( + "subselection must be a selection string, an" + " AtomGroup or Universe or None" + ), + None) # _fit_to DOES subtract center of mass, will provide proper min_rmsd mobile_atoms, new_rmsd = _fit_to(mobile_coordinates, ref_coordinates, diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index 44a6d5056ff..d926d286b26 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -566,10 +566,13 @@ def __init__(self, filename, n_atoms=None, mmap=None, **kwargs): # the number of frames from somewhere such as the time variable: if self.n_frames is None: self.n_frames = self.trjfile.variables['time'].shape[0] - except KeyError as e: - errmsg = ("NCDF trajectory {0} does not contain frame " - "information".format(self.filename)) - raise_from(ValueError(errmsg), None) + except KeyError: + raise_from( + ValueError( + ("NCDF trajectory {0} does not contain frame " + "information").format(self.filename) + ), + None) try: self.remarks = self.trjfile.title diff --git a/package/MDAnalysis/core/__init__.py b/package/MDAnalysis/core/__init__.py index 5c4f114c0d1..04ec4affb5a 100644 --- a/package/MDAnalysis/core/__init__.py +++ b/package/MDAnalysis/core/__init__.py @@ -266,7 +266,7 @@ def set(self, value): self.value = self.mapping[value] except KeyError: six.raise_from( - ValueError("flag must be None or one of " + str(self.mapping.keys()), + ValueError("flag must be None or one of " + str(self.mapping.keys())), None) return self.get() diff --git a/package/MDAnalysis/core/groups.py b/package/MDAnalysis/core/groups.py index 7d781638586..95e38e600a3 100644 --- a/package/MDAnalysis/core/groups.py +++ b/package/MDAnalysis/core/groups.py @@ -2904,11 +2904,13 @@ def split(self, level): 'topology format in use.'.format(level)), None) except KeyError: - errmsg = ( - "level = '{0}' not supported, " - "must be one of {1}".format(level, accessors.keys()) - ) - raise_from(ValueError(errmsg), None) + raise_from( + ValueError( + ( + "level = '{0}' not supported, " + "must be one of {1}").format(level, accessors.keys()) + ), + None) return [self[levelindices == index] for index in unique_int_1d(levelindices)] From 8ea58e8476f66ee99658292507803212347da7b8 Mon Sep 17 00:00:00 2001 From: Joao MC Teixeira Date: Tue, 5 Nov 2019 12:04:08 -0500 Subject: [PATCH 15/15] removes var before raise Error on TOPParser --- package/MDAnalysis/topology/TOPParser.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/package/MDAnalysis/topology/TOPParser.py b/package/MDAnalysis/topology/TOPParser.py index 7124041ba0b..c3cd99785fb 100644 --- a/package/MDAnalysis/topology/TOPParser.py +++ b/package/MDAnalysis/topology/TOPParser.py @@ -235,9 +235,11 @@ def next_getter(): try: next_section = line.split("%FLAG")[1].strip() except IndexError: - msg = ("%FLAG section not found, formatting error " - "for PARM7 file {0} ".format(self.filename)) - raise_from(IndexError(msg), None) + raise_from( + IndexError(( + "%FLAG section not found, formatting error " + "for PARM7 file {0} ").format(self.filename)), + None) # strip out a few values to play with them n_atoms = len(attrs['name'])