Skip to content

Commit

Permalink
Merge pull request #61 from DiamondLightSource/copier-pyright
Browse files Browse the repository at this point in the history
Update copier and adopt pyright
  • Loading branch information
GDYendell authored Oct 14, 2024
2 parents 751233b + 97b3756 commit bdab4fa
Show file tree
Hide file tree
Showing 21 changed files with 210 additions and 108 deletions.
6 changes: 4 additions & 2 deletions .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Changes here will be overwritten by Copier
_commit: 2.1.0-40-g9e70b8b
_commit: 2.3.0
_src_path: gh:DiamondLightSource/python-copier-template
author_email: [email protected]
author_name: Gary Yendell
component_lifecycle: experimental
component_owner: user:mef65357
component_type: library
description: Control system agnostic framework for building Device support in Python
that will work for both EPICS and Tango
distribution_name: fastcs
Expand All @@ -14,4 +16,4 @@ github_org: DiamondLightSource
package_name: fastcs
pypi: true
repo_name: FastCS
type_checker: mypy
type_checker: pyright
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.1.0/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.3.0/how-to.html).
14 changes: 8 additions & 6 deletions .github/pages/make_switcher.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Make switcher.json to allow docs to switch between different versions."""

import json
import logging
from argparse import ArgumentParser
Expand All @@ -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
Expand Down Expand Up @@ -52,21 +55,20 @@ def get_versions(ref: str, add: str | None) -> list[str]:
return versions


def write_json(path: Path, repository: str, versions: str):
def write_json(path: Path, repository: str, versions: list[str]):
"""Write the JSON switcher to path."""
org, repo_name = repository.split("/")
pages_url = f"https://{org}.github.io"
if repo_name != f"{org}.github.io":
# Only add the repo name if it isn't the source for the org pages site
pages_url += f"/{repo_name}"
struct = [
{"version": version, "url": f"{pages_url}/{version}/"} for version in versions
{"version": version, "url": f"https://{org}.github.io/{repo_name}/{version}/"}
for version in versions
]
text = json.dumps(struct, indent=2)
print(f"JSON switcher:\n{text}")
path.write_text(text, encoding="utf-8")


def main(args=None):
"""Parse args and write switcher."""
parser = ArgumentParser(
description="Make a versions.json file from gh-pages directories"
)
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ cov.xml

# Sphinx documentation
docs/_build/
docs/_api

# PyBuilder
target/
Expand Down
2 changes: 1 addition & 1 deletion catalog-info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ metadata:
title: FastCS
description: Control system agnostic framework for building Device support in Python that will work for both EPICS and Tango
spec:
type: documentation
type: library
lifecycle: experimental
owner: user:mef65357
16 changes: 16 additions & 0 deletions docs/_api.rst
Original file line number Diff line number Diff line change
@@ -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 fastcs and all its
subpackages
API
===

.. autosummary::
:toctree: _api
:template: custom-module-template.rst
:recursive:

fastcs
37 changes: 37 additions & 0 deletions docs/_templates/custom-module-template.rst
Original file line number Diff line number Diff line change
@@ -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 %}
19 changes: 14 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -83,6 +86,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"

Expand Down
2 changes: 1 addition & 1 deletion docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Technical reference material including APIs and release notes.
:maxdepth: 1
:glob:
reference/*
API <_api/fastcs>
genindex
Release Notes <https://github.com/DiamondLightSource/FastCS/releases>
```
17 changes: 0 additions & 17 deletions docs/reference/api.md

This file was deleted.

13 changes: 7 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies = [
"aioserial",
"numpy",
"pydantic",
"pvi~=0.9.0",
"pvi~=0.10.0",
"pytango",
"softioc",
]
Expand All @@ -26,11 +26,11 @@ requires-python = ">=3.11"
[project.optional-dependencies]
dev = [
"copier",
"mypy",
"myst-parser",
"pipdeptree",
"pre-commit",
"pydata-sphinx-theme>=0.12",
"pyright",
"pytest",
"pytest-cov",
"pytest-mock",
Expand Down Expand Up @@ -59,8 +59,9 @@ name = "Martin Gaughran"
[tool.setuptools_scm]
version_file = "src/fastcs/_version.py"

[tool.mypy]
ignore_missing_imports = true # Ignore missing stubs in imported modules
[tool.pyright]
typeCheckingMode = "standard"
reportMissingImports = false # Ignore missing stubs in imported modules

[tool.pytest.ini_options]
# Run pytest with all our checkers, and don't spam us with massive tracebacks on error
Expand Down Expand Up @@ -93,12 +94,12 @@ passenv = *
allowlist_externals =
pytest
pre-commit
mypy
pyright
sphinx-build
sphinx-autobuild
commands =
pre-commit: pre-commit run --all-files --show-diff-on-failure {posargs}
type-checking: mypy src tests {posargs}
type-checking: pyright src tests {posargs}
tests: pytest --cov=fastcs --cov-report term --cov-report xml:cov.xml {posargs}
docs: sphinx-{posargs:build -EW --keep-going} -T docs build/html
"""
Expand Down
8 changes: 8 additions & 0 deletions src/fastcs/__init__.py
Original file line number Diff line number Diff line change
@@ -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__"]
16 changes: 12 additions & 4 deletions src/fastcs/__main__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
"""Interface for ``python -m fastcs``."""

from argparse import ArgumentParser
from collections.abc import Sequence

from . import __version__

__all__ = ["main"]


def main(args=None):
def main(args: Sequence[str] | None = None) -> None:
"""Argument parser for the CLI."""
parser = ArgumentParser()
parser.add_argument("-v", "--version", action="version", version=__version__)
args = parser.parse_args(args)
parser.add_argument(
"-v",
"--version",
action="version",
version=__version__,
)
parser.parse_args(args)


# test with: python -m fastcs
if __name__ == "__main__":
main()
20 changes: 11 additions & 9 deletions src/fastcs/backends/epics/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
LED,
ButtonPanel,
ComboBox,
Component,
ComponentUnion,
Device,
Grid,
Group,
ReadWidget,
ReadWidgetUnion,
SignalR,
SignalRW,
SignalW,
Expand All @@ -22,7 +22,7 @@
TextWrite,
ToggleButton,
Tree,
WriteWidget,
WriteWidgetUnion,
)
from pydantic import ValidationError

Expand Down Expand Up @@ -56,7 +56,7 @@ def _get_pv(self, attr_path: list[str], name: str):
return f"{attr_prefix}:{name.title().replace('_', '')}"

@staticmethod
def _get_read_widget(attribute: AttrR) -> ReadWidget:
def _get_read_widget(attribute: AttrR) -> ReadWidgetUnion:
match attribute.datatype:
case Bool():
return LED()
Expand All @@ -68,7 +68,7 @@ def _get_read_widget(attribute: AttrR) -> ReadWidget:
raise FastCSException(f"Unsupported type {type(datatype)}: {datatype}")

@staticmethod
def _get_write_widget(attribute: AttrW) -> WriteWidget:
def _get_write_widget(attribute: AttrW) -> WriteWidgetUnion:
match attribute.allowed_values:
case allowed_values if allowed_values is not None:
return ComboBox(choices=allowed_values)
Expand All @@ -87,7 +87,7 @@ def _get_write_widget(attribute: AttrW) -> WriteWidget:

def _get_attribute_component(
self, attr_path: list[str], name: str, attribute: Attribute
):
) -> SignalR | SignalW | SignalRW:
pv = self._get_pv(attr_path, name)
name = name.title().replace("_", "")

Expand All @@ -108,6 +108,8 @@ def _get_attribute_component(
case AttrW():
write_widget = self._get_write_widget(attribute)
return SignalW(name=name, write_pv=pv, write_widget=write_widget)
case _:
raise FastCSException(f"Unsupported attribute type: {type(attribute)}")

def _get_command_component(self, attr_path: list[str], name: str):
pv = self._get_pv(attr_path, name)
Expand Down Expand Up @@ -136,8 +138,8 @@ def create_gui(self, options: EpicsGUIOptions | None = None) -> None:
formatter = DLSFormatter()
formatter.format(device, options.output_path)

def extract_mapping_components(self, mapping: SingleMapping) -> list[Component]:
components: Tree[Component] = []
def extract_mapping_components(self, mapping: SingleMapping) -> Tree:
components: Tree = []
attr_path = mapping.controller.path

for name, sub_controller in mapping.controller.get_sub_controllers().items():
Expand All @@ -151,7 +153,7 @@ def extract_mapping_components(self, mapping: SingleMapping) -> list[Component]:
)
)

groups: dict[str, list[Component]] = {}
groups: dict[str, list[ComponentUnion]] = {}
for attr_name, attribute in mapping.attributes.items():
try:
signal = self._get_attribute_component(
Expand Down
Loading

0 comments on commit bdab4fa

Please sign in to comment.