Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Unit Tests

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Check out source
uses: actions/checkout@v5

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}

- name: Install package with test dependencies
run: python -m pip install ".[test]"

- name: Run tests
run: pytest
14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "pyaml-test-lattice"
description = "Lattices and configuration files for pyAML tests and tutorials"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.11"
requires-python = ">=3.10"
dynamic = ["version"]
keywords = ["accelerator", "synchrotron"]

Expand All @@ -17,17 +17,14 @@ classifiers = [
"Natural Language :: English",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering :: Physics",
]

dependencies = [
"accelerator-toolbox>=0.6.1",
]

[project.urls]
Homepage = "https://python-accelerator-middle-layer.github.io/documentation/"
Repository = "https://github.com/python-accelerator-middle-layer/pyaml-test-lattice"
Expand Down Expand Up @@ -69,9 +66,12 @@ allow-direct-references = true
[tool.hatch.build.hooks.vcs]
version-file = "src/pyaml_test_lattice/_version.py"

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
line-length = 127
target-version = "py311"
target-version = "py310"

[tool.ruff.lint]
# Basic, sane default set: pycodestyle (E,W), pyflakes (F),
Expand All @@ -98,6 +98,6 @@ indent-style = "space"
skip-magic-trailing-comma = false

[tool.mypy]
python_version = "3.11"
python_version = "3.10"
strict = false
ignore_missing_imports = true
17 changes: 11 additions & 6 deletions src/pyaml_test_lattice/registries.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""Automatic registries for packaged lattice and configuration files."""

from collections.abc import Iterator, KeysView
from importlib.abc import Traversable
from importlib.resources import files
from pprint import pformat

try:
from importlib.resources.abc import Traversable # Python 3.12+
except ImportError: # Python 3.10 / 3.11
from importlib.abc import Traversable


class _Registry:
"""Dictionary-like registry of packaged files.
Expand Down Expand Up @@ -49,8 +53,8 @@ def _visit(self, directory: Traversable, prefix: str = "") -> None:
elif entry.is_dir():
self._visit(entry, key)

def __getitem__(self, key: str) -> str:
"""Return the filesystem path of a packaged resource.
def __getitem__(self, key: str) -> Traversable:
"""Return the packaged resource, ready to be read.

Parameters
----------
Expand All @@ -59,10 +63,11 @@ def __getitem__(self, key: str) -> str:

Returns
-------
str
Filesystem path to the requested packaged resource.
importlib.abc.Traversable
The requested packaged resource. Supports ``.read_text()`` and
``.read_bytes()``, and stringifies to its filesystem path.
"""
return str(self._files[key])
return self._files[key]

def __iter__(self) -> Iterator[str]:
"""Iterate over registered resource paths.
Expand Down
46 changes: 46 additions & 0 deletions tests/test_lattice_and_configuration_access.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Checks that the usage documented in README.md actually works.

These tests double as copy-paste examples: they use the registries exactly
as the README describes, nothing more.
"""

from importlib.resources import files

from pyaml_test_lattice import configurations, lattices

LATTICE_KEY = "fodo_1gev_6d.json"
CONFIGURATION_KEY = "pyaml/tango/tango-pyaml/fodo_1gev_6d_pyaml.yaml"


def test_lattice_file_can_be_read_as_text():
lattice_file = lattices[LATTICE_KEY]
lattice_json = lattice_file.read_text()

assert lattice_json != ""


def test_configuration_file_can_be_read_as_text():
config_file = configurations[CONFIGURATION_KEY]
config_text = config_file.read_text()

assert config_text != ""


def test_lattice_key_is_listed():
assert LATTICE_KEY in lattices.keys()


def test_configuration_key_is_listed():
assert CONFIGURATION_KEY in configurations.keys()


def test_printing_a_registry_shows_its_description():
# A "<filename>.description" file next to a data file is shown when the
# registry is printed, as documented in the README. Read the sidecar
# file's actual content instead of hardcoding it, so this test keeps
# checking that the registry extracts it correctly even if the
# description text itself changes.
description_file = files("pyaml_test_lattice") / "data" / "lattice" / f"{LATTICE_KEY}.description"
expected_description = description_file.read_text(encoding="utf-8").strip()

assert expected_description in str(lattices)
14 changes: 14 additions & 0 deletions tests/test_package_import.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Sanity check that the package can be imported.

This is a regression test for the kind of failure reported against Python
3.14: an import error inside ``pyaml_test_lattice`` (or one of its
submodules) makes this test fail at collection time, on every Python version
the package claims to support.
"""

import pyaml_test_lattice


def test_package_imports_and_has_a_version():
assert isinstance(pyaml_test_lattice.__version__, str)
assert pyaml_test_lattice.__version__ != ""
14 changes: 14 additions & 0 deletions tests/test_supported_python_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Keeps the supported Python range honest.

Update MIN_PYTHON / MAX_PYTHON together with `requires-python` in
pyproject.toml and the CI matrix in .github/workflows/unit-tests.yml.
"""

import sys

MIN_PYTHON = (3, 10)
MAX_PYTHON = (3, 14)


def test_running_python_version_is_within_the_supported_range():
assert MIN_PYTHON <= sys.version_info[:2] <= MAX_PYTHON