From 7acf8acb43318cf17114a72a3fca72babbf73963 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 11:28:35 +0000 Subject: [PATCH 1/3] AGENTS.md: declare the systems and architectures a plugin works on Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01Tdiso1u1ZhikSutj2Qs5Cg --- AGENTS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index c0806c0..418845f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -58,6 +58,12 @@ File and class names must match: `daq_move_.py` holds `DAQ_Move_`; ` to develop them. The list is defined once in `pymodaq_utils.plugin_tools.contract`, with when each method is called and what it returns (table in the developer guide, "The methods of a plugin"). +- (Actuators and detectors.) A plugin that works on some systems only (a Windows driver, a Raspberry Pi board) + declares it in the instrument class, for instance `supported_platforms = ('win32',)` (values of `sys.platform`: `win32`, `linux`, `darwin`) and + optionally `supported_architectures = ('aarch64', 'armv7l')` (values of `platform.machine()`). PyMoDAQ then refuses + to initialize it elsewhere with a message, and `check_plugin --fix-classifiers` updates the `Operating System` + classifiers of the `pyproject.toml` (PMQ320 reports a mismatch). The module must still be importable on every system + (PMQ317): import Windows-only code lazily. Needs `pymodaq>=5.3.5`. - `ini_stage(controller=None)` returns `(info: str, initialized: bool)`. If `self.is_master`, create the controller; otherwise store the `controller` passed in (several axes share one controller). - Class attributes: `is_multiaxes`, `_axis_names`, `_controller_units`, `_epsilons`, From 503034a80de4f88f460b09322871726258fff5c0 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 14:02:47 +0000 Subject: [PATCH 2/3] Classifiers are computed when building (Operating System from supported_platforms, Python from requires-python) Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01Tdiso1u1ZhikSutj2Qs5Cg --- .github/scripts/check_template_versions.py | 9 ++---- AGENTS.md | 5 ++-- pyproject.toml | 33 ++++++++++------------ 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/.github/scripts/check_template_versions.py b/.github/scripts/check_template_versions.py index b18d607..9cdf010 100644 --- a/.github/scripts/check_template_versions.py +++ b/.github/scripts/check_template_versions.py @@ -8,7 +8,7 @@ ------------------------------------------------ 1. Create the ``5.4.x`` branch from ``5.3.x`` and make it the default branch of the template repository. 2. On it, raise the floors in pyproject.toml (``pymodaq>=5.4.0``...), the "PyMoDAQ 5.3.x" wording in README.rst and - AGENTS.md, the Python classifiers/requires-python and the matrix of reusable-compatibility.yml if they changed. + AGENTS.md, requires-python and the matrix of reusable-compatibility.yml if they changed. 3. Point the three caller workflows (``@5.3.x`` in tests.yml, compatibility.yml, python-publish.yml) to ``@5.4.x``. 4. Run this script: it must print OK. Keep ``5.3.x`` for hotfixes. """ @@ -78,11 +78,8 @@ def main() -> int: same_minor = [v for v in versions if minor(v) == branch_minor][-1] with urllib.request.urlopen(f'https://pypi.org/pypi/pymodaq/{same_minor}/json', timeout=30) as response: data = json.load(response)['info'] - theirs = python_minors(data['classifiers']) - ours = python_minors(project['classifiers']) - if theirs and ours != theirs: - problems.append(f'Python classifiers of pyproject.toml are 3.{ours[0]}-3.{ours[-1]}, pymodaq {same_minor} says ' - f'3.{theirs[0]}-3.{theirs[-1]}') + # the Python classifiers of a plugin are computed from requires-python when it is built (dynamic classifiers) + ours = theirs = python_minors(data['classifiers']) requires = data.get('requires_python') or '' if requires and requires != project.get('requires-python'): problems.append(f'requires-python is {project.get("requires-python")!r}, pymodaq {same_minor} has {requires!r}') diff --git a/AGENTS.md b/AGENTS.md index 418845f..0b9216a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,8 +61,9 @@ what it returns (table in the developer guide, "The methods of a plugin"). - (Actuators and detectors.) A plugin that works on some systems only (a Windows driver, a Raspberry Pi board) declares it in the instrument class, for instance `supported_platforms = ('win32',)` (values of `sys.platform`: `win32`, `linux`, `darwin`) and optionally `supported_architectures = ('aarch64', 'armv7l')` (values of `platform.machine()`). PyMoDAQ then refuses - to initialize it elsewhere with a message, and `check_plugin --fix-classifiers` updates the `Operating System` - classifiers of the `pyproject.toml` (PMQ320 reports a mismatch). The module must still be importable on every system + to initialize it elsewhere with a message, and the `Operating System` and `Programming Language :: Python :: 3.x` classifiers are + computed when the package is built (`classifiers` is dynamic in the `pyproject.toml`, the others are in + `[tool.pymodaq] classifiers`). The module must still be importable on every system (PMQ317): import Windows-only code lazily. Needs `pymodaq>=5.3.5`. - `ini_stage(controller=None)` returns `(info: str, initialized: bool)`. If `self.is_master`, create the controller; otherwise store the `controller` passed in (several axes share one controller). diff --git a/pyproject.toml b/pyproject.toml index 2db3617..c8de085 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,32 +30,16 @@ maintainers = [ # nottodo: leave everything below as is! -dynamic = ["version", "urls", "entry-points"] +dynamic = ["version", "urls", "entry-points", "classifiers"] readme = "README.rst" license = { file="LICENSE" } requires-python = ">=3.10" -classifiers = [ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Operating System :: OS Independent", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Programming Language :: Python :: 3.13", - "Topic :: Scientific/Engineering :: Human Machine Interfaces", - "Topic :: Scientific/Engineering :: Visualization", - "Topic :: Software Development :: Libraries :: Python Modules", - "Topic :: Software Development :: User Interfaces", -] - [build-system] requires = [ "hatchling>=1.9.0", "hatch-vcs", "toml", - "pymodaq_utils>=0.0.6", + "pymodaq_utils>=5.3.6", ] build-backend = "hatchling.build" @@ -64,3 +48,16 @@ build-backend = "hatchling.build" [tool.hatch.version] source = "vcs" +[tool.pymodaq] +# the "Operating System" and "Programming Language :: Python :: 3.x" classifiers are added when building the package, +# from supported_platforms in your instrument plugins and from requires-python +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Topic :: Scientific/Engineering :: Human Machine Interfaces", + "Topic :: Scientific/Engineering :: Visualization", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: User Interfaces", +] From 38cc4f2943a0a7299ed3e9f5a66f70e01f586134 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 14:02:59 +0000 Subject: [PATCH 3/3] AGENTS.md: wording of the platforms bullet Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01Tdiso1u1ZhikSutj2Qs5Cg --- AGENTS.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 0b9216a..fc1ef4a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,12 +59,13 @@ to develop them. The list is defined once in `pymodaq_utils.plugin_tools.contrac what it returns (table in the developer guide, "The methods of a plugin"). - (Actuators and detectors.) A plugin that works on some systems only (a Windows driver, a Raspberry Pi board) - declares it in the instrument class, for instance `supported_platforms = ('win32',)` (values of `sys.platform`: `win32`, `linux`, `darwin`) and - optionally `supported_architectures = ('aarch64', 'armv7l')` (values of `platform.machine()`). PyMoDAQ then refuses - to initialize it elsewhere with a message, and the `Operating System` and `Programming Language :: Python :: 3.x` classifiers are - computed when the package is built (`classifiers` is dynamic in the `pyproject.toml`, the others are in - `[tool.pymodaq] classifiers`). The module must still be importable on every system - (PMQ317): import Windows-only code lazily. Needs `pymodaq>=5.3.5`. + declares it in the instrument class, for instance `supported_platforms = ('win32',)` (values of `sys.platform`: + `win32`, `linux`, `darwin`) and optionally `supported_architectures = ('aarch64', 'armv7l')` (values of + `platform.machine()`). PyMoDAQ then refuses to initialize it elsewhere with a message. The `Operating System` and + `Programming Language :: Python :: 3.x` classifiers are computed when the package is built (`classifiers` is + dynamic in the `pyproject.toml`, the others are in `[tool.pymodaq] classifiers`). A plugin working on several + systems must stay importable on all of them: import Windows-only code lazily (PMQ317; not reported when every + instrument is `('win32',)`). Needs `pymodaq>=5.3.6`. - `ini_stage(controller=None)` returns `(info: str, initialized: bool)`. If `self.is_master`, create the controller; otherwise store the `controller` passed in (several axes share one controller). - Class attributes: `is_multiaxes`, `_axis_names`, `_controller_units`, `_epsilons`,