diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 839c93f..687bd1c 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -16,36 +16,20 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install run: | python -m pip install --upgrade pip - pip install -r requirements.txt + pip install ".[test]" - name: Test run: | pytest tests -v - examples: - name: examples - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements.txt - - name: Test + - name: Examples run: | python examples/fodo.py diff --git a/README.md b/README.md index f9ccd1f..247faba 100644 --- a/README.md +++ b/README.md @@ -65,11 +65,18 @@ In order to develop and test this Python implementation locally, please follow t ```bash conda activate pals-python ``` - Please double check the environment name in the `environment.yml` file. + (This is the environment name in the `environment.yml` file.) +3. Install Python PALS in development (editable) mode: + ```bash + pip install -e ".[test]" + ``` Once you have created the environment with all the required dependencies, you can run the examples available in the [examples](https://github.com/campa-consortium/pals-python/tree/main/examples) directory. -You can also run the unit tests available in the [tests](https://github.com/campa-consortium/pals-python/tree/main/tests) directory via ``pytest tests -v``. +You can also run the unit tests available in the [tests](https://github.com/campa-consortium/pals-python/tree/main/tests) directory via +```bash +pytest tests -v +``` Here, the command line option `-v` increases the verbosity of the output. You can also use the command line option `-s` to display any test output directly in the console (useful for debugging). Please refer to [pytest's documentation](https://docs.pytest.org/en/stable/) for further details on the available command line options and/or run `pytest --help`. diff --git a/examples/fodo.py b/examples/fodo.py index 5757603..a90cbe3 100644 --- a/examples/fodo.py +++ b/examples/fodo.py @@ -1,11 +1,6 @@ import json -import os -import sys import yaml -# Add the parent directory to sys.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src/"))) - from pals import MagneticMultipoleParameters from pals import Drift from pals import Quadrupole diff --git a/pyproject.toml b/pyproject.toml index 62041ca..1c15359 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ dependencies = [ "pyyaml", "toml", ] -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name="Axel Huebl", email="axelhuebl@lbl.gov" }, { name="Edoardo Zoni", email="ezoni@lbl.gov" }, @@ -30,11 +30,11 @@ classifiers = [ "Intended Audience :: Science/Research", "Natural Language :: English", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "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", "Operating System :: OS Independent", "Topic :: Scientific/Engineering", "Topic :: Software Development", @@ -49,4 +49,4 @@ Repository = "https://github.com/campa-consortium/pals-python" Issues = "https://github.com/campa-consortium/pals-python/issues" [tool.setuptools.packages.find] -where = ["src"] \ No newline at end of file +where = ["src"] diff --git a/tests/test_schema.py b/tests/test_elements.py similarity index 66% rename from tests/test_schema.py rename to tests/test_elements.py index 74e271b..940bf1c 100644 --- a/tests/test_schema.py +++ b/tests/test_elements.py @@ -1,11 +1,3 @@ -import json -import os -import sys -import yaml - -# Add the parent directory to sys.path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src/"))) - from pydantic import ValidationError from pals import MagneticMultipoleParameters @@ -68,6 +60,8 @@ def test_Drift(): def test_Quadrupole(): + import yaml + # Create one drift element with custom name and length element_name = "quadrupole_element" element_length = 1.0 @@ -118,53 +112,3 @@ def test_BeamLine(): # Extend first line with second line line1.line.extend(line2.line) assert line1.line == [element1, element2, element3] - - -def test_yaml(): - # Create one base element - element1 = BaseElement(name="element1") - # Create one thick element - element2 = ThickElement(name="element2", length=2.0) - # Create line with both elements - line = BeamLine(name="line", line=[element1, element2]) - # Serialize the BeamLine object to YAML - yaml_data = yaml.dump(line.model_dump(), default_flow_style=False) - print(f"\n{yaml_data}") - # Write the YAML data to a test file - test_file = "line.yaml" - with open(test_file, "w") as file: - file.write(yaml_data) - # Read the YAML data from the test file - with open(test_file, "r") as file: - yaml_data = yaml.safe_load(file) - # Parse the YAML data back into a BeamLine object - loaded_line = BeamLine(**yaml_data) - # Remove the test file - os.remove(test_file) - # Validate loaded BeamLine object - assert line == loaded_line - - -def test_json(): - # Create one base element - element1 = BaseElement(name="element1") - # Create one thick element - element2 = ThickElement(name="element2", length=2.0) - # Create line with both elements - line = BeamLine(name="line", line=[element1, element2]) - # Serialize the BeamLine object to JSON - json_data = json.dumps(line.model_dump(), sort_keys=True, indent=2) - print(f"\n{json_data}") - # Write the JSON data to a test file - test_file = "line.json" - with open(test_file, "w") as file: - file.write(json_data) - # Read the JSON data from the test file - with open(test_file, "r") as file: - json_data = json.loads(file.read()) - # Parse the JSON data back into a BeamLine object - loaded_line = BeamLine(**json_data) - # Remove the test file - os.remove(test_file) - # Validate loaded BeamLine object - assert line == loaded_line diff --git a/tests/test_serialization.py b/tests/test_serialization.py new file mode 100644 index 0000000..eb718cd --- /dev/null +++ b/tests/test_serialization.py @@ -0,0 +1,57 @@ +import json +import os +import yaml + +from pals import BaseElement +from pals import ThickElement +from pals import BeamLine + + +def test_yaml(): + # Create one base element + element1 = BaseElement(name="element1") + # Create one thick element + element2 = ThickElement(name="element2", length=2.0) + # Create line with both elements + line = BeamLine(name="line", line=[element1, element2]) + # Serialize the BeamLine object to YAML + yaml_data = yaml.dump(line.model_dump(), default_flow_style=False) + print(f"\n{yaml_data}") + # Write the YAML data to a test file + test_file = "line.yaml" + with open(test_file, "w") as file: + file.write(yaml_data) + # Read the YAML data from the test file + with open(test_file, "r") as file: + yaml_data = yaml.safe_load(file) + # Parse the YAML data back into a BeamLine object + loaded_line = BeamLine(**yaml_data) + # Remove the test file + os.remove(test_file) + # Validate loaded BeamLine object + assert line == loaded_line + + +def test_json(): + # Create one base element + element1 = BaseElement(name="element1") + # Create one thick element + element2 = ThickElement(name="element2", length=2.0) + # Create line with both elements + line = BeamLine(name="line", line=[element1, element2]) + # Serialize the BeamLine object to JSON + json_data = json.dumps(line.model_dump(), sort_keys=True, indent=2) + print(f"\n{json_data}") + # Write the JSON data to a test file + test_file = "line.json" + with open(test_file, "w") as file: + file.write(json_data) + # Read the JSON data from the test file + with open(test_file, "r") as file: + json_data = json.loads(file.read()) + # Parse the JSON data back into a BeamLine object + loaded_line = BeamLine(**json_data) + # Remove the test file + os.remove(test_file) + # Validate loaded BeamLine object + assert line == loaded_line