xdiffly 0.2.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. xdiffly-0.2.6/PKG-INFO +210 -0
  2. xdiffly-0.2.6/README.md +189 -0
  3. xdiffly-0.2.6/pyproject.toml +86 -0
  4. xdiffly-0.2.6/xdiff/__init__.py +25 -0
  5. xdiffly-0.2.6/xdiff/comparators/__init__.py +19 -0
  6. xdiffly-0.2.6/xdiff/comparators/base.py +20 -0
  7. xdiffly-0.2.6/xdiff/comparators/netcdf.py +286 -0
  8. xdiffly-0.2.6/xdiff/compare/__init__.py +38 -0
  9. xdiffly-0.2.6/xdiff/compare/ncdiff.py +34 -0
  10. xdiffly-0.2.6/xdiff/conf/__init__.py +26 -0
  11. xdiffly-0.2.6/xdiff/conf/global_settings.py +26 -0
  12. xdiffly-0.2.6/xdiff/core/__init__.py +15 -0
  13. xdiffly-0.2.6/xdiff/core/dask_runtime.py +114 -0
  14. xdiffly-0.2.6/xdiff/core/main.py +84 -0
  15. xdiffly-0.2.6/xdiff/core/service.py +242 -0
  16. xdiffly-0.2.6/xdiff/discovery/__init__.py +5 -0
  17. xdiffly-0.2.6/xdiff/discovery/filesystem.py +20 -0
  18. xdiffly-0.2.6/xdiff/exceptions/__init__.py +13 -0
  19. xdiffly-0.2.6/xdiff/exceptions/all_nan.py +2 -0
  20. xdiffly-0.2.6/xdiff/exceptions/last_timestep.py +2 -0
  21. xdiffly-0.2.6/xdiff/exceptions/no_match.py +5 -0
  22. xdiffly-0.2.6/xdiff/exceptions/unsupported_artifact.py +5 -0
  23. xdiffly-0.2.6/xdiff/management/__init__.py +7 -0
  24. xdiffly-0.2.6/xdiff/management/cli.py +248 -0
  25. xdiffly-0.2.6/xdiff/matching/__init__.py +5 -0
  26. xdiffly-0.2.6/xdiff/matching/default.py +42 -0
  27. xdiffly-0.2.6/xdiff/model/__init__.py +20 -0
  28. xdiffly-0.2.6/xdiff/model/artifact.py +58 -0
  29. xdiffly-0.2.6/xdiff/model/compare_result.py +32 -0
  30. xdiffly-0.2.6/xdiff/model/comparison.py +88 -0
  31. xdiffly-0.2.6/xdiff/model/match.py +15 -0
  32. xdiffly-0.2.6/xdiff/model/report.py +42 -0
  33. xdiffly-0.2.6/xdiff/model/request.py +88 -0
  34. xdiffly-0.2.6/xdiff/printlib/__init__.py +2 -0
  35. xdiffly-0.2.6/xdiff/printlib/formatter.py +219 -0
  36. xdiffly-0.2.6/xdiff/printlib/progress.py +335 -0
  37. xdiffly-0.2.6/xdiff/utils/__init__.py +0 -0
  38. xdiffly-0.2.6/xdiff/utils/log.py +64 -0
  39. xdiffly-0.2.6/xdiff/utils/module_loading.py +30 -0
  40. xdiffly-0.2.6/xdiff/utils/regex.py +65 -0
xdiffly-0.2.6/PKG-INFO ADDED
@@ -0,0 +1,210 @@
1
+ Metadata-Version: 2.3
2
+ Name: xdiffly
3
+ Version: 0.2.6
4
+ Summary: X-Diff: a general-purpose tool for exploring differences between datasets (netCDF today, more targets to come)
5
+ Author: Antonio Mariani
6
+ Author-email: Antonio Mariani <antonio.mariani@cmcc.it>
7
+ Requires-Dist: xarray>=2024.6.0,<2025.0.0
8
+ Requires-Dist: pandas>=2.2.2,<3.0.0
9
+ Requires-Dist: netcdf4>=1.7.1,<2.0.0
10
+ Requires-Dist: rich>=13.7.1,<14.0.0
11
+ Requires-Dist: click>=8.3.1,<9.0.0
12
+ Requires-Dist: dask>=2024.6.0,<2025.0.0
13
+ Requires-Dist: distributed>=2024.6.0,<2025.0.0
14
+ Requires-Dist: bokeh>=3.1.0,<4.0.0
15
+ Requires-Python: >=3.10, <3.14
16
+ Project-URL: Changelog, https://github.com/anto6715/X-Diff/blob/master/CHANGES.md
17
+ Project-URL: Homepage, https://github.com/anto6715/X-Diff
18
+ Project-URL: Issues, https://github.com/anto6715/X-Diff/issues
19
+ Project-URL: Repository, https://github.com/anto6715/X-Diff
20
+ Description-Content-Type: text/markdown
21
+
22
+ # X-Diff
23
+
24
+ `xdiff` is the CLI for **X-Diff**, a general diff tool name where `X` can stand for different comparison targets.
25
+ Today, X-Diff supports detailed comparison of netCDF files and helps users identify differences between datasets stored
26
+ in netCDF format.
27
+
28
+ ![Python](https://img.shields.io/badge/Python-3.10--3.13-blue.svg)
29
+ [![Tests](https://github.com/anto6715/ncCompare/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/anto6715/ncCompare/actions/workflows/tests.yml)
30
+ [![Coverage](https://codecov.io/gh/anto6715/ncCompare/graph/badge.svg?branch=master)](https://codecov.io/gh/anto6715/ncCompare)
31
+
32
+ ![Output](https://github.com/anto6715/ncCompare/raw/master/docs/output.png)
33
+
34
+ ## Installation
35
+
36
+ ### Install uv
37
+
38
+ Follow the official installer:
39
+
40
+ ```shell
41
+ curl -LsSf https://astral.sh/uv/install.sh | sh
42
+ ```
43
+
44
+ ### Install in a local virtual environment (recommended for development)
45
+
46
+ `xdiff` currently supports Python 3.10 through 3.13. Create the project-local environment and install dependencies from `uv.lock` with:
47
+
48
+ ```shell
49
+ uv sync --python 3.13
50
+ ```
51
+
52
+ Run the CLI through uv:
53
+
54
+ ```shell
55
+ uv run xdiff --help
56
+ ```
57
+
58
+ ### Install globally with uv tool
59
+
60
+ The package is published on PyPI as `xdiffly`; it installs the `xdiff` command.
61
+
62
+ ```shell
63
+ uv tool install --python 3.13 xdiffly
64
+ ```
65
+
66
+ `uv tool install` installs `xdiffly` in uv's global tool environment (similar to `pipx`), not inside this repository's `.venv`. After installation, run it as `xdiff`.
67
+
68
+ ## Usage
69
+
70
+ From a source checkout, prefix commands with `uv run`. If you installed with `uv tool install`, use `xdiff` directly.
71
+
72
+ ```shell
73
+ uv run xdiff [OPTIONS] COMMAND [ARGS]...
74
+
75
+ netCDF comparison tool.
76
+
77
+ Options:
78
+ --version Show the version and exit.
79
+ -h, --help Show this message and exit.
80
+
81
+ Commands:
82
+ dirs Compare two directories of netCDF files.
83
+ files Compare two netCDF files directly, even if their filenames differ.
84
+
85
+ ```
86
+
87
+ ### Select Variables
88
+
89
+ It is possible to choose which parameter to compare:
90
+
91
+ ```shell
92
+ uv run xdiff dirs folder1 folder2 -v votemper -v vosaline
93
+ ```
94
+
95
+ ![Variables](https://github.com/anto6715/ncCompare/raw/master/docs/variables.png)
96
+
97
+ ### Filter files
98
+
99
+ By default **xdiff** iterates over all files in **folder1** and expects to find them in **folder2**. Using filters,
100
+ it is possible to select only a subset of input files. For example:
101
+
102
+ ```shell
103
+ uv run xdiff dirs folder1 folder2 -f "*_grid_T.nc"
104
+ ```
105
+
106
+ ### Compare files with different filenames
107
+
108
+ It is possible to compare two files with different filenames directly:
109
+
110
+ ```shell
111
+ uv run xdiff files a/my-simu_19820101_grid_T.nc b/another-exp_19820101_grid_T.nc
112
+ ```
113
+
114
+ For directory comparisons, files with different names can still be matched if they share a common substring.
115
+ For example, given:
116
+
117
+ - `a/my-simu_19820101_grid_T.nc`
118
+ - `b/another-exp_19820101_grid_T.nc`
119
+
120
+ Pass the common part as a regex pattern:
121
+
122
+ ```shell
123
+ uv run xdiff dirs folder1 folder2 --common-pattern "\d{8}"
124
+ ```
125
+
126
+ The pattern is matched against both filenames using `re.findall`. Two files are considered a pair when the
127
+ pattern produces the same match in both names — in this case the shared date `19820101`.
128
+
129
+ ### Dask file-level execution
130
+
131
+ `xdiff` still defaults to serial execution, but Dask support is installed by default. When you want Dask-backed file-level execution, see [docs/dask.md](docs/dask.md) for local-cluster and external-scheduler examples.
132
+
133
+ ## Testing
134
+
135
+ GitHub Actions runs the test suite on every pull request and on pushes to `master`. Coverage is uploaded from CI to Codecov, which powers the README coverage badge.
136
+
137
+ To run the same checks locally, install the project and dev dependencies with a single command:
138
+
139
+ ```shell
140
+ uv sync --group dev
141
+ ```
142
+
143
+ Then run the suite:
144
+
145
+ ```shell
146
+ uv run pytest --cov --cov-report=term-missing --cov-report=xml
147
+ ```
148
+
149
+ The Codecov badge will start showing a real percentage after the workflow runs successfully on GitHub and the repository is connected to Codecov.
150
+
151
+ ## Changelog
152
+
153
+ This repository uses `towncrier` for release notes. Every pull request must include a changelog entry under `changes.d/` for user-facing changes, for example:
154
+
155
+ ```text
156
+ changes.d/123.bugfix.md
157
+ changes.d/124.doc.md
158
+ changes.d/+internal-cleanup.misc.md
159
+ ```
160
+
161
+ Use the pull request number as the filename prefix when you want Towncrier to render a linked PR reference. With the current configuration, `changes.d/123.bugfix.md` will render as `[#123]` in `CHANGES.md`. Use `+` instead of a number when there is no associated PR to link.
162
+
163
+ Create a changelog entry with the Towncrier CLI:
164
+
165
+ ```shell
166
+ uv run towncrier create 123.bugfix.md --content "Improved CLI filtering so directory comparisons skip unrelated files more reliably."
167
+ ```
168
+
169
+ Create an orphan entry when there is no associated PR:
170
+
171
+ ```shell
172
+ uv run towncrier create +internal-cleanup.misc.md --content "Cleaned up internal comparison helpers and simplified related tests."
173
+ ```
174
+
175
+ If you omit `--content`, `towncrier create` will open your editor so you can write the entry interactively.
176
+
177
+ Validate or preview changelog entries locally with:
178
+
179
+ ```shell
180
+ uv run towncrier build --draft --version 0.2.6
181
+ ```
182
+
183
+ To mirror the CI-style branch check after committing or staging your changelog entry:
184
+
185
+ ```shell
186
+ git fetch origin master:refs/remotes/origin/master
187
+ uv run towncrier check --compare-with origin/master --staged
188
+ ```
189
+
190
+ Release notes are generated from `release/X.Y.Z` branches. Open a PR from `release/X.Y.Z` to `master`, and CI will:
191
+
192
+ 1. set `pyproject.toml` to version `X.Y.Z`
193
+ 2. run `towncrier build --yes --version X.Y.Z`
194
+ 3. commit the updated `CHANGES.md` and consumed changelog entries back to the release branch
195
+
196
+ In normal feature work, contributors should create entries with `towncrier create` and optionally preview them with `towncrier build --draft`. The final non-draft `towncrier build --yes` step is handled by the release workflow in [`.github/workflows/release-changelog.yml`](.github/workflows/release-changelog.yml).
197
+
198
+ After the release PR is merged, merge `master` back into `develop` so the generated changelog and consumed entry deletions return to the integration branch.
199
+
200
+ ## Author
201
+
202
+ - Antonio Mariani (antonio.mariani@cmcc.it)
203
+
204
+ ## Contributing
205
+
206
+ Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
207
+
208
+ ## Contact
209
+
210
+ For any questions or suggestions, please open an issue on the project's GitHub repository.
@@ -0,0 +1,189 @@
1
+ # X-Diff
2
+
3
+ `xdiff` is the CLI for **X-Diff**, a general diff tool name where `X` can stand for different comparison targets.
4
+ Today, X-Diff supports detailed comparison of netCDF files and helps users identify differences between datasets stored
5
+ in netCDF format.
6
+
7
+ ![Python](https://img.shields.io/badge/Python-3.10--3.13-blue.svg)
8
+ [![Tests](https://github.com/anto6715/ncCompare/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/anto6715/ncCompare/actions/workflows/tests.yml)
9
+ [![Coverage](https://codecov.io/gh/anto6715/ncCompare/graph/badge.svg?branch=master)](https://codecov.io/gh/anto6715/ncCompare)
10
+
11
+ ![Output](https://github.com/anto6715/ncCompare/raw/master/docs/output.png)
12
+
13
+ ## Installation
14
+
15
+ ### Install uv
16
+
17
+ Follow the official installer:
18
+
19
+ ```shell
20
+ curl -LsSf https://astral.sh/uv/install.sh | sh
21
+ ```
22
+
23
+ ### Install in a local virtual environment (recommended for development)
24
+
25
+ `xdiff` currently supports Python 3.10 through 3.13. Create the project-local environment and install dependencies from `uv.lock` with:
26
+
27
+ ```shell
28
+ uv sync --python 3.13
29
+ ```
30
+
31
+ Run the CLI through uv:
32
+
33
+ ```shell
34
+ uv run xdiff --help
35
+ ```
36
+
37
+ ### Install globally with uv tool
38
+
39
+ The package is published on PyPI as `xdiffly`; it installs the `xdiff` command.
40
+
41
+ ```shell
42
+ uv tool install --python 3.13 xdiffly
43
+ ```
44
+
45
+ `uv tool install` installs `xdiffly` in uv's global tool environment (similar to `pipx`), not inside this repository's `.venv`. After installation, run it as `xdiff`.
46
+
47
+ ## Usage
48
+
49
+ From a source checkout, prefix commands with `uv run`. If you installed with `uv tool install`, use `xdiff` directly.
50
+
51
+ ```shell
52
+ uv run xdiff [OPTIONS] COMMAND [ARGS]...
53
+
54
+ netCDF comparison tool.
55
+
56
+ Options:
57
+ --version Show the version and exit.
58
+ -h, --help Show this message and exit.
59
+
60
+ Commands:
61
+ dirs Compare two directories of netCDF files.
62
+ files Compare two netCDF files directly, even if their filenames differ.
63
+
64
+ ```
65
+
66
+ ### Select Variables
67
+
68
+ It is possible to choose which parameter to compare:
69
+
70
+ ```shell
71
+ uv run xdiff dirs folder1 folder2 -v votemper -v vosaline
72
+ ```
73
+
74
+ ![Variables](https://github.com/anto6715/ncCompare/raw/master/docs/variables.png)
75
+
76
+ ### Filter files
77
+
78
+ By default **xdiff** iterates over all files in **folder1** and expects to find them in **folder2**. Using filters,
79
+ it is possible to select only a subset of input files. For example:
80
+
81
+ ```shell
82
+ uv run xdiff dirs folder1 folder2 -f "*_grid_T.nc"
83
+ ```
84
+
85
+ ### Compare files with different filenames
86
+
87
+ It is possible to compare two files with different filenames directly:
88
+
89
+ ```shell
90
+ uv run xdiff files a/my-simu_19820101_grid_T.nc b/another-exp_19820101_grid_T.nc
91
+ ```
92
+
93
+ For directory comparisons, files with different names can still be matched if they share a common substring.
94
+ For example, given:
95
+
96
+ - `a/my-simu_19820101_grid_T.nc`
97
+ - `b/another-exp_19820101_grid_T.nc`
98
+
99
+ Pass the common part as a regex pattern:
100
+
101
+ ```shell
102
+ uv run xdiff dirs folder1 folder2 --common-pattern "\d{8}"
103
+ ```
104
+
105
+ The pattern is matched against both filenames using `re.findall`. Two files are considered a pair when the
106
+ pattern produces the same match in both names — in this case the shared date `19820101`.
107
+
108
+ ### Dask file-level execution
109
+
110
+ `xdiff` still defaults to serial execution, but Dask support is installed by default. When you want Dask-backed file-level execution, see [docs/dask.md](docs/dask.md) for local-cluster and external-scheduler examples.
111
+
112
+ ## Testing
113
+
114
+ GitHub Actions runs the test suite on every pull request and on pushes to `master`. Coverage is uploaded from CI to Codecov, which powers the README coverage badge.
115
+
116
+ To run the same checks locally, install the project and dev dependencies with a single command:
117
+
118
+ ```shell
119
+ uv sync --group dev
120
+ ```
121
+
122
+ Then run the suite:
123
+
124
+ ```shell
125
+ uv run pytest --cov --cov-report=term-missing --cov-report=xml
126
+ ```
127
+
128
+ The Codecov badge will start showing a real percentage after the workflow runs successfully on GitHub and the repository is connected to Codecov.
129
+
130
+ ## Changelog
131
+
132
+ This repository uses `towncrier` for release notes. Every pull request must include a changelog entry under `changes.d/` for user-facing changes, for example:
133
+
134
+ ```text
135
+ changes.d/123.bugfix.md
136
+ changes.d/124.doc.md
137
+ changes.d/+internal-cleanup.misc.md
138
+ ```
139
+
140
+ Use the pull request number as the filename prefix when you want Towncrier to render a linked PR reference. With the current configuration, `changes.d/123.bugfix.md` will render as `[#123]` in `CHANGES.md`. Use `+` instead of a number when there is no associated PR to link.
141
+
142
+ Create a changelog entry with the Towncrier CLI:
143
+
144
+ ```shell
145
+ uv run towncrier create 123.bugfix.md --content "Improved CLI filtering so directory comparisons skip unrelated files more reliably."
146
+ ```
147
+
148
+ Create an orphan entry when there is no associated PR:
149
+
150
+ ```shell
151
+ uv run towncrier create +internal-cleanup.misc.md --content "Cleaned up internal comparison helpers and simplified related tests."
152
+ ```
153
+
154
+ If you omit `--content`, `towncrier create` will open your editor so you can write the entry interactively.
155
+
156
+ Validate or preview changelog entries locally with:
157
+
158
+ ```shell
159
+ uv run towncrier build --draft --version 0.2.6
160
+ ```
161
+
162
+ To mirror the CI-style branch check after committing or staging your changelog entry:
163
+
164
+ ```shell
165
+ git fetch origin master:refs/remotes/origin/master
166
+ uv run towncrier check --compare-with origin/master --staged
167
+ ```
168
+
169
+ Release notes are generated from `release/X.Y.Z` branches. Open a PR from `release/X.Y.Z` to `master`, and CI will:
170
+
171
+ 1. set `pyproject.toml` to version `X.Y.Z`
172
+ 2. run `towncrier build --yes --version X.Y.Z`
173
+ 3. commit the updated `CHANGES.md` and consumed changelog entries back to the release branch
174
+
175
+ In normal feature work, contributors should create entries with `towncrier create` and optionally preview them with `towncrier build --draft`. The final non-draft `towncrier build --yes` step is handled by the release workflow in [`.github/workflows/release-changelog.yml`](.github/workflows/release-changelog.yml).
176
+
177
+ After the release PR is merged, merge `master` back into `develop` so the generated changelog and consumed entry deletions return to the integration branch.
178
+
179
+ ## Author
180
+
181
+ - Antonio Mariani (antonio.mariani@cmcc.it)
182
+
183
+ ## Contributing
184
+
185
+ Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
186
+
187
+ ## Contact
188
+
189
+ For any questions or suggestions, please open an issue on the project's GitHub repository.
@@ -0,0 +1,86 @@
1
+ [project]
2
+ name = "xdiffly"
3
+ version = "0.2.6"
4
+ description = "X-Diff: a general-purpose tool for exploring differences between datasets (netCDF today, more targets to come)"
5
+ authors = [
6
+ {name = "Antonio Mariani", email = "antonio.mariani@cmcc.it"}
7
+ ]
8
+ readme = "README.md"
9
+ requires-python = ">=3.10,<3.14"
10
+ dependencies = [
11
+ "xarray>=2024.6.0,<2025.0.0",
12
+ "pandas>=2.2.2,<3.0.0",
13
+ "netcdf4>=1.7.1,<2.0.0",
14
+ "rich>=13.7.1,<14.0.0",
15
+ "click>=8.3.1,<9.0.0",
16
+ "dask>=2024.6.0,<2025.0.0",
17
+ "distributed>=2024.6.0,<2025.0.0",
18
+ "bokeh>=3.1.0,<4.0.0",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/anto6715/X-Diff"
23
+ Repository = "https://github.com/anto6715/X-Diff"
24
+ Issues = "https://github.com/anto6715/X-Diff/issues"
25
+ Changelog = "https://github.com/anto6715/X-Diff/blob/master/CHANGES.md"
26
+
27
+ [project.scripts]
28
+ xdiff = "xdiff.management:start_from_command_line_interface"
29
+
30
+ [dependency-groups]
31
+ dev = [
32
+ "pytest>=8.0,<9.0.0",
33
+ "pytest-cov>=5.0,<6.0.0",
34
+ "towncrier>=25.8,<26.0.0",
35
+ ]
36
+
37
+ [build-system]
38
+ requires = ["uv_build>=0.9.5,<0.10.0"]
39
+ build-backend = "uv_build"
40
+
41
+ [tool.uv.build-backend]
42
+ module-name = "xdiff"
43
+ module-root = ""
44
+
45
+ [tool.pytest.ini_options]
46
+ filterwarnings = [
47
+ "ignore:numpy.ndarray size changed, may indicate binary incompatibility.*:RuntimeWarning",
48
+ ]
49
+
50
+ [tool.coverage.run]
51
+ source = ["xdiff"]
52
+
53
+ [tool.coverage.report]
54
+ show_missing = true
55
+
56
+ [tool.towncrier]
57
+ directory = "changes.d"
58
+ name = "X-Diff"
59
+ package = "xdiff"
60
+ filename = "CHANGES.md"
61
+ start_string = "<!-- towncrier release notes start -->\n"
62
+ title_format = "## __[xdiff-{version}](https://github.com/anto6715/X-Diff/tree/{version}) - {project_date}__"
63
+ issue_format = "[#{issue}](https://github.com/anto6715/X-Diff/pull/{issue})"
64
+ underlines = ["", "", ""]
65
+ template = "changes.d/changelog_template.jinja"
66
+ changelog_format = "markdown"
67
+
68
+ [[tool.towncrier.type]]
69
+ directory = "feature"
70
+ name = "🚀 Features"
71
+ showcontent = true
72
+
73
+ [[tool.towncrier.type]]
74
+ directory = "bugfix"
75
+ name = "🔧 Bugfixes"
76
+ showcontent = true
77
+
78
+ [[tool.towncrier.type]]
79
+ directory = "doc"
80
+ name = "Documentation"
81
+ showcontent = true
82
+
83
+ [[tool.towncrier.type]]
84
+ directory = "misc"
85
+ name = "Miscellaneous"
86
+ showcontent = true
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+
5
+ from xdiff import conf as settings
6
+ from xdiff.utils.log import configure_logging
7
+
8
+ MIN_SUPPORTED_PYTHON = (3, 10)
9
+ MAX_SUPPORTED_PYTHON = (3, 14)
10
+
11
+
12
+ def validate_runtime() -> None:
13
+ version = sys.version_info[:2]
14
+ if MIN_SUPPORTED_PYTHON <= version < MAX_SUPPORTED_PYTHON:
15
+ return
16
+
17
+ raise RuntimeError(
18
+ "xdiff supports Python 3.10 through 3.13. "
19
+ f"The current interpreter is Python {version[0]}.{version[1]}."
20
+ )
21
+
22
+
23
+ def setup():
24
+ validate_runtime()
25
+ configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
@@ -0,0 +1,19 @@
1
+ """Comparator implementations for each artifact type."""
2
+
3
+ from importlib import import_module
4
+
5
+ from xdiff.comparators.base import ArtifactComparator
6
+
7
+ __all__ = ["ArtifactComparator", "NetcdfComparator"]
8
+
9
+
10
+ def __getattr__(name: str):
11
+ if name == "NetcdfComparator":
12
+ comparator = getattr(import_module("xdiff.comparators.netcdf"), name)
13
+ globals()[name] = comparator
14
+ return comparator
15
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
16
+
17
+
18
+ def __dir__() -> list[str]:
19
+ return sorted(__all__)
@@ -0,0 +1,20 @@
1
+ """Base interfaces for artifact comparators."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+
7
+ from xdiff.model.artifact import ArtifactKind
8
+ from xdiff.model.comparison import Comparison
9
+ from xdiff.model.match import ArtifactMatch
10
+ from xdiff.model.request import CompareRequest
11
+
12
+
13
+ class ArtifactComparator(ABC):
14
+ """Compares a matched pair of artifacts."""
15
+
16
+ artifact_kind: ArtifactKind
17
+
18
+ @abstractmethod
19
+ def compare(self, match: ArtifactMatch, request: CompareRequest) -> Comparison:
20
+ """Return the comparison outcome for a single matched pair."""