diff --git a/.copier-answers.yml b/.copier-answers.yml index 8f7e8de45..9e8e4cf69 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,11 @@ # Changes here will be overwritten by Copier -_commit: 2.0.1 +_commit: 2.5.0 _src_path: gh:DiamondLightSource/python-copier-template author_email: callum.forrester@diamond.ac.uk author_name: Callum Forrester +component_lifecycle: production component_owner: user:vid18871 +component_type: service description: Lightweight bluesky-as-a-service wrapper application. Also usable as a library. distribution_name: blueapi diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b66046bc2..d0fae1bda 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -47,4 +47,4 @@ "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind", // After the container is created, install the python project in editable form "postCreateCommand": "pip install $([ -f dev-requirements.txt ] && echo '-c dev-requirements.txt') -e '.[dev]' && pre-commit install" -} \ No newline at end of file +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 05162541c..2978529ba 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.0.1/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.5.0/how-to.html). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..aa65892f3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug Report +about: The template to use for reporting bugs and usability issues +title: " " +labels: 'bug' +assignees: '' + +--- + +Describe the bug, including a clear and concise description of the expected behavior, the actual behavior and the context in which you encountered it (ideally include details of your environment). + +## Steps To Reproduce +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md new file mode 100644 index 000000000..52c84dd85 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue.md @@ -0,0 +1,13 @@ +--- +name: Issue +about: The standard template to use for feature requests, design discussions and tasks +title: " " +labels: '' +assignees: '' + +--- + +A brief description of the issue, including specific stakeholders and the business case where appropriate + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 000000000..8200afe5c --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,8 @@ +Fixes #ISSUE + +### Instructions to reviewer on how to test: +1. Do thing x +2. Confirm thing y happens + +### Checks for reviewer +- [ ] Would the PR title make sense to a user on a set of release notes diff --git a/.github/pages/index.html b/.github/pages/index.html index 80f0a0091..c495f39f2 100644 --- a/.github/pages/index.html +++ b/.github/pages/index.html @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/.github/pages/make_switcher.py b/.github/pages/make_switcher.py index 14577cce6..c06813afa 100755 --- a/.github/pages/make_switcher.py +++ b/.github/pages/make_switcher.py @@ -1,3 +1,5 @@ +"""Make switcher.json to allow docs to switch between different versions.""" + import json import logging from argparse import ArgumentParser @@ -6,6 +8,7 @@ def report_output(stdout: bytes, label: str) -> list[str]: + """Print and return something received frm stdout.""" ret = stdout.decode().strip().split("\n") print(f"{label}: {ret}") return ret @@ -53,6 +56,7 @@ def get_versions(ref: str, add: str | None) -> list[str]: def write_json(path: Path, repository: str, versions: list[str]): + """Write the JSON switcher to path.""" org, repo_name = repository.split("/") struct = [ {"version": version, "url": f"https://{org}.github.io/{repo_name}/{version}/"} @@ -64,6 +68,7 @@ def write_json(path: Path, repository: str, versions: list[str]): def main(args=None): + """Parse args and write switcher.""" parser = ArgumentParser( description="Make a versions.json file from gh-pages directories" ) diff --git a/.github/workflows/_container.yml b/.github/workflows/_container.yml index 7833d83a1..8688011c3 100644 --- a/.github/workflows/_container.yml +++ b/.github/workflows/_container.yml @@ -43,7 +43,9 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and export to Docker local cache - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_RECORD_UPLOAD: false with: context: . # Need load and tags so we can test it below @@ -64,7 +66,9 @@ jobs: - name: Push cached image to container registry if: github.ref_type == 'tag' - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 + env: + DOCKER_BUILD_RECORD_UPLOAD: false # This does not build the image again, it will find the image in the # Docker cache and publish it with: diff --git a/.github/workflows/_docs.yml b/.github/workflows/_docs.yml index 40446e332..a1cafcaed 100644 --- a/.github/workflows/_docs.yml +++ b/.github/workflows/_docs.yml @@ -47,8 +47,8 @@ jobs: if: github.ref_type == 'tag' || github.ref_name == 'main' # We pin to the SHA, not the tag, for security reasons. # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3.9.3 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: .github/pages - keep_files: true \ No newline at end of file + keep_files: true diff --git a/.github/workflows/_pypi.yml b/.github/workflows/_pypi.yml index 0c5258dbe..8032bbaac 100644 --- a/.github/workflows/_pypi.yml +++ b/.github/workflows/_pypi.yml @@ -15,3 +15,5 @@ jobs: - name: Publish to PyPI using trusted publishing uses: pypa/gh-action-pypi-publish@release/v1 + with: + attestations: false diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index b49fa7dca..81b626438 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -23,7 +23,7 @@ jobs: - name: Create GitHub Release # We pin to the SHA, not the tag, for security reasons. # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 + uses: softprops/action-gh-release@e7a8f85e1c67a31e6ed99a94b41bd0b71bbee6b8 # v2.0.9 with: prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }} files: "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f45e2aaad..485b82b66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: runs-on: ["ubuntu-latest"] # can add windows-latest, macos-latest - python-version: ["3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] include: # Include one that runs in the dev environment - runs-on: "ubuntu-latest" @@ -39,6 +39,7 @@ jobs: if: needs.check.outputs.branch-pr == '' uses: ./.github/workflows/_container.yml permissions: + contents: read packages: write docs: diff --git a/.gitignore b/.gitignore index a05f166b6..472e30e96 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ cov.xml # Sphinx documentation docs/_build/ +docs/_api # PyBuilder target/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4af381a0c..8c709a4bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,7 @@ repos: - id: check-yaml exclude: ^helm\/.*\/templates\/.*|catalog-info.yaml - id: check-merge-conflict + - id: end-of-file-fixer - repo: local hooks: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 66ad6324d..933c580cd 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,4 +2,4 @@ "recommendations": [ "ms-vscode-remote.remote-containers", ] -} \ No newline at end of file +} diff --git a/.vscode/launch.json b/.vscode/launch.json index 8291038c7..7e47213ba 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -78,4 +78,4 @@ "default": "" }, ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index c129d991b..101c75fa7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,8 @@ "editor.codeActionsOnSave": { "source.organizeImports": "explicit" }, + "files.insertFinalNewline": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", }, -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 946e69d4b..c999e8646 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,4 +13,4 @@ "problemMatcher": [], } ] -} \ No newline at end of file +} diff --git a/Dockerfile b/Dockerfile index dd1a2398f..06b988263 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # The devcontainer should use the developer target and run as root with podman # or docker with user namespaces. ARG PYTHON_VERSION=3.11 -FROM python:${PYTHON_VERSION} as developer +FROM python:${PYTHON_VERSION} AS developer # Add any system dependencies for the developer/build environment here RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -13,13 +13,13 @@ RUN python -m venv /venv ENV PATH=/venv/bin:$PATH # The build stage installs the context into the venv -FROM developer as build +FROM developer AS build COPY . /context WORKDIR /context RUN touch dev-requirements.txt && pip install --upgrade pip && pip install -c dev-requirements.txt . # The runtime stage copies the built venv into a slim runtime container -FROM python:${PYTHON_VERSION}-slim as runtime +FROM python:${PYTHON_VERSION}-slim AS runtime # Add apt-get system dependecies for runtime here if needed RUN apt-get update && apt-get install -y --no-install-recommends \ # Git required for installing packages at runtime diff --git a/README.md b/README.md index 5e44be3d9..b026487e5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![CI](https://github.com/DiamondLightSource/blueapi/actions/workflows/ci.yml/badge.svg)](https://github.com/DiamondLightSource/blueapi/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/DiamondLightSource/blueapi/branch/main/graph/badge.svg)](https://codecov.io/gh/DiamondLightSource/blueapi) [![PyPI](https://img.shields.io/pypi/v/blueapi.svg)](https://pypi.org/project/blueapi) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0) # blueapi diff --git a/docs/_api.rst b/docs/_api.rst new file mode 100644 index 000000000..d0f030ac4 --- /dev/null +++ b/docs/_api.rst @@ -0,0 +1,16 @@ +:orphan: + +.. + This page is not included in the TOC tree, but must exist so that the + autosummary pages are generated for blueapi and all its + subpackages + +API +=== + +.. autosummary:: + :toctree: _api + :template: custom-module-template.rst + :recursive: + + blueapi diff --git a/docs/_templates/custom-module-template.rst b/docs/_templates/custom-module-template.rst new file mode 100644 index 000000000..9aeca5401 --- /dev/null +++ b/docs/_templates/custom-module-template.rst @@ -0,0 +1,37 @@ +{{ ('``' + fullname + '``') | underline }} + +{%- set filtered_members = [] %} +{%- for item in members %} + {%- if item in functions + classes + exceptions + attributes %} + {% set _ = filtered_members.append(item) %} + {%- endif %} +{%- endfor %} + +.. automodule:: {{ fullname }} + :members: + + {% block modules %} + {% if modules %} + .. rubric:: Submodules + + .. autosummary:: + :toctree: + :template: custom-module-template.rst + :recursive: + {% for item in modules %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block members %} + {% if filtered_members %} + .. rubric:: Members + + .. autosummary:: + :nosignatures: + {% for item in filtered_members %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} diff --git a/docs/conf.py b/docs/conf.py index 23fb13a2b..0e96d9dea 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,8 +1,9 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html +"""Configuration file for the Sphinx documentation builder. + +This file only contains a selection of the most common options. For a full +list see the documentation: +https://www.sphinx-doc.org/en/master/usage/configuration.html +""" import sys from pathlib import Path @@ -32,6 +33,8 @@ extensions = [ # Use this for generating API docs "sphinx.ext.autodoc", + # and making summary tables at the top of API docs + "sphinx.ext.autosummary", # This can parse google style docstrings "sphinx.ext.napoleon", # For linking to external sphinx documentation @@ -84,6 +87,12 @@ # Don't inherit docstrings from baseclasses autodoc_inherit_docstrings = False +# Document only what is in __all__ +autosummary_ignore_module_all = False + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + # Output graphviz directive produced images in a scalable format graphviz_output_format = "svg" @@ -139,10 +148,10 @@ # Theme options for pydata_sphinx_theme # We don't check switcher because there are 3 possible states for a repo: # 1. New project, docs are not published so there is no switcher -# 2. Existing project with latest skeleton, switcher exists and works -# 3. Existing project with old skeleton that makes broken switcher, +# 2. Existing project with latest copier template, switcher exists and works +# 3. Existing project with old copier template that makes broken switcher, # switcher exists but is broken -# Point 3 makes checking switcher difficult, because the updated skeleton +# Point 3 makes checking switcher difficult, because the updated copier template # will fix the switcher at the end of the docs workflow, but never gets a chance # to complete as the docs build warns and fails. html_theme_options = { @@ -170,7 +179,7 @@ # A dictionary of values to pass into the template engine’s context for all pages html_context = { "github_user": github_user, - "github_repo": project, + "github_repo": github_repo, "github_version": version, "doc_path": "docs", } diff --git a/docs/explanations/lifecycle.md b/docs/explanations/lifecycle.md index f0455d28b..78018f1f3 100644 --- a/docs/explanations/lifecycle.md +++ b/docs/explanations/lifecycle.md @@ -124,5 +124,3 @@ The plan is executed. While it is running, the `Worker` will publish If an error occurs during any of the stages from "Request" onwards it is sent back to the user over the message bus. - - diff --git a/docs/how-to/add-plans-and-devices.md b/docs/how-to/add-plans-and-devices.md index a2c12e0b2..28aca4df3 100644 --- a/docs/how-to/add-plans-and-devices.md +++ b/docs/how-to/add-plans-and-devices.md @@ -100,4 +100,3 @@ host machine, include the following in your `values.yaml`: ``` You can then clone projects into the scratch directory and blueapi will automatically incorporate them on startup. You must still include configuration to load the plans and devices from specific modules within those packages, see above. - diff --git a/docs/how-to/contribute.md b/docs/how-to/contribute.md index f9c4ca1d7..6e4197970 100644 --- a/docs/how-to/contribute.md +++ b/docs/how-to/contribute.md @@ -1,2 +1,2 @@ ```{include} ../../.github/CONTRIBUTING.md -``` \ No newline at end of file +``` diff --git a/docs/reference.md b/docs/reference.md index 3be116edd..3b6db4d05 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -7,6 +7,7 @@ Technical reference material including APIs and release notes. :glob: reference/* +API <_api/blueapi> genindex Release Notes ``` diff --git a/docs/reference/api.md b/docs/reference/api.md deleted file mode 100644 index 1d29fbcd7..000000000 --- a/docs/reference/api.md +++ /dev/null @@ -1,10 +0,0 @@ -# API - -This is the internal API reference for blueapi - -```python -import blueapi -blueapi.__version__ -``` - -Version number as calculated by https://github.com/pypa/setuptools_scm diff --git a/docs/reference/asyncapi.yaml b/docs/reference/asyncapi.yaml index 96d314297..f78394420 100644 --- a/docs/reference/asyncapi.yaml +++ b/docs/reference/asyncapi.yaml @@ -263,4 +263,3 @@ components: description: Estimated time remaining until operation completion, if known type: number format: float - diff --git a/docs/reference/messaging-spec.md b/docs/reference/messaging-spec.md index 363577c80..d5c52e5d6 100644 --- a/docs/reference/messaging-spec.md +++ b/docs/reference/messaging-spec.md @@ -4,4 +4,3 @@ The Blueapi service publishes Bluesky documents and other events to the message bus, allowing subscribers to keep track of the status of plans, as well as other status changes. This page documents the channels to which clients can subscribe to receive these messages and their structure. - diff --git a/docs/reference/rest-spec.md b/docs/reference/rest-spec.md index 8db73b848..7a16c50b9 100644 --- a/docs/reference/rest-spec.md +++ b/docs/reference/rest-spec.md @@ -2,5 +2,3 @@ Blueapi runs a FastAPI server through which the blueapi worker can be interacted with. Here the [openapi docs page](./openapi.yaml) documents all possible endpoints of this server. - - diff --git a/docs/tutorials/installation.md b/docs/tutorials/installation.md index effcec222..bd9cfb2e2 100644 --- a/docs/tutorials/installation.md +++ b/docs/tutorials/installation.md @@ -2,7 +2,7 @@ ## Check your version of python -You will need python 3.8 or later. You can check your version of python by +You will need python 3.10 or later. You can check your version of python by typing into a terminal: ``` python3 --version diff --git a/helm/blueapi/templates/configmap.yaml b/helm/blueapi/templates/configmap.yaml index 868a78279..43ea33b03 100644 --- a/helm/blueapi/templates/configmap.yaml +++ b/helm/blueapi/templates/configmap.yaml @@ -5,4 +5,3 @@ metadata: data: config.yaml: |- {{- toYaml .Values.worker | nindent 4 }} - diff --git a/pyproject.toml b/pyproject.toml index a8a22e2d4..8658d979a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=64", "setuptools_scm[toml]>=6.2"] +requires = ["setuptools>=64", "setuptools_scm[toml]>=8"] build-backend = "setuptools.build_meta" [project] @@ -9,6 +9,7 @@ classifiers = [ "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] description = "Lightweight bluesky-as-a-service wrapper application. Also usable as a library." dependencies = [ @@ -49,6 +50,7 @@ dev = [ "pre-commit>=3.8.0", "pydata-sphinx-theme>=0.15.4", "mypy", + "pytest", "pytest-cov", "pytest-asyncio", "responses", @@ -78,7 +80,7 @@ name = "Callum Forrester" [tool.setuptools_scm] -write_to = "src/blueapi/_version.py" +version_file = "src/blueapi/_version.py" [tool.mypy] ignore_missing_imports = true # Ignore missing stubs in imported modules @@ -124,7 +126,7 @@ allowlist_externals = sphinx-build sphinx-autobuild commands = - pre-commit: pre-commit run --all-files {posargs} + pre-commit: pre-commit run --all-files --show-diff-on-failure {posargs} type-checking: mypy src tests {posargs} tests: pytest --cov=blueapi --cov-report term --cov-report xml:cov.xml tests/unit_tests {posargs} docs: sphinx-{posargs:build -EW --keep-going} -T docs build/html @@ -135,13 +137,14 @@ commands = src = ["src", "tests"] line-length = 88 lint.select = [ - "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b - "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 - "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e - "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f - "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w - "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i - "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e + "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f + "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w + "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i + "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self ] [tool.ruff.lint.flake8-bugbear] @@ -151,3 +154,9 @@ extend-immutable-calls = [ "fastapi.Task", "dodal.common.inject", ] + +[tool.ruff.lint.per-file-ignores] +# By default, private member access is allowed in tests +# See https://github.com/DiamondLightSource/python-copier-template/issues/154 +# Remove this line to forbid private member access in tests +"tests/**/*" = ["SLF001"] diff --git a/src/blueapi/__init__.py b/src/blueapi/__init__.py index 26d23badb..a2ffbf369 100644 --- a/src/blueapi/__init__.py +++ b/src/blueapi/__init__.py @@ -1,3 +1,11 @@ +"""Top level API. + +.. data:: __version__ + :type: str + + Version number as calculated by https://github.com/pypa/setuptools_scm +""" + from ._version import __version__ __all__ = ["__version__"] diff --git a/src/blueapi/startup/simmotor.py b/src/blueapi/startup/simmotor.py index 84067ba21..1d8f9c4a6 100644 --- a/src/blueapi/startup/simmotor.py +++ b/src/blueapi/startup/simmotor.py @@ -43,7 +43,7 @@ def set(self, value: float) -> None: distance = value - old_setpoint self.sim_state["setpoint"] = value self.sim_state["setpoint_ts"] = ttime.time() - self.setpoint._run_subs( + self.setpoint._run_subs( # noqa sub_type=self.setpoint.SUB_VALUE, old_value=old_setpoint, value=self.sim_state["setpoint"], @@ -54,7 +54,7 @@ def update_state(position: float) -> None: old_readback = self.sim_state["readback"] self.sim_state["readback"] = self._readback_func(position) self.sim_state["readback_ts"] = ttime.time() - self.readback._run_subs( + self.readback._run_subs( # noqa sub_type=self.readback.SUB_VALUE, old_value=old_readback, value=self.sim_state["readback"], diff --git a/src/blueapi/worker/task_worker.py b/src/blueapi/worker/task_worker.py index d9aa38e86..db760f421 100644 --- a/src/blueapi/worker/task_worker.py +++ b/src/blueapi/worker/task_worker.py @@ -239,11 +239,9 @@ def start(self) -> None: if self._started.is_set(): raise WorkerAlreadyStartedError("Worker is already running") self._wait_until_stopped() - fut = run_worker_in_own_thread(self) + run_worker_in_own_thread(self) self._wait_until_started() - add_span_attributes({WORKER_THREAD_STATE: fut._state}) - @start_as_current_span(TRACER) def stop(self) -> None: LOGGER.info("Attempting to stop worker") diff --git a/src/script/rabbitmq_setup/enabled_plugins b/src/script/rabbitmq_setup/enabled_plugins index 454685a05..37920ac73 100644 --- a/src/script/rabbitmq_setup/enabled_plugins +++ b/src/script/rabbitmq_setup/enabled_plugins @@ -1 +1 @@ -[rabbitmq_management,rabbitmq_prometheus,rabbitmq_stomp]. \ No newline at end of file +[rabbitmq_management,rabbitmq_prometheus,rabbitmq_stomp]. diff --git a/tests/conftest.py b/tests/conftest.py index 8f311754b..b61c09e9d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,5 @@ import asyncio -from typing import cast +from typing import Any, cast # Based on https://docs.pytest.org/en/latest/example/simple.html#control-skipping-of-tests-according-to-command-line-option # noqa: E501 import pytest @@ -39,3 +39,18 @@ def exporter() -> TracerProvider: # Use SimpleSpanProcessor to keep tests quick provider.add_span_processor(SimpleSpanProcessor(exporter)) return exporter + + +@pytest.hookimpl(tryfirst=True) +def pytest_exception_interact(call: pytest.CallInfo[Any]): + if call.excinfo is not None: + raise call.excinfo.value + else: + raise RuntimeError( + f"{call} has no exception data, an unknown error has occurred" + ) + + +@pytest.hookimpl(tryfirst=True) +def pytest_internalerror(excinfo: pytest.ExceptionInfo[Any]): + raise excinfo.value diff --git a/tests/system_tests/devices.json b/tests/system_tests/devices.json index b13566d48..c6c153503 100644 --- a/tests/system_tests/devices.json +++ b/tests/system_tests/devices.json @@ -149,4 +149,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/tests/system_tests/plans.json b/tests/system_tests/plans.json index 76d17457a..d9a8b551e 100644 --- a/tests/system_tests/plans.json +++ b/tests/system_tests/plans.json @@ -1165,4 +1165,4 @@ } } ] -} \ No newline at end of file +}