diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a832683..0697e05 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ exclude: '^docs/conf.py' repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v6.0.0 hooks: - id: trailing-whitespace - id: check-added-large-files @@ -19,7 +19,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.8.2 + rev: v0.16.0 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/docs/requirements.txt b/docs/requirements.txt index a1b9d2b..c20cf60 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,9 @@ +furo +myst-nb # Requirements file for ReadTheDocs, check .readthedocs.yml. # To build the module reference correctly, make sure every external package # under `install_requires` in `setup.cfg` is also listed here! # sphinx_rtd_theme myst-parser[linkify] sphinx>=3.2.1 -myst-nb -furo sphinx-autodoc-typehints diff --git a/setup.py b/setup.py index d94e095..bced235 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,10 @@ """ - Setup file for ensembldb. - Use setup.cfg to configure your project. +Setup file for ensembldb. +Use setup.cfg to configure your project. - This file was generated with PyScaffold 4.6. - PyScaffold helps you to put up the scaffold of your new Python project. - Learn more under: https://pyscaffold.org/ +This file was generated with PyScaffold 4.6. +PyScaffold helps you to put up the scaffold of your new Python project. +Learn more under: https://pyscaffold.org/ """ from setuptools import setup @@ -12,7 +12,7 @@ if __name__ == "__main__": try: setup(use_scm_version={"version_scheme": "no-guess-dev"}) - except: # noqa + except: print( "\n\nAn error occurred while building the project, " "please ensure you have the most updated version of setuptools, " diff --git a/src/ensembldb/__init__.py b/src/ensembldb/__init__.py index 7501a7f..f975f4f 100644 --- a/src/ensembldb/__init__.py +++ b/src/ensembldb/__init__.py @@ -15,6 +15,6 @@ finally: del version, PackageNotFoundError +from .ensdb import EnsDb from .record import EnsDbRecord from .registry import EnsDbRegistry -from .ensdb import EnsDb \ No newline at end of file diff --git a/src/ensembldb/ensdb.py b/src/ensembldb/ensdb.py index c81d215..d7acac9 100644 --- a/src/ensembldb/ensdb.py +++ b/src/ensembldb/ensdb.py @@ -1,5 +1,4 @@ import sqlite3 -from typing import Dict, List, Optional, Union from biocframe import BiocFrame from genomicranges import GenomicRanges @@ -63,7 +62,7 @@ def _check_column_exists(self, table: str, column: str) -> bool: except sqlite3.OperationalError: return False - def genes(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) -> GenomicRanges: + def genes(self, filter: dict[str, str | list[str]] | None = None) -> GenomicRanges: """Retrieve genes as GenomicRanges. Args: @@ -83,7 +82,7 @@ def genes(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) -> Ge entrez_col = ", g.entrezid" if has_entrez else "" query = f""" - SELECT + SELECT g.gene_id, g.gene_name, g.gene_biotype, g.seq_name, g.gene_seq_start, g.gene_seq_end, g.seq_strand{entrez_col}, c.seq_length @@ -114,7 +113,7 @@ def genes(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) -> Ge return self._make_gr(bf, prefix="gene_") - def transcripts(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) -> GenomicRanges: + def transcripts(self, filter: dict[str, str | list[str]] | None = None) -> GenomicRanges: """Retrieve transcripts as GenomicRanges. Args: @@ -130,7 +129,7 @@ def transcripts(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) A GenomicRanges object containing transcript coordinates and metadata. """ query = """ - SELECT + SELECT t.tx_id, t.tx_biotype, t.gene_id, t.tx_seq_start, t.tx_seq_end, g.seq_name, g.seq_strand, g.gene_name, @@ -166,7 +165,7 @@ def transcripts(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) return self._make_gr(bf, prefix="tx_") - def exons(self, filter: Optional[Dict[str, Union[str, List[str]]]] = None) -> GenomicRanges: + def exons(self, filter: dict[str, str | list[str]] | None = None) -> GenomicRanges: """Retrieve exons as GenomicRanges. Args: diff --git a/src/ensembldb/record.py b/src/ensembldb/record.py index a1e7b8a..382437e 100644 --- a/src/ensembldb/record.py +++ b/src/ensembldb/record.py @@ -2,7 +2,6 @@ from dataclasses import dataclass from datetime import date, datetime -from typing import Optional __author__ = "Jayaram Kancherla" __copyright__ = "Jayaram Kancherla" @@ -15,22 +14,22 @@ class EnsDbRecord: ensdb_id: str # e.g., "AH12345" title: str - species: Optional[str] - taxonomy_id: Optional[str] - genome: Optional[str] - description: Optional[str] + species: str | None + taxonomy_id: str | None + genome: str | None + description: str | None url: str - release_date: Optional[date] - ensembl_version: Optional[str] = None + release_date: date | None + ensembl_version: str | None = None @classmethod - def from_db_row(cls, row: tuple) -> "EnsDbRecord": + def from_db_row(cls, row: tuple) -> EnsDbRecord: """Build a record from a database query row.""" rid, title, species, tax_id, genome, desc, url, date_str = row ah_id = f"AH{rid}" - rel_date: Optional[date] = None + rel_date: date | None = None if date_str: try: rel_date = datetime.strptime(str(date_str).split(" ")[0], "%Y-%m-%d").date() diff --git a/src/ensembldb/registry.py b/src/ensembldb/registry.py index 4b1c852..ed956f8 100644 --- a/src/ensembldb/registry.py +++ b/src/ensembldb/registry.py @@ -1,7 +1,7 @@ import os import sqlite3 from pathlib import Path -from typing import Any, Dict, List, Optional, Union +from typing import Any from pybiocfilecache import BiocFileCache @@ -19,7 +19,7 @@ class EnsDbRegistry: def __init__( self, - cache_dir: Optional[Union[str, Path]] = None, + cache_dir: str | Path | None = None, force: bool = False, ) -> None: """Initialize the EnsDb registry. @@ -35,7 +35,7 @@ def __init__( self._cache_dir.mkdir(parents=True, exist_ok=True) self._bfc = BiocFileCache(self._cache_dir) - self._registry_map: Dict[str, EnsDbRecord] = {} + self._registry_map: dict[str, EnsDbRecord] = {} self._initialize_registry(force=force) def _initialize_registry(self, force: bool = False): @@ -100,7 +100,7 @@ def _initialize_registry(self, force: bool = False): record = EnsDbRecord.from_db_row(row) self._registry_map[record.ensdb_id] = record - def list_ensdbs(self) -> List[str]: + def list_ensdbs(self) -> list[str]: """List available EnsDb IDs.""" return sorted(list(self._registry_map.keys())) @@ -151,7 +151,7 @@ def load_db(self, ensdb_id: str, force: bool = False) -> EnsDb: path = self.download(ensdb_id, force=force) return EnsDb(path) - def _get_filepath(self, resource: Any) -> Optional[str]: + def _get_filepath(self, resource: Any) -> str | None: if hasattr(resource, "rpath"): rel_path = str(resource.rpath) elif hasattr(resource, "get"): diff --git a/tests/conftest.py b/tests/conftest.py index 260d0e0..17f527f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1,10 @@ """ - Dummy conftest.py for ensembldb. +Dummy conftest.py for ensembldb. - If you don't know what this is for, just leave it empty. - Read more about conftest.py under: - - https://docs.pytest.org/en/stable/fixture.html - - https://docs.pytest.org/en/stable/writing_plugins.html +If you don't know what this is for, just leave it empty. +Read more about conftest.py under: +- https://docs.pytest.org/en/stable/fixture.html +- https://docs.pytest.org/en/stable/writing_plugins.html """ # import pytest