dir-content-diff 1.8.1__tar.gz → 1.9.1__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 (72) hide show
  1. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/workflows/publish-sdist.yml +2 -2
  2. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/workflows/run-tox.yml +2 -2
  3. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.pre-commit-config.yaml +1 -1
  4. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/CHANGELOG.md +17 -1
  5. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/CONTRIBUTING.md +1 -1
  6. dir_content_diff-1.9.1/MANIFEST.in +3 -0
  7. {dir_content_diff-1.8.1/dir_content_diff.egg-info → dir_content_diff-1.9.1}/PKG-INFO +23 -15
  8. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff/__init__.py +6 -6
  9. dir_content_diff-1.9.1/dir_content_diff/comparators/__init__.py +1 -0
  10. dir_content_diff-1.9.1/dir_content_diff/comparators/dependencies.json +9 -0
  11. dir_content_diff-1.9.1/dir_content_diff/comparators/morphio.py +43 -0
  12. {dir_content_diff-1.8.1/dir_content_diff → dir_content_diff-1.9.1/dir_content_diff/comparators}/pandas.py +6 -5
  13. dir_content_diff-1.9.1/dir_content_diff/comparators/voxcell.py +132 -0
  14. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff/util.py +50 -0
  15. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1/dir_content_diff.egg-info}/PKG-INFO +23 -15
  16. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff.egg-info/SOURCES.txt +13 -4
  17. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff.egg-info/requires.txt +18 -7
  18. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/api_ref.rst +3 -1
  19. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/pyproject.toml +4 -1
  20. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/setup.py +15 -12
  21. dir_content_diff-1.9.1/tests/comparators/__init__.py +1 -0
  22. dir_content_diff-1.9.1/tests/comparators/test_morphio.py +82 -0
  23. {dir_content_diff-1.8.1/tests → dir_content_diff-1.9.1/tests/comparators}/test_pandas.py +19 -16
  24. dir_content_diff-1.9.1/tests/comparators/test_voxcell.py +351 -0
  25. dir_content_diff-1.9.1/tests/test_missing_deps.py +35 -0
  26. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/test_pytest_plugin.py +2 -2
  27. dir_content_diff-1.9.1/tests/test_util.py +39 -0
  28. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/test_version.py +2 -2
  29. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tox.ini +35 -16
  30. dir_content_diff-1.8.1/MANIFEST.in +0 -1
  31. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.auto-changelog +0 -0
  32. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.auto-changelog-template.hbs +0 -0
  33. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.codespellignorelines +0 -0
  34. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.codespellrc +0 -0
  35. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.copier-answers.yml +0 -0
  36. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.coveragerc +0 -0
  37. /dir_content_diff-1.8.1/.coveragerc_py38 → /dir_content_diff-1.9.1/.coveragerc_min_versions +0 -0
  38. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.flake8 +0 -0
  39. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.gitattributes +0 -0
  40. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
  41. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  42. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
  43. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/ISSUE_TEMPLATE/how_to_use.yaml +0 -0
  44. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/dependabot.yml +0 -0
  45. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/pull_request_template.md +0 -0
  46. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.github/workflows/commitlint.yml +0 -0
  47. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.gitignore +0 -0
  48. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.gitreview +0 -0
  49. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.pylintrc +0 -0
  50. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/.readthedocs.yml +0 -0
  51. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/AUTHORS.md +0 -0
  52. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/LICENSE.txt +0 -0
  53. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/README.md +0 -0
  54. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/codecov.yml +0 -0
  55. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/commitlint.config.js +0 -0
  56. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff/base_comparators.py +0 -0
  57. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff/pytest_plugin.py +0 -0
  58. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff.egg-info/dependency_links.txt +0 -0
  59. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff.egg-info/entry_points.txt +0 -0
  60. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/dir_content_diff.egg-info/top_level.txt +0 -0
  61. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/Makefile +0 -0
  62. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/.gitignore +0 -0
  63. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/changelog.rst +0 -0
  64. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/conf.py +0 -0
  65. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/contributing.rst +0 -0
  66. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/docs/source/index.rst +0 -0
  67. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/package.json +0 -0
  68. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/setup.cfg +0 -0
  69. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/__init__.py +0 -0
  70. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/conftest.py +0 -0
  71. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/generate_test_files.py +0 -0
  72. {dir_content_diff-1.8.1 → dir_content_diff-1.9.1}/tests/test_base.py +0 -0
@@ -11,10 +11,10 @@ jobs:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v4
14
- - name: Set up Python 3.8
14
+ - name: Set up Python 3.10
15
15
  uses: actions/setup-python@v5
16
16
  with:
17
- python-version: 3.8
17
+ python-version: "3.10"
18
18
  - name: Build a wheel and a source tarball
19
19
  run: |
20
20
  pip install setuptools>=42 build setuptools_scm[toml]>=3.4
@@ -13,12 +13,12 @@ jobs:
13
13
  runs-on: ubuntu-latest
14
14
  strategy:
15
15
  matrix:
16
- python-version: ["3.8", "3.9", "3.10", "3.11"]
16
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
17
17
  min_versions: ["min_versions", "latest_versions"]
18
18
  exclude:
19
19
  - min_versions: "min_versions"
20
20
  include:
21
- - python-version: "3.8"
21
+ - python-version: "3.9"
22
22
  min_versions: "min_versions"
23
23
 
24
24
  steps:
@@ -1,5 +1,5 @@
1
1
  default_language_version:
2
- python: python3.8
2
+ python: python3.10
3
3
  repos:
4
4
  - repo: https://github.com/pre-commit/pre-commit-hooks
5
5
  rev: v4.4.0
@@ -1,8 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.9.1](https://github.com/BlueBrain/dir-content-diff/compare/1.9.0..1.9.1)
4
+
5
+ > 29 August 2024
6
+
7
+ ### CI Improvements
8
+
9
+ - Fix publish job (Adrien Berchet - [#62](https://github.com/BlueBrain/dir-content-diff/pull/62))
10
+
11
+ ## [1.9.0](https://github.com/BlueBrain/dir-content-diff/compare/1.8.1..1.9.0)
12
+
13
+ > 29 August 2024
14
+
15
+ ### New Features
16
+
17
+ - Add new specific comparators (Adrien Berchet - [#60](https://github.com/BlueBrain/dir-content-diff/pull/60))
18
+
3
19
  ## [1.8.1](https://github.com/BlueBrain/dir-content-diff/compare/1.8.0..1.8.1)
4
20
 
5
- > 26 April 2024
21
+ > 1 May 2024
6
22
 
7
23
  ### Build
8
24
 
@@ -59,7 +59,7 @@ When you wish to contribute to the code base, please consider the following guid
59
59
  or
60
60
 
61
61
  ```shell
62
- tox -e py38 -e lint -e docs -e check-packaging
62
+ tox -e py310 -e lint -e docs -e check-packaging
63
63
  ```
64
64
 
65
65
  * Commit your changes using a descriptive commit message.
@@ -0,0 +1,3 @@
1
+ global-exclude *.py[co] .DS_Store
2
+
3
+ include dir_content_diff/comparators/dependencies.json
@@ -1,23 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dir-content-diff
3
- Version: 1.8.1
3
+ Version: 1.9.1
4
4
  Summary: Simple tool to compare directory contents.
5
5
  Home-page: https://dir-content-diff.readthedocs.io
6
6
  Author: Blue Brain Project, EPFL
7
7
  License: Apache License 2.0
8
8
  Project-URL: Tracker, https://github.com/BlueBrain/dir-content-diff/issues
9
9
  Project-URL: Source, https://github.com/BlueBrain/dir-content-diff
10
- Classifier: Development Status :: 4 - Beta
10
+ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
15
  Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
20
- Requires-Python: >=3.8
20
+ Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE.txt
23
23
  License-File: AUTHORS.md
@@ -26,28 +26,36 @@ Requires-Dist: dicttoxml>=1.7.12
26
26
  Requires-Dist: diff_pdf_visually>=1.7
27
27
  Requires-Dist: jsonpath-ng>=1.5
28
28
  Requires-Dist: PyYaml>=6
29
- Provides-Extra: pandas
30
- Requires-Dist: pandas>=1.4; extra == "pandas"
31
- Requires-Dist: pyarrow>=11; extra == "pandas"
32
- Requires-Dist: tables>=3.7; extra == "pandas"
29
+ Provides-Extra: all-comparators
30
+ Requires-Dist: pandas>=1.4; extra == "all-comparators"
31
+ Requires-Dist: pyarrow>=11; extra == "all-comparators"
32
+ Requires-Dist: tables>=3.7; extra == "all-comparators"
33
+ Requires-Dist: morphio>=3.3.6; extra == "all-comparators"
34
+ Requires-Dist: morph_tool>=2.9; extra == "all-comparators"
35
+ Requires-Dist: voxcell>=3.1.1; extra == "all-comparators"
33
36
  Provides-Extra: docs
34
37
  Requires-Dist: docutils<0.21; extra == "docs"
35
38
  Requires-Dist: m2r2; extra == "docs"
36
39
  Requires-Dist: sphinx; extra == "docs"
37
40
  Requires-Dist: sphinx-bluebrain-theme; extra == "docs"
38
- Requires-Dist: pandas>=1.4; extra == "docs"
39
- Requires-Dist: pyarrow>=11; extra == "docs"
40
- Requires-Dist: tables>=3.7; extra == "docs"
41
41
  Provides-Extra: test
42
42
  Requires-Dist: coverage>=7.2; extra == "test"
43
43
  Requires-Dist: dicttoxml>=1.7.16; extra == "test"
44
- Requires-Dist: matplotlib>=3; extra == "test"
44
+ Requires-Dist: matplotlib>=3.4; extra == "test"
45
45
  Requires-Dist: rst2pdf>=0.99; extra == "test"
46
+ Requires-Dist: packaging>=20; extra == "test"
47
+ Requires-Dist: pandas>=1.4; extra == "test"
46
48
  Requires-Dist: pytest>=6.2; extra == "test"
47
49
  Requires-Dist: pytest-html<4,>=2; extra == "test"
48
- Requires-Dist: pandas>=1.4; extra == "test"
49
- Requires-Dist: pyarrow>=11; extra == "test"
50
- Requires-Dist: tables>=3.7; extra == "test"
50
+ Provides-Extra: pandas
51
+ Requires-Dist: pandas>=1.4; extra == "pandas"
52
+ Requires-Dist: pyarrow>=11; extra == "pandas"
53
+ Requires-Dist: tables>=3.7; extra == "pandas"
54
+ Provides-Extra: morphio
55
+ Requires-Dist: morphio>=3.3.6; extra == "morphio"
56
+ Requires-Dist: morph_tool>=2.9; extra == "morphio"
57
+ Provides-Extra: voxcell
58
+ Requires-Dist: voxcell>=3.1.1; extra == "voxcell"
51
59
 
52
60
  [![Version](https://img.shields.io/pypi/v/dir-content-diff)](https://github.com/BlueBrain/dir-content-diff/releases)
53
61
  [![Build status](https://github.com/BlueBrain/dir-content-diff/actions/workflows/run-tox.yml/badge.svg?branch=main)](https://github.com/BlueBrain/dir-content-diff/actions)
@@ -4,7 +4,6 @@ Simple tool to compare directory contents.
4
4
  """
5
5
  import copy
6
6
  import importlib.metadata
7
- import logging
8
7
  import re
9
8
  from pathlib import Path
10
9
 
@@ -14,13 +13,12 @@ from dir_content_diff.base_comparators import JsonComparator
14
13
  from dir_content_diff.base_comparators import PdfComparator
15
14
  from dir_content_diff.base_comparators import XmlComparator
16
15
  from dir_content_diff.base_comparators import YamlComparator
16
+ from dir_content_diff.util import LOGGER
17
17
  from dir_content_diff.util import diff_msg_formatter
18
18
  from dir_content_diff.util import format_ext
19
19
 
20
20
  __version__ = importlib.metadata.version("dir-content-diff")
21
21
 
22
- L = logging.getLogger(__name__)
23
-
24
22
 
25
23
  _DEFAULT_COMPARATORS = {
26
24
  None: DefaultComparator(),
@@ -125,7 +123,7 @@ def compare_files(ref_file, comp_file, comparator, *args, return_raw_diffs=False
125
123
  differences if they are different.
126
124
  """
127
125
  # Get the compared file
128
- L.debug("Compare: %s and %s", ref_file, comp_file)
126
+ LOGGER.debug("Compare: %s and %s", ref_file, comp_file)
129
127
 
130
128
  try:
131
129
  return comparator(ref_file, comp_file, *args, return_raw_diffs=return_raw_diffs, **kwargs)
@@ -173,7 +171,7 @@ def export_formatted_file(file, formatted_file, comparator, **kwargs):
173
171
  """
174
172
  if hasattr(comparator, "save_capability") and comparator.save_capability:
175
173
  # pylint: disable=protected-access
176
- L.debug("Format: %s into %s", file, formatted_file)
174
+ LOGGER.debug("Format: %s into %s", file, formatted_file)
177
175
  data = comparator.load(
178
176
  file,
179
177
  **kwargs.get(
@@ -204,7 +202,9 @@ def export_formatted_file(file, formatted_file, comparator, **kwargs):
204
202
  ),
205
203
  )
206
204
  else:
207
- L.info("Skip formatting for '%s' because the comparator has no saving capability.", file)
205
+ LOGGER.info(
206
+ "Skip formatting for '%s' because the comparator has no saving capability.", file
207
+ )
208
208
 
209
209
 
210
210
  def compare_trees(
@@ -0,0 +1 @@
1
+ """Sub-package of dir-content-diff for specific comparators."""
@@ -0,0 +1,9 @@
1
+ {
2
+ "pandas": [
3
+ "pandas>=1.4",
4
+ "pyarrow>=11",
5
+ "tables>=3.7"
6
+ ],
7
+ "morphio": ["morphio>=3.3.6", "morph_tool>=2.9"],
8
+ "voxcell": ["voxcell>=3.1.1"]
9
+ }
@@ -0,0 +1,43 @@
1
+ """Extension module to process morphology files with MorphIO and morph-tool."""
2
+ from dir_content_diff import register_comparator
3
+ from dir_content_diff.base_comparators import BaseComparator
4
+ from dir_content_diff.util import import_error_message
5
+
6
+ try:
7
+ from morph_tool import diff
8
+ from morphio.mut import Morphology
9
+ except ImportError: # pragma: no cover
10
+ import_error_message(__name__)
11
+
12
+
13
+ class MorphologyComparator(BaseComparator):
14
+ """Comparator for morphology files."""
15
+
16
+ def load(self, path, **kwargs):
17
+ """Load a morphology file into a :class:`morphio.Morphology` object."""
18
+ return Morphology(path, **kwargs)
19
+
20
+ def diff(self, ref, comp, *args, **kwargs):
21
+ """Compare data from two morphology files.
22
+
23
+ Args:
24
+ ref_path (str): The path to the reference morphology file.
25
+ comp_path (str): The path to the compared morphology file.
26
+ *args: See :func:`morph_tool.diff` for details.
27
+ **kwargs: See :func:`morph_tool.diff` for details.
28
+
29
+ Returns:
30
+ bool or list(str): ``False`` if the morphologies are considered as equal or a list of
31
+ strings explaining why they are not considered as equal.
32
+ """
33
+ diffs = diff(ref, comp, *args, **kwargs)
34
+ if not diffs:
35
+ return False
36
+ return [diffs.info]
37
+
38
+
39
+ def register(force=False):
40
+ """Register morphology file extensions."""
41
+ register_comparator(".asc", MorphologyComparator(), force=force)
42
+ register_comparator(".h5", MorphologyComparator(), force=force)
43
+ register_comparator(".swc", MorphologyComparator(), force=force)
@@ -1,11 +1,12 @@
1
1
  """Extension module to process files with Pandas."""
2
- try:
3
- import pandas as pd
4
- except ImportError as exception: # pragma: no cover
5
- raise ImportError("Could not import pandas package, please install it.") from exception
6
-
7
2
  from dir_content_diff import register_comparator
8
3
  from dir_content_diff.base_comparators import BaseComparator
4
+ from dir_content_diff.util import import_error_message
5
+
6
+ try:
7
+ import pandas as pd
8
+ except ImportError: # pragma: no cover
9
+ import_error_message(__name__)
9
10
 
10
11
 
11
12
  class DataframeComparator(BaseComparator):
@@ -0,0 +1,132 @@
1
+ """Extension module to process files with Voxcell."""
2
+ from dir_content_diff import register_comparator
3
+ from dir_content_diff.base_comparators import BaseComparator
4
+ from dir_content_diff.comparators.pandas import DataframeComparator
5
+ from dir_content_diff.util import import_error_message
6
+
7
+ try:
8
+ import numpy as np
9
+ from voxcell import CellCollection
10
+ from voxcell import VoxelData
11
+ except ImportError: # pragma: no cover
12
+ import_error_message(__name__)
13
+
14
+
15
+ class NrrdComparator(BaseComparator):
16
+ """Comparator for NRRD files."""
17
+
18
+ def load(self, path, **kwargs):
19
+ """Load a NRRD file into a :class:`numpy.ndarray`."""
20
+ return VoxelData.load_nrrd(str(path), **kwargs)
21
+
22
+ def save(self, data, path, **kwargs):
23
+ """Save data to a NRRD file."""
24
+ return data.save_nrrd(str(path), **kwargs)
25
+
26
+ def format_diff(self, difference, **kwargs):
27
+ """Format one element difference."""
28
+ k, v = difference
29
+ return f"\n{k}: {v}"
30
+
31
+ def sort(self, differences, **kwargs):
32
+ """Do not sort the entries to keep voxel dimensions as first entry."""
33
+ return differences
34
+
35
+ def diff(self, ref, comp, *args, precision=None, **kwargs):
36
+ """Compare data from two NRRD files.
37
+
38
+ Note: NRRD files can contain their creation date, so their hashes are depends on
39
+ this creation date, even if the actual data are the same. This comparator only compares the
40
+ actual data in the files.
41
+
42
+ Args:
43
+ ref_path (str): The path to the reference CSV file.
44
+ comp_path (str): The path to the compared CSV file.
45
+ precision (int): The desired precision, default is exact precision.
46
+
47
+ Returns:
48
+ bool or list(str): ``False`` if the DataFrames are considered as equal or a list of
49
+ strings explaining why they are not considered as equal.
50
+ """
51
+ errors = {}
52
+
53
+ try:
54
+ if precision is not None:
55
+ np.testing.assert_array_almost_equal(
56
+ ref.voxel_dimensions, comp.voxel_dimensions, *args, decimal=precision, **kwargs
57
+ )
58
+ else:
59
+ np.testing.assert_array_equal(
60
+ ref.voxel_dimensions, comp.voxel_dimensions, *args, **kwargs
61
+ )
62
+ except AssertionError as exception:
63
+ errors["Voxel dimensions"] = exception.args[0]
64
+
65
+ try:
66
+ if precision is not None:
67
+ np.testing.assert_array_almost_equal(
68
+ ref.raw, comp.raw, *args, decimal=precision, **kwargs
69
+ )
70
+ else:
71
+ np.testing.assert_array_equal(ref.raw, comp.raw, *args, **kwargs)
72
+ except AssertionError as exception:
73
+ errors["Internal raw data"] = exception.args[0]
74
+
75
+ if len(errors) == 0:
76
+ return False
77
+ return errors
78
+
79
+ def report(self, ref_file, comp_file, formatted_differences, diff_args, diff_kwargs, **kwargs):
80
+ """Create a report from the formatted differences."""
81
+ # pylint: disable=arguments-differ
82
+ if "precision" not in diff_kwargs:
83
+ diff_kwargs["precision"] = None
84
+ return super().report(
85
+ ref_file,
86
+ comp_file,
87
+ formatted_differences,
88
+ diff_args,
89
+ diff_kwargs,
90
+ **kwargs,
91
+ )
92
+
93
+
94
+ class Mvd3Comparator(DataframeComparator):
95
+ """Comparator for MVD3 files.
96
+
97
+ Note: MVD3 files can contain their creation date, so their hashes are depends on
98
+ this creation date, even if the data are the same.
99
+
100
+ This comparator inherits from the :class:`dir_content_diff.pandas.DataframeComparator`, read
101
+ the doc of this comparator for details on args and kwargs.
102
+ """
103
+
104
+ def load(self, path, **kwargs):
105
+ """Load a MVD3 file into a :class:`pandas.DataFrame`."""
106
+ return CellCollection.load_mvd3(path, **kwargs).as_dataframe()
107
+
108
+ def save(self, data, path, **kwargs):
109
+ """Save data to a CellCollection file."""
110
+ return CellCollection.from_dataframe(data).save_mvd3(path, **kwargs)
111
+
112
+
113
+ class CellCollectionComparator(DataframeComparator):
114
+ """Comparator for any type of CellCollection file.
115
+
116
+ This comparator inherits from the :class:`dir_content_diff.pandas.DataframeComparator`, read
117
+ the doc of this comparator for details on args and kwargs.
118
+ """
119
+
120
+ def load(self, path, **kwargs):
121
+ """Load a CellCollection file into a :class:`pandas.DataFrame`."""
122
+ return CellCollection.load(path, **kwargs).as_dataframe()
123
+
124
+ def save(self, data, path, **kwargs):
125
+ """Save data to a CellCollection file."""
126
+ return CellCollection.from_dataframe(data).save(path, **kwargs)
127
+
128
+
129
+ def register():
130
+ """Register Voxcell extensions."""
131
+ register_comparator(".nrrd", NrrdComparator())
132
+ register_comparator(".mvd3", Mvd3Comparator())
@@ -1,6 +1,11 @@
1
1
  """Some utils used by the ``dir-content-diff`` package."""
2
+ import importlib.resources
3
+ import json
4
+ import logging
2
5
  import re
6
+ from pathlib import Path
3
7
 
8
+ LOGGER = logging.getLogger("dir-content-diff")
4
9
  _ext_pattern = re.compile(r"\.?(.*)")
5
10
 
6
11
 
@@ -103,3 +108,48 @@ def diff_msg_formatter(
103
108
  f"{kwargs_used}"
104
109
  f"{reason_used}"
105
110
  )
111
+
112
+
113
+ def _retrieve_dependencies():
114
+ """Get the comparator dependencies."""
115
+ try:
116
+ # Package is installed or the cwd is the root of the project
117
+ root_dir = importlib.resources.files("dir_content_diff") # pylint: disable=no-member
118
+ except ModuleNotFoundError: # pragma: no cover
119
+ # Package is not installed and the cwd is not the root of the project
120
+ root_dir = Path(__file__).parent / "dir_content_diff"
121
+ deps_file = root_dir / "comparators" / "dependencies.json"
122
+ with deps_file.open() as f:
123
+ deps = json.load(f)
124
+ return deps
125
+
126
+
127
+ COMPARATOR_DEPENDENCIES = _retrieve_dependencies()
128
+
129
+
130
+ def import_error_message(name):
131
+ """Raise a log entry for the missing dependencies."""
132
+ name = name.split(".")[-1]
133
+ try:
134
+ dependencies = COMPARATOR_DEPENDENCIES[name]
135
+ except KeyError as exception:
136
+ msg = (
137
+ f"The module {name} has no registered dependency, please add dependencies in the "
138
+ "dependencies.json file"
139
+ )
140
+ raise KeyError(msg) from exception
141
+
142
+ if len(dependencies) > 1:
143
+ req_plural = "s are"
144
+ requirements = ", ".join(dependencies[:-1]) + f" and {dependencies[-1]}"
145
+ else:
146
+ req_plural = " is"
147
+ requirements = str(dependencies[0])
148
+
149
+ msg = (
150
+ f"Loading the {name} module without the required dependencies installed "
151
+ f"(requirement{req_plural} the following: {requirements}). "
152
+ "Will crash at runtime if the related functionalities are used. "
153
+ f"These dependencies can be installed with 'pip install dir-content-diff[{name}]'."
154
+ )
155
+ LOGGER.warning(msg)
@@ -1,23 +1,23 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dir-content-diff
3
- Version: 1.8.1
3
+ Version: 1.9.1
4
4
  Summary: Simple tool to compare directory contents.
5
5
  Home-page: https://dir-content-diff.readthedocs.io
6
6
  Author: Blue Brain Project, EPFL
7
7
  License: Apache License 2.0
8
8
  Project-URL: Tracker, https://github.com/BlueBrain/dir-content-diff/issues
9
9
  Project-URL: Source, https://github.com/BlueBrain/dir-content-diff
10
- Classifier: Development Status :: 4 - Beta
10
+ Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: License :: OSI Approved :: Apache Software License
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
15
  Classifier: Programming Language :: Python :: 3.9
17
16
  Classifier: Programming Language :: Python :: 3.10
18
17
  Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
20
- Requires-Python: >=3.8
20
+ Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE.txt
23
23
  License-File: AUTHORS.md
@@ -26,28 +26,36 @@ Requires-Dist: dicttoxml>=1.7.12
26
26
  Requires-Dist: diff_pdf_visually>=1.7
27
27
  Requires-Dist: jsonpath-ng>=1.5
28
28
  Requires-Dist: PyYaml>=6
29
- Provides-Extra: pandas
30
- Requires-Dist: pandas>=1.4; extra == "pandas"
31
- Requires-Dist: pyarrow>=11; extra == "pandas"
32
- Requires-Dist: tables>=3.7; extra == "pandas"
29
+ Provides-Extra: all-comparators
30
+ Requires-Dist: pandas>=1.4; extra == "all-comparators"
31
+ Requires-Dist: pyarrow>=11; extra == "all-comparators"
32
+ Requires-Dist: tables>=3.7; extra == "all-comparators"
33
+ Requires-Dist: morphio>=3.3.6; extra == "all-comparators"
34
+ Requires-Dist: morph_tool>=2.9; extra == "all-comparators"
35
+ Requires-Dist: voxcell>=3.1.1; extra == "all-comparators"
33
36
  Provides-Extra: docs
34
37
  Requires-Dist: docutils<0.21; extra == "docs"
35
38
  Requires-Dist: m2r2; extra == "docs"
36
39
  Requires-Dist: sphinx; extra == "docs"
37
40
  Requires-Dist: sphinx-bluebrain-theme; extra == "docs"
38
- Requires-Dist: pandas>=1.4; extra == "docs"
39
- Requires-Dist: pyarrow>=11; extra == "docs"
40
- Requires-Dist: tables>=3.7; extra == "docs"
41
41
  Provides-Extra: test
42
42
  Requires-Dist: coverage>=7.2; extra == "test"
43
43
  Requires-Dist: dicttoxml>=1.7.16; extra == "test"
44
- Requires-Dist: matplotlib>=3; extra == "test"
44
+ Requires-Dist: matplotlib>=3.4; extra == "test"
45
45
  Requires-Dist: rst2pdf>=0.99; extra == "test"
46
+ Requires-Dist: packaging>=20; extra == "test"
47
+ Requires-Dist: pandas>=1.4; extra == "test"
46
48
  Requires-Dist: pytest>=6.2; extra == "test"
47
49
  Requires-Dist: pytest-html<4,>=2; extra == "test"
48
- Requires-Dist: pandas>=1.4; extra == "test"
49
- Requires-Dist: pyarrow>=11; extra == "test"
50
- Requires-Dist: tables>=3.7; extra == "test"
50
+ Provides-Extra: pandas
51
+ Requires-Dist: pandas>=1.4; extra == "pandas"
52
+ Requires-Dist: pyarrow>=11; extra == "pandas"
53
+ Requires-Dist: tables>=3.7; extra == "pandas"
54
+ Provides-Extra: morphio
55
+ Requires-Dist: morphio>=3.3.6; extra == "morphio"
56
+ Requires-Dist: morph_tool>=2.9; extra == "morphio"
57
+ Provides-Extra: voxcell
58
+ Requires-Dist: voxcell>=3.1.1; extra == "voxcell"
51
59
 
52
60
  [![Version](https://img.shields.io/pypi/v/dir-content-diff)](https://github.com/BlueBrain/dir-content-diff/releases)
53
61
  [![Build status](https://github.com/BlueBrain/dir-content-diff/actions/workflows/run-tox.yml/badge.svg?branch=main)](https://github.com/BlueBrain/dir-content-diff/actions)
@@ -4,7 +4,7 @@
4
4
  .codespellrc
5
5
  .copier-answers.yml
6
6
  .coveragerc
7
- .coveragerc_py38
7
+ .coveragerc_min_versions
8
8
  .flake8
9
9
  .gitattributes
10
10
  .gitignore
@@ -35,7 +35,6 @@ tox.ini
35
35
  .github/workflows/run-tox.yml
36
36
  dir_content_diff/__init__.py
37
37
  dir_content_diff/base_comparators.py
38
- dir_content_diff/pandas.py
39
38
  dir_content_diff/pytest_plugin.py
40
39
  dir_content_diff/util.py
41
40
  dir_content_diff.egg-info/PKG-INFO
@@ -44,6 +43,11 @@ dir_content_diff.egg-info/dependency_links.txt
44
43
  dir_content_diff.egg-info/entry_points.txt
45
44
  dir_content_diff.egg-info/requires.txt
46
45
  dir_content_diff.egg-info/top_level.txt
46
+ dir_content_diff/comparators/__init__.py
47
+ dir_content_diff/comparators/dependencies.json
48
+ dir_content_diff/comparators/morphio.py
49
+ dir_content_diff/comparators/pandas.py
50
+ dir_content_diff/comparators/voxcell.py
47
51
  docs/Makefile
48
52
  docs/source/.gitignore
49
53
  docs/source/api_ref.rst
@@ -55,6 +59,11 @@ tests/__init__.py
55
59
  tests/conftest.py
56
60
  tests/generate_test_files.py
57
61
  tests/test_base.py
58
- tests/test_pandas.py
62
+ tests/test_missing_deps.py
59
63
  tests/test_pytest_plugin.py
60
- tests/test_version.py
64
+ tests/test_util.py
65
+ tests/test_version.py
66
+ tests/comparators/__init__.py
67
+ tests/comparators/test_morphio.py
68
+ tests/comparators/test_pandas.py
69
+ tests/comparators/test_voxcell.py
@@ -4,14 +4,23 @@ diff_pdf_visually>=1.7
4
4
  jsonpath-ng>=1.5
5
5
  PyYaml>=6
6
6
 
7
+ [all_comparators]
8
+ pandas>=1.4
9
+ pyarrow>=11
10
+ tables>=3.7
11
+ morphio>=3.3.6
12
+ morph_tool>=2.9
13
+ voxcell>=3.1.1
14
+
7
15
  [docs]
8
16
  docutils<0.21
9
17
  m2r2
10
18
  sphinx
11
19
  sphinx-bluebrain-theme
12
- pandas>=1.4
13
- pyarrow>=11
14
- tables>=3.7
20
+
21
+ [morphio]
22
+ morphio>=3.3.6
23
+ morph_tool>=2.9
15
24
 
16
25
  [pandas]
17
26
  pandas>=1.4
@@ -21,10 +30,12 @@ tables>=3.7
21
30
  [test]
22
31
  coverage>=7.2
23
32
  dicttoxml>=1.7.16
24
- matplotlib>=3
33
+ matplotlib>=3.4
25
34
  rst2pdf>=0.99
35
+ packaging>=20
36
+ pandas>=1.4
26
37
  pytest>=6.2
27
38
  pytest-html<4,>=2
28
- pandas>=1.4
29
- pyarrow>=11
30
- tables>=3.7
39
+
40
+ [voxcell]
41
+ voxcell>=3.1.1
@@ -8,6 +8,8 @@ This page presents the complete API documentation.
8
8
 
9
9
  dir_content_diff
10
10
  dir_content_diff.base_comparators
11
+ dir_content_diff.comparators.morphio
12
+ dir_content_diff.comparators.pandas
13
+ dir_content_diff.comparators.voxcell
11
14
  dir_content_diff.util
12
- dir_content_diff.pandas
13
15
  dir_content_diff.pytest_plugin
@@ -10,10 +10,10 @@ build-backend = "setuptools.build_meta"
10
10
  [tool.black]
11
11
  line-length = 100
12
12
  target-version = [
13
- "py38",
14
13
  "py39",
15
14
  "py310",
16
15
  "py311",
16
+ "py312",
17
17
  ]
18
18
 
19
19
  [tool.pydocstyle]
@@ -33,3 +33,6 @@ force_single_line = true
33
33
  testpaths = [
34
34
  "tests",
35
35
  ]
36
+ markers = [
37
+ "comparators_missing_deps: marks tests for missing dependencies",
38
+ ]