diff --git a/Mikado/configuration/configuration.py b/Mikado/configuration/configuration.py index 74c5bb5d4..16217ba83 100644 --- a/Mikado/configuration/configuration.py +++ b/Mikado/configuration/configuration.py @@ -15,7 +15,7 @@ import toml import json from ..exceptions import InvalidConfiguration -from pkg_resources import resource_filename +from ..utilities.resources import resource_file try: from yaml import CSafeLoader as yLoader except ImportError: @@ -118,7 +118,7 @@ def load_scoring(self, logger=None): options = [os.path.abspath(self.pick.scoring_file), os.path.abspath(os.path.join(os.path.dirname(self.filename or ""), self.pick.scoring_file)), - os.path.abspath(os.path.join(resource_filename("Mikado.configuration", "scoring_files"), + os.path.abspath(os.path.join(resource_file("Mikado.configuration", "scoring_files"), self.pick.scoring_file))] if self.filename is not None: diff --git a/Mikado/configuration/configurator.py b/Mikado/configuration/configurator.py index c8d01320c..a4192b745 100644 --- a/Mikado/configuration/configurator.py +++ b/Mikado/configuration/configurator.py @@ -14,9 +14,9 @@ from multiprocessing import get_start_method from logging import Logger import yaml -from pkg_resources import resource_stream from ..exceptions import InvalidConfiguration from ..utilities.log_utils import create_default_logger +from ..utilities.resources import resource_binary_stream import random import toml from .configuration import MikadoConfiguration @@ -52,7 +52,7 @@ def create_cluster_config(config: Union[MikadoConfiguration, DaijinConfiguration cluster_config = args.cluster_config else: cluster_config = "daijin_hpc.yaml" - with open(cluster_config, "wb") as out, resource_stream("Mikado.daijin", "hpc.yaml") as original: + with open(cluster_config, "wb") as out, resource_binary_stream("Mikado.daijin", "hpc.yaml") as original: for pos, line in enumerate(original): out.write(line) if pos == 0: diff --git a/Mikado/configuration/daijin_configurator.py b/Mikado/configuration/daijin_configurator.py index b9a0dc0db..eb9e494a4 100644 --- a/Mikado/configuration/daijin_configurator.py +++ b/Mikado/configuration/daijin_configurator.py @@ -5,13 +5,13 @@ import os import toml import yaml -from pkg_resources import resource_stream from .configurator import create_cluster_config, load_and_validate_config from . import print_config from .daijin_configuration import DaijinConfiguration from .._transcripts.scoring_configuration import ScoringFile from ..exceptions import InvalidConfiguration from ..utilities.log_utils import create_default_logger +from ..utilities.resources import resource_binary_stream import sys import pysam try: @@ -208,9 +208,9 @@ def create_daijin_config(args: Namespace, config=None, level="ERROR", piped=Fals if args.scoring: if args.copy_scoring is not False: with open(args.copy_scoring, "wt") as out: - with resource_stream("Mikado", os.path.join("configuration", - "scoring_files", - args.scoring)) as original: + with resource_binary_stream("Mikado", os.path.join("configuration", + "scoring_files", + args.scoring)) as original: for line in original: print(line.decode(), file=out, end="") args.scoring = os.path.abspath(args.copy_scoring) diff --git a/Mikado/daijin/__init__.py b/Mikado/daijin/__init__.py index f8a94b5dd..91c76e4da 100644 --- a/Mikado/daijin/__init__.py +++ b/Mikado/daijin/__init__.py @@ -13,21 +13,21 @@ import time from snakemake.utils import min_version from ..configuration.daijin_configurator import create_daijin_config -import pkg_resources +from ..utilities.resources import resource_exists, resource_file, resource_listdir try: from yaml import CSafeLoader as yLoader except ImportError: from yaml import SafeLoader as yLoader -system_hpc_yaml = pkg_resources.resource_filename("Mikado", os.path.join("daijin", "hpc.yaml")) +system_hpc_yaml = resource_file("Mikado", os.path.join("daijin", "hpc.yaml")) min_version("3.6") TIME_START = time.time() NOW = datetime.datetime.fromtimestamp(TIME_START).strftime('%Y-%m-%d_%H:%M:%S') -DAIJIN_DIR = pkg_resources.resource_filename("Mikado", "daijin") -assert pkg_resources.resource_exists("Mikado", "daijin") +DAIJIN_DIR = resource_file("Mikado", "daijin") +assert resource_exists("Mikado", "daijin") # noinspection PyPep8Naming @@ -197,7 +197,7 @@ def create_config_parser(): scoring_file.add_argument("--scoring", type=str, default=None, help="""Available scoring files. Either provide your own of choose from one of the pre-packaged scoring files: - {}""".format("\n".join(["- {}".format(_) for _ in pkg_resources.resource_listdir( + {}""".format("\n".join(["- {}".format(_) for _ in resource_listdir( "Mikado", os.path.join("configuration", "scoring_files"))] ))) scoring_file.add_argument("--custom-scoring", type=str, default=None, diff --git a/Mikado/daijin/assemble.py b/Mikado/daijin/assemble.py index fe833b239..b528129b5 100644 --- a/Mikado/daijin/assemble.py +++ b/Mikado/daijin/assemble.py @@ -5,10 +5,10 @@ import os from ..configuration import DaijinConfiguration from . import get_sub_commands, system_hpc_yaml, NOW -import pkg_resources import shutil import sys import inspect +from ..utilities.resources import resource_exists, resource_file try: import drmaa _ = drmaa.Session() @@ -131,7 +131,7 @@ def assemble_transcripts_pipeline(args): os.symlink(os.path.abspath(lr_file), out) # Launch using SnakeMake - assert pkg_resources.resource_exists("Mikado", os.path.join("daijin", "assemble.smk")) + assert resource_exists("Mikado", os.path.join("daijin", "assemble.smk")) additional_config = {} if args.threads is not None: @@ -207,7 +207,6 @@ def assemble_transcripts_pipeline(args): raise KeyError("No configfile key found") snakemake.snakemake( - pkg_resources.resource_filename("Mikado", - os.path.join("daijin", "assemble.smk")), + resource_file("Mikado", os.path.join("daijin", "assemble.smk")), **kwds ) diff --git a/Mikado/daijin/assemble.smk b/Mikado/daijin/assemble.smk index d6054fd6b..1a0ebdb1b 100644 --- a/Mikado/daijin/assemble.smk +++ b/Mikado/daijin/assemble.smk @@ -2,8 +2,8 @@ import os import subprocess from shutil import which import functools -import pkg_resources import re +from Mikado.utilities.resources import resource_file from Mikado.utilities.file_type import filetype @@ -15,7 +15,7 @@ except AttributeError: # Short read fields -envdir = pkg_resources.resource_filename("Mikado.daijin", "envs") +envdir = resource_file("Mikado.daijin", "envs") R1 = [] R2 = [] diff --git a/Mikado/daijin/mikado.py b/Mikado/daijin/mikado.py index 60434e193..058aa7f0d 100644 --- a/Mikado/daijin/mikado.py +++ b/Mikado/daijin/mikado.py @@ -5,11 +5,11 @@ import os from ..configuration import DaijinConfiguration from . import get_sub_commands, system_hpc_yaml, NOW -import pkg_resources from dataclasses import asdict import shutil import sys import inspect +from ..utilities.resources import resource_exists, resource_file try: import drmaa _ = drmaa.Session() @@ -67,8 +67,7 @@ def mikado_pipeline(args): raise OSError("{} is not a directory!".format("daijin_logs")) # Launch using SnakeMake - assert pkg_resources.resource_exists("Mikado", - os.path.join("daijin", "mikado.smk")) + assert resource_exists("Mikado", os.path.join("daijin", "mikado.smk")) cluster_var = None if args.no_drmaa is True and sub_cmd: @@ -147,7 +146,6 @@ def mikado_pipeline(args): raise KeyError("No configfile key found") snakemake.snakemake( - pkg_resources.resource_filename("Mikado", - os.path.join("daijin", "mikado.smk")), + resource_file("Mikado", os.path.join("daijin", "mikado.smk")), **kwds ) diff --git a/Mikado/daijin/mikado.smk b/Mikado/daijin/mikado.smk index 35566a5ba..79a5ed5f7 100644 --- a/Mikado/daijin/mikado.smk +++ b/Mikado/daijin/mikado.smk @@ -1,6 +1,6 @@ import os from shutil import which -import pkg_resources +from Mikado.utilities.resources import resource_file from Bio.Data import CodonTable from Mikado.serializers.blast_serializer.tabular_utils import blast_keys import functools @@ -41,7 +41,7 @@ try: except AttributeError: CFG=workflow.overwrite_configfile -envdir = pkg_resources.resource_filename("Mikado.daijin", "envs") +envdir = resource_file("Mikado.daijin", "envs") REF = config["reference"]["genome"] diff --git a/Mikado/subprograms/configure.py b/Mikado/subprograms/configure.py index cbb5b7185..a305960ad 100644 --- a/Mikado/subprograms/configure.py +++ b/Mikado/subprograms/configure.py @@ -6,7 +6,6 @@ import yaml import os import re -from pkg_resources import resource_filename, resource_stream import glob import argparse import sys @@ -17,6 +16,7 @@ from ..exceptions import InvalidConfiguration from ..utilities import comma_split, percentage, merge_dictionaries from ..utilities.namespace import Namespace +from ..utilities.resources import resource_binary_stream, resource_file from ..configuration.configurator import load_and_validate_config from ..configuration import print_config import tempfile @@ -136,9 +136,9 @@ def create_config(args): if args.scoring is not None: if args.copy_scoring is not False: with open(args.copy_scoring, "wt") as out: - with resource_stream("Mikado", os.path.join("configuration", - "scoring_files", - args.scoring)) as original: + with resource_binary_stream("Mikado", os.path.join("configuration", + "scoring_files", + args.scoring)) as original: for line in original: print(line.decode().rstrip(), file=out) args.scoring = args.copy_scoring @@ -224,7 +224,7 @@ def configure_parser(): :rtype: argparse.ArgumentParser """ - scoring_folder = resource_filename("Mikado", os.path.join("configuration", "scoring_files")) + scoring_folder = resource_file("Mikado", os.path.join("configuration", "scoring_files")) trailing = re.compile(r"^{}".format(os.path.sep)) fold_path = re.compile(scoring_folder) diff --git a/Mikado/utilities/resources.py b/Mikado/utilities/resources.py new file mode 100644 index 000000000..607370bc3 --- /dev/null +++ b/Mikado/utilities/resources.py @@ -0,0 +1,31 @@ +"""Helpers for accessing package data files.""" + +import os +from importlib import resources + + +def _resource_parts(*parts): + for part in parts: + for chunk in str(part).replace(os.sep, "/").split("/"): + if chunk not in ("", "."): + yield chunk + + +def resource(package, *path_parts): + return resources.files(package).joinpath(*_resource_parts(*path_parts)) + + +def resource_file(package, *parts): + return str(resource(package, *parts)) + + +def resource_binary_stream(package, *parts): + return resource(package, *parts).open("rb") + + +def resource_exists(package, *parts): + return resource(package, *parts).exists() + + +def resource_listdir(package, *parts): + return [entry.name for entry in resource(package, *parts).iterdir()] diff --git a/environment.yml b/environment.yml index 1578f2436..2f14d690f 100644 --- a/environment.yml +++ b/environment.yml @@ -4,7 +4,7 @@ channels: - bioconda dependencies: - python>3.8,<3.11 - - setuptools<80.9 + - setuptools - cython==0.29.32 - biopython==1.79 - docutils==0.19 diff --git a/pyproject.toml b/pyproject.toml index 79e66ef15..a054e6331 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools<80.9","wheel==0.37.1","Cython==0.29.32","numpy==1.23.3","scipy==1.11.1"] +requires = ["setuptools","wheel==0.37.1","Cython==0.29.32","numpy==1.23.3","scipy==1.11.1"] build-backend = "setuptools.build_meta" [tool.pytest] diff --git a/requirements.txt b/requirements.txt index 7202792eb..dbde92623 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -setuptools<80.9 cython==0.29.32 biopython==1.79 docutils==0.19 diff --git a/sample_data/Snakefile b/sample_data/Snakefile index e8257461e..bd76b4b37 100644 --- a/sample_data/Snakefile +++ b/sample_data/Snakefile @@ -10,12 +10,12 @@ from Mikado.configuration.configuration import MikadoConfiguration import subprocess import gzip from snakemake import logger as snake_logger -import pkg_resources +from Mikado.utilities.resources import resource_file import Mikado import dataclasses import marshmallow_dataclass -prod_conda = pkg_resources.resource_filename("Mikado.daijin", os.path.join("envs", "prodigal.yaml")) +prod_conda = resource_file("Mikado.daijin", os.path.join("envs", "prodigal.yaml")) swissprot = "uniprot_sprot_plants.fasta.gz" swissprot_noat = "uniprot_sprot_plants.not_at.fasta" diff --git a/setup.cfg b/setup.cfg index 93d2fe486..99386ebe5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [options] setup_requires = - setuptools<80.9 + setuptools [aliases] test=pytest @@ -34,4 +34,3 @@ markers = # # See https://docs.python.org/3/library/warnings.html and # # https://docs.pytest.org/en/latest/warnings.html # # -# ignore:^Use of \.\. or absolute path in a resource path is not allowed and will raise exceptions in a future release\.$:DeprecationWarning:pkg_resources diff --git a/setup.py b/setup.py index f95396c6f..acaccf57d 100644 --- a/setup.py +++ b/setup.py @@ -87,7 +87,7 @@ author_email="lucventurini@gmail.com", license="LGPL-3.0-or-later", tests_require=["pytest"], - setup_requires=["setuptools<80.9"], + setup_requires=["setuptools"], classifiers=[ "Development Status :: 5 - Production/Stable", "Topic :: Scientific/Engineering :: Bio-Informatics",