Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CI tests for Python 3.12 #65

Merged
merged 2 commits into from
Dec 8, 2023
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
6 changes: 6 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
6 changes: 3 additions & 3 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
dicom-version: ["2023c"]
steps:
- uses: actions/checkout@v3
Expand All @@ -32,15 +32,15 @@ jobs:
id: cache-dicom
uses: actions/cache@v3
with:
path: dicom_validator/tests/fixtures
path: dicom_validator/tests/fixtures/standard
key: ${{ matrix.dicom-version }}
enableCrossOsArchive: true

- name: Download DICOM standard
if: steps.cache-dicom.outputs.cache-hit != 'true'
run: |
pip install -e .
python .github/workflows/get_revision.py ${{ matrix.dicom-version }} "`pwd`/dicom_validator/tests/fixtures"
python .github/workflows/get_revision.py ${{ matrix.dicom-version }} "`pwd`/dicom_validator/tests/fixtures/standard"

- name: Run tests with coverage
run: |
Expand Down
29 changes: 16 additions & 13 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ The released versions correspond to PyPi releases.

## [Version 0.5.0] (Unreleased)

### Infrastructure
* add CI tests for Python 3.12

## [Version 0.4.1](https://pypi.python.org/pypi/dicom-validator/0.4.1) (2023-11-09)
Mostly a bugfix release for the condition parser.

Expand All @@ -11,14 +14,14 @@ Mostly a bugfix release for the condition parser.

### Features
* added handling of conditional includes (needed for SR documents)
(see [#39](../.. /issues/39))
(see [#39](../../issues/39))

### Fixes
* an empty tag with type 1C was not handled as an error
* Condition parser: the value index for some expressions is now correctly parsed
* Condition parser: the parsing is now stricter to avoid some false positives
* Condition parser: condition for AT values have not been correctly parsed if
the condition used equality comparison (see [#58](../.. /issues/58))
the condition used equality comparison (see [#58](../../issues/58))

### Changes
* `lxml` is used instead of `xml` to speed up the xml parsing
Expand All @@ -32,14 +35,14 @@ Mostly a bugfix release for the condition parser.
Adds support for functional group macros.

### Features
* added support for validating functional group macros, see [#27](../.. /issues/27)
* added support for validating functional group macros, see [#27](../../issues/27)
* added option `--recreate-json` for testing purposes (per default, the json files are only
recreated after a `dicom-validator` version change)

### Fixes
* fixed handling of unverifiable and condition, see [#32](../.. /issues/32)
* fixed too broad matching for "otherwise" condition, see [#29](../.. /issues/29)
* fixed too strict handling without "otherwise" condition, see [#38](../.. /issues/38)
* fixed handling of unverifiable and condition, see [#32](../../issues/32)
* fixed too broad matching for "otherwise" condition, see [#29](../../issues/29)
* fixed too strict handling without "otherwise" condition, see [#38](../../issues/38)
* ignore private tags during validation (had been flagged as unexpected)

### Infrastructure
Expand All @@ -52,12 +55,12 @@ Fixes several issues with the condition parser.
* Condition parser: multiple or expressions handled correctly
* Condition parser: handle a few more complicated conditions
* Condition parser: handle conditions without values,
see [#15](../.. /issues/15)
* Condition parser: fixed handling of "zero" and "non-zero" values
see [#17](../.. /issues/17)
see [#15](../../issues/15)
* Condition parser: fixed handling of "zero" and "non-zero" values,
see [#17](../../issues/17)
* Condition parser: handle a few more simple expressions
* Condition parser: ignore equality conditions with missing values
(caused crash, see [#20](../.. /issues/20)
(caused crash, see [#20](../../issues/20))

### Changes
* Removed support for Python 3.6, added support for Python 3.11
Expand All @@ -70,14 +73,14 @@ Fixes a regression introduced with the last release.

### Fixes
- fixed regression that broke the validator command line tool,
see [#9](../../issues/9))
see [#9](../../issues/9)

## [Version 0.3.3](https://pypi.python.org/pypi/dicom-validator/0.3.3) (2021-11-20)
This is a bugfix release.

### Fixes
- all tags including PixelData are now loaded to account for dependencies on PixelData
see [#6](../../issues/6))
(see [#6](../../issues/6))

## [Version 0.3.2](https://pypi.python.org/pypi/dicom-validator/0.3.2) (2021-07-30)
Renamed from dcm-spec-tools to dicom-validator and moved into pydicom organization.
Expand All @@ -97,7 +100,7 @@ No functional changes have been made in this release.

### Fixes
* handled empty rows in some editions (caused crash for 2019 edition)
* account for added columns in IOD and UID tables see [#3](../../issues/3))
* account for added columns in IOD and UID tables (see [#3](../../issues/3))

### Infrastructure
* changed CI to GitHub actions
Expand Down
3 changes: 0 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
## Validator

#### IOD Validator
* module checks
* check condition for conditional modules :on:
* check optional modules for consistence
* check tags
* check condition for 1C/2C attributes
* several "Required" statements
Expand Down
2 changes: 1 addition & 1 deletion dicom_validator/spec_reader/part3_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def module_description(self, section):
"""
if section not in self._module_descriptions:
section_node = self._get_section_node(section)
if section_node:
if section_node is not None:
description = self._parse_module_description(section_node)
self._module_descriptions[section] = description
try:
Expand Down
6 changes: 4 additions & 2 deletions dicom_validator/spec_reader/spec_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ def _get_doc_tree(self):
raise SpecReaderFileError(f"Missing docbook file {doc_name}")
try:
self._doc_trees[self.part_nr] = ElementTree.parse(doc_name)
except ElementTree.ParseError:
raise SpecReaderFileError(f"Parse error in docbook file {doc_name}")
except ElementTree.ParseError as e:
raise SpecReaderFileError(
f"Parse error in docbook file {doc_name}: {e}"
)
return self._doc_trees.get(self.part_nr)

def _get_doc_root(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["2014a", "2014b", "2014c", "2015a", "2015b", "2015c", "2016a", "2016b", "2016c", "2016d", "2016e", "2017a", "2017b", "2017c", "2017d", "2017e", "2018a", "2018b", "2018c", "2018d", "2018e", "2019a", "2019b", "2019c", "2019d", "2019e", "2020a", "2020b", "2020c", "2020d", "2020e", "2021a", "2021b", "2021c", "2021d", "2021e", "2022a", "2022b", "2022c", "2022d", "2022e", "2023a", "2023b", "2023c"]
["2014a", "2014b", "2014c", "2015a", "2015b", "2015c", "2016a", "2016b", "2016c", "2016d", "2016e", "2017a", "2017b", "2017c", "2017d", "2017e", "2018a", "2018b", "2018c", "2018d", "2018e", "2019a", "2019b", "2019c", "2019d", "2019e", "2020a", "2020b", "2020c", "2020d", "2020e", "2021a", "2021b", "2021c", "2021d", "2021e", "2022a", "2022b", "2022c", "2022d", "2022e", "2023a", "2023b", "2023c", "2023d", "2023e"]
13 changes: 9 additions & 4 deletions dicom_validator/tests/spec_reader/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,20 @@ def fixture_path():


@pytest.fixture(scope="session")
def spec_fixture_path(fixture_path):
yield fixture_path / CURRENT_REVISION / "docbook"
def standard_path(fixture_path):
yield fixture_path / "standard"


@pytest.fixture(scope="session")
def dict_info(fixture_path):
def spec_fixture_path(standard_path):
yield standard_path / CURRENT_REVISION / "docbook"


@pytest.fixture(scope="session")
def dict_info(standard_path):
from dicom_validator.spec_reader.edition_reader import EditionReader

json_fixture_path = fixture_path / CURRENT_REVISION / "json"
json_fixture_path = standard_path / CURRENT_REVISION / "json"
with open(json_fixture_path / EditionReader.dict_info_json) as info_file:
info = json.load(info_file)
yield info
Expand Down
15 changes: 9 additions & 6 deletions dicom_validator/tests/spec_reader/test_edition_reader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import shutil
import time
from pathlib import Path
from unittest.mock import patch
Expand Down Expand Up @@ -253,13 +252,17 @@ def create_json_files(cls, docbook_path, json_path):

@patch("dicom_validator.spec_reader.edition_reader.urlretrieve")
@patch("dicom_validator.spec_reader.spec_reader.ElementTree", ElementTree)
def test_get_non_existing_revision(retrieve_mock, fs, fixture_path, edition_path):
def test_get_non_existing_revision(
retrieve_mock, fs, fixture_path, standard_path, edition_path
):
def retrieve(url, path):
# copy over the data from the existing fixture as fake download
source = str(path).replace("2014c", "dummy")
shutil.copy(source, str(path))
# map the data from the existing fixture as fake download
source = str(path).replace("2014c", "dummy").replace("standard" + os.sep, "")
fs.add_real_file(source, target_path=path)

root_path = Path(fs.add_real_directory(fixture_path).path)
root_dir = fs.add_real_directory(standard_path).path
fs.add_real_directory(fixture_path / "dummy", target_path=standard_path / "dummy")
root_path = Path(root_dir)
reader = EditionReader(root_path)
retrieve_mock.side_effect = lambda url, path: retrieve(url, path)
json_path = root_path / "2014c" / "json"
Expand Down
13 changes: 10 additions & 3 deletions dicom_validator/tests/test_cmdline_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,33 @@

from dicom_validator.validate_iods import main

CURRENT_REVISION = "2023c"


@pytest.fixture(scope="session")
def fixture_path():
yield Path(__file__).parent / "fixtures"


@pytest.fixture(scope="session")
def standard_path(fixture_path):
yield fixture_path / "standard"


@pytest.fixture
def dicom_fixture_path(fixture_path):
yield fixture_path / "dicom"


def test_validate_sr(caplog, fixture_path, dicom_fixture_path):
def test_validate_sr(caplog, standard_path, dicom_fixture_path):
rtdose_path = dicom_fixture_path / "rtdose.dcm"
# recreate json files to avoid getting the cached ones
# relies on the fact that this test is run first
cmd_line_args = [
"-src",
str(fixture_path),
str(standard_path),
"-r",
"local",
CURRENT_REVISION,
"--recreate-json",
str(rtdose_path),
]
Expand Down
9 changes: 7 additions & 2 deletions dicom_validator/tests/validator/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,13 @@ def pytest_configure(config):


@pytest.fixture(scope="session")
def json_fixture_path():
yield Path(__file__).parent.parent / "fixtures" / CURRENT_REVISION / "json"
def standard_path():
yield Path(__file__).parent.parent / "fixtures" / "standard"


@pytest.fixture(scope="session")
def json_fixture_path(standard_path):
yield standard_path / CURRENT_REVISION / "json"


@pytest.fixture(scope="session")
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Operating System :: POSIX :: Linux",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
Expand Down