Skip to content

Commit bd4d826

Browse files
authored
Migrate upstream changes from SE and GRanges (#72)
1 parent 3ba21d4 commit bd4d826

File tree

5 files changed

+100
-52
lines changed

5 files changed

+100
-52
lines changed

.github/workflows/publish-pypi.yml

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies, run tests and lint with a single version of Python
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3-
41
name: Publish to PyPI
52

63
on:
@@ -19,10 +16,10 @@ jobs:
1916
steps:
2017
- uses: actions/checkout@v4
2118

22-
- name: Set up Python 3.11
19+
- name: Set up Python 3.12
2320
uses: actions/setup-python@v5
2421
with:
25-
python-version: 3.11
22+
python-version: 3.12
2623

2724
- name: Install dependencies
2825
run: |
@@ -33,6 +30,14 @@ jobs:
3330
run: |
3431
tox
3532
33+
- name: Build Project and Publish
34+
run: |
35+
python -m tox -e clean,build
36+
37+
# This uses the trusted publisher workflow so no token is required.
38+
- name: Publish to PyPI
39+
uses: pypa/gh-action-pypi-publish@release/v1
40+
3641
- name: Build docs
3742
run: |
3843
tox -e docs
@@ -45,11 +50,3 @@ jobs:
4550
branch: gh-pages # The branch the action should deploy to.
4651
folder: ./docs/_build/html
4752
clean: true # Automatically remove deleted files from the deploy branch
48-
49-
- name: Build Project and Publish
50-
run: |
51-
python -m tox -e clean,build
52-
53-
# This uses the trusted publisher workflow so no token is required.
54-
- name: Publish to PyPI
55-
uses: pypa/gh-action-pypi-publish@release/v1

.github/workflows/run-tests.yml

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,73 @@
1-
name: Run tests
1+
name: Test the library
22

33
on:
44
push:
5-
branches: [master]
5+
branches:
6+
- master # for legacy repos
7+
- main
68
pull_request:
9+
branches:
10+
- master # for legacy repos
11+
- main
12+
workflow_dispatch: # Allow manually triggering the workflow
13+
schedule:
14+
# Run roughly every 15 days at 00:00 UTC
15+
# (useful to check if updates on dependencies break the package)
16+
- cron: "0 0 1,16 * *"
17+
18+
permissions:
19+
contents: read
20+
21+
concurrency:
22+
group: >-
23+
${{ github.workflow }}-${{ github.ref_type }}-
24+
${{ github.event.pull_request.number || github.sha }}
25+
cancel-in-progress: true
726

827
jobs:
9-
build:
10-
runs-on: ubuntu-latest
28+
test:
1129
strategy:
1230
matrix:
13-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
14-
15-
name: Python ${{ matrix.python-version }}
31+
python: ["3.10", "3.11", "3.12", "3.13", "3.14"]
32+
platform:
33+
- ubuntu-latest
34+
- macos-latest
35+
# - windows-latest
36+
runs-on: ${{ matrix.platform }}
37+
name: Python ${{ matrix.python }}, ${{ matrix.platform }}
1638
steps:
1739
- uses: actions/checkout@v4
1840

19-
- name: Setup Python
20-
uses: actions/setup-python@v5
41+
- uses: actions/setup-python@v5
42+
id: setup-python
2143
with:
22-
python-version: ${{ matrix.python-version }}
23-
cache: "pip"
44+
python-version: ${{ matrix.python }}
2445

2546
- name: Install dependencies
2647
run: |
2748
python -m pip install --upgrade pip
28-
pip install tox
49+
pip install tox coverage
2950
30-
- name: Test with tox
31-
run: |
51+
- name: Run tests
52+
run: >-
53+
pipx run --python '${{ steps.setup-python.outputs.python-path }}'
3254
tox
55+
-- -rFEx --durations 10 --color yes --cov --cov-branch --cov-report=xml # pytest args
56+
57+
- name: Check for codecov token availability
58+
id: codecov-check
59+
shell: bash
60+
run: |
61+
if [ ${{ secrets.CODECOV_TOKEN }} != '' ]; then
62+
echo "codecov=true" >> $GITHUB_OUTPUT;
63+
else
64+
echo "codecov=false" >> $GITHUB_OUTPUT;
65+
fi
66+
67+
- name: Upload coverage reports to Codecov with GitHub Action
68+
uses: codecov/codecov-action@v5
69+
if: ${{ steps.codecov-check.outputs.codecov == 'true' }}
70+
env:
71+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
72+
slug: ${{ github.repository }}
73+
flags: ${{ matrix.platform }} - py${{ matrix.python }}

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## Version 0.6.0
4+
5+
- Changed related to SummarizedExperiment and implementation of `CompressedGenomicRangesList` in the genomic ranges package.
6+
- Update versions of relevant dependency packages.
7+
38
## Version 0.5.8 - 0.5.9
49

510
- Rename `reduced_dims` to `reduced_dimensions`. Constructor accepts both these arguments for backwards compatibility.

setup.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ python_requires = >=3.9
4949
# For more information, check out https://semver.org/.
5050
install_requires =
5151
importlib-metadata; python_version<"3.8"
52-
summarizedexperiment>=0.5.3
52+
summarizedexperiment>=0.6.3
53+
compressed-lists>=0.4.3
5354

5455
[options.packages.find]
5556
where = src

src/singlecellexperiment/SingleCellExperiment.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from collections import OrderedDict
24
from typing import Any, Dict, List, Optional, Sequence, Union
35
from warnings import warn
@@ -105,15 +107,15 @@ def __init__(
105107
column_data: Optional[biocframe.BiocFrame] = None,
106108
row_names: Optional[List[str]] = None,
107109
column_names: Optional[List[str]] = None,
108-
metadata: Optional[dict] = None,
110+
metadata: Optional[Union[Dict[str, Any], ut.NamedList]] = None,
109111
reduced_dimensions: Optional[Dict[str, Any]] = None,
110112
reduced_dims: Optional[Dict[str, Any]] = None, # deprecated name
111113
main_experiment_name: Optional[str] = None,
112114
alternative_experiments: Optional[Dict[str, Any]] = None,
113115
row_pairs: Optional[Any] = None,
114116
column_pairs: Optional[Any] = None,
115117
alternative_experiment_check_dim_names: bool = True,
116-
validate: bool = True,
118+
_validate: bool = True,
117119
**kwargs,
118120
) -> None:
119121
"""Initialize a single-cell experiment.
@@ -198,7 +200,7 @@ def __init__(
198200
199201
Defaults to None.
200202
201-
validate:
203+
_validate:
202204
Internal use only.
203205
204206
kwargs:
@@ -213,7 +215,7 @@ def __init__(
213215
row_names=row_names,
214216
column_names=column_names,
215217
metadata=metadata,
216-
validate=validate,
218+
_validate=_validate,
217219
**kwargs,
218220
)
219221
self._main_experiment_name = main_experiment_name
@@ -234,7 +236,7 @@ def __init__(
234236
self._row_pairs = row_pairs if row_pairs is not None else {}
235237
self._column_pairs = column_pairs if column_pairs is not None else {}
236238

237-
if validate:
239+
if _validate:
238240
_validate_reduced_dims(self._reduced_dims, self._shape)
239241
_validate_alternative_experiments(
240242
self._alternative_experiments,
@@ -283,6 +285,7 @@ def __deepcopy__(self, memo=None, _nil=[]):
283285
alternative_experiments=_alt_expt_copy,
284286
row_pairs=_row_pair_copy,
285287
column_pairs=_col_pair_copy,
288+
_validate=False,
286289
)
287290

288291
def __copy__(self):
@@ -304,6 +307,7 @@ def __copy__(self):
304307
alternative_experiments=self._alternative_experiments,
305308
row_pairs=self._row_pairs,
306309
column_pairs=self._column_pairs,
310+
_validate=False,
307311
)
308312

309313
def copy(self):
@@ -403,7 +407,7 @@ def get_reduced_dims(self) -> Dict[str, Any]:
403407
"""Alias for :py:meth:`~get_reduced_dimensions`, for back-compatibility."""
404408
return self.get_reduced_dimensions()
405409

406-
def set_reduced_dimensions(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
410+
def set_reduced_dimensions(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> SingleCellExperiment:
407411
"""Set new reduced dimensions.
408412
409413
Args:
@@ -423,7 +427,7 @@ def set_reduced_dimensions(self, reduced_dims: Dict[str, Any], in_place: bool =
423427
output._reduced_dims = reduced_dims
424428
return output
425429

426-
def set_reduced_dims(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
430+
def set_reduced_dims(self, reduced_dims: Dict[str, Any], in_place: bool = False) -> SingleCellExperiment:
427431
"""Alias for :py:meth:`~set_reduced_dimensions`, for back-compatibility."""
428432
return self.set_reduced_dimensions(reduced_dims=reduced_dims, in_place=in_place)
429433

@@ -471,7 +475,7 @@ def get_reduced_dim_names(self) -> Dict[str, Any]:
471475
"""Alias for :py:meth:`~get_reduced_dimension_names`, for back-compatibility."""
472476
return self.get_reduced_dimension_names()
473477

474-
def set_reduced_dimension_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
478+
def set_reduced_dimension_names(self, names: List[str], in_place: bool = False) -> SingleCellExperiment:
475479
"""Replace :py:attr:`~.reduced_dims`'s names.
476480
477481
Args:
@@ -497,7 +501,7 @@ def set_reduced_dimension_names(self, names: List[str], in_place: bool = False)
497501
output._reduced_dims = new_reduced_dims
498502
return output
499503

500-
def set_reduced_dim_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
504+
def set_reduced_dim_names(self, names: List[str], in_place: bool = False) -> SingleCellExperiment:
501505
"""Alias for :py:meth:`~set_reduced_dimension_names`, for back-compatibility."""
502506
return self.set_reduced_dimension_names(names=names, in_place=in_place)
503507

@@ -573,7 +577,7 @@ def reduced_dimension(self, name: Union[str, int]) -> Any:
573577
"""Alias for :py:meth:`~get_reduced_dimension`, for back-compatibility."""
574578
return self.get_reduced_dimension(name=name)
575579

576-
def set_reduced_dimension(self, name: str, embedding: Any, in_place: bool = False) -> "SingleCellExperiment":
580+
def set_reduced_dimension(self, name: str, embedding: Any, in_place: bool = False) -> SingleCellExperiment:
577581
"""Add or replace :py:attr:`~singlecellexperiment.SingleCellExperiment.reduced_dimension`'s.
578582
579583
Args:
@@ -613,7 +617,7 @@ def get_main_experiment_name(self) -> Optional[str]:
613617
"""
614618
return self._main_experiment_name
615619

616-
def set_main_experiment_name(self, name: Optional[str], in_place: bool = False) -> "SingleCellExperiment":
620+
def set_main_experiment_name(self, name: Optional[str], in_place: bool = False) -> SingleCellExperiment:
617621
"""Set new experiment data (assays).
618622
619623
Args:
@@ -671,7 +675,7 @@ def get_alternative_experiments(self, with_dim_names: bool = True) -> Dict[str,
671675

672676
def set_alternative_experiments(
673677
self, alternative_experiments: Dict[str, Any], with_dim_names: bool = True, in_place: bool = False
674-
) -> "SingleCellExperiment":
678+
) -> SingleCellExperiment:
675679
"""Set new alternative experiments.
676680
677681
Args:
@@ -725,7 +729,7 @@ def get_alternative_experiment_names(self) -> List[str]:
725729
"""
726730
return list(self._alternative_experiments.keys())
727731

728-
def set_alternative_experiment_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
732+
def set_alternative_experiment_names(self, names: List[str], in_place: bool = False) -> SingleCellExperiment:
729733
"""Replace :py:attr:`~.alternative_experiment`'s names.
730734
731735
Args:
@@ -821,7 +825,7 @@ def alternative_experiment(self, name: Union[str, int]) -> Any:
821825

822826
def set_alternative_experiment(
823827
self, name: str, alternative_experiment: Any, with_dim_names: bool = True, in_place: bool = False
824-
) -> "SingleCellExperiment":
828+
) -> SingleCellExperiment:
825829
"""Add or replace :py:attr:`~singlecellexperiment.SingleCellExperiment.alternative_experiment`'s.
826830
827831
Args:
@@ -872,7 +876,7 @@ def get_row_pairs(self) -> Dict[str, Any]:
872876
"""
873877
return self._row_pairs
874878

875-
def set_row_pairs(self, pairs: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
879+
def set_row_pairs(self, pairs: Dict[str, Any], in_place: bool = False) -> SingleCellExperiment:
876880
"""Replace :py:attr:`~.row_pairs`'s names.
877881
878882
Args:
@@ -918,7 +922,7 @@ def get_row_pair_names(self) -> List[str]:
918922
"""
919923
return list(self._row_pairs.keys())
920924

921-
def set_row_pair_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
925+
def set_row_pair_names(self, names: List[str], in_place: bool = False) -> SingleCellExperiment:
922926
"""Replace :py:attr:`~.row_pair`'s names.
923927
924928
Args:
@@ -970,7 +974,7 @@ def get_column_pairs(self) -> Dict[str, Any]:
970974
"""
971975
return self._column_pairs
972976

973-
def set_column_pairs(self, pairs: Dict[str, Any], in_place: bool = False) -> "SingleCellExperiment":
977+
def set_column_pairs(self, pairs: Dict[str, Any], in_place: bool = False) -> SingleCellExperiment:
974978
"""Replace :py:attr:`~.column_pairs`'s names.
975979
976980
Args:
@@ -1016,7 +1020,7 @@ def get_column_pair_names(self) -> List[str]:
10161020
"""
10171021
return list(self._column_pairs.keys())
10181022

1019-
def set_column_pair_names(self, names: List[str], in_place: bool = False) -> "SingleCellExperiment":
1023+
def set_column_pair_names(self, names: List[str], in_place: bool = False) -> SingleCellExperiment:
10201024
"""Replace :py:attr:`~.column_pair`'s names.
10211025
10221026
Args:
@@ -1066,7 +1070,7 @@ def get_slice(
10661070
self,
10671071
rows: Optional[Union[str, int, bool, Sequence]],
10681072
columns: Optional[Union[str, int, bool, Sequence]],
1069-
) -> "SingleCellExperiment":
1073+
) -> SingleCellExperiment:
10701074
"""Alias for :py:attr:`~__getitem__`."""
10711075

10721076
slicer = self._generic_slice(rows=rows, columns=columns)
@@ -1183,7 +1187,7 @@ def to_anndata(self, include_alternative_experiments: bool = False):
11831187
return obj, adatas
11841188

11851189
@classmethod
1186-
def from_anndata(cls, input: "anndata.AnnData") -> "SingleCellExperiment":
1190+
def from_anndata(cls, input: "anndata.AnnData") -> SingleCellExperiment:
11871191
"""Create a ``SingleCellExperiment`` from :py:class:`~anndata.AnnData`.
11881192
11891193
Args:
@@ -1253,19 +1257,19 @@ def to_mudata(self):
12531257
######>> combine ops <<#####
12541258
############################
12551259

1256-
def relaxed_combine_rows(self, *other) -> "SingleCellExperiment":
1260+
def relaxed_combine_rows(self, *other) -> SingleCellExperiment:
12571261
"""Wrapper around :py:func:`~relaxed_combine_rows`."""
12581262
return relaxed_combine_rows(self, *other)
12591263

1260-
def relaxed_combine_columns(self, *other) -> "SingleCellExperiment":
1264+
def relaxed_combine_columns(self, *other) -> SingleCellExperiment:
12611265
"""Wrapper around :py:func:`~relaxed_combine_columns`."""
12621266
return relaxed_combine_columns(self, *other)
12631267

1264-
def combine_rows(self, *other) -> "SingleCellExperiment":
1268+
def combine_rows(self, *other) -> SingleCellExperiment:
12651269
"""Wrapper around :py:func:`~combine_rows`."""
12661270
return combine_rows(self, *other)
12671271

1268-
def combine_columns(self, *other) -> "SingleCellExperiment":
1272+
def combine_columns(self, *other) -> SingleCellExperiment:
12691273
"""Wrapper around :py:func:`~combine_columns`."""
12701274
return combine_columns(self, *other)
12711275

0 commit comments

Comments
 (0)