Skip to content

Commit 010de2d

Browse files
committed
Drop Python 3.9 support
1 parent 6708eb1 commit 010de2d

File tree

9 files changed

+71
-91
lines changed

9 files changed

+71
-91
lines changed

.github/workflows/cd.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- uses: actions/checkout@v4
2020
- uses: actions/setup-python@v5
2121
with:
22-
python-version: '3.9'
22+
python-version: '3.10'
2323
- name: Install dependencies
2424
run: |
2525
python -m pip install --upgrade pip

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
# Use macos-13 because pip binary packages for ARM aren't
2626
# available for many dependencies
2727
os: [macos-13, macos-14, ubuntu-latest]
28-
python-version: ["3.9", "3.10", "3.11", "3.12"]
28+
python-version: ["3.10", "3.11", "3.12"]
2929
exclude:
3030
# Just run macos tests on one Python version
3131
- os: macos-13
@@ -34,8 +34,6 @@ jobs:
3434
python-version: "3.11"
3535
- os: macos-13
3636
python-version: "3.12"
37-
- os: macos-14
38-
python-version: "3.9"
3937
- os: macos-14
4038
python-version: "3.10"
4139
- os: macos-14

bio2zarr/core.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
import multiprocessing
88
import os
99
import os.path
10-
import sys
1110
import threading
1211
import time
13-
import warnings
1412

1513
import humanfriendly
1614
import numcodecs
@@ -256,22 +254,6 @@ def setup_progress_counter(counter):
256254
_progress_counter = counter
257255

258256

259-
def warn_py39_mac():
260-
if sys.platform == "darwin" and sys.version_info[:2] == (3, 9):
261-
warnings.warn(
262-
"There is a known issue with bio2zarr on MacOS Python 3.9 "
263-
"in which OS-level named semaphores are leaked. "
264-
"You will also probably see warnings like 'There appear to be N "
265-
"leaked semaphore objects at shutdown'. "
266-
"While this is likely harmless for a few runs, it could lead to "
267-
"issues if you do a lot of conversion. To get prevent this issue "
268-
"either: (1) use --worker-processes=0 or (2) upgrade to a newer "
269-
"Python version. See https://github.com/sgkit-dev/bio2zarr/issues/209 "
270-
"for more details.",
271-
stacklevel=2,
272-
)
273-
274-
275257
class ParallelWorkManager(contextlib.AbstractContextManager):
276258
def __init__(self, worker_processes=1, progress_config=None):
277259
# Need to specify this explicitly to suppport Macs and
@@ -284,7 +266,6 @@ def __init__(self, worker_processes=1, progress_config=None):
284266
# production. See note on the SynchronousExecutor class.
285267
self.executor = SynchronousExecutor()
286268
else:
287-
warn_py39_mac()
288269
self.executor = cf.ProcessPoolExecutor(
289270
max_workers=worker_processes,
290271
mp_context=ctx,

bio2zarr/plink.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def iter_alleles_and_genotypes(self, start, stop, shape, num_alleles):
5151
gt = np.zeros(shape, dtype=np.int8)
5252
phased = np.zeros(shape[:-1], dtype=bool)
5353
for i, (ref, alt) in enumerate(
54-
zip(ref_field[start:stop], alt_field[start:stop])
54+
zip(ref_field[start:stop], alt_field[start:stop], strict=False)
5555
):
5656
alleles = np.full(num_alleles, constants.STR_FILL, dtype="O")
5757
alleles[0] = ref
@@ -189,11 +189,11 @@ def validate(bed_path, zarr_path):
189189
assert call_genotype.shape[2] == 2
190190

191191
row_id = 0
192-
for bed_row, zarr_row in zip(bed_genotypes, call_genotype):
192+
for bed_row, zarr_row in zip(bed_genotypes, call_genotype, strict=False):
193193
# print("ROW", row_id)
194194
# print(bed_row, zarr_row)
195195
row_id += 1
196-
for bed_call, zarr_call in zip(bed_row, zarr_row):
196+
for bed_call, zarr_call in zip(bed_row, zarr_row, strict=False):
197197
if bed_call == -127:
198198
assert list(zarr_call) == [-1, -1]
199199
elif bed_call == 0:

bio2zarr/vcf.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def scan_vcf(path, target_num_partitions):
258258
samples=[vcz.Sample(sample_id) for sample_id in vcf.samples],
259259
contigs=[
260260
vcz.Contig(contig_id, length)
261-
for contig_id, length in zip(vcf.seqnames, contig_lengths)
261+
for contig_id, length in zip(vcf.seqnames, contig_lengths, strict=False)
262262
],
263263
filters=filters,
264264
fields=fields,
@@ -638,7 +638,9 @@ def chunks(self, partition_id, start_chunk=0):
638638
chunk_cumulative_records = self.chunk_record_index(partition_id)
639639
chunk_num_records = np.diff(chunk_cumulative_records)
640640
for count, cumulative in zip(
641-
chunk_num_records[start_chunk:], chunk_cumulative_records[start_chunk + 1 :]
641+
chunk_num_records[start_chunk:],
642+
chunk_cumulative_records[start_chunk + 1 :],
643+
strict=False,
642644
):
643645
path = partition_path / f"{cumulative}"
644646
chunk = self.read_chunk(path)
@@ -1023,6 +1025,7 @@ def iter_alleles(self, start, stop, num_alleles):
10231025
for ref, alt in zip(
10241026
ref_field.iter_values(start, stop),
10251027
alt_field.iter_values(start, stop),
1028+
strict=False,
10261029
):
10271030
alleles = np.full(num_alleles, constants.STR_FILL, dtype="O")
10281031
alleles[0] = ref[0]
@@ -1046,6 +1049,7 @@ def iter_alleles_and_genotypes(self, start, stop, shape, num_alleles):
10461049
yield from zip(
10471050
self.iter_alleles(start, stop, num_alleles),
10481051
self.iter_genotypes(shape, start, stop),
1052+
strict=False,
10491053
)
10501054

10511055
def generate_schema(

bio2zarr/vcf_utils.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from collections.abc import Sequence
88
from dataclasses import dataclass
99
from enum import Enum
10-
from typing import IO, Any, Optional, Union
10+
from typing import IO, Any
1111

1212
import cyvcf2
1313
import humanfriendly
@@ -33,7 +33,7 @@ def get_file_offset(vfp: int) -> int:
3333
return vfp >> 16 & address_mask
3434

3535

36-
def read_bytes_as_value(f: IO[Any], fmt: str, nodata: Optional[Any] = None) -> Any:
36+
def read_bytes_as_value(f: IO[Any], fmt: str, nodata: Any | None = None) -> Any:
3737
"""Read bytes using a `struct` format string and return the unpacked data value.
3838
3939
Parameters
@@ -85,8 +85,8 @@ class Region:
8585
"""
8686

8787
contig: str
88-
start: Optional[int] = None
89-
end: Optional[int] = None
88+
start: int | None = None
89+
end: int | None = None
9090

9191
def __post_init__(self):
9292
assert self.contig is not None
@@ -197,9 +197,7 @@ def get_first_locus_in_bin(csi: CSIIndex, bin: int) -> int:
197197
return (bin - first_bin_on_level) * (max_span // level_size) + 1
198198

199199

200-
def read_csi(
201-
file: PathType, storage_options: Optional[dict[str, str]] = None
202-
) -> CSIIndex:
200+
def read_csi(file: PathType, storage_options: dict[str, str] | None = None) -> CSIIndex:
203201
"""Parse a CSI file into a `CSIIndex` object.
204202
205203
Parameters
@@ -314,7 +312,7 @@ def offsets(self) -> Any:
314312

315313

316314
def read_tabix(
317-
file: PathType, storage_options: Optional[dict[str, str]] = None
315+
file: PathType, storage_options: dict[str, str] | None = None
318316
) -> TabixIndex:
319317
"""Parse a tabix file into a `TabixIndex` object.
320318
@@ -472,7 +470,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
472470
def contig_record_counts(self):
473471
if self.index is None:
474472
return {self.sequence_names[0]: RECORD_COUNT_UNKNOWN}
475-
d = dict(zip(self.sequence_names, self.index.record_counts))
473+
d = dict(zip(self.sequence_names, self.index.record_counts, strict=False))
476474
if self.file_type == VcfFileType.BCF:
477475
d = {k: v for k, v in d.items() if v > 0}
478476
return d
@@ -512,8 +510,8 @@ def _filter_empty_and_refine(self, regions):
512510

513511
def partition_into_regions(
514512
self,
515-
num_parts: Optional[int] = None,
516-
target_part_size: Union[None, int, str] = None,
513+
num_parts: int | None = None,
514+
target_part_size: None | int | str = None,
517515
):
518516
if num_parts is None and target_part_size is None:
519517
raise ValueError("One of num_parts or target_part_size must be specified")

bio2zarr/vcz_verification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def assert_format_val_equal(vcf_val, zarr_val, vcf_type, vcf_number):
116116
assert isinstance(vcf_val, np.ndarray)
117117
if vcf_type in ("String", "Character"):
118118
assert len(vcf_val) == len(zarr_val)
119-
for v, z in zip(vcf_val, zarr_val):
119+
for v, z in zip(vcf_val, zarr_val, strict=False):
120120
if vcf_number == "1":
121121
assert v == z
122122
else:

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ dependencies = [
2626
"cyvcf2",
2727
"bed_reader",
2828
]
29-
requires-python = ">=3.9"
29+
requires-python = ">=3.10"
3030
classifiers = [
3131
"Development Status :: 4 - Beta",
3232
"License :: OSI Approved :: Apache Software License",
@@ -37,7 +37,6 @@ classifiers = [
3737
"Intended Audience :: Science/Research",
3838
"Programming Language :: Python",
3939
"Programming Language :: Python :: 3",
40-
"Programming Language :: Python :: 3.9",
4140
"Programming Language :: Python :: 3.10",
4241
"Programming Language :: Python :: 3.11",
4342
"Programming Language :: Python :: 3.12",
@@ -76,8 +75,8 @@ testpaths = "tests"
7675
addopts = "--cov=bio2zarr --cov-report term-missing"
7776

7877
[tool.ruff]
79-
# Assume Python 3.9
80-
target-version = "py39"
78+
# Assume Python 3.10
79+
target-version = "py310"
8180

8281
# Same as Black.
8382
line-length = 88

0 commit comments

Comments
 (0)