Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ repos:

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.6
rev: v0.16.0
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
9 changes: 5 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
Learn more under: https://pyscaffold.org/
"""

from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as build_ext_orig
import pathlib
import os
import pathlib
import shutil
import sys

import pybind11
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext as build_ext_orig


### Adapted from dolomite_base: https://github.com/ArtifactDB/dolomite-base/blob/master/setup.py
Expand Down Expand Up @@ -72,7 +73,7 @@ def build_cmake(self, ext):
ext_modules=[CMakeExtension("rds2py")],
cmdclass={"build_ext": build_ext},
)
except: # noqa
except:
print(
"\n\nAn error occurred while building the project, "
"please ensure you have the most updated version of setuptools, "
Expand Down
16 changes: 7 additions & 9 deletions src/rds2py/PyRdaReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
by higher-level functions.
"""

from typing import Any, Dict
from typing import Any

from .lib_rds_parser import RdaObject, RdsReader
from .PyRdsReader import PyRdsParser
Expand All @@ -18,8 +18,6 @@
class PyRdaParserError(Exception):
"""Exception raised for errors during RData parsing."""

pass


class PyRdaParser:
"""Parser for reading RData files.
Expand All @@ -43,7 +41,7 @@ def __init__(self, file_path: str):
try:
self.rda_object = RdaObject(file_path)
except Exception as e:
raise PyRdaParserError(f"Error initializing 'PyRdaParser': {str(e)}")
raise PyRdaParserError(f"Error initializing 'PyRdaParser': {e!s}")

def get_object_names(self):
"""Get the names of all objects stored in the RData file.
Expand All @@ -61,7 +59,7 @@ def get_object_count(self) -> int:
"""
return self.rda_object.get_object_count()

def parse(self) -> Dict[str, Dict[str, Any]]:
def parse(self) -> dict[str, dict[str, Any]]:
"""Parse all objects in the RData file.

Returns:
Expand All @@ -81,9 +79,9 @@ def parse(self) -> Dict[str, Dict[str, Any]]:

return result
except Exception as e:
raise PyRdaParserError(f"Error parsing RData file: {str(e)}")
raise PyRdaParserError(f"Error parsing RData file: {e!s}")

def parse_object(self, name: str) -> Dict[str, Any]:
def parse_object(self, name: str) -> dict[str, Any]:
"""Parse a single named object from the RData file.

Args:
Expand All @@ -98,7 +96,7 @@ def parse_object(self, name: str) -> Dict[str, Any]:
reader = self.rda_object.get_object_by_name(name)
return helper._process_object(reader)
except Exception as e:
raise PyRdaParserError(f"Error parsing object '{name}': {str(e)}")
raise PyRdaParserError(f"Error parsing object '{name}': {e!s}")


class _RdsProcessorHelper(PyRdsParser):
Expand All @@ -107,5 +105,5 @@ class _RdsProcessorHelper(PyRdsParser):
def __init__(self):
self.R_MIN = -2147483648

def _process_object(self, obj: RdsReader) -> Dict[str, Any]:
def _process_object(self, obj: RdsReader) -> dict[str, Any]:
return super()._process_object(obj)
32 changes: 15 additions & 17 deletions src/rds2py/PyRdsReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
dictionary representation that can be further processed by higher-level functions.
"""

from typing import Any, Dict, List, Union
from typing import Any
from warnings import warn

import numpy as np
Expand All @@ -15,8 +15,6 @@
class PyRdsParserError(Exception):
"""Exception raised for errors during RDS parsing."""

pass


class PyRdsParser:
"""Parser for reading RDS files.
Expand Down Expand Up @@ -55,9 +53,9 @@ def __init__(self, file_path: str):

self.root_object = robject
except Exception as e:
raise PyRdsParserError(f"Error initializing 'PyRdsParser': {str(e)}")
raise PyRdsParserError(f"Error initializing 'PyRdsParser': {e!s}")

def parse(self) -> Dict[str, Any]:
def parse(self) -> dict[str, Any]:
"""Parse the entire RDS file into a dictionary structure.

Returns:
Expand All @@ -74,12 +72,12 @@ def parse(self) -> Dict[str, Any]:
try:
return self._process_object(self.root_object)
except Exception as e:
raise PyRdsParserError(f"Error parsing RDS object: {str(e)}")
raise PyRdsParserError(f"Error parsing RDS object: {e!s}")

def _process_object(self, obj: RdsReader) -> Dict[str, Any]:
def _process_object(self, obj: RdsReader) -> dict[str, Any]:
try:
rtype = obj.get_rtype()
result: Dict[str, Any] = {"type": rtype}
result: dict[str, Any] = {"type": rtype}

if rtype == "S4":
result["package_name"] = obj.get_package_name()
Expand Down Expand Up @@ -116,9 +114,9 @@ def _process_object(self, obj: RdsReader) -> Dict[str, Any]:

return result
except Exception as e:
raise PyRdsParserError(f"Error processing object: {str(e)}")
raise PyRdsParserError(f"Error processing object: {e!s}")

def _handle_r_special_cases(self, data: np.ndarray, rtype: str, size: int) -> Union[np.ndarray, range]:
def _handle_r_special_cases(self, data: np.ndarray, rtype: str, size: int) -> np.ndarray | range:
"""Handle special R data representations."""
try:
# Special handling for R integer containing NA
Expand All @@ -137,7 +135,7 @@ def _handle_r_special_cases(self, data: np.ndarray, rtype: str, size: int) -> Un

return data
except Exception as e:
raise PyRdsParserError(f"Error handling R special cases: {str(e)}")
raise PyRdsParserError(f"Error handling R special cases: {e!s}")

def _get_numeric_data(self, obj: RdsReader, rtype: str) -> np.ndarray:
try:
Expand All @@ -155,12 +153,12 @@ def _get_numeric_data(self, obj: RdsReader, rtype: str) -> np.ndarray:

return data
except Exception as e:
raise PyRdsParserError(f"Error getting numeric data: {str(e)}")
raise PyRdsParserError(f"Error getting numeric data: {e!s}")

def _process_vector(self, obj: RdsReader) -> List[Dict[str, Any]]:
def _process_vector(self, obj: RdsReader) -> list[dict[str, Any]]:
return [self._process_object(obj.load_vec_element(i)) for i in range(obj.get_rsize())]

def _process_attributes(self, obj: RdsReader) -> Dict[str, Dict[str, Any]]:
def _process_attributes(self, obj: RdsReader) -> dict[str, dict[str, Any]]:
try:
attributes = {}
for name in obj.get_attribute_names():
Expand All @@ -169,10 +167,10 @@ def _process_attributes(self, obj: RdsReader) -> Dict[str, Dict[str, Any]]:

return attributes
except Exception as e:
raise PyRdsParserError(f"Error processing attributes: {str(e)}")
raise PyRdsParserError(f"Error processing attributes: {e!s}")

def get_dimensions(self) -> Union[tuple, None]:
def get_dimensions(self) -> tuple | None:
try:
return self.root_object.get_dimensions()
except Exception as e:
raise PyRdsParserError(f"Error getting dimensions: {str(e)}")
raise PyRdsParserError(f"Error getting dimensions: {e!s}")
4 changes: 2 additions & 2 deletions src/rds2py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
del version, PackageNotFoundError


from .generics import read_rds, read_rda, save_rds, register_parser
from .rdsutils import parse_rds, parse_rda, write_rds, write_rda
from .generics import read_rda, read_rds, register_parser, save_rds
from .rdsutils import parse_rda, parse_rds, write_rda, write_rds
10 changes: 5 additions & 5 deletions src/rds2py/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from functools import singledispatch
from importlib import import_module
from typing import Any, List, Optional
from typing import Any
from warnings import warn

from .rdsutils import get_class, parse_rda, parse_rds
Expand Down Expand Up @@ -92,7 +92,7 @@ def read_rds(path: str, **kwargs):
return _dispatcher(_robj, **kwargs)


def read_rda(path: str, objects: Optional[List[str]] = None, **kwargs) -> dict:
def read_rda(path: str, objects: list[str] | None = None, **kwargs) -> dict:
"""Read an RData file and convert each object to an appropriate Python type.

This function parses all (or selected) objects and dispatches each one
Expand Down Expand Up @@ -153,7 +153,7 @@ def _dispatcher(robject: dict, **kwargs):
return command(robject, **kwargs)
except Exception as e:
warn(
f"Failed to coerce RDS object to class: '{_class_name}', returning the dictionary, {str(e)}",
f"Failed to coerce RDS object to class: '{_class_name}', returning the dictionary, {e!s}",
RuntimeWarning,
)
else:
Expand Down Expand Up @@ -182,7 +182,7 @@ def decorator(func):


@singledispatch
def save_rds(x: Any, path: Optional[str] = None):
def save_rds(x: Any, path: str | None = None):
"""Save a Python object as RDS file.

Args:
Expand All @@ -196,7 +196,7 @@ def save_rds(x: Any, path: Optional[str] = None):


# Import all modules with save_rds registrations to ensure they are loaded
from . import ( # noqa: E402
from . import (
save_atomic, # noqa: F401
save_compressed_list, # noqa: F401
save_delayed_matrix, # noqa: F401
Expand Down
6 changes: 3 additions & 3 deletions src/rds2py/rdsutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
information from parsed objects.
"""

from typing import Any, Dict, List, Optional
from typing import Any

from .lib_rds_parser import write_rda as _write_rda_native
from .PyRdaReader import PyRdaParser
Expand Down Expand Up @@ -32,7 +32,7 @@ def parse_rds(path: str) -> dict:
return realized


def parse_rda(path: str, objects: Optional[List[str]] = None) -> Dict[str, dict]:
def parse_rda(path: str, objects: list[str] | None = None) -> dict[str, dict]:
"""Parse an RData file into a dictionary of named objects.

Args:
Expand Down Expand Up @@ -73,7 +73,7 @@ def write_rds(obj: Any, path: str) -> None:
save_rds(obj, path)


def write_rda(objects: Dict[str, Any], path: str) -> None:
def write_rda(objects: dict[str, Any], path: str) -> None:
"""Write multiple named Python objects to a gzip-compressed RData file.

Each value is converted using :py:func:`~.write_rds`.
Expand Down
16 changes: 7 additions & 9 deletions src/rds2py/save_atomic.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Functions for saving atomic R vector types from Python objects."""

from typing import Optional

import numpy as np
from biocutils import BooleanList, FloatList, IntegerList, Names, StringList

Expand All @@ -17,7 +15,7 @@
@save_rds.register(float)
@save_rds.register(str)
@save_rds.register(type(None))
def _save_rds_primitives(x, path: Optional[str] = None):
def _save_rds_primitives(x, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

if path is not None:
Expand All @@ -27,12 +25,12 @@ def _save_rds_primitives(x, path: Optional[str] = None):


@save_rds.register(np.generic)
def _save_rds_numpy_scalars(x: np.generic, path: Optional[str] = None):
def _save_rds_numpy_scalars(x: np.generic, path: str | None = None):
return save_rds(x.item(), path=path)


@save_rds.register(BooleanList)
def _save_rds_booleanlist(x: BooleanList, path: Optional[str] = None):
def _save_rds_booleanlist(x: BooleanList, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

cleaned = [-2147483648 if val is None else (1 if val else 0) for val in x]
Expand All @@ -44,7 +42,7 @@ def _save_rds_booleanlist(x: BooleanList, path: Optional[str] = None):


@save_rds.register(IntegerList)
def _save_rds_integerlist(x: IntegerList, path: Optional[str] = None):
def _save_rds_integerlist(x: IntegerList, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

cleaned = [-2147483648 if val is None else val for val in x]
Expand All @@ -56,7 +54,7 @@ def _save_rds_integerlist(x: IntegerList, path: Optional[str] = None):


@save_rds.register(FloatList)
def _save_rds_floatlist(x: FloatList, path: Optional[str] = None):
def _save_rds_floatlist(x: FloatList, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

cleaned = [np.nan if val is None else val for val in x]
Expand All @@ -68,7 +66,7 @@ def _save_rds_floatlist(x: FloatList, path: Optional[str] = None):


@save_rds.register(StringList)
def _save_rds_stringlist(x: StringList, path: Optional[str] = None):
def _save_rds_stringlist(x: StringList, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

converted = list(x)
Expand All @@ -79,7 +77,7 @@ def _save_rds_stringlist(x: StringList, path: Optional[str] = None):


@save_rds.register(Names)
def _save_rds_names(x: Names, path: Optional[str] = None):
def _save_rds_names(x: Names, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

converted = list(x)
Expand Down
6 changes: 2 additions & 4 deletions src/rds2py/save_compressed_list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Functions and classes for parsing Compressed List data structures."""

from typing import Optional

from biocutils.package_utils import is_package_installed

from .generics import save_rds
Expand All @@ -14,7 +12,7 @@
from compressed_lists import CompressedList, Partitioning

@save_rds.register(CompressedList)
def _save_rds_compressedlist(x: CompressedList, path: Optional[str] = None):
def _save_rds_compressedlist(x: CompressedList, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

def _get(obj, name):
Expand Down Expand Up @@ -63,7 +61,7 @@ def _get(obj, name):
return converted

@save_rds.register(Partitioning)
def _save_rds_partitioning(x: Partitioning, path: Optional[str] = None):
def _save_rds_partitioning(x: Partitioning, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

def _get(obj, name):
Expand Down
6 changes: 2 additions & 4 deletions src/rds2py/save_delayed_matrix.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import Optional

from biocutils.package_utils import is_package_installed

from .generics import save_rds
Expand All @@ -13,7 +11,7 @@
from delayedarray import DelayedArray

@save_rds.register(DelayedArray)
def _save_rds_delayedarray(x: DelayedArray, path: Optional[str] = None):
def _save_rds_delayedarray(x: DelayedArray, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

def _get(obj, name):
Expand Down Expand Up @@ -41,7 +39,7 @@ def _get(obj, name):
from hdf5array import Hdf5CompressedSparseMatrixSeed

@save_rds.register(Hdf5CompressedSparseMatrixSeed)
def _save_rds_h5sparse_seed(x: Hdf5CompressedSparseMatrixSeed, path: Optional[str] = None):
def _save_rds_h5sparse_seed(x: Hdf5CompressedSparseMatrixSeed, path: str | None = None):
from .lib_rds_parser import write_rds as _write_rds_native

converted = {
Expand Down
Loading
Loading