# Buggy code
def _get_dh_pairs(self):
    """Finds donor-hydrogen pairs.

    Returns
    -------
    donors, hydrogens: AtomGroup, AtomGroup
        AtomGroups corresponding to all donors and all hydrogens. AtomGroups are ordered such that, if zipped, will
        produce a list of donor-hydrogen pairs.
    """

    # If donors_sel is not provided, use topology to find d-h pairs
    if not self.donors_sel:
        if len(self.u.bonds) == 0:
            raise Exception(
                "Cannot assign donor-hydrogen pairs via topology as no bonded information is present. "
                "Please either: load a topology file with bonded information; use the guess_bonds() "
                "topology guesser; or set HydrogenBondAnalysis.donors_sel so that a distance cutoff "
                "can be used."
            )

        hydrogens = self.u.select_atoms(self.hydrogens_sel)
        donors = sum(h.bonded_atoms[0] for h in hydrogens)

    # Otherwise, use d_h_cutoff as a cutoff distance
    else:
        hydrogens = self.u.select_atoms(self.hydrogens_sel)
        donors = self.u.select_atoms(self.donors_sel)
        donors_indices, hydrogen_indices = capped_distance(
            donors.positions,
            hydrogens.positions,
            max_cutoff=self.d_h_cutoff,
            box=self.u.dimensions,
            return_distances=False,
        ).T

        donors = donors[donors_indices]
        hydrogens = hydrogens[hydrogen_indices]

    return donors, hydrogens


# Traceback (KeyError)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda3/envs/py36/lib/python3.6/site-packages/MDAnalysis/core/universe.py in __getattr__(self, key)
509         try:
--> 510             segment = self._instant_selectors[key]
511         except KeyError:

KeyError: 'bonds'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-12-763dc8d4b193> in <module>
----> 1 gro.bonds

~/anaconda3/envs/py36/lib/python3.6/site-packages/MDAnalysis/core/universe.py in __getattr__(self, key)
510             segment = self._instant_selectors[key]
511         except KeyError:
--> 512             raise AttributeError('No attribute "{}".'.format(key))
513         else:
514             warnings.warn("Instant selector Universe.<segid> "

AttributeError: No attribute "bonds".

# Fixed code
def _get_dh_pairs(self):
    """Finds donor-hydrogen pairs.

    Returns
    -------
    donors, hydrogens: AtomGroup, AtomGroup
        AtomGroups corresponding to all donors and all hydrogens. AtomGroups are ordered such that, if zipped, will
        produce a list of donor-hydrogen pairs.
    """

    # If donors_sel is not provided, use topology to find d-h pairs
    if not self.donors_sel:
        # We're using u._topology.bonds rather than u.bonds as it is a million times faster to access.
        # This is because u.bonds also calculates properties of each bond (e.g bond length).
        # See https://github.com/MDAnalysis/mdanalysis/issues/2396#issuecomment-596251787
        if not (
            hasattr(self.u._topology, "bonds")
            and len(self.u._topology.bonds.values) != 0
        ):
            raise NoDataError(
                "Cannot assign donor-hydrogen pairs via topology as no bond information is present. "
                "Please either: load a topology file with bond information; use the guess_bonds() "
                "topology guesser; or set HydrogenBondAnalysis.donors_sel so that a distance cutoff "
                "can be used."
            )

        hydrogens = self.u.select_atoms(self.hydrogens_sel)
        donors = sum(h.bonded_atoms[0] for h in hydrogens)

    # Otherwise, use d_h_cutoff as a cutoff distance
    else:
        hydrogens = self.u.select_atoms(self.hydrogens_sel)
        donors = self.u.select_atoms(self.donors_sel)
        donors_indices, hydrogen_indices = capped_distance(
            donors.positions,
            hydrogens.positions,
            max_cutoff=self.d_h_cutoff,
            box=self.u.dimensions,
            return_distances=False,
        ).T

        donors = donors[donors_indices]
        hydrogens = hydrogens[hydrogen_indices]

    return donors, hydrogens