Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
085fc2c
Add test to validate examples in the main PALS repository
EZoni Dec 17, 2025
4e722cc
Merge branch 'main' into run_examples_from_pals
EZoni Feb 9, 2026
22c0f45
Use BeamLine.from_file to read from file
EZoni Feb 9, 2026
82a2486
Start draft of new Lattice class
EZoni Feb 10, 2026
89a5e53
Reexport, rebuild new Lattice class
EZoni Feb 10, 2026
d45ba9d
Replace `line` with `branches`, list of `BeamLine`s only
EZoni Feb 13, 2026
3e0d72a
Simplify For Now
ax3l Feb 17, 2026
11db528
Revert changes to Lattice class
EZoni Feb 18, 2026
10d54f3
Merge branch 'main' into run_examples_from_pals
EZoni Feb 18, 2026
b39c90e
Merge branch 'main' into run_examples_from_pals
EZoni Feb 19, 2026
cfe45e8
Update test
EZoni Feb 19, 2026
69e73ff
Workaround for 'use' syntax
EZoni Feb 19, 2026
0a9732d
Split CI workflow into three separate workflows
EZoni Feb 19, 2026
0e9b38d
Fix upstream examples workflow
EZoni Feb 19, 2026
5960c67
Rename internal examples as local examples
EZoni Feb 19, 2026
d9fe6f3
CI Updates
ax3l Feb 20, 2026
5707a69
Rename test_upstream_examples.py to avoid confusion with pytest
EZoni Feb 20, 2026
ed6f59c
Improve upstream example validation
EZoni Feb 20, 2026
7d77edb
Improve comment on new 'use' syntax
EZoni Feb 20, 2026
926399b
Merge branch 'main' into run_examples_from_pals
EZoni Feb 24, 2026
f066a5b
Do not test with Python 3.10
EZoni Feb 24, 2026
b1c76b7
Add instructions to validation script
EZoni Feb 24, 2026
8ebee3d
Add inline comments before ad-hoc validation
EZoni Feb 24, 2026
127796e
Adopt new naming convention
EZoni Feb 25, 2026
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: pals
name: tests

on:
push:
Expand All @@ -7,15 +7,15 @@ on:
pull_request:

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-pals-python
group: ${{ github.ref }}-${{ github.head_ref }}-local-examples
Copy link
Copy Markdown
Member

@ax3l ax3l Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name local is confusing.

Maybe inrepo vs standard/upstream repo?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had done some brainstorming on this and came up with the pair local/upstream, but let's revisit as you suggest.

Regarding inrepo, I would prefer to use a real single word (rather than a "crasis" of two words), if possible.

I propose some alternative pairs here, let me know if you like any of these:

  • repo/standard
  • repo/reference
  • implementation/standard
  • implementation/reference

The rationale behind implementation being that these are the examples shipped with the Python implementation of the standard, rather than the examples shipped with the standard itself.

Copy link
Copy Markdown
Member

@ax3l ax3l Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just examples?

This refers to the local repo anyway by default and the other one is "standard/online examples"?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I applied this suggestion in 127796e.

Now we have:

  • unit tests
  • examples (shipped within this repository)
  • standard examples (shipped within the main PALS repository)

Since you pre-approved the PR, I will merge and we can always revisit the details anytime.

cancel-in-progress: true

permissions:
contents: read # access to check out code and install dependencies

jobs:
tests:
name: tests
local-examples:
name: local examples
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -30,9 +30,6 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install ".[test]"
- name: Test
run: |
pytest tests -v
- name: Examples
- name: Run local examples
run: |
python examples/fodo.py
35 changes: 35 additions & 0 deletions .github/workflows/unit_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: tests

on:
push:
branches:
- "main"
pull_request:

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-unit-tests
cancel-in-progress: true

permissions:
contents: read # access to check out code and install dependencies

jobs:
Comment thread
ax3l marked this conversation as resolved.
unit-tests:
name: unit tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install
run: |
python -m pip install --upgrade pip
pip install ".[test]"
- name: Run unit tests
run: |
pytest tests -v
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
45 changes: 45 additions & 0 deletions .github/workflows/upstream_examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: tests
Comment thread
EZoni marked this conversation as resolved.
Outdated

on:
push:
branches:
- "main"
pull_request:

concurrency:
group: ${{ github.ref }}-${{ github.head_ref }}-upstream-examples
cancel-in-progress: true

permissions:
contents: read # access to check out code and install dependencies

jobs:
upstream-examples:
name: upstream examples
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v6
- name: Checkout upstream PALS repo
uses: actions/checkout@v6
with:
repository: pals-project/pals
path: pals_temp
fetch-depth: 1
sparse-checkout: |
examples/
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install
run: |
python -m pip install --upgrade pip
pip install ".[test]"
- name: Run upstream examples
run: |
for file in pals_temp/examples/*.pals.yaml; do
python tests/validate_upstream_examples.py --path "${file}"
done
10 changes: 10 additions & 0 deletions src/pals/kinds/mixin/all_element_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,17 @@ def unpack_element_list_structure(
f"but we got {item!r}"
)
name, fields = list(item.items())[0]
# In addition to the existing shorthand `- element_name`
# (a plain string reference), also allow the alternative
# reference syntax `- use: element_name`.
# If the value is not a dict but the key is 'use',
# treat it as a reference to an existing element name
# and wrap it in a PlaceholderName so downstream code
# can resolve it.
if not isinstance(fields, dict):
if name == "use" and isinstance(fields, str):
new_list.append(PlaceholderName(fields))
continue
Comment thread
EZoni marked this conversation as resolved.
raise TypeError(
f"Value for element key {name!r} must be a dict (the element's properties), "
f"but we got {fields!r}"
Expand Down
49 changes: 49 additions & 0 deletions tests/validate_upstream_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"""Utility script to validate upstream PALS example files.

This script is not run by pytest and is intended to be used as a standalone script.
Run it from the repository root like:

python tests/validate_upstream_examples.py --path /path/to/example.pals.yaml

Before running, download the desired upstream PALS example files from pals-project/pals/examples.
"""

import argparse

from pals import load
from pals.kinds import PlaceholderName
from pals.kinds.BeamLine import BeamLine
from pals.kinds.Drift import Drift
from pals.kinds.Lattice import Lattice
from pals.kinds.Quadrupole import Quadrupole


def main():
# Parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"--path",
required=True,
help="Path to the example file",
)
args = parser.parse_args()
example_file = args.path
# Parse and validate YAML data from file
lattice = load(example_file)
# The following assertions are based on the upstream PALS example file
# fodo.pals.yaml from pals-project/pals/examples
assert isinstance(lattice.facility[0], Drift)
assert lattice.facility[0].name == "drift1"
assert isinstance(lattice.facility[1], Quadrupole)
assert lattice.facility[1].name == "quad1"
assert isinstance(lattice.facility[2], BeamLine)
assert lattice.facility[2].name == "fodo_cell"
assert isinstance(lattice.facility[3], BeamLine)
assert lattice.facility[3].name == "fodo_channel"
assert isinstance(lattice.facility[4], Lattice)
assert lattice.facility[4].name == "fodo_lattice"
assert isinstance(lattice.facility[5], PlaceholderName)


if __name__ == "__main__":
main()