pymmcore-plus 0.11.0__tar.gz → 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/PKG-INFO +5 -6
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/pyproject.toml +6 -7
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/_build.py +4 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/_cli.py +7 -7
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/_logger.py +4 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/_util.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_config.py +5 -3
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_config_group.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_metadata.py +2 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_mmcore_plus.py +4 -6
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_property.py +3 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_sequencing.py +8 -6
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/__init__.py +3 -3
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_device_signal_view.py +8 -6
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_norm_slot.py +2 -4
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_prop_event_mixin.py +7 -4
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_protocol.py +5 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/install.py +4 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/_engine.py +5 -7
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/_protocol.py +1 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/_runner.py +29 -21
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/_thread_relay.py +5 -3
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_5d_writer_base.py +3 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_img_sequence_writer.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_ome_zarr_writer.py +6 -6
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_tensorstore_handler.py +3 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_util.py +1 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/metadata/functions.py +2 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/metadata/schema.py +23 -23
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/metadata/serialize.py +5 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_config_file.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_config_group.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_core_device.py +3 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_core_link.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_device.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_microscope.py +4 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_pixel_size_config.py +3 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/_property.py +2 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/conftest.py +3 -1
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/io/test_image_sequence_writer.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/io/test_ome_tiff.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/io/test_zarr_writers.py +9 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_bench.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_cli.py +4 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_config_group_class.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_core.py +3 -2
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_device_class.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_events.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_mda.py +23 -4
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_metadata.py +5 -4
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_misc.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_model.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_property_class.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_sequencing.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_thread_relay.py +1 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/.gitignore +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/LICENSE +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/README.md +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_adapter.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_constants.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/_device.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_psygnal.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_qsignals.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/events/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/events/_protocol.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/events/_psygnal.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/events/_qsignals.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/mda/handlers/_ome_tiff_writer.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/metadata/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/model/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/py.typed +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/seq_tester.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/__init__.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/local_config.cfg +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_adapter_class.py +0 -0
- {pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/tests/test_pixel_config_class.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pymmcore-plus
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: pymmcore superset providing improved APIs, event handling, and a pure python acquisition engine
|
|
5
5
|
Project-URL: Source, https://github.com/pymmcore-plus/pymmcore-plus
|
|
6
6
|
Project-URL: Tracker, https://github.com/pymmcore-plus/pymmcore-plus/issues
|
|
@@ -16,7 +16,6 @@ Classifier: License :: OSI Approved :: BSD License
|
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
17
|
Classifier: Programming Language :: Python
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -24,7 +23,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
24
23
|
Classifier: Topic :: System :: Hardware
|
|
25
24
|
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
26
25
|
Classifier: Topic :: Utilities
|
|
27
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.9
|
|
28
27
|
Requires-Dist: numpy>=1.17.3
|
|
29
28
|
Requires-Dist: platformdirs>=3.0.0
|
|
30
29
|
Requires-Dist: psygnal>=0.7
|
|
@@ -33,7 +32,7 @@ Requires-Dist: rich>=10.2.0
|
|
|
33
32
|
Requires-Dist: tensorstore
|
|
34
33
|
Requires-Dist: typer>=0.4.2
|
|
35
34
|
Requires-Dist: typing-extensions
|
|
36
|
-
Requires-Dist: useq-schema>=0.
|
|
35
|
+
Requires-Dist: useq-schema>=0.5.0
|
|
37
36
|
Requires-Dist: wrapt>=1.14
|
|
38
37
|
Provides-Extra: cli
|
|
39
38
|
Requires-Dist: rich>=10.2.0; extra == 'cli'
|
|
@@ -53,7 +52,7 @@ Requires-Dist: mkdocstrings-python==1.1.2; extra == 'docs'
|
|
|
53
52
|
Requires-Dist: mkdocstrings==0.22.0; extra == 'docs'
|
|
54
53
|
Provides-Extra: io
|
|
55
54
|
Requires-Dist: tifffile>=2021.6.14; extra == 'io'
|
|
56
|
-
Requires-Dist: zarr
|
|
55
|
+
Requires-Dist: zarr<3,>=2.2; extra == 'io'
|
|
57
56
|
Provides-Extra: test
|
|
58
57
|
Requires-Dist: msgpack; extra == 'test'
|
|
59
58
|
Requires-Dist: msgspec; extra == 'test'
|
|
@@ -65,7 +64,7 @@ Requires-Dist: rich; extra == 'test'
|
|
|
65
64
|
Requires-Dist: tifffile>=2021.6.14; extra == 'test'
|
|
66
65
|
Requires-Dist: typer>=0.4.2; extra == 'test'
|
|
67
66
|
Requires-Dist: xarray; extra == 'test'
|
|
68
|
-
Requires-Dist: zarr
|
|
67
|
+
Requires-Dist: zarr<3,>=2.2; extra == 'test'
|
|
69
68
|
Description-Content-Type: text/markdown
|
|
70
69
|
|
|
71
70
|
# pymmcore-plus
|
|
@@ -9,7 +9,7 @@ name = "pymmcore-plus"
|
|
|
9
9
|
description = "pymmcore superset providing improved APIs, event handling, and a pure python acquisition engine"
|
|
10
10
|
keywords = ["microscope", "micro-manager", "smart-microscopy"]
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
13
|
license = { text = "BSD 3-Clause License" }
|
|
14
14
|
authors = [
|
|
15
15
|
{ name = "Talley Lambert", email = "talley.lambert@gmail.com" },
|
|
@@ -24,7 +24,6 @@ classifiers = [
|
|
|
24
24
|
"Operating System :: OS Independent",
|
|
25
25
|
"Programming Language :: Python",
|
|
26
26
|
"Programming Language :: Python :: 3",
|
|
27
|
-
"Programming Language :: Python :: 3.8",
|
|
28
27
|
"Programming Language :: Python :: 3.9",
|
|
29
28
|
"Programming Language :: Python :: 3.10",
|
|
30
29
|
"Programming Language :: Python :: 3.11",
|
|
@@ -40,7 +39,7 @@ dependencies = [
|
|
|
40
39
|
"psygnal >=0.7",
|
|
41
40
|
"pymmcore >=10.7.0.71.0",
|
|
42
41
|
"typing-extensions", # not actually required at runtime
|
|
43
|
-
"useq-schema >=0.
|
|
42
|
+
"useq-schema >=0.5.0",
|
|
44
43
|
"wrapt >=1.14",
|
|
45
44
|
"tensorstore",
|
|
46
45
|
# cli requirements included by default for now
|
|
@@ -52,7 +51,7 @@ dependencies = [
|
|
|
52
51
|
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
|
|
53
52
|
[project.optional-dependencies]
|
|
54
53
|
cli = ["typer >=0.4.2", "rich >=10.2.0"]
|
|
55
|
-
io = ["tifffile >=2021.6.14", "zarr >=2.2"]
|
|
54
|
+
io = ["tifffile >=2021.6.14", "zarr >=2.2,<3"]
|
|
56
55
|
test = [
|
|
57
56
|
"msgspec",
|
|
58
57
|
"msgpack",
|
|
@@ -63,7 +62,7 @@ test = [
|
|
|
63
62
|
"rich",
|
|
64
63
|
"typer >=0.4.2",
|
|
65
64
|
"tifffile >=2021.6.14",
|
|
66
|
-
"zarr >=2.2",
|
|
65
|
+
"zarr >=2.2,<3",
|
|
67
66
|
"xarray",
|
|
68
67
|
]
|
|
69
68
|
dev = ["ipython", "mypy", "pdbpp", "pre-commit", "ruff", "tensorstore-stubs"]
|
|
@@ -72,7 +71,7 @@ docs = [
|
|
|
72
71
|
"mkdocs-material",
|
|
73
72
|
"mkdocstrings ==0.22.0",
|
|
74
73
|
"mkdocstrings-python ==1.1.2",
|
|
75
|
-
"mkdocs-typer ==0.0.3"
|
|
74
|
+
"mkdocs-typer ==0.0.3",
|
|
76
75
|
# "griffe @ git+https://github.com/tlambert03/griffe@recursion"
|
|
77
76
|
]
|
|
78
77
|
|
|
@@ -102,7 +101,7 @@ sources = ["src"]
|
|
|
102
101
|
# https://beta.ruff.rs/docs/rules/
|
|
103
102
|
[tool.ruff]
|
|
104
103
|
line-length = 88
|
|
105
|
-
target-version = "
|
|
104
|
+
target-version = "py39"
|
|
106
105
|
|
|
107
106
|
[tool.ruff.lint]
|
|
108
107
|
pydocstyle = { convention = "numpy" }
|
|
@@ -11,12 +11,15 @@ import subprocess
|
|
|
11
11
|
import tempfile
|
|
12
12
|
from contextlib import contextmanager
|
|
13
13
|
from pathlib import Path
|
|
14
|
-
from typing import
|
|
14
|
+
from typing import TYPE_CHECKING
|
|
15
15
|
from urllib.request import Request, urlopen
|
|
16
16
|
|
|
17
17
|
from rich import print
|
|
18
18
|
from rich.prompt import Prompt
|
|
19
19
|
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from collections.abc import Iterator, Sequence
|
|
22
|
+
|
|
20
23
|
MM_REPO = "micro-manager/micro-manager"
|
|
21
24
|
MMCORE_AND_DEV = "micro-manager/mmCoreAndDevices"
|
|
22
25
|
MM_REPO_URL = f"https://github.com/{MM_REPO}.git"
|
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
import time
|
|
7
7
|
from contextlib import suppress
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import Optional, Union, cast
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
12
|
import typer
|
|
@@ -31,7 +31,7 @@ def _show_version_and_exit(value: bool) -> None:
|
|
|
31
31
|
import pymmcore
|
|
32
32
|
|
|
33
33
|
typer.echo(f"pymmcore-plus v{pymmcore_plus.__version__}")
|
|
34
|
-
typer.echo(f"pymmcore v{pymmcore.__version__}")
|
|
34
|
+
typer.echo(f"pymmcore v{pymmcore.__version__}")
|
|
35
35
|
typer.echo(f"MMCore v{pymmcore.CMMCore().getAPIVersionInfo()}")
|
|
36
36
|
raise typer.Exit()
|
|
37
37
|
|
|
@@ -53,7 +53,7 @@ def _main(
|
|
|
53
53
|
# fix for windows CI encoding and emoji printing
|
|
54
54
|
if getattr(sys.stdout, "encoding", None) != "utf-8":
|
|
55
55
|
with suppress(AttributeError):
|
|
56
|
-
sys.stdout.reconfigure(encoding="utf-8") # type: ignore [attr
|
|
56
|
+
sys.stdout.reconfigure(encoding="utf-8") # type: ignore [union-attr]
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
if "mkdocs" in sys.argv[0]: # pragma: no cover
|
|
@@ -190,10 +190,10 @@ def run(
|
|
|
190
190
|
None, help="Asymmetric range of z-stack below position."
|
|
191
191
|
),
|
|
192
192
|
z_step: Optional[float] = typer.Option(None, help="Step size of z-stack."),
|
|
193
|
-
z_relative: Optional[
|
|
193
|
+
z_relative: Optional[list[float]] = typer.Option(
|
|
194
194
|
None, "-zr", help="Relative z-positions to acquire (may use multiple times)."
|
|
195
195
|
),
|
|
196
|
-
z_absolute: Optional[
|
|
196
|
+
z_absolute: Optional[list[float]] = typer.Option(
|
|
197
197
|
None, "-za", help="Absolute z-positions to acquire (may use multiple times)."
|
|
198
198
|
),
|
|
199
199
|
t_interval: Optional[float] = typer.Option(
|
|
@@ -207,7 +207,7 @@ def run(
|
|
|
207
207
|
axis_order: Optional[str] = typer.Option(
|
|
208
208
|
None, help="Order of axes to acquire (e.g. 'TPCZ')."
|
|
209
209
|
),
|
|
210
|
-
channel: Optional[
|
|
210
|
+
channel: Optional[list[str]] = typer.Option(
|
|
211
211
|
None,
|
|
212
212
|
help="\bChannel to acquire. Argument is a string of the following form:\n"
|
|
213
213
|
'\b - name: "DAPI"\n'
|
|
@@ -294,7 +294,7 @@ def run(
|
|
|
294
294
|
|
|
295
295
|
@app.command()
|
|
296
296
|
def build_dev(
|
|
297
|
-
devices: Optional[
|
|
297
|
+
devices: Optional[list[str]] = typer.Argument(
|
|
298
298
|
None, help=f"Device adapters to build. Defaults to {DEFAULT_PACKAGES}"
|
|
299
299
|
),
|
|
300
300
|
dest: Path = typer.Option(
|
|
@@ -6,7 +6,10 @@ import sys
|
|
|
6
6
|
from contextlib import contextmanager
|
|
7
7
|
from logging.handlers import RotatingFileHandler
|
|
8
8
|
from pathlib import Path
|
|
9
|
-
from typing import
|
|
9
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Iterator
|
|
10
13
|
|
|
11
14
|
__all__ = ["logger"]
|
|
12
15
|
|
|
@@ -18,8 +18,9 @@ from typing import TYPE_CHECKING, cast, overload
|
|
|
18
18
|
from platformdirs import user_data_dir
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
+
from collections.abc import Iterator
|
|
21
22
|
from re import Pattern
|
|
22
|
-
from typing import Any, Callable,
|
|
23
|
+
from typing import Any, Callable, Literal, TypeVar
|
|
23
24
|
|
|
24
25
|
QtConnectionType = Literal["AutoConnection", "DirectConnection", "QueuedConnection"]
|
|
25
26
|
|
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from collections import defaultdict
|
|
6
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from typing import TYPE_CHECKING, Any, overload
|
|
7
7
|
|
|
8
8
|
import pymmcore
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Iterable, Iterator
|
|
12
|
+
|
|
11
13
|
from typing_extensions import TypeAlias # py310
|
|
12
14
|
|
|
13
|
-
DevPropValueTuple: TypeAlias =
|
|
14
|
-
DevPropTuple: TypeAlias =
|
|
15
|
+
DevPropValueTuple: TypeAlias = tuple[str, str, str]
|
|
16
|
+
DevPropTuple: TypeAlias = tuple[str, str]
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class Configuration(pymmcore.Configuration):
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""pythonic wrapper on pymmcore.Metadata object."""
|
|
2
2
|
|
|
3
|
-
from collections.abc import Mapping
|
|
3
|
+
from collections.abc import ItemsView, Iterator, KeysView, Mapping, ValuesView
|
|
4
4
|
from types import new_class
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, cast
|
|
6
6
|
|
|
7
7
|
import pymmcore
|
|
8
8
|
|
|
@@ -10,17 +10,14 @@ from collections import defaultdict
|
|
|
10
10
|
from contextlib import contextmanager, suppress
|
|
11
11
|
from datetime import datetime
|
|
12
12
|
from pathlib import Path
|
|
13
|
+
from re import Pattern
|
|
13
14
|
from textwrap import dedent
|
|
14
15
|
from threading import RLock, Thread
|
|
15
16
|
from typing import (
|
|
16
17
|
TYPE_CHECKING,
|
|
17
18
|
Any,
|
|
18
19
|
Callable,
|
|
19
|
-
Iterable,
|
|
20
|
-
Iterator,
|
|
21
20
|
NamedTuple,
|
|
22
|
-
Pattern,
|
|
23
|
-
Sequence,
|
|
24
21
|
TypeVar,
|
|
25
22
|
overload,
|
|
26
23
|
)
|
|
@@ -51,6 +48,7 @@ from ._sequencing import can_sequence_events
|
|
|
51
48
|
from .events import CMMCoreSignaler, PCoreSignaler, _get_auto_core_callback_class
|
|
52
49
|
|
|
53
50
|
if TYPE_CHECKING:
|
|
51
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
54
52
|
from typing import Literal, TypedDict
|
|
55
53
|
|
|
56
54
|
import numpy as np
|
|
@@ -1594,7 +1592,7 @@ class CMMCorePlus(pymmcore.CMMCore):
|
|
|
1594
1592
|
|
|
1595
1593
|
try:
|
|
1596
1594
|
channel_group = self.getPropertyFromCache("Core", "ChannelGroup")
|
|
1597
|
-
channel = self.getCurrentConfigFromCache(channel_group)
|
|
1595
|
+
channel: str = self.getCurrentConfigFromCache(channel_group)
|
|
1598
1596
|
except Exception:
|
|
1599
1597
|
channel = "Default"
|
|
1600
1598
|
tags["Channel"] = channel
|
|
@@ -2010,7 +2008,7 @@ class CMMCorePlus(pymmcore.CMMCore):
|
|
|
2010
2008
|
|
|
2011
2009
|
:sparkles: *This method is new in `CMMCorePlus`.*
|
|
2012
2010
|
"""
|
|
2013
|
-
_current = {
|
|
2011
|
+
_current: dict[str, str] = {
|
|
2014
2012
|
self.getCameraDevice(): "Camera",
|
|
2015
2013
|
self.getXYStageDevice(): "XYStage",
|
|
2016
2014
|
self.getFocusDevice(): "Focus",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from functools import cached_property
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypedDict
|
|
5
5
|
|
|
6
6
|
from pymmcore import g_Keyword_Label, g_Keyword_State
|
|
7
7
|
|
|
@@ -9,6 +9,8 @@ from ._constants import DeviceType, PropertyType
|
|
|
9
9
|
from .events._device_signal_view import _DevicePropValueSignal
|
|
10
10
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Sequence
|
|
13
|
+
|
|
12
14
|
from ._mmcore_plus import CMMCorePlus
|
|
13
15
|
|
|
14
16
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from itertools import product
|
|
4
|
-
from typing import TYPE_CHECKING, Literal,
|
|
4
|
+
from typing import TYPE_CHECKING, Literal, overload
|
|
5
5
|
|
|
6
6
|
from useq import AcquireImage, MDAEvent
|
|
7
7
|
|
|
8
8
|
from pymmcore_plus.core._constants import DeviceType
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
|
|
11
13
|
from pymmcore_plus import CMMCorePlus
|
|
12
14
|
|
|
13
15
|
|
|
@@ -18,12 +20,12 @@ class SequencedEvent(MDAEvent):
|
|
|
18
20
|
calculate sequences for x, y, z, and exposure based on an a sequence of events.
|
|
19
21
|
"""
|
|
20
22
|
|
|
21
|
-
events:
|
|
23
|
+
events: tuple[MDAEvent, ...]
|
|
22
24
|
|
|
23
|
-
exposure_sequence:
|
|
24
|
-
x_sequence:
|
|
25
|
-
y_sequence:
|
|
26
|
-
z_sequence:
|
|
25
|
+
exposure_sequence: tuple[float, ...]
|
|
26
|
+
x_sequence: tuple[float, ...]
|
|
27
|
+
y_sequence: tuple[float, ...]
|
|
28
|
+
z_sequence: tuple[float, ...]
|
|
27
29
|
|
|
28
30
|
# technically this is more like a field, but it requires a core instance
|
|
29
31
|
# to getConfigData for channels, so we leave it as a method.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any
|
|
1
|
+
from typing import TYPE_CHECKING, Any
|
|
2
2
|
|
|
3
3
|
from pymmcore_plus._util import signals_backend
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ __all__ = [
|
|
|
18
18
|
]
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def _get_auto_core_callback_class() ->
|
|
21
|
+
def _get_auto_core_callback_class() -> type[PCoreSignaler]:
|
|
22
22
|
if signals_backend() == "qt":
|
|
23
23
|
from ._qsignals import QCoreSignaler
|
|
24
24
|
|
|
@@ -26,7 +26,7 @@ def _get_auto_core_callback_class() -> Type[PCoreSignaler]:
|
|
|
26
26
|
return CMMCoreSignaler
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
def __dir__() ->
|
|
29
|
+
def __dir__() -> list[str]: # pragma: no cover
|
|
30
30
|
return [*list(globals()), "QCoreSignaler"]
|
|
31
31
|
|
|
32
32
|
|
{pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_device_signal_view.py
RENAMED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any
|
|
2
4
|
|
|
3
5
|
if TYPE_CHECKING:
|
|
4
6
|
from pymmcore_plus.core import CMMCorePlus
|
|
5
7
|
|
|
6
|
-
from ._prop_event_mixin import _C
|
|
8
|
+
from ._prop_event_mixin import _C
|
|
7
9
|
|
|
8
10
|
|
|
9
11
|
class _DevicePropValueSignal:
|
|
10
12
|
def __init__(
|
|
11
|
-
self, device_label: str, property_name:
|
|
13
|
+
self, device_label: str, property_name: str | None, mmcore: CMMCorePlus
|
|
12
14
|
) -> None:
|
|
13
15
|
self._dev = device_label
|
|
14
16
|
self._prop = property_name
|
|
@@ -18,13 +20,13 @@ class _DevicePropValueSignal:
|
|
|
18
20
|
sig = self._mmc.events.devicePropertyChanged(self._dev, self._prop)
|
|
19
21
|
return sig.connect(callback) # type: ignore
|
|
20
22
|
|
|
21
|
-
def disconnect(self, callback: _C) -> None:
|
|
23
|
+
def disconnect(self, callback: _C | None = None) -> None:
|
|
22
24
|
sig = self._mmc.events.devicePropertyChanged(self._dev, self._prop)
|
|
23
|
-
|
|
25
|
+
sig.disconnect(callback)
|
|
24
26
|
|
|
25
27
|
def emit(self, *args: Any) -> Any:
|
|
26
28
|
"""Emits the signal with the given arguments."""
|
|
27
29
|
self._mmc.events.devicePropertyChanged(self._dev, self._prop).emit(*args)
|
|
28
30
|
|
|
29
|
-
def __call__(self, property: str) ->
|
|
31
|
+
def __call__(self, property: str) -> _DevicePropValueSignal:
|
|
30
32
|
return _DevicePropValueSignal(self._dev, property, self._mmc)
|
|
@@ -8,13 +8,11 @@ from types import MethodType
|
|
|
8
8
|
from typing import TYPE_CHECKING, Any, Callable, Union
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
-
from typing import Tuple
|
|
12
|
-
|
|
13
11
|
from typing_extensions import TypeGuard # py310
|
|
14
12
|
|
|
15
|
-
MethodRef =
|
|
13
|
+
MethodRef = tuple[weakref.ReferenceType[object], str, Callable | None]
|
|
16
14
|
NormedCallback = Union[MethodRef, Callable]
|
|
17
|
-
StoredSlot =
|
|
15
|
+
StoredSlot = tuple[NormedCallback, int | None]
|
|
18
16
|
ReducerFunc = Callable[[tuple, tuple], tuple]
|
|
19
17
|
|
|
20
18
|
|
{pymmcore_plus-0.11.0 → pymmcore_plus-0.12.0}/src/pymmcore_plus/core/events/_prop_event_mixin.py
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Callable, ClassVar,
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, TypeVar
|
|
4
4
|
|
|
5
5
|
from ._norm_slot import denormalize_slot, normalize_slot
|
|
6
6
|
from ._protocol import PCoreSignaler
|
|
@@ -8,8 +8,8 @@ from ._protocol import PCoreSignaler
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
9
|
from ._norm_slot import NormedCallback
|
|
10
10
|
|
|
11
|
-
PropKey =
|
|
12
|
-
PropKeyDict =
|
|
11
|
+
PropKey = tuple[str, str | None, NormedCallback]
|
|
12
|
+
PropKeyDict = dict[PropKey, Callable]
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
_C = TypeVar("_C", bound=Callable[..., Any])
|
|
@@ -64,8 +64,11 @@ class _PropertySignal:
|
|
|
64
64
|
self._events.propertyChanged.connect(_wrapper)
|
|
65
65
|
return callback
|
|
66
66
|
|
|
67
|
-
def disconnect(self, callback: Callable) -> None:
|
|
67
|
+
def disconnect(self, callback: Callable | None = None) -> None:
|
|
68
68
|
"""Disconnect `callback` from this device and/or property."""
|
|
69
|
+
if callback is None:
|
|
70
|
+
self._events.propertyChanged.disconnect()
|
|
71
|
+
return
|
|
69
72
|
key = (self._device, self._property, normalize_slot(callback))
|
|
70
73
|
cb = self._events.property_callbacks.pop(key, None)
|
|
71
74
|
if cb is None:
|
|
@@ -12,8 +12,11 @@ class PSignalInstance(Protocol):
|
|
|
12
12
|
def connect(self, slot: Callable) -> Any:
|
|
13
13
|
"""Connect slot to this signal."""
|
|
14
14
|
|
|
15
|
-
def disconnect(self, slot: Callable) -> Any:
|
|
16
|
-
"""Disconnect slot from this signal.
|
|
15
|
+
def disconnect(self, slot: Optional[Callable] = None) -> Any:
|
|
16
|
+
"""Disconnect slot from this signal.
|
|
17
|
+
|
|
18
|
+
If `None`, all slots should be disconnected.
|
|
19
|
+
"""
|
|
17
20
|
|
|
18
21
|
def emit(self, *args: Any) -> Any:
|
|
19
22
|
"""Emits the signal with the given arguments."""
|
|
@@ -10,7 +10,7 @@ import tempfile
|
|
|
10
10
|
from contextlib import contextmanager, nullcontext
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from platform import system
|
|
13
|
-
from typing import TYPE_CHECKING, Callable,
|
|
13
|
+
from typing import TYPE_CHECKING, Callable, Protocol
|
|
14
14
|
from urllib.request import urlopen, urlretrieve
|
|
15
15
|
|
|
16
16
|
import typer
|
|
@@ -18,6 +18,8 @@ import typer
|
|
|
18
18
|
from pymmcore_plus._util import USER_DATA_MM_PATH
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
+
from collections.abc import Iterator
|
|
22
|
+
from contextlib import AbstractContextManager
|
|
21
23
|
|
|
22
24
|
class _MsgLogger(Protocol):
|
|
23
25
|
def __call__(self, text: str, color: str = "", emoji: str = "") -> None: ...
|
|
@@ -70,7 +72,7 @@ def _get_download_name(url: str) -> str:
|
|
|
70
72
|
return ""
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
def _get_spinner(log_msg: _MsgLogger) -> Callable[[str],
|
|
75
|
+
def _get_spinner(log_msg: _MsgLogger) -> Callable[[str], AbstractContextManager]:
|
|
74
76
|
if log_msg is _pretty_print:
|
|
75
77
|
spinner = _spinner
|
|
76
78
|
else:
|
|
@@ -5,10 +5,7 @@ from contextlib import suppress
|
|
|
5
5
|
from itertools import product
|
|
6
6
|
from typing import (
|
|
7
7
|
TYPE_CHECKING,
|
|
8
|
-
Iterable,
|
|
9
|
-
Iterator,
|
|
10
8
|
NamedTuple,
|
|
11
|
-
Sequence,
|
|
12
9
|
cast,
|
|
13
10
|
)
|
|
14
11
|
|
|
@@ -29,6 +26,8 @@ from pymmcore_plus.metadata import (
|
|
|
29
26
|
from ._protocol import PMDAEngine
|
|
30
27
|
|
|
31
28
|
if TYPE_CHECKING:
|
|
29
|
+
from collections.abc import Iterable, Iterator, Sequence
|
|
30
|
+
|
|
32
31
|
from numpy.typing import NDArray
|
|
33
32
|
|
|
34
33
|
from pymmcore_plus.core import CMMCorePlus
|
|
@@ -54,12 +53,11 @@ class MDAEngine(PMDAEngine):
|
|
|
54
53
|
attempt to combine MDAEvents into a single `SequencedEvent` if
|
|
55
54
|
[`core.canSequenceEvents()`][pymmcore_plus.CMMCorePlus.canSequenceEvents]
|
|
56
55
|
reports that the events can be sequenced. This can be set after instantiation.
|
|
57
|
-
By default, this is `
|
|
58
|
-
|
|
59
|
-
set to `True` to improve performance.
|
|
56
|
+
By default, this is `True`, however in various testing and demo scenarios, you
|
|
57
|
+
may wish to set it to `False` in order to avoid unexpected behavior.
|
|
60
58
|
"""
|
|
61
59
|
|
|
62
|
-
def __init__(self, mmc: CMMCorePlus, use_hardware_sequencing: bool =
|
|
60
|
+
def __init__(self, mmc: CMMCorePlus, use_hardware_sequencing: bool = True) -> None:
|
|
63
61
|
self._mmc = mmc
|
|
64
62
|
self.use_hardware_sequencing = use_hardware_sequencing
|
|
65
63
|
|
|
@@ -4,7 +4,7 @@ from abc import abstractmethod
|
|
|
4
4
|
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
|
-
from
|
|
7
|
+
from collections.abc import Iterable, Iterator
|
|
8
8
|
|
|
9
9
|
from numpy.typing import NDArray
|
|
10
10
|
from useq import MDAEvent, MDASequence
|