Skip to content

Commit c7850fc

Browse files
authored
Merge pull request #287 from tomwhite/drop-python-3.9
Drop Python 3.9
2 parents 013687f + 7db7586 commit c7850fc

File tree

10 files changed

+23
-45
lines changed

10 files changed

+23
-45
lines changed

.github/workflows/cd.yml

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

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ jobs:
2424
# Use macos-13 because pip binary packages for ARM aren't
2525
# available for many dependencies
2626
os: [macos-13, macos-14, ubuntu-latest]
27-
python-version: ["3.9", "3.10", "3.11", "3.12"]
27+
python-version: ["3.10", "3.11", "3.12"]
2828
exclude:
2929
# Just run macos tests on one Python version
3030
- os: macos-13
@@ -33,8 +33,6 @@ jobs:
3333
python-version: "3.11"
3434
- os: macos-13
3535
python-version: "3.12"
36-
- os: macos-14
37-
python-version: "3.9"
3836
- os: macos-14
3937
python-version: "3.10"
4038
- 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
@@ -216,22 +214,6 @@ def setup_progress_counter(counter):
216214
_progress_counter = counter
217215

218216

219-
def warn_py39_mac():
220-
if sys.platform == "darwin" and sys.version_info[:2] == (3, 9):
221-
warnings.warn(
222-
"There is a known issue with bio2zarr on MacOS Python 3.9 "
223-
"in which OS-level named semaphores are leaked. "
224-
"You will also probably see warnings like 'There appear to be N "
225-
"leaked semaphore objects at shutdown'. "
226-
"While this is likely harmless for a few runs, it could lead to "
227-
"issues if you do a lot of conversion. To get prevent this issue "
228-
"either: (1) use --worker-processes=0 or (2) upgrade to a newer "
229-
"Python version. See https://github.com/sgkit-dev/bio2zarr/issues/209 "
230-
"for more details.",
231-
stacklevel=2,
232-
)
233-
234-
235217
class ParallelWorkManager(contextlib.AbstractContextManager):
236218
def __init__(self, worker_processes=1, progress_config=None):
237219
# Need to specify this explicitly to suppport Macs and
@@ -244,7 +226,6 @@ def __init__(self, worker_processes=1, progress_config=None):
244226
# production. See note on the SynchronousExecutor class.
245227
self.executor = SynchronousExecutor()
246228
else:
247-
warn_py39_mac()
248229
self.executor = cf.ProcessPoolExecutor(
249230
max_workers=worker_processes,
250231
mp_context=ctx,

bio2zarr/plink.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ def validate(bed_path, zarr_path):
185185
assert call_genotype.shape[2] == 2
186186

187187
row_id = 0
188-
for bed_row, zarr_row in zip(bed_genotypes, call_genotype):
188+
for bed_row, zarr_row in zip(bed_genotypes, call_genotype, strict=True):
189189
# print("ROW", row_id)
190190
# print(bed_row, zarr_row)
191191
row_id += 1
192-
for bed_call, zarr_call in zip(bed_row, zarr_row):
192+
for bed_call, zarr_call in zip(bed_row, zarr_row, strict=True):
193193
if bed_call == -127:
194194
assert list(zarr_call) == [-1, -1]
195195
elif bed_call == 0:

bio2zarr/typing.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
from pathlib import Path
2-
from typing import Union
32

4-
PathType = Union[str, Path]
3+
PathType = str | Path

bio2zarr/vcf2zarr/icf.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def scan_vcf(path, target_num_partitions, *, local_alleles):
289289
samples=[Sample(sample_id) for sample_id in vcf.samples],
290290
contigs=[
291291
Contig(contig_id, length)
292-
for contig_id, length in zip(vcf.seqnames, contig_lengths)
292+
for contig_id, length in zip(vcf.seqnames, contig_lengths, strict=True)
293293
],
294294
filters=filters,
295295
fields=fields,
@@ -764,7 +764,9 @@ def chunks(self, partition_id, start_chunk=0):
764764
chunk_cumulative_records = self.chunk_record_index(partition_id)
765765
chunk_num_records = np.diff(chunk_cumulative_records)
766766
for count, cumulative in zip(
767-
chunk_num_records[start_chunk:], chunk_cumulative_records[start_chunk + 1 :]
767+
chunk_num_records[start_chunk:],
768+
chunk_cumulative_records[start_chunk + 1 :],
769+
strict=True,
768770
):
769771
path = partition_path / f"{cumulative}"
770772
chunk = self.read_chunk(path)

bio2zarr/vcf2zarr/vcz.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ def encode_alleles_partition(self, partition_index):
760760
for ref, alt in zip(
761761
ref_field.iter_values(partition.start, partition.stop),
762762
alt_field.iter_values(partition.start, partition.stop),
763+
strict=True,
763764
):
764765
j = alleles.next_buffer_row()
765766
alleles.buff[j, :] = constants.STR_FILL

bio2zarr/vcf2zarr/verification.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def assert_format_val_equal(vcf_val, zarr_val, vcf_type, vcf_number):
114114
assert isinstance(vcf_val, np.ndarray)
115115
if vcf_type in ("String", "Character"):
116116
assert len(vcf_val) == len(zarr_val)
117-
for v, z in zip(vcf_val, zarr_val):
117+
for v, z in zip(vcf_val, zarr_val, strict=True):
118118
if vcf_number == "1":
119119
assert v == z
120120
else:

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
if self.start is not None:
@@ -194,9 +194,7 @@ def get_first_locus_in_bin(csi: CSIIndex, bin: int) -> int:
194194
return (bin - first_bin_on_level) * (max_span // level_size) + 1
195195

196196

197-
def read_csi(
198-
file: PathType, storage_options: Optional[dict[str, str]] = None
199-
) -> CSIIndex:
197+
def read_csi(file: PathType, storage_options: dict[str, str] | None = None) -> CSIIndex:
200198
"""Parse a CSI file into a `CSIIndex` object.
201199
202200
Parameters
@@ -311,7 +309,7 @@ def offsets(self) -> Any:
311309

312310

313311
def read_tabix(
314-
file: PathType, storage_options: Optional[dict[str, str]] = None
312+
file: PathType, storage_options: dict[str, str] | None = None
315313
) -> TabixIndex:
316314
"""Parse a tabix file into a `TabixIndex` object.
317315
@@ -452,7 +450,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
452450
return False
453451

454452
def contig_record_counts(self):
455-
d = dict(zip(self.sequence_names, self.index.record_counts))
453+
d = dict(zip(self.sequence_names, self.index.record_counts, strict=True))
456454
if self.file_type == VcfFileType.BCF:
457455
d = {k: v for k, v in d.items() if v > 0}
458456
return d
@@ -483,8 +481,8 @@ def _filter_empty_and_refine(self, regions):
483481

484482
def partition_into_regions(
485483
self,
486-
num_parts: Optional[int] = None,
487-
target_part_size: Union[None, int, str] = None,
484+
num_parts: int | None = None,
485+
target_part_size: None | int | str = None,
488486
):
489487
if num_parts is None and target_part_size is None:
490488
raise ValueError("One of num_parts or target_part_size must be specified")

pyproject.toml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ dependencies = [
2424
"cyvcf2",
2525
"bed_reader",
2626
]
27-
requires-python = ">=3.9"
27+
requires-python = ">=3.10"
2828
classifiers = [
2929
"Development Status :: 4 - Beta",
3030
"License :: OSI Approved :: Apache Software License",
@@ -35,7 +35,6 @@ classifiers = [
3535
"Intended Audience :: Science/Research",
3636
"Programming Language :: Python",
3737
"Programming Language :: Python :: 3",
38-
"Programming Language :: Python :: 3.9",
3938
"Programming Language :: Python :: 3.10",
4039
"Programming Language :: Python :: 3.11",
4140
"Programming Language :: Python :: 3.12",
@@ -74,8 +73,8 @@ testpaths = "tests"
7473
addopts = "--cov=bio2zarr --cov-report term-missing"
7574

7675
[tool.ruff]
77-
# Assume Python 3.9
78-
target-version = "py39"
76+
# Assume Python 3.10
77+
target-version = "py310"
7978

8079
# Same as Black.
8180
line-length = 88

0 commit comments

Comments
 (0)