Skip to content
Merged
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
52 changes: 52 additions & 0 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Publish to PyPI

on:
push:
tags: "*"

jobs:
build:
runs-on: ubuntu-latest
permissions:
id-token: write
repository-projects: write
contents: write
pages: write

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.12

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox

- name: Test with tox
run: |
tox

- name: Build Project and Publish
run: |
python -m tox -e clean,build

# This uses the trusted publisher workflow so no token is required.
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Publish to PyPI' step
Uses Step
uses 'pypa/gh-action-pypi-publish' with ref 'release/v1', not a pinned commit hash

- name: Build docs
run: |
tox -e docs

- run: touch ./docs/_build/html/.nojekyll

- name: GH Pages Deployment
uses: JamesIves/github-pages-deploy-action@v4

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Publish to PyPI' step
Uses Step
uses 'JamesIves/github-pages-deploy-action' with ref 'v4', not a pinned commit hash
with:
branch: gh-pages # The branch the action should deploy to.
folder: ./docs/_build/html
clean: true # Automatically remove deleted files from the deploy branch
51 changes: 0 additions & 51 deletions .github/workflows/pypi-publish.yml

This file was deleted.

40 changes: 0 additions & 40 deletions .github/workflows/pypi-test.yml

This file was deleted.

73 changes: 73 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
name: Test the library

on:
push:
branches:
- master # for legacy repos
- main
pull_request:
branches:
- master # for legacy repos
- main
workflow_dispatch: # Allow manually triggering the workflow
schedule:
# Run roughly every 15 days at 00:00 UTC
# (useful to check if updates on dependencies break the package)
- cron: "0 0 1,16 * *"

permissions:
contents: read

concurrency:
group: >-
${{ github.workflow }}-${{ github.ref_type }}-
${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true

jobs:
test:
strategy:
matrix:
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
platform:
- ubuntu-latest
- macos-latest
- windows-latest
runs-on: ${{ matrix.platform }}
name: Python ${{ matrix.python }}, ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
id: setup-python
with:
python-version: ${{ matrix.python }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install tox coverage

- name: Run tests
run: >-
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
tox
-- -rFEx --durations 10 --color yes --cov --cov-branch --cov-report=xml # pytest args

- name: Check for codecov token availability
id: codecov-check
shell: bash
run: |
if [ ${{ secrets.CODECOV_TOKEN }} != '' ]; then
echo "codecov=true" >> $GITHUB_OUTPUT;
else
echo "codecov=false" >> $GITHUB_OUTPUT;
fi

- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v5

Check warning

Code scanning / CodeQL

Unpinned tag for a non-immutable Action in workflow Medium

Unpinned 3rd party Action 'Test the library' step
Uses Step
uses 'codecov/codecov-action' with ref 'v5', not a pinned commit hash
if: ${{ steps.codecov-check.outputs.codecov == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
slug: ${{ github.repository }}
flags: ${{ matrix.platform }} - py${{ matrix.python }}
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Changelog

## Version 0.3.0
## Version 0.3.0 - 0.3.1

- Provide a base `BiocObject` class similar to the `Annotated` class in Bioconductor. The class provides `metadata` slot, accessors and validation functions.
- Renaming code files to follow pep guidelines
- Update Github actions and workflow to the new biocsetup versions
- Changes to improve `NamedList`, `Names` classes
- get name at index
- delete method for namedlist/names
- add is_unique
- add lint errors
- linting documentation, typehints etc

## Version 0.2.3

Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
PyScaffold helps you to put up the scaffold of your new Python project.
Learn more under: https://pyscaffold.org/
"""

from setuptools import setup

if __name__ == "__main__":
Expand Down
16 changes: 9 additions & 7 deletions src/biocutils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
finally:
del version, PackageNotFoundError

from .Factor import Factor
from .StringList import StringList
from .IntegerList import IntegerList
from .FloatList import FloatList
from .BooleanList import BooleanList
from .Names import Names
from .NamedList import NamedList
from .factor import Factor
from .string_list import StringList
from .integer_list import IntegerList
from .float_list import FloatList
from .boolean_list import BooleanList
from .names import Names
from .named_list import NamedList

from .factorize import factorize
from .intersect import intersect
Expand Down Expand Up @@ -60,3 +60,5 @@

from .get_height import get_height
from .is_high_dimensional import is_high_dimensional

from .bioc_object import BiocObject
2 changes: 2 additions & 0 deletions src/biocutils/_utils_combine.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def _check_array_dimensions(x, active: int) -> bool:
+ ")"
)

return True


def _coerce_sparse_matrix(first, combined, module):
if isinstance(first, module.csr_matrix):
Expand Down
3 changes: 2 additions & 1 deletion src/biocutils/assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def assign(x: Any, indices: Sequence[int], replacement: Any) -> Any:
:py:func:`~biocutils.assign_sequence.assign_sequence` instead.

Args:
x: Object to be assignted.
x:
Object to be assignted.

Returns:
The object after assignment, typically the same type as ``x``.
Expand Down
6 changes: 3 additions & 3 deletions src/biocutils/assign_rows.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ def assign_rows(x: Any, indices: Sequence[int], replacement: Any) -> Any:
tmp = [slice(None)] * len(x.shape)
tmp[0] = indices
output[(*tmp,)] = replacement

return output


@assign_rows.register
def _assign_rows_numpy(
x: numpy.ndarray, indices: Sequence[int], replacement: Any
) -> numpy.ndarray:
def _assign_rows_numpy(x: numpy.ndarray, indices: Sequence[int], replacement: Any) -> numpy.ndarray:
tmp = [slice(None)] * len(x.shape)
tmp[0] = indices
output = numpy.copy(x)
output[(*tmp,)] = replacement

return output
8 changes: 2 additions & 6 deletions src/biocutils/assign_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,14 @@ def _assign_sequence_list(x: list, indices: Sequence[int], replacement: Any) ->


@assign_sequence.register
def _assign_sequence_numpy(
x: numpy.ndarray, indices: Sequence[int], replacement: Any
) -> numpy.ndarray:
def _assign_sequence_numpy(x: numpy.ndarray, indices: Sequence[int], replacement: Any) -> numpy.ndarray:
output = numpy.copy(x)
output[indices] = replacement
return output


@assign_sequence.register
def _assign_sequence_range(
x: range, indices: Sequence[int], replacement: Any
) -> Union[range, list]:
def _assign_sequence_range(x: range, indices: Sequence[int], replacement: Any) -> Union[range, list]:
if (
isinstance(replacement, range)
and isinstance(indices, range)
Expand Down
17 changes: 6 additions & 11 deletions src/biocutils/bioc_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@
from typing import Any, Dict, Optional, Union
from warnings import warn

try:
from typing import Self
except ImportError:
Self = "BiocObject"

from .NamedList import NamedList
from .named_list import NamedList

__author__ = "Jayaram Kancherla"
__copyright__ = "jkanche"
Expand Down Expand Up @@ -40,22 +35,22 @@ class BiocObject:
Provides a standardized `metadata` slot and copy-on-write semantics.
"""

def __init__(self, metadata: Optional[Union[Dict[str, Any], NamedList]] = None, validate: bool = True) -> None:
def __init__(self, metadata: Optional[Union[Dict[str, Any], NamedList]] = None, _validate: bool = True) -> None:
"""Initialize the BiocObject.

Args:
metadata:
Additional metadata. Defaults to an empty NamedList.

validate:
_validate:
Whether to validate the input. Defaults to True.
"""
if validate and metadata is not None:
if _validate and metadata is not None:
_validate_metadata(metadata)

self._metadata = sanitize_metadata(metadata)

def _define_output(self, in_place: bool = False) -> Self:
def _define_output(self, in_place: bool = False) -> BiocObject:
"""Internal utility to handle in-place vs copy-on-modify."""
if in_place:
return self
Expand Down Expand Up @@ -93,7 +88,7 @@ def get_metadata(self) -> NamedList:
"""Alias for :py:attr:`~metadata` getter."""
return self.metadata

def set_metadata(self, metadata: Optional[Union[Dict[str, Any], NamedList]], in_place: bool = False) -> Self:
def set_metadata(self, metadata: Optional[Union[Dict[str, Any], NamedList]], in_place: bool = False) -> BiocObject:
"""Set new metadata.

Args:
Expand Down
Loading