Skip to content

Commit 6504819

Browse files
Merge pull request #233 from jeromekelleher/add-warning
Add warning on Python 39 for macs
2 parents d1d3f9e + 4bcf2bb commit 6504819

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

bio2zarr/core.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import multiprocessing
88
import os
99
import os.path
10+
import sys
1011
import threading
1112
import time
13+
import warnings
1214

1315
import humanfriendly
1416
import numcodecs
@@ -87,6 +89,11 @@ def du(path):
8789

8890

8991
class SynchronousExecutor(cf.Executor):
92+
# Arguably we should use workers=0 as the default and use this
93+
# executor implementation. However, the docs are fairly explicit
94+
# about saying we shouldn't instantiate Future objects directly,
95+
# so it's best to keep this as a semi-secret debugging interface
96+
# for now.
9097
def submit(self, fn, /, *args, **kwargs):
9198
future = cf.Future()
9299
future.set_result(fn(*args, **kwargs))
@@ -215,6 +222,22 @@ def setup_progress_counter(counter):
215222
_progress_counter = counter
216223

217224

225+
def warn_py39_mac():
226+
if sys.platform == "darwin" and sys.version_info[:2] == (3, 9):
227+
warnings.warn(
228+
"There is a known issue with bio2zarr on MacOS Python 3.9 "
229+
"in which OS-level named semaphores are leaked. "
230+
"You will also probably see warnings like 'There appear to be N "
231+
"leaked semaphore objects at shutdown'. "
232+
"While this is likely harmless for a few runs, it could lead to "
233+
"issues if you do a lot of conversion. To get prevent this issue "
234+
"either: (1) use --worker-processes=0 or (2) upgrade to a newer "
235+
"Python version. See https://github.com/sgkit-dev/bio2zarr/issues/209 "
236+
"for more details.",
237+
stacklevel=2,
238+
)
239+
240+
218241
class ParallelWorkManager(contextlib.AbstractContextManager):
219242
def __init__(self, worker_processes=1, progress_config=None):
220243
# Need to specify this explicitly to suppport Macs and
@@ -223,9 +246,11 @@ def __init__(self, worker_processes=1, progress_config=None):
223246
global _progress_counter
224247
_progress_counter = ctx.Value("Q", 0)
225248
if worker_processes <= 0:
226-
# NOTE: this is only for testing, not for production use!
249+
# NOTE: this is only for testing and debugging, not for
250+
# production. See note on the SynchronousExecutor class.
227251
self.executor = SynchronousExecutor()
228252
else:
253+
warn_py39_mac()
229254
self.executor = cf.ProcessPoolExecutor(
230255
max_workers=worker_processes,
231256
mp_context=ctx,

tests/test_core.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ def test_error_in_workers_on_exit(self, total, workers):
104104
# Raises a TypeError:
105105
pwm.submit(frozenset, j)
106106

107+
@pytest.mark.parametrize("workers", [0, 1, 2])
108+
def test_warn_mac_os(self, recwarn, workers):
109+
with core.ParallelWorkManager(workers):
110+
pass
111+
if workers > 0 and sys.platform == "darwin" and sys.version_info[:2] == (3, 9):
112+
assert len(recwarn) >= 1
113+
w = recwarn.pop(UserWarning)
114+
assert str(w.message).startswith("There is a known issue")
115+
else:
116+
assert len(recwarn) == 0
117+
107118

108119
class TestChunkAlignedSlices:
109120
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)