Skip to content

Commit

Permalink
Refactor deprecated pkg_resources usage
Browse files Browse the repository at this point in the history
- Locate resources relative to `__file__`
- Support egg/zip with `open_file_for_reading`
  • Loading branch information
speleo3 committed Dec 10, 2023
1 parent a62e2a4 commit 50f62c6
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 10 deletions.
9 changes: 5 additions & 4 deletions propka/bonds.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import logging
import math
import json
import pkg_resources
from pathlib import Path
import propka.calculations
from typing import TYPE_CHECKING

Expand All @@ -35,6 +35,8 @@ class BondMaker:
TODO - the documentation for this class needs to be improved.
"""
def __init__(self):
from propka.input import open_file_for_reading

# predefined bonding distances
self.distances = {'S-S': DISULFIDE_DISTANCE,
'F-F': FLUORIDE_DISTANCE}
Expand All @@ -51,9 +53,8 @@ def __init__(self):
+ [self.default_dist_squared])
self.max_sq_distance = max(distances)
# protein bonding data
self.data_file_name = (
pkg_resources.resource_filename(__name__, 'protein_bonds.json'))
with open(self.data_file_name, 'rt') as json_file:
self.data_file_name = Path(__file__).parent / 'protein_bonds.json'
with open_file_for_reading(self.data_file_name) as json_file:
self.protein_bonds = json.load(json_file)
self.intra_residue_backbone_bonds = {'N': ['CA'], 'CA': ['N', 'C'],
'C': ['CA', 'O'], 'O': ['C']}
Expand Down
19 changes: 15 additions & 4 deletions propka/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
:func:`get_atom_lines_from_input`) have been removed.
"""
import typing
from typing import Iterator, Tuple
from typing import Iterator, Tuple, Union
import contextlib
import io
import zipfile
from pathlib import Path
from pkg_resources import resource_filename
from propka.lib import protein_precheck
from propka.atom import Atom
from propka.conformation_container import ConformationContainer
Expand All @@ -34,6 +35,16 @@ def open_file_for_reading(
input_file.seek(0)
return contextlib.nullcontext(input_file)

input_file = Path(input_file)

if not input_file.is_file():
for p in input_file.parents:
if not zipfile.is_zipfile(p):
continue
zf = zipfile.ZipFile(p)
stream = zf.open(str(input_file.relative_to(p)))
return io.TextIOWrapper(stream)

return contextlib.closing(open(input_file, 'rt'))


Expand Down Expand Up @@ -122,7 +133,7 @@ def read_molecule_file(filename: str, mol_container: MolecularContainer, stream=
return mol_container


def read_parameter_file(input_file, parameters: Parameters) -> Parameters:
def read_parameter_file(input_file: Union[Path, str], parameters: Parameters) -> Parameters:
"""Read a parameter file.
Args:
Expand All @@ -133,7 +144,7 @@ def read_parameter_file(input_file, parameters: Parameters) -> Parameters:
"""
# try to locate the parameter file
try:
ifile = resource_filename(__name__, input_file)
ifile = Path(__file__).parent / input_file
input_ = open_file_for_reading(ifile)
except (IOError, FileNotFoundError, ValueError, KeyError):
input_ = open_file_for_reading(input_file)
Expand Down
4 changes: 2 additions & 2 deletions propka/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import sys
import logging
import argparse
import pkg_resources
from pathlib import Path


_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -246,7 +246,7 @@ def build_parser(parser=None):
"--version", action="version", version=f"%(prog)s {propka.__version__}")
group.add_argument(
"-p", "--parameters", dest="parameters",
default=pkg_resources.resource_filename(__name__, "propka.cfg"),
default=str(Path(__file__).parent / "propka.cfg"),
help="set the parameter file [{default:s}]")
try:
group.add_argument(
Expand Down
29 changes: 29 additions & 0 deletions tests/test_input.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import propka.input as m
import zipfile


def test_open_file_for_reading(tmp_path):
path = tmp_path / "tmp.txt"
path.write_text("One\nTwo\nThree\n")
# str
with m.open_file_for_reading(str(path)) as outer:
assert outer.read() == "One\nTwo\nThree\n"
assert outer.closed
# Path
with m.open_file_for_reading(path) as outer:
# TextIO
with m.open_file_for_reading(outer) as inner:
assert inner.readline() == "One\n"
assert not outer.closed
assert outer.readline() == "Two\n"
assert outer.closed


def test_open_file_for_reading__zipfile(tmp_path):
zippath = tmp_path / "tmp.zip"
arcname = "foo/bar.txt"
with zipfile.ZipFile(zippath, "w") as ziphandle:
ziphandle.writestr(arcname, "One\nTwo\nThree\n")
with m.open_file_for_reading(zippath / arcname) as outer:
assert outer.readline() == "One\n"
assert outer.closed

0 comments on commit 50f62c6

Please sign in to comment.