From 65cae0e45c30ef9f9b1e9a6ae99a252b639661f8 Mon Sep 17 00:00:00 2001 From: Kiyoon Kim Date: Fri, 6 Dec 2024 17:31:08 +0900 Subject: [PATCH 1/4] refactor: fix lint and some type issues --- pdb2pqr/__main__.py | 6 +-- pdb2pqr/_version.py | 1 + pdb2pqr/aa.py | 16 +++----- pdb2pqr/biomolecule.py | 65 ++++++++++++++++++--------------- pdb2pqr/debump.py | 10 +++-- pdb2pqr/definitions.py | 9 ++--- pdb2pqr/forcefield.py | 11 +++--- pdb2pqr/hydrogens/__init__.py | 59 ++++++++++++++++++------------ pdb2pqr/hydrogens/optimize.py | 1 + pdb2pqr/hydrogens/structures.py | 21 +++++------ pdb2pqr/inputgen.py | 29 +++++++++------ pdb2pqr/io.py | 25 +++++++------ pdb2pqr/ligand/peoe.py | 6 +-- pdb2pqr/ligand/topology.py | 2 +- pdb2pqr/main.py | 14 +++---- pdb2pqr/na.py | 4 +- pdb2pqr/pdb.py | 6 ++- pdb2pqr/psize.py | 20 ++++------ pdb2pqr/quatfit.py | 3 +- pdb2pqr/residue.py | 15 ++++---- pdb2pqr/structures.py | 8 ++-- pdb2pqr/topology.py | 27 ++------------ pdb2pqr/utilities.py | 3 +- tests/common.py | 2 +- 24 files changed, 177 insertions(+), 186 deletions(-) diff --git a/pdb2pqr/__main__.py b/pdb2pqr/__main__.py index 39181295..4d2ba94e 100644 --- a/pdb2pqr/__main__.py +++ b/pdb2pqr/__main__.py @@ -7,15 +7,11 @@ """ import logging -from sys import version_info from pdb2pqr.main import main -assert version_info >= (3, 5) - - _LOGGER = logging.getLogger(__name__) -logging.captureWarnings(True) +logging.captureWarnings(capture=True) if __name__ == "__main__": diff --git a/pdb2pqr/_version.py b/pdb2pqr/_version.py index 59a2c3e6..7a3b16df 100644 --- a/pdb2pqr/_version.py +++ b/pdb2pqr/_version.py @@ -1,4 +1,5 @@ """PDB2PQR Version number. + Store the version here so: * we don't load dependencies by storing it in :file:`__init__.py` diff --git a/pdb2pqr/aa.py b/pdb2pqr/aa.py index 984ff31a..82df94d9 100644 --- a/pdb2pqr/aa.py +++ b/pdb2pqr/aa.py @@ -138,7 +138,6 @@ def set_state(self): self.ffname = f"NEUTRAL-C{self.ffname}" else: self.ffname = f"C{self.ffname}" - return def rebuild_tetrahedral(self, atomname): """Rebuild a tetrahedral hydrogen group. @@ -167,7 +166,7 @@ def rebuild_tetrahedral(self, atomname): for bond in self.reference.map[bondname].bonds: if bond.startswith("H"): hcount += 1 - elif bond != "C-1" and bond != "N+1": + elif bond not in ("C-1", "N+1"): nextatomname = bond # Check if this is a tetrahedral group if hcount != 3 or nextatomname is None: @@ -275,7 +274,7 @@ def __init__(self, atoms, ref): Amino.__init__(self, atoms, ref) self.reference = ref - def letter_code(self): + def letter_code(self) -> str: """Return letter code for amino acid. :return: amino acid 1-letter code @@ -407,9 +406,7 @@ def set_state(self): If SS-bonded, use CYX. If negatively charged, use CYM. If HG is not present, use CYX. """ - if "CYX" in self.patches or self.name == "CYX": - self.ffname = "CYX" - elif self.ss_bonded: + if "CYX" in self.patches or self.name == "CYX" or self.ss_bonded: self.ffname = "CYX" elif "CYM" in self.patches or self.name == "CYM": self.ffname = "CYM" @@ -548,10 +545,7 @@ def set_state(self): elif ( self.get_atom("NE2").hdonor and not self.get_atom("NE2").hacceptor - ): - if self.has_atom("HD1"): - self.remove_atom("HD1") - elif ( + ) or ( self.get_atom("ND1").hacceptor and not self.get_atom("ND1").hdonor ): @@ -568,7 +562,7 @@ def set_state(self): self.ffname = "HIE" else: errstr = ( - f"Invalid type for {str(self)}! Missing both HD1 and HE2 " + f"Invalid type for {self!s}! Missing both HD1 and HE2 " "atoms. If you receive this error while using the " "--assign-only option you can only resolve it by adding HD1, " "HE2 or both to this residue." diff --git a/pdb2pqr/biomolecule.py b/pdb2pqr/biomolecule.py index cb5222a1..cea675e0 100644 --- a/pdb2pqr/biomolecule.py +++ b/pdb2pqr/biomolecule.py @@ -55,23 +55,27 @@ def __init__(self, pdblist, definition): num_chains += 1 for record in pdblist: if isinstance(record, (pdb.ATOM, pdb.HETATM)): - if record.chain_id == "": - if num_chains > 1 and record.res_name not in [ + if ( + record.chain_id == "" + and num_chains > 1 + and record.res_name + not in [ "WAT", "HOH", - ]: - # Assign a chain ID - try: - record.chain_id = ( - string.ascii_uppercase - + string.ascii_lowercase - + string.digits - )[count] - except IndexError: - raise Exception( - "Too many chains exist in biomolecule. " - "Consider preparing subsets." - ) + ] + ): + # Assign a chain ID + try: + record.chain_id = ( + string.ascii_uppercase + + string.ascii_lowercase + + string.digits + )[count] + except IndexError: + raise Exception( + "Too many chains exist in biomolecule. " + "Consider preparing subsets." + ) chain_id = record.chain_id res_seq = record.res_seq @@ -221,7 +225,7 @@ def set_hip(self): if isinstance(residue, aa.HIS): self.apply_patch("HIP", residue) - def set_termini(self, neutraln=False, neutralc=False): + def set_termini(self, *, neutraln=False, neutralc=False): """Set the termini for a protein. First set all known termini by looking at the ends of the chain. Then @@ -237,7 +241,7 @@ def set_termini(self, neutraln=False, neutralc=False): # First assign the known termini chain = None for chain in self.chains: - self.assign_termini(chain, neutraln, neutralc) + self.assign_termini(chain, neutraln=neutraln, neutralc=neutralc) # Now determine if there are any hidden chains letters = string.ascii_uppercase + string.ascii_lowercase ch_num = 0 @@ -255,11 +259,12 @@ def set_termini(self, neutraln=False, neutralc=False): if isinstance(residue, aa.Amino): if residue.has_atom("OXT") and not residue.is_c_term: fixflag = 1 - elif isinstance(residue, na.Nucleic): - if ( - residue.has_atom("H3T") or residue.name.endswith("3") - ) and not residue.is3term: - fixflag = 1 + elif ( + isinstance(residue, na.Nucleic) + and (residue.has_atom("H3T") or residue.name.endswith("3")) + and not residue.is3term + ): + fixflag = 1 if fixflag: # Get an available chain ID chainid = letters[0] @@ -284,8 +289,12 @@ def set_termini(self, neutraln=False, neutralc=False): newchain.add_residue(res) chain.residues.remove(res) res.set_chain_id(chainid[0]) - self.assign_termini(chain, neutraln, neutralc) - self.assign_termini(newchain, neutraln, neutralc) + self.assign_termini( + chain, neutraln=neutraln, neutralc=neutralc + ) + self.assign_termini( + newchain, neutraln=neutraln, neutralc=neutralc + ) reslist = [] ch_num += 1 ch_num += 1 @@ -459,9 +468,7 @@ def set_reference_distance(self): atom.refdistance = -1 elif residue.is_c_term and atom.name == "HO": atom.refdistance = 3 - elif residue.is_n_term and ( - atom.name == "H3" or atom.name == "H2" - ): + elif residue.is_n_term and (atom.name in ("H3", "H2")): atom.refdistance = 2 else: path = util.shortest_path(map_, atom, caatom) @@ -482,7 +489,7 @@ def remove_hydrogens(self): if atom.is_hydrogen: residue.remove_atom(atom.name) - def assign_termini(self, chain, neutraln=False, neutralc=False): + def assign_termini(self, chain, *, neutraln=False, neutralc=False): """Assign the termini for the given chain. Assignment made by looking at the start and end residues. @@ -612,7 +619,7 @@ def update_bonds(self): res2.peptide_c = None res1.peptide_n = None - def apply_patch(self, patchname, residue): + def apply_patch(self, patchname: str, residue: residue_.Residue): """Apply a patch to the given residue. This is one of the key functions in PDB2PQR. A similar function diff --git a/pdb2pqr/debump.py b/pdb2pqr/debump.py index ba027149..1071450b 100644 --- a/pdb2pqr/debump.py +++ b/pdb2pqr/debump.py @@ -132,7 +132,7 @@ def get_bump_score_atom(self, atom): cutoff = atom_size + other_size if dist < cutoff: bumpscore += 1000.0 - _LOGGER.debug(f"BUMPSCORE {str(bumpscore)}") + _LOGGER.debug(f"BUMPSCORE {bumpscore!s}") return bumpscore def debump_biomolecule(self): @@ -159,7 +159,9 @@ def debump_biomolecule(self): if not isinstance(residue, aa.Amino): continue # Initialize variables - conflict_names = self.find_residue_conflicts(residue, True) + conflict_names = self.find_residue_conflicts( + residue, write_conflict_info=True + ) if not conflict_names: continue # Otherwise debump the residue @@ -177,7 +179,7 @@ def debump_biomolecule(self): _LOGGER.warning(text) _LOGGER.debug("Done checking if we must debump any residues.") - def find_residue_conflicts(self, residue, write_conflict_info=False): + def find_residue_conflicts(self, residue, *, write_conflict_info=False): """Find conflicts between residues. :param residue: residue to check @@ -269,7 +271,7 @@ def debump_residue(self, residue, conflict_names): if score == 0: if not self.find_residue_conflicts(residue): _LOGGER.debug( - f"No conflicts found at angle {repr(newangle)}" + f"No conflicts found at angle {newangle!r}" ) return True else: diff --git a/pdb2pqr/definitions.py b/pdb2pqr/definitions.py index 2624fa9b..61f4d8c2 100644 --- a/pdb2pqr/definitions.py +++ b/pdb2pqr/definitions.py @@ -5,6 +5,7 @@ .. codeauthor:: Yong Huang """ +import contextlib import copy import logging import re @@ -105,10 +106,8 @@ def endElement(self, name): elif name == "name": self.curobj.name = self.content elif self.curelement != "": - try: + with contextlib.suppress(ValueError): self.content = float(self.content) - except ValueError: - pass setattr(self.curobj, self.curelement, self.content) self.content = "" @@ -227,7 +226,7 @@ def __str__(self): text += f"Apply to: {self.applyto}\n" text += "Atoms to add: \n" for atom in self.map: - text += f"\t{str(self.map[atom])}\n" + text += f"\t{self.map[atom]!s}\n" text += "Atoms to remove: \n" for remove in self.remove: text += f"\t{remove}\n" @@ -249,7 +248,7 @@ def __str__(self): text = f"{self.name}\n" text += "Atoms: \n" for atom in self.map: - text += f"\t{str(self.map[atom])}\n" + text += f"\t{self.map[atom]!s}\n" text += "Dihedrals: \n" for dihedral in self.dihedrals: text += f"\t{dihedral}\n" diff --git a/pdb2pqr/forcefield.py b/pdb2pqr/forcefield.py index 61c42f6a..c5643124 100644 --- a/pdb2pqr/forcefield.py +++ b/pdb2pqr/forcefield.py @@ -38,8 +38,7 @@ def __init__(self, map_, reference): @classmethod def update_map(cls, toname, fromname, map_): - """Update the given map by adding a pointer from a new name to an - object. + """Update the given map by adding a pointer from a new name to an object. .. todo:: Should this be a staticmethod instead of classmethod? @@ -195,7 +194,7 @@ def __init__(self, ff_name, definition, userff, usernames=None): self.name = str(ff_name) defpath = "" defpath = io.test_dat_file(ff_name) if userff is None else userff - with open(defpath, "rt", encoding="utf-8") as ff_file: + with open(defpath, encoding="utf-8") as ff_file: lines = ff_file.readlines() for line in lines: if not line.startswith("#"): @@ -243,7 +242,7 @@ def __init__(self, ff_name, definition, userff, usernames=None): raise ValueError("Unable to identify .names file.") handler = ForcefieldHandler(self.map, definition.map) sax.make_parser() - with open(names_path, "rt", encoding="utf-8") as namesfile: + with open(names_path, encoding="utf-8") as namesfile: sax.parseString(namesfile.read(), handler) def has_residue(self, resname): @@ -1048,11 +1047,11 @@ def get(self, name): """ try: return getattr(self, name) - except AttributeError: + except AttributeError as e: message = ( f'Unable to access object "{name}" in class ForcefieldAtom' ) - raise KeyError(message) + raise KeyError(message) from e def __str__(self): txt = f"{self.name}:\n" diff --git a/pdb2pqr/hydrogens/__init__.py b/pdb2pqr/hydrogens/__init__.py index 8c054dfc..b0899d76 100644 --- a/pdb2pqr/hydrogens/__init__.py +++ b/pdb2pqr/hydrogens/__init__.py @@ -74,7 +74,7 @@ def create_handler(hyd_path=HYD_DEF_PATH): """ handler = HydrogenHandler() hyd_path = io.test_dat_file(hyd_path) - with open(hyd_path, "rt") as hyd_file: + with open(hyd_path) as hyd_file: sax.make_parser() sax.parseString(hyd_file.read(), handler) return handler @@ -120,8 +120,8 @@ def switchstate(self, states, amb, state_id): raise IndexError("Invalid State ID!") # First Remove all Hs - residue = getattr(amb, "residue") - hdef = getattr(amb, "hdef") + residue = amb.residue + hdef = amb.hdef for conf in hdef.conformations: hname = conf.hname boundname = conf.boundatom @@ -176,10 +176,12 @@ def switchstate(self, states, amb, state_id): # flag the added hydrogen residue.get_atom(hname).titratableH = True residue.get_atom(hname).addIntraBond(boundname) + return None @classmethod def pka_switchstate(cls, amb, state_id_): """Switch a residue to a new state by first removing all hydrogens. + This routine is used in pKa calculations only! :param amb: the amibiguity to switch @@ -191,8 +193,8 @@ def pka_switchstate(cls, amb, state_id_): state_id = titrationdict[state_id_] state_id = state_id.split("+") new_state_id = [int(i) for i in state_id] - residue = getattr(amb, "residue") - hdef = getattr(amb, "hdef") + residue = amb.residue + hdef = amb.hdef for conf in hdef.conformations: hname = conf.hname boundname = conf.boundatom @@ -278,6 +280,7 @@ def cleanup(self): def is_optimizeable(self, residue): """Check to see if the given residue is optimizeable. + There are three ways to identify a residue: 1. By name (i.e., HIS) @@ -306,7 +309,7 @@ def is_optimizeable(self, residue): # If alcoholic, make sure the hydrogen is present if optinstance is not None and optinstance.opttype == "Alcoholic": - atomname = list(optinstance.map.keys())[0] + atomname = next(iter(optinstance.map.keys())) if not residue.reference.has_atom(atomname): optinstance = None return optinstance @@ -425,12 +428,18 @@ def optimize_hydrogens(self): continue if not (closeatom.hacceptor or closeatom.hdonor): continue - if atom.hdonor and not atom.hacceptor: - if not closeatom.hacceptor: - continue - if atom.hacceptor: - if not atom.hdonor and not closeatom.hdonor: - continue + if ( + atom.hdonor + and not atom.hacceptor + and not closeatom.hacceptor + ): + continue + if ( + atom.hacceptor + and not atom.hdonor + and not closeatom.hdonor + ): + continue dist = util.distance(atom.coords, closeatom.coords) if dist < 4.3: residue = atom.residue @@ -505,13 +514,14 @@ def optimize_hydrogens(self): seenlist = [] for obj in network: for hbond in obj.hbonds: - if hbond.atom2 in self.atomlist: - if not isinstance(hbond.atom1.residue, aa.WAT): - if not isinstance(hbond.atom2.residue, aa.WAT): - # Only get one hbond pair - if (hbond.atom2, hbond.atom1) not in seenlist: - hbondmap[hbond] = hbond.dist - seenlist.append((hbond.atom1, hbond.atom2)) + if hbond.atom2 in self.atomlist and not isinstance( + hbond.atom1.residue, aa.WAT + ): + if not isinstance(hbond.atom2.residue, aa.WAT): + # Only get one hbond pair + if (hbond.atom2, hbond.atom1) not in seenlist: + hbondmap[hbond] = hbond.dist + seenlist.append((hbond.atom1, hbond.atom2)) hbondlist = util.sort_dict_by_value(hbondmap) hbondlist.reverse() for hbond in hbondlist: @@ -536,11 +546,12 @@ def optimize_hydrogens(self): for obj in network: for hbond in obj.hbonds: residue = hbond.atom1.residue - if isinstance(residue, aa.WAT): - if isinstance(hbond.atom2.residue, aa.WAT): - if (hbond.atom2, hbond.atom1) not in seenlist: - hbondmap[hbond] = hbond.dist - seenlist.append((hbond.atom1, hbond.atom2)) + if isinstance(residue, aa.WAT) and isinstance( + hbond.atom2.residue, aa.WAT + ): + if (hbond.atom2, hbond.atom1) not in seenlist: + hbondmap[hbond] = hbond.dist + seenlist.append((hbond.atom1, hbond.atom2)) hbondlist = util.sort_dict_by_value(hbondmap) hbondlist.reverse() for hbond in hbondlist: diff --git a/pdb2pqr/hydrogens/optimize.py b/pdb2pqr/hydrogens/optimize.py index d25576de..99ebab85 100644 --- a/pdb2pqr/hydrogens/optimize.py +++ b/pdb2pqr/hydrogens/optimize.py @@ -427,6 +427,7 @@ def get_positions_with_two_bonds(cls, atom): def try_positions_with_two_bonds_h(self, donor, acc, newname, loc1, loc2): """Try adding a new hydrogen to the two potential locations. + If both form hydrogen bonds, place at whatever returns the best bond as determined by get_pair_energy. diff --git a/pdb2pqr/hydrogens/structures.py b/pdb2pqr/hydrogens/structures.py index a80cc178..791a8742 100644 --- a/pdb2pqr/hydrogens/structures.py +++ b/pdb2pqr/hydrogens/structures.py @@ -199,7 +199,7 @@ def fix_flip(self, bondatom): """ residue = bondatom.residue # Initialize some variables - atomlist = [atom for atom in residue.atoms] + atomlist = list(residue.atoms) # Set a flag to see whether to delete the FLIPs or not flag = 0 if bondatom.name.endswith("FLIP"): @@ -233,7 +233,7 @@ def finalize(self): residue = self.residue if residue.fixed: return - atomlist = [atom for atom in residue.atoms] + atomlist = list(residue.atoms) for atom in atomlist: if atom.name.endswith("FLIP"): self.routines.cells.remove_cell(atom) @@ -290,8 +290,7 @@ class Alcoholic(optimize.Optimize): """The class for alcoholic residue.""" def __init__(self, residue, optinstance, routines): - """Initialize the alcoholic class by removing the alcoholic hydrogen - if it exists. + """Initialize the alcoholic class by removing the alcoholic hydrogen if it exists. :param residue: the residue to optimize :type residue: Residue @@ -307,7 +306,7 @@ def __init__(self, residue, optinstance, routines): self.routines = routines self.atomlist = [] self.hbonds = [] - name = list(optinstance.map.keys())[0] + name = next(iter(optinstance.map.keys())) self.hname = name bondname = residue.reference.get_atom(name).bonds[0] self.atomlist.append(residue.get_atom(bondname)) @@ -513,7 +512,7 @@ def complete(self): self.finalize() residue.fixed = 1 # Remove all LP atoms - atomlist = [atom for atom in residue.atoms] + atomlist = list(residue.atoms) for atom in atomlist: if atom.name.startswith("LP"): residue.remove_atom(atom.name) @@ -795,7 +794,7 @@ def complete(self): self.finalize() residue = self.residue - atomlist = [atom for atom in residue.atoms] + atomlist = list(residue.atoms) for atom in atomlist: if atom.name.startswith("LP"): residue.remove_atom(atom.name) @@ -1242,12 +1241,12 @@ class HydrogenConformation: hydrogen conformations as specified in the hydrogen data file. """ - def __init__(self, hname, boundatom, bondlength): + def __init__(self, hname: str, boundatom: str, bondlength: float): """ Args: - hname : The hydrogen name (string) - boundatom : The atom the hydrogen is bound to (string) - bondlength : The bond length (float) + hname: The hydrogen name + boundatom: The atom the hydrogen is bound to + bondlength: The bond length """ self.hname = hname self.boundatom = boundatom diff --git a/pdb2pqr/inputgen.py b/pdb2pqr/inputgen.py index 916f9546..87f38053 100644 --- a/pdb2pqr/inputgen.py +++ b/pdb2pqr/inputgen.py @@ -19,7 +19,7 @@ class Elec: """An object for the ELEC section of an APBS input file.""" def __init__( - self, pqrpath, size, method, asyncflag, istrng=0, potdx=False + self, pqrpath, size, method, asyncflag, istrng=0, *, potdx=False ): """Initialize object. @@ -149,7 +149,7 @@ class Input: """Each object of this class is one APBS input file.""" def __init__( - self, pqrpath, size, method, asyncflag, istrng=0, potdx=False + self, pqrpath, size, method, asyncflag, istrng=0, *, potdx=False ): """Initialize the input file class. @@ -181,11 +181,11 @@ def __init__( self.pqrname = self.pqrpath.name self.asyncflag = asyncflag # Initialize variables to default elec values - elec1 = Elec(pqrpath, size, method, asyncflag, istrng, potdx) + elec1 = Elec(pqrpath, size, method, asyncflag, istrng, potdx=potdx) if not potdx: - elec2 = Elec(pqrpath, size, method, asyncflag, istrng, potdx) - setattr(elec2, "sdie", 2.0) - setattr(elec2, "write", []) + elec2 = Elec(pqrpath, size, method, asyncflag, istrng, potdx=potdx) + elec2.sdie = 2.0 + elec2.write = [] else: elec2 = "" self.elecs = [elec1, elec2] @@ -218,7 +218,7 @@ def print_input_files(self, output_path): # Temporarily disable async flag for elec in self.elecs: elec.asyncflag = False - with open(outname, "wt") as out_file: + with open(outname, "w") as out_file: out_file.write(str(self)) # Now make the async files elec = self.elecs[0] @@ -228,10 +228,10 @@ def print_input_files(self, output_path): for elec in self.elecs: elec.asyncflag = True elec.async_ = i - with open(outname, "wt") as out_file: + with open(outname, "w") as out_file: out_file.write(str(self)) else: - with open(path, "wt") as out_file: + with open(path, "w") as out_file: out_file.write(str(self)) def dump_pickle(self): @@ -252,7 +252,7 @@ def split_input(filename): :type filename: str """ nproc = 0 - with open(filename, "rt") as file_: + with open(filename) as file_: text = "" while True: line = file_.readline() @@ -384,10 +384,15 @@ def main(): else: size.run_psize(filename) input_ = Input( - filename, size, args.method, args.asynch, args.istrng, args.potdx + filename, + size, + args.method, + args.asynch, + args.istrng, + potdx=args.potdx, ) path = Path(filename) - output_path = path.parent + path.stem + Path(".in") + output_path = f"{path.parent}/{path.stem}.in" input_.print_input_files(output_path) diff --git a/pdb2pqr/io.py b/pdb2pqr/io.py index 9086f21c..0c4851b6 100644 --- a/pdb2pqr/io.py +++ b/pdb2pqr/io.py @@ -6,7 +6,6 @@ # import argparse from collections import Counter from pathlib import Path -from sys import path as sys_path import requests @@ -261,7 +260,8 @@ def print_pqr_header_cif( "PQR file generated by PDB2PQR", TITLE_STR, "", - f"Forcefield used: {force_field}\n" "", + f"Forcefield used: {force_field}\n", + "", ] ) if ffout is not None: @@ -307,7 +307,8 @@ def print_pqr_header_cif( ";", "3", ";", - f"Total charge on this biomolecule: {charge:.4f} e" ";", + f"Total charge on this biomolecule: {charge:.4f} e", + ";", "", ] ) @@ -435,11 +436,11 @@ def get_pdb_file(name): """ path = Path(name) if path.is_file(): - return open(path, "rt", encoding="utf-8") + return open(path, encoding="utf-8") url_path = f"https://files.rcsb.org/download/{path.stem}.pdb" _LOGGER.debug(f"Attempting to fetch PDB from {url_path}") resp = requests.get(url_path) - if resp.status_code != 200: + if resp.status_code != requests.codes["ok"]: errstr = f"Got code {resp.status_code} while retrieving {url_path}" raise IOError(errstr) return io.StringIO(resp.text) @@ -492,12 +493,14 @@ def get_definitions( aa_path_ = test_xml_file(aa_path) na_path_ = test_xml_file(na_path) patch_path_ = test_xml_file(patch_path) - with open(aa_path_, "rt") as aa_file: - with open(na_path_, "rt") as na_file: - with open(patch_path_, "rt") as patch_file: - definitions = defns.Definition( - aa_file=aa_file, na_file=na_file, patch_file=patch_file - ) + with ( + open(aa_path_) as aa_file, + open(na_path_) as na_file, + open(patch_path_) as patch_file, + ): + definitions = defns.Definition( + aa_file=aa_file, na_file=na_file, patch_file=patch_file + ) return definitions diff --git a/pdb2pqr/ligand/peoe.py b/pdb2pqr/ligand/peoe.py index 982b7d54..6e78c98c 100644 --- a/pdb2pqr/ligand/peoe.py +++ b/pdb2pqr/ligand/peoe.py @@ -3,7 +3,7 @@ The PEOE method is described in: Paul Czodrowski, Ingo Dramburg, Christoph A. Sotriffer Gerhard Klebe. Development, validation, and application of adapted PEOE charges to estimate pKa values of functional -groups in protein–ligand complexes. Proteins, 65, 424-437, 2006. +groups in protein-ligand complexes. Proteins, 65, 424-437, 2006. https://doi.org/10.1002/prot.21110 """ @@ -111,10 +111,10 @@ def assign_terms(atoms, term_dict): atom_type = "O.OH" try: atom.poly_terms = term_dict[atom_type] - except KeyError: + except KeyError as e: raise KeyError( f"Unable to find polynomial terms for atom type {atom_type}" - ) + ) from e return atoms diff --git a/pdb2pqr/ligand/topology.py b/pdb2pqr/ligand/topology.py index b7d0b018..baf2c50f 100644 --- a/pdb2pqr/ligand/topology.py +++ b/pdb2pqr/ligand/topology.py @@ -17,4 +17,4 @@ def __init__(self, molecule): self.atom_dict = {} for atom in molecule.atoms: self.atom_dict[atom.name] = atom - raise NotImplementedError() + raise NotImplementedError diff --git a/pdb2pqr/main.py b/pdb2pqr/main.py index a4736371..bc82bdc8 100644 --- a/pdb2pqr/main.py +++ b/pdb2pqr/main.py @@ -322,7 +322,7 @@ def print_pqr(args, pqr_lines, header_lines, missing_lines, is_cif): in header) :param bool is_cif: flag indicating CIF format """ - with open(args.output_pqr, "wt") as outfile: + with open(args.output_pqr, "w") as outfile: # Adding whitespaces if --whitespace is in the options if header_lines: _LOGGER.warning( @@ -365,7 +365,7 @@ def print_pdb(args, pdb_lines, header_lines, missing_lines, is_cif): header) :param bool is_cif: flag indicating CIF format """ - with open(args.pdb_output, "wt") as outfile: + with open(args.pdb_output, "w") as outfile: # Adding whitespaces if --whitespace is in the options if header_lines: _LOGGER.warning( @@ -417,7 +417,7 @@ def setup_molecule(pdblist, definition, ligand_path): """ if ligand_path is not None: ligand = Mol2Molecule() - with open(ligand_path, "rt", encoding="utf-8") as ligand_file: + with open(ligand_path, encoding="utf-8") as ligand_file: ligand.read(ligand_file) else: ligand = None @@ -785,7 +785,7 @@ def main_driver(args: argparse.Namespace): pdblist, definition, args.ligand ) _LOGGER.info("Setting termini states for biomolecule chains.") - biomolecule.set_termini(args.neutraln, args.neutralc) + biomolecule.set_termini(neutraln=args.neutraln, neutralc=args.neutralc) biomolecule.update_bonds() if args.clean: _LOGGER.info( @@ -890,11 +890,11 @@ def dx_to_cube(): logging.basicConfig(level=log_level) _LOGGER.debug(f"Got arguments: {args}", args) _LOGGER.info(f"Reading PQR from {args.pqr_input}...") - with open(args.pqr_input, "rt") as pqr_file: + with open(args.pqr_input) as pqr_file: atom_list = io.read_pqr(pqr_file) _LOGGER.info(f"Reading DX from {args.dx_input}...") - with open(args.dx_input, "rt") as dx_file: + with open(args.dx_input) as dx_file: dx_dict = io.read_dx(dx_file) _LOGGER.info(f"Writing Cube to {args.output}...") - with open(args.output, "wt") as cube_file: + with open(args.output, "w") as cube_file: io.write_cube(cube_file, dx_dict, atom_list) diff --git a/pdb2pqr/na.py b/pdb2pqr/na.py index 7766f443..b01d7625 100644 --- a/pdb2pqr/na.py +++ b/pdb2pqr/na.py @@ -11,9 +11,7 @@ class Nucleic(residue.Residue): - """This class provides standard features of the nucleic acids listed - below. - """ + """This class provides standard features of the nucleic acids listed below.""" def __init__(self, atoms, ref): sample_atom = atoms[-1] diff --git a/pdb2pqr/pdb.py b/pdb2pqr/pdb.py index b722d553..44eb4809 100644 --- a/pdb2pqr/pdb.py +++ b/pdb2pqr/pdb.py @@ -565,8 +565,10 @@ def __init__( self.chain_id = line[21].strip() self.res_seq = int(line[22:26].strip()) self.ins_code = line[26].strip() - except IndexError: - raise ValueError("Residue name must be less than 4 characters!") + except IndexError as e: + raise ValueError( + "Residue name must be less than 4 characters!" + ) from e self.x = float(line[30:38].strip()) self.y = float(line[38:46].strip()) self.z = float(line[46:54].strip()) diff --git a/pdb2pqr/psize.py b/pdb2pqr/psize.py index 4ceba176..bdd33f5e 100755 --- a/pdb2pqr/psize.py +++ b/pdb2pqr/psize.py @@ -112,7 +112,7 @@ def parse_input(self, filename): :param filename: string with path to PDB- or PQR-format file. :type filename: str """ - with open(filename, "rt", encoding="utf-8") as file_: + with open(filename, encoding="utf-8") as file_: self.parse_lines(file_.readlines()) def parse_lines(self, lines): @@ -158,8 +158,7 @@ def set_length(self, maxlen, minlen): """ for i in range(3): self.mol_length[i] = maxlen[i] - minlen[i] - if self.mol_length[i] < 0.1: - self.mol_length[i] = 0.1 + self.mol_length[i] = max(self.mol_length[i], 0.1) return self.mol_length def set_coarse_grid_dims(self, mol_length): @@ -186,8 +185,7 @@ def set_fine_grid_dims(self, mol_length, coarse_length): """ for i in range(3): self.fine_length[i] = mol_length[i] + self.fadd - if self.fine_length[i] > coarse_length[i]: - self.fine_length[i] = coarse_length[i] + self.fine_length[i] = min(self.fine_length[i], coarse_length[i]) return self.fine_length def set_center(self, maxlen, minlen): @@ -218,8 +216,7 @@ def set_fine_grid_points(self, fine_length): for i in range(3): temp_num[i] = int(fine_length[i] / self.space + 0.5) self.ngrid[i] = 32 * (int((temp_num[i] - 1) / 32.0 + 0.5)) + 1 - if self.ngrid[i] < 33: - self.ngrid[i] = 33 + self.ngrid[i] = max(self.ngrid[i], 33) return self.ngrid def set_smallest(self, ngrid): @@ -275,8 +272,7 @@ def set_proc_grid(self, ngrid, nsmall): return self.proc_grid def set_focus(self, fine_length, nproc, coarse_length): - """Calculate the number of levels of focusing required for each - processor subdomain. + """Calculate the number of levels of focusing required for each processor subdomain. :param fine_length: fine grid length :type fine_length: [float, float, float] @@ -293,10 +289,8 @@ def set_focus(self, fine_length, nproc, coarse_length): + 1.0 ) nfocus = nfoc[0] - if nfoc[1] > nfocus: - nfocus = nfoc[1] - if nfoc[2] > nfocus: - nfocus = nfoc[2] + nfocus = max(nfoc[1], nfocus) + nfocus = max(nfoc[2], nfocus) if nfocus > 0: nfocus = nfocus + 1 self.nfocus = nfocus diff --git a/pdb2pqr/quatfit.py b/pdb2pqr/quatfit.py index 0364a445..c65d10ec 100644 --- a/pdb2pqr/quatfit.py +++ b/pdb2pqr/quatfit.py @@ -79,8 +79,7 @@ def qtransform(numpoints, defcoords, refcenter, fitcenter, rotation): def qfit(numpoints, refcoords, defcoords): - """Method for getting new atom coordinates from sets of reference and - definition coordinates. + """Method for getting new atom coordinates from sets of reference and definition coordinates. .. todo:: Remove hard-coded parameters of function. diff --git a/pdb2pqr/residue.py b/pdb2pqr/residue.py index 18e227e9..54f7731f 100644 --- a/pdb2pqr/residue.py +++ b/pdb2pqr/residue.py @@ -4,6 +4,8 @@ .. codeauthor:: Nathan Baker """ +from __future__ import annotations + import logging from . import pdb, structures @@ -24,7 +26,7 @@ class Residue: residue and other helper functions. """ - def __init__(self, atoms): + def __init__(self, atoms: list[pdb.ATOM | pdb.HETATM]): """Initialize the class :param atoms: list of atom-like (:class:`HETATM` or :class:`ATOM`) @@ -32,12 +34,12 @@ def __init__(self, atoms): :type atoms: list """ sample_atom = atoms[-1] - self.atoms = [] + self.atoms: list[structures.Atom] = [] self.name = sample_atom.res_name self.chain_id = sample_atom.chain_id self.res_seq = sample_atom.res_seq self.ins_code = sample_atom.ins_code - self.map = {} + self.map: dict[str, structures.Atom] = {} self.naname = None self.reference = None self.is_n_term = None @@ -164,13 +166,13 @@ def rename_atom(self, oldname, newname): self.map[newname] = atom del self.map[oldname] - def get_atom(self, name): + def get_atom(self, name: str) -> structures.Atom | None: """Retrieve a residue atom based on its name. :param resname: name of the residue to retrieve :type resname: str :return: residue - :rtype: structures.Atom + :rtype: structures.Atom | None """ return self.map.get(name) @@ -330,8 +332,7 @@ def reorder(self): # Change the list pointer self.atoms = templist[:] - @staticmethod - def letter_code(): + def letter_code(self) -> str: """Default letter code for residue. :return: letter code for residue diff --git a/pdb2pqr/structures.py b/pdb2pqr/structures.py index 2db2bd09..a7bf94e4 100644 --- a/pdb2pqr/structures.py +++ b/pdb2pqr/structures.py @@ -175,10 +175,10 @@ def from_pqr_line(cls, line): atom.type = token elif token[:4] == "ATOM": atom.type = "ATOM" - words = [token[4:]] + words + words = [token[4:], *words] elif token[:6] == "HETATM": atom.type = "HETATM" - words = [token[6:]] + words + words = [token[6:], *words] else: err = f"Unable to parse line: {line}" raise ValueError(err) @@ -236,10 +236,10 @@ def from_qcd_line(cls, line, atom_serial): atom.type = token elif token[:4] == "ATOM": atom.type = "ATOM" - words = [token[4:]] + words + words = [token[4:], *words] elif token[:6] == "HETATM": atom.type = "HETATM" - words = [token[6:]] + words + words = [token[6:], *words] else: err = f"Unable to parse line: {line}" raise ValueError(err) diff --git a/pdb2pqr/topology.py b/pdb2pqr/topology.py index 16249c5b..f909241b 100644 --- a/pdb2pqr/topology.py +++ b/pdb2pqr/topology.py @@ -99,15 +99,7 @@ def startElement(self, tag_name, _): self.curr_atom = TopologyAtom(self.curr_reference) else: _LOGGER.info("** Don't know what to do with this atom!") - elif tag_name == "x": - self.curr_element = tag_name - elif tag_name == "y": - self.curr_element = tag_name - elif tag_name == "z": - self.curr_element = tag_name - elif tag_name == "bond": - self.curr_element = tag_name - elif tag_name == "altname": + elif tag_name in ("x", "y", "z", "bond", "altname"): self.curr_element = tag_name elif tag_name == "dihedral": self.curr_element = tag_name @@ -142,17 +134,7 @@ def endElement(self, tag_name): """ if not self.incomplete: self.curr_element = None - if tag_name == "x": - pass - elif tag_name == "y": - pass - elif tag_name == "z": - pass - elif tag_name == "name": - pass - elif tag_name == "bond": - pass - elif tag_name == "altname": + if tag_name in ("x", "y", "z", "name", "bond", "altname"): pass elif tag_name == "atom": self.curr_atom = None @@ -174,9 +156,8 @@ def endElement(self, tag_name): self.curr_residue = None elif tag_name != "topology": _LOGGER.info(f"** NOT handling {tag_name} end tag") - else: - if tag_name == "incomplete": - self.incomplete = 0 + elif tag_name == "incomplete": + self.incomplete = 0 def characters(self, text): """Parse characters in topology XML file. diff --git a/pdb2pqr/utilities.py b/pdb2pqr/utilities.py index 3966867c..f1b26cf7 100644 --- a/pdb2pqr/utilities.py +++ b/pdb2pqr/utilities.py @@ -14,7 +14,6 @@ import logging import math -# from pathlib import Path import numpy as np from .config import CHARGE_ERROR, RADIANS_TO_DEGREES, SMALL_NUMBER @@ -73,7 +72,7 @@ def shortest_path(graph, start, end, path=[]): connected :rtype: list """ - path = path + [start] + path = [*path, start] if start == end: return path if start not in graph: diff --git a/tests/common.py b/tests/common.py index 0185d00d..fd3042e4 100644 --- a/tests/common.py +++ b/tests/common.py @@ -247,7 +247,7 @@ def run_propka_for_tests(input_pdb, compare_file, pH): definition = io.get_definitions() pdblist, _ = io.get_molecule(input_pdb) biomolecule, definition, _ = setup_molecule(pdblist, definition, None) - biomolecule.set_termini(False, False) + biomolecule.set_termini(neutraln=False, neutralc=False) biomolecule.update_bonds() biomolecule.remove_hydrogens() From 76573d52c3e90f41b0ca2ccd1b58feb7243f52b6 Mon Sep 17 00:00:00 2001 From: Kiyoon Kim Date: Fri, 6 Dec 2024 17:36:07 +0900 Subject: [PATCH 2/4] refactor: fix lints in tests/ --- tests/common.py | 17 ++++++++--------- tests/core_test.py | 2 +- tests/io_test.py | 16 ++++++++-------- tests/ligand_test.py | 38 +++++++++++++++++++------------------- tests/regression_test.py | 2 +- tests/test_version.py | 1 - 6 files changed, 37 insertions(+), 39 deletions(-) diff --git a/tests/common.py b/tests/common.py index fd3042e4..421b992a 100644 --- a/tests/common.py +++ b/tests/common.py @@ -5,8 +5,8 @@ import logging from pathlib import Path -import numpy -import pandas +import numpy as np +import pandas as pd from pdb2pqr.main import build_main_parser, main_driver from pdb2pqr.structures import Atom @@ -92,12 +92,11 @@ def pqr_to_dict(pqr_file): row_dict["q"] = atom.charge row_dict["r"] = atom.radius pqr.append(row_dict) - return pandas.DataFrame(pqr) + return pd.DataFrame(pqr) def pqr_distance(df1, df2): - """Calculate distances between positions, charges, and radii from two PQR - dataframes. + """Calculate distances between positions, charges, and radii from two PQR dataframes. Args: df1: PQR dataframe @@ -139,7 +138,7 @@ def pqr_distance(df1, df2): for c_val in ("p", "q", "r"): n_val = f"d{c_val}" n2_val = f"d{c_val}2" - d_frame[n_val] = numpy.sqrt(d_frame[n2_val]) + d_frame[n_val] = np.sqrt(d_frame[n2_val]) d_frame = d_frame.drop(n2_val, axis="columns") return d_frame @@ -154,11 +153,11 @@ def compare_pqr(pqr1_path, pqr2_path, compare_resnames=False): pqr1_path: Path to first PQR par2_path: Path to second PQR """ - with open(pqr1_path, "rt", encoding="utf-8") as pqr1_file: + with open(pqr1_path, encoding="utf-8") as pqr1_file: df1 = pqr_to_dict(pqr1_file) _LOGGER.debug(f"PQR 1 has shape {df1.shape}") - with open(pqr2_path, "rt", encoding="utf-8") as pqr2_file: + with open(pqr2_path, encoding="utf-8") as pqr2_file: df2 = pqr_to_dict(pqr2_file) _LOGGER.debug(f"PQR 2 has shape {df2.shape}") @@ -265,7 +264,7 @@ def run_propka_for_tests(input_pdb, compare_file, pH): # f.write(f"{key},{val}\n") compare = {} - with open(compare_file, "r") as f: + with open(compare_file) as f: for line in f.readlines()[1:]: line = line.strip() if len(line) == 0: diff --git a/tests/core_test.py b/tests/core_test.py index b3c4a8df..f7c71a49 100644 --- a/tests/core_test.py +++ b/tests/core_test.py @@ -46,7 +46,7 @@ LONG_NUCLEIC_SET = {"5V0O"} LONG_SET = LONG_PROTEIN_SET | LONG_NUCLEIC_SET #: Tests that should fail (broken backbones) -BROKEN_SET = {"1EJG", "3U7T", "1EJG", "4MGP", "2V75"} +BROKEN_SET = {"1EJG", "3U7T", "4MGP", "2V75"} #: Tests for naming residues with different protonation states NAMING_TESTS = [] for ff in ["CHARMM", "AMBER", "PARSE", "SWANSON", "TYL06"]: diff --git a/tests/io_test.py b/tests/io_test.py index 56853ae3..8fe3f8f6 100644 --- a/tests/io_test.py +++ b/tests/io_test.py @@ -23,7 +23,7 @@ def test_read_pqr(input_pqr): :param input_pqr: path to PQR file to test :type input_pqr: str """ - with open(input_pqr, "rt") as pqr_file: + with open(input_pqr) as pqr_file: read_pqr(pqr_file) @@ -33,7 +33,7 @@ def test_read_qcd(): Doesn't test functionality. """ qcd_path = DATA_DIR / "dummy.qcd" - with open(qcd_path, "rt") as qcd_file: + with open(qcd_path) as qcd_file: read_qcd(qcd_file) @@ -44,18 +44,18 @@ def test_dx2cube(tmp_path): cube_gen = tmp_path / "test.cube" cube_test = DATA_DIR / "dx2cube.cube" _LOGGER.info(f"Reading PQR from {pqr_path}...") - with open(pqr_path, "rt") as pqr_file: + with open(pqr_path) as pqr_file: atom_list = read_pqr(pqr_file) _LOGGER.info(f"Reading DX from {dx_path}...") - with open(dx_path, "rt") as dx_file: + with open(dx_path) as dx_file: dx_dict = read_dx(dx_file) _LOGGER.info(f"Writing Cube to {cube_gen}...") - with open(cube_gen, "wt") as cube_file: + with open(cube_gen, "w") as cube_file: write_cube(cube_file, dx_dict, atom_list) _LOGGER.info(f"Reading this cube from {cube_gen}...") - this_lines = [line.strip() for line in open(cube_gen, "rt")] + this_lines = [line.strip() for line in open(cube_gen)] _LOGGER.info(f"Reading test cube from {cube_test}...") - test_lines = [line.strip() for line in open(cube_test, "rt")] + test_lines = [line.strip() for line in open(cube_test)] differ = Differ() differences = [ line @@ -66,5 +66,5 @@ def test_dx2cube(tmp_path): if differences: for diff in differences: _LOGGER.error(f"Found difference: {diff}") - raise ValueError() + raise ValueError _LOGGER.info("No differences found in output") diff --git a/tests/ligand_test.py b/tests/ligand_test.py index 22afffe1..159ac9c1 100644 --- a/tests/ligand_test.py +++ b/tests/ligand_test.py @@ -29,14 +29,14 @@ "adp.mol2", "acetate.mol2", } -ALL_LIGANDS = sorted(list(ALL_LIGANDS)) +ALL_LIGANDS = sorted(ALL_LIGANDS) def test_peoe_charges(): """Specifically test PEOE charges.""" ligand = Mol2Molecule() mol2_path = Path("tests/data/1HPX-ligand.mol2") - with open(mol2_path, "rt") as mol2_file: + with open(mol2_path) as mol2_file: ligand.read(mol2_file) # WARNING: Nathan? The old_total_charge is never used # old_total_charge = sum( @@ -56,7 +56,7 @@ def test_assign_parameters(input_mol2): """Tests to break basic ligand functionality.""" ligand = Mol2Molecule() mol2_path = Path("tests/data") / input_mol2 - with open(mol2_path, "rt") as mol2_file: + with open(mol2_path) as mol2_file: ligand.read(mol2_file) old_total_charge = sum( atom.formal_charge for atom in ligand.atoms.values() @@ -98,17 +98,17 @@ def test_formal_charge(input_mol2): """Testing formal charge calculation.""" ligand = Mol2Molecule() mol2_path = Path("tests/data") / input_mol2 - with open(mol2_path, "rt") as mol2_file: + with open(mol2_path) as mol2_file: ligand.read(mol2_file) expected_results = FORMAL_CHARGE_RESULTS[input_mol2] errors = [] for iatom, atom in enumerate(ligand.atoms.values()): try: expected_charge = expected_results[iatom] - except IndexError: + except IndexError as e: err = f"Missing result for {atom.name}, {atom.type}, " err += f"{atom.formal_charge}" - raise IndexError(err) + raise IndexError(err) from e if not isclose(atom.formal_charge, expected_charge): err = ( f"Atom {atom.name} {atom.type} with bond order " @@ -127,7 +127,7 @@ def test_torsions(input_mol2): """Test assignment of torsion angles.""" ligand = Mol2Molecule() mol2_path = Path("tests/data") / input_mol2 - with open(mol2_path, "rt") as mol2_file: + with open(mol2_path) as mol2_file: ligand.read(mol2_file) test = set() # Only test heavy-atom torsions @@ -141,14 +141,14 @@ def test_torsions(input_mol2): if len(diff) > 0: err = ( f"Torsion test failed for {input_mol2}:\n" - f"Got: {sorted(list(test))}\n" - f"Expected: {sorted(list(expected))}\n" - f"Difference: {sorted(list(diff))}" + f"Got: {sorted(test)}\n" + f"Expected: {sorted(expected)}\n" + f"Difference: {sorted(diff)}" ) raise ValueError(err) - except KeyError: - err = f"No results for {input_mol2}: {sorted(list(ligand.torsions))}" - raise KeyError(err) + except KeyError as e: + err = f"No results for {input_mol2}: {sorted(ligand.torsions)}" + raise KeyError(err) from e @pytest.mark.parametrize("input_mol2", ALL_LIGANDS) @@ -156,21 +156,21 @@ def test_rings(input_mol2): """Test assignment of torsion angles.""" ligand = Mol2Molecule() mol2_path = Path("tests/data") / input_mol2 - with open(mol2_path, "rt") as mol2_file: + with open(mol2_path) as mol2_file: ligand.read(mol2_file) test = ligand.rings try: benchmark = RING_RESULTS[input_mol2] - except KeyError: + except KeyError as e: err = f"Missing expected results for {input_mol2}: {test}" - raise KeyError(err) + raise KeyError(err) from e diff = test ^ benchmark if len(diff) > 0: err = ( f"Ring test failed for {input_mol2}:\n" - f"Got: {sorted(list(test))}\n" - f"Expected: {sorted(list(benchmark))}\n" - f"Difference: {sorted(list(diff))}" + f"Got: {sorted(test)}\n" + f"Expected: {sorted(benchmark)}\n" + f"Difference: {sorted(diff)}" ) raise ValueError(err) for atom_name in ligand.atoms: diff --git a/tests/regression_test.py b/tests/regression_test.py index 310cb1b4..c5374d80 100644 --- a/tests/regression_test.py +++ b/tests/regression_test.py @@ -143,7 +143,7 @@ def test_forcefields(args, input_pdb, output_pqr, expected_pqr, tmp_path): ), pytest.param( f"--userff={common.DATA_DIR / 'custom-ff.dat'} " - + f"--usernames={common.DATA_DIR / 'custom.names'} --whitespace", + f"--usernames={common.DATA_DIR / 'custom.names'} --whitespace", common.DATA_DIR / "1AFS.pdb", "output.pqr", common.DATA_DIR / "1AFS_userff_usernames_whitespace.pqr", diff --git a/tests/test_version.py b/tests/test_version.py index 2391f3f8..6d01812e 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -10,4 +10,3 @@ def test_version_exists(): def test_version(): assert re.match(r"[0-9]+\.[0-9]+\.[0-9]+", __version__) - print(f"VERSION: {__version__}") From 7a7dcbadca5e523c239df6c8cacbd388355d93d9 Mon Sep 17 00:00:00 2001 From: Kiyoon Kim Date: Mon, 9 Dec 2024 13:55:57 +0900 Subject: [PATCH 3/4] refactor: remove RET503 rule --- pdb2pqr/hydrogens/__init__.py | 1 - pyproject.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/pdb2pqr/hydrogens/__init__.py b/pdb2pqr/hydrogens/__init__.py index b0899d76..215ea1fd 100644 --- a/pdb2pqr/hydrogens/__init__.py +++ b/pdb2pqr/hydrogens/__init__.py @@ -176,7 +176,6 @@ def switchstate(self, states, amb, state_id): # flag the added hydrogen residue.get_atom(hname).titratableH = True residue.get_atom(hname).addIntraBond(boundname) - return None @classmethod def pka_switchstate(cls, amb, state_id_): diff --git a/pyproject.toml b/pyproject.toml index af7e6d36..ff710239 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,7 +44,6 @@ select = [ "RUF", # ruff-specific "RET501", # return "RET502", # return - "RET503", # return "PTH", # path "NPY", # numpy "PD", # pandas From b1ad7983b32877fcbde59cdc7e7e24836965574a Mon Sep 17 00:00:00 2001 From: Kiyoon Kim Date: Mon, 16 Dec 2024 00:36:50 +0900 Subject: [PATCH 4/4] refactor: remove contextlib --- pdb2pqr/definitions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdb2pqr/definitions.py b/pdb2pqr/definitions.py index 61f4d8c2..53636c45 100644 --- a/pdb2pqr/definitions.py +++ b/pdb2pqr/definitions.py @@ -5,7 +5,6 @@ .. codeauthor:: Yong Huang """ -import contextlib import copy import logging import re @@ -106,8 +105,10 @@ def endElement(self, name): elif name == "name": self.curobj.name = self.content elif self.curelement != "": - with contextlib.suppress(ValueError): + try: self.content = float(self.content) + except ValueError: + pass setattr(self.curobj, self.curelement, self.content) self.content = ""