From 2b3d6673753b9689ef8c75dd6c87c3d74e3d4cbd Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Tue, 3 Feb 2026 13:10:40 -0700 Subject: [PATCH 1/3] Refresh pre-commit --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f598d494..96bf748c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,12 +10,12 @@ repos: - id: check-toml - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.13.0 + rev: v0.14.5 hooks: - id: ruff-check args: [--fix] - id: ruff-format - repo: https://github.com/numpy/numpydoc - rev: "v1.9.0" + rev: "v1.10.0" hooks: - id: numpydoc-validation From b32a790a3bc0e7fa202ba3ababbde4d9f308068d Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Tue, 3 Feb 2026 12:51:17 -0700 Subject: [PATCH 2/3] v30.0.1 release notes --- doc/changes/DM-54006.misc.rst | 1 - doc/lsst.ctrl.bps/CHANGES.rst | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) delete mode 100644 doc/changes/DM-54006.misc.rst diff --git a/doc/changes/DM-54006.misc.rst b/doc/changes/DM-54006.misc.rst deleted file mode 100644 index 79bf9ef9..00000000 --- a/doc/changes/DM-54006.misc.rst +++ /dev/null @@ -1 +0,0 @@ -Bumped minimum Python version to 3.12. Dropped ``black`` and ``isort`` sections from ``pyproject.toml``. Switched docs action to use ``sphinxutils``. diff --git a/doc/lsst.ctrl.bps/CHANGES.rst b/doc/lsst.ctrl.bps/CHANGES.rst index a3293e2f..ae88b6a3 100644 --- a/doc/lsst.ctrl.bps/CHANGES.rst +++ b/doc/lsst.ctrl.bps/CHANGES.rst @@ -1,3 +1,17 @@ +lsst-ctrl-bps v30.0.1 (2026-02-03) +================================== + +Dropped Python 3.11. +Tested with Python 3.14. + +Other Changes and Additions +--------------------------- + +- - Bumped minimum Python version to 3.12. + - Dropped ``black`` and ``isort`` sections from ``pyproject.toml``. + - Switched documentation build to use ``sphinxutils``. (`DM-54006 `_) + + lsst-ctrl-bps v30.0.0 (2026-01-16) ================================== From f0cd54445bbd70809273b1611a25d28f9e216a31 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Tue, 3 Feb 2026 13:09:30 -0700 Subject: [PATCH 3/3] Fix some docstrings sphinx isn't complaining about them for reasons that are not entirely clear. --- python/lsst/ctrl/bps/bps_config.py | 6 +++--- .../lsst/ctrl/bps/clustered_quantum_graph.py | 13 ++++++------ python/lsst/ctrl/bps/construct.py | 3 ++- python/lsst/ctrl/bps/generic_workflow.py | 2 +- python/lsst/ctrl/bps/initialize.py | 3 ++- .../lsst/ctrl/bps/quantum_clustering_funcs.py | 2 +- python/lsst/ctrl/bps/transform.py | 20 +++++++++---------- python/lsst/ctrl/bps/wms_service.py | 10 +++++----- tests/cqg_test_utils.py | 10 +++++----- 9 files changed, 36 insertions(+), 33 deletions(-) diff --git a/python/lsst/ctrl/bps/bps_config.py b/python/lsst/ctrl/bps/bps_config.py index 24d18bc9..c2a10799 100644 --- a/python/lsst/ctrl/bps/bps_config.py +++ b/python/lsst/ctrl/bps/bps_config.py @@ -87,7 +87,7 @@ class BpsConfig(Config): afterwards. WMS settings takes precedence over provided defaults. wms_service_class_fqn : `str`, optional Fully qualified name of the WMS service class to use to get plugin's - specific default settings. If ``None`` (default), the WMS service + specific default settings. If `None` (default), the WMS service class provided by 1. ``other`` config, @@ -256,7 +256,7 @@ def search(self, key, opt=None): ---------- key : `str` Key to look for in config. - opt : `dict` [`str`, `Any`], optional + opt : `dict` [`str`, `~typing.Any`], optional Options dictionary to use while searching. All are optional. ``"curvals"`` @@ -264,7 +264,7 @@ def search(self, key, opt=None): (curr_) or variable replacements. (`dict`, optional) ``"default"`` - Value to return if not found. (`Any`, optional) + Value to return if not found. (`~typing.Any`, optional) ``"replaceEnvVars"`` If search result is string, whether to replace environment variables inside it with special placeholder (). diff --git a/python/lsst/ctrl/bps/clustered_quantum_graph.py b/python/lsst/ctrl/bps/clustered_quantum_graph.py index aa770772..47892476 100644 --- a/python/lsst/ctrl/bps/clustered_quantum_graph.py +++ b/python/lsst/ctrl/bps/clustered_quantum_graph.py @@ -61,7 +61,7 @@ class QuantaCluster: be unique within ClusteredQuantumGraph. label : `str` Value used to group clusters. - tags : `dict` [`str`, `Any`], optional + tags : `dict` [`str`, `~typing.Any`], optional Arbitrary key/value pairs for the cluster. Raises @@ -248,7 +248,8 @@ def add_cluster(self, clusters_for_adding): Parameters ---------- - clusters_for_adding : `QuantaCluster` or `Iterable` [`QuantaCluster`] + clusters_for_adding : `QuantaCluster` or \ + `~collections.abc.Iterable` [`QuantaCluster`] The cluster to be added to the ClusteredQuantumGraph. """ for cluster in ensure_iterable(clusters_for_adding): @@ -311,7 +312,7 @@ def __iter__(self): Returns ------- - names : `Iterator` [`str`] + names : `~collections.abc.Iterator` [`str`] Iterator over names of clusters. """ return self._cluster_graph.nodes() @@ -321,7 +322,7 @@ def clusters(self): Returns ------- - clusters : `Iterator` [`lsst.ctrl.bps.QuantaCluster`] + clusters : `~collections.abc.Iterator` [`lsst.ctrl.bps.QuantaCluster`] Iterator over clusters in topological order. """ return map(self.get_cluster, topological_sort(self._cluster_graph)) @@ -337,7 +338,7 @@ def successors(self, name): Returns ------- - clusters : `Iterator` [`lsst.ctrl.bps.QuantaCluster`] + clusters : `~collections.abc.Iterator` [`lsst.ctrl.bps.QuantaCluster`] Iterator over successors of given cluster. """ return map(self.get_cluster, self._cluster_graph.successors(name)) @@ -353,7 +354,7 @@ def predecessors(self, name): Returns ------- - clusters : `Iterator` [`lsst.ctrl.bps.QuantaCluster`] + clusters : `~collections.abc.Iterator` [`lsst.ctrl.bps.QuantaCluster`] Iterator over predecessors of given cluster. """ return map(self.get_cluster, self._cluster_graph.predecessors(name)) diff --git a/python/lsst/ctrl/bps/construct.py b/python/lsst/ctrl/bps/construct.py index 75c77b0e..492f4d96 100644 --- a/python/lsst/ctrl/bps/construct.py +++ b/python/lsst/ctrl/bps/construct.py @@ -181,7 +181,8 @@ def create_job_files( The mapping between file keys and file paths. prefix : `str` | `pathlib.Path` The root directory to which the files will be written. - path_creator : `Callable` [[`Path`, `Path`], `Path`] + path_creator : `~collections.abc.Callable` \ + [[`pathlib.Path`, `pathlib.Path`], `pathlib.Path`] File category that determines actions that need to be taken during file creation. diff --git a/python/lsst/ctrl/bps/generic_workflow.py b/python/lsst/ctrl/bps/generic_workflow.py index 4feaed05..65889d95 100644 --- a/python/lsst/ctrl/bps/generic_workflow.py +++ b/python/lsst/ctrl/bps/generic_workflow.py @@ -428,7 +428,7 @@ def get_files( ---------- data : `bool`, optional Whether to return the file data as well as the file object name - (The default is False). + (The default is `False`). transfer_only : `bool`, optional Whether to only return files for which a workflow management system would be responsible for transferring. diff --git a/python/lsst/ctrl/bps/initialize.py b/python/lsst/ctrl/bps/initialize.py index f6166854..166c9ac3 100644 --- a/python/lsst/ctrl/bps/initialize.py +++ b/python/lsst/ctrl/bps/initialize.py @@ -58,7 +58,8 @@ def init_submission( ---------- config_file : `str` Name of the configuration file. - validators : `Iterable[Callable[[BpsConfig], None]]`, optional + validators : `~collections.abc.Iterable` \ + [`~collections.abc.Callable` [[`BpsConfig`], `None`]], optional A list of functions performing checks on the given configuration. Each function should take a single argument, a BpsConfig object, and raise if the check fails. By default, no checks are performed. diff --git a/python/lsst/ctrl/bps/quantum_clustering_funcs.py b/python/lsst/ctrl/bps/quantum_clustering_funcs.py index 5d524e84..efebef37 100644 --- a/python/lsst/ctrl/bps/quantum_clustering_funcs.py +++ b/python/lsst/ctrl/bps/quantum_clustering_funcs.py @@ -789,7 +789,7 @@ def get_cluster_name_from_info( ------- cluster_name : `str` Name of the cluster in which to add the given node. - info : dict [`str`, `Any`] + info : dict [`str`, `~typing.Any`] Information needed if creating a new node. """ # Gather info for cluster name template into a dictionary. diff --git a/python/lsst/ctrl/bps/transform.py b/python/lsst/ctrl/bps/transform.py index a57a6ac0..faafbc0a 100644 --- a/python/lsst/ctrl/bps/transform.py +++ b/python/lsst/ctrl/bps/transform.py @@ -210,7 +210,7 @@ def _enhance_command(config, generic_workflow, gwjob, cached_job_values): gwjob : `lsst.ctrl.bps.GenericWorkflowJob` Generic workflow job to which the updated executable, arguments, and values should be saved. - cached_job_values : `dict` [`str`, dict[`str`, `Any`]] + cached_job_values : `dict` [`str`, dict[`str`, `~typing.Any`]] Cached values common across jobs with same label. Updated if values aren't already saved for given gwjob's label. """ @@ -286,7 +286,7 @@ def _fill_arguments(use_shared, generic_workflow, arguments, cmdvals): Generic workflow containing the job. arguments : `str` String containing placeholders. - cmdvals : `dict` [`str`, `Any`] + cmdvals : `dict` [`str`, `~typing.Any`] Any command line values that can be used to replace placeholders. Returns @@ -365,14 +365,14 @@ def _get_job_values(config, search_opt, cmd_line_key): ---------- config : `lsst.ctrl.bps.BpsConfig` Bps configuration. - search_opt : `dict` [`str`, `Any`] + search_opt : `dict` [`str`, `~typing.Any`] Search options to be used when searching config. cmd_line_key : `str` or None Which command line key to search for (e.g., "runQuantumCommand"). Returns ------- - job_values : `dict` [ `str`, `Any` ]` + job_values : `dict` [ `str`, `~typing.Any` ]` A mapping between job attributes and their values. """ _LOG.debug("cmd_line_key=%s, search_opt=%s", cmd_line_key, search_opt) @@ -443,7 +443,7 @@ def _handle_job_values(quantum_job_values, gwjob, attributes=_ATTRS_ALL): Job values for running single Quantum. gwjob : `lsst.ctrl.bps.GenericWorkflowJob` Generic workflow job in which to store the universal values. - attributes : `Iterable` [`str`], optional + attributes : `~collections.abc.Iterable` [`str`], optional Job attributes to be set in the job following different rules. The default value is _ATTRS_ALL. """ @@ -463,7 +463,7 @@ def _handle_job_values_universal(quantum_job_values, gwjob, attributes=_ATTRS_UN Job values for running single Quantum. gwjob : `lsst.ctrl.bps.GenericWorkflowJob` Generic workflow job in which to store the universal values. - attributes : `Iterable` [`str`], optional + attributes : `~collections.abc.Iterable` [`str`], optional Job attributes to be set in the job following different rules. The default value is _ATTRS_UNIVERSAL. """ @@ -502,11 +502,11 @@ def _handle_job_values_max(quantum_job_values, gwjob, attributes=_ATTRS_MAX): Parameters ---------- - quantum_job_values : `dict` [`str`, `Any`] + quantum_job_values : `dict` [`str`, `~typing.Any`] Job values for running single Quantum. gwjob : `lsst.ctrl.bps.GenericWorkflowJob` Generic workflow job in which to store the aggregate values. - attributes : `Iterable` [`str`], optional + attributes : `~collections.abc.Iterable` [`str`], optional Job attributes to be set in the job following different rules. The default value is _ATTR_MAX. """ @@ -547,11 +547,11 @@ def _handle_job_values_sum(quantum_job_values, gwjob, attributes=_ATTRS_SUM): Parameters ---------- - quantum_job_values : `dict` [`str`, `Any`] + quantum_job_values : `dict` [`str`, `~typing.Any`] Job values for running single Quantum. gwjob : `lsst.ctrl.bps.GenericWorkflowJob` Generic workflow job in which to store the aggregate values. - attributes : `Iterable` [`str`], optional + attributes : `~collections.abc.Iterable` [`str`], optional Job attributes to be set in the job following different rules. The default value is _ATTRS_SUM. """ diff --git a/python/lsst/ctrl/bps/wms_service.py b/python/lsst/ctrl/bps/wms_service.py index 61ea7b17..7665526d 100644 --- a/python/lsst/ctrl/bps/wms_service.py +++ b/python/lsst/ctrl/bps/wms_service.py @@ -121,14 +121,14 @@ def context(self) -> dict[str, Any]: Returns ------- - context : `dict` [`str`, `Any`] + context : `dict` [`str`, `~typing.Any`] A copy of the dictionary representing the mapping between *every* template variable and its value. Notes ----- The property returns a *shallow* copy of the dictionary representing - the context as the intended purpose of the ``WmsSpecificInfo`` is to + the context as the intended purpose of the `WmsSpecificInfo` is to pass a small number of brief messages from WMS to BPS reporting subsystem. Hence, it is assumed that the dictionary will only contain immutable objects (e.g. strings, numbers). @@ -157,7 +157,7 @@ def add_message(self, template: str, context: dict[str, Any] | None = None, **kw ---------- template : `str` A message template. - context : `dict` [`str`, `Any`], optional + context : `dict` [`str`, `~typing.Any`], optional A mapping between template variables and their values. **kwargs Additional keyword arguments. @@ -296,7 +296,7 @@ def defaults(self): ----- This property is currently being used in ``BpsConfig.__init__()``. As long as that's the case it cannot be changed to return - a ``BpsConfig`` instance. + a `BpsConfig` instance. """ return None @@ -386,7 +386,7 @@ def list_submitted_jobs(self, wms_id=None, user=None, require_bps=True, pass_thr Returns ------- - job_ids : `list` [`Any`] + job_ids : `list` [`~typing.Any`] Only job ids to be used by cancel and other functions. Typically this means top-level jobs (i.e., not children jobs). """ diff --git a/tests/cqg_test_utils.py b/tests/cqg_test_utils.py index 997e1fa1..5a60969e 100644 --- a/tests/cqg_test_utils.py +++ b/tests/cqg_test_utils.py @@ -41,7 +41,7 @@ def check_cqg(cqg, truth=None): ---------- cqg : `lsst.ctrl.bps.ClusteredQuantumGraph` ClusteredQuantumGraph to be checked for correctness. - truth : `dict` [`str`, `Any`], optional + truth : `dict` [`str`, `~typing.Any`], optional Information describing what this cluster should look like. """ cqg.validate() @@ -62,7 +62,7 @@ def replace_node_name(name, label, dims): Cluster name. label : `str` Cluster label. - dims : `dict` [`str`, `Any`] + dims : `dict` [`str`, `~typing.Any`] Dimension names and values in order to make new name unique. Returns @@ -92,7 +92,7 @@ def dump_cqg(cqg): Returns ------- - info : `dict` [`str`, `Any`] + info : `dict` [`str`, `~typing.Any`] Dictionary represention of ClusteredQuantumGraph. """ info = {"name": cqg.name, "nodes": {}} @@ -121,9 +121,9 @@ def compare_cqg_dicts(truth, cqg): Parameters ---------- - truth : `dict` [`str`, `Any`] + truth : `dict` [`str`, `~typing.Any`] Representation of the expected ClusteredQuantumGraph. - cqg : `dict` [`str`, `Any`] + cqg : `dict` [`str`, `~typing.Any`] Representation of the calculated ClusteredQuantumGraph. Raises