dir-content-diff 1.13.0__tar.gz → 1.14.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.
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/workflows/commitlint.yml +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/workflows/publish-sdist.yml +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/workflows/run-tox.yml +4 -4
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/CHANGELOG.md +28 -0
- {dir_content_diff-1.13.0/dir_content_diff.egg-info → dir_content_diff-1.14.1}/PKG-INFO +86 -5
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/README.md +84 -3
- dir_content_diff-1.14.1/dir_content_diff/__init__.py +53 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/base_comparators.py +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/cli/__init__.py +35 -3
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/__init__.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/morphio.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/pandas.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/voxcell.py +1 -1
- dir_content_diff-1.14.1/dir_content_diff/config.py +225 -0
- dir_content_diff-1.14.1/dir_content_diff/core.py +463 -0
- dir_content_diff-1.14.1/dir_content_diff/parallel_utils.py +100 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/pytest_plugin.py +2 -2
- dir_content_diff-1.14.1/dir_content_diff/registry.py +114 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/util.py +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1/dir_content_diff.egg-info}/PKG-INFO +86 -5
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff.egg-info/SOURCES.txt +5 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff.egg-info/requires.txt +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/conf.py +2 -6
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/setup.py +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/__init__.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/comparators/__init__.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/comparators/test_morphio.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/comparators/test_pandas.py +18 -17
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/comparators/test_voxcell.py +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/conftest.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/generate_test_files.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_attrs_validation.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_base.py +130 -76
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_cli.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_missing_deps.py +1 -1
- dir_content_diff-1.14.1/tests/test_parallel_execution.py +371 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_pytest_plugin.py +1 -1
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_util.py +2 -2
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tests/test_version.py +1 -1
- dir_content_diff-1.13.0/dir_content_diff/__init__.py +0 -613
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.auto-changelog +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.auto-changelog-template.hbs +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.codespellignorelines +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.codespellrc +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.copier-answers.yml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.copyright.tmpl +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.coveragerc +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.coveragerc_min_versions +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.gitattributes +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/ISSUE_TEMPLATE/bug_report.yaml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/ISSUE_TEMPLATE/feature_request.yaml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/ISSUE_TEMPLATE/how_to_use.yaml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/dependabot.yml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.github/pull_request_template.md +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.gitignore +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.gitreview +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.pre-commit-config.yaml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.pylintrc +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/.readthedocs.yml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/AUTHORS.md +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/CONTRIBUTING.md +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/LICENSE.txt +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/MANIFEST.in +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/codecov.yml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/commitlint.config.js +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/dependencies.json +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff.egg-info/dependency_links.txt +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff.egg-info/entry_points.txt +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff.egg-info/top_level.txt +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/Makefile +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/.gitignore +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/api_ref.rst +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/changelog.rst +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/contributing.rst +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/docs/source/index.rst +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/package.json +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/pyproject.toml +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/setup.cfg +0 -0
- {dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/tox.ini +0 -0
|
@@ -11,8 +11,8 @@ jobs:
|
|
|
11
11
|
env:
|
|
12
12
|
PR_TITLE: ${{ github.event.pull_request.title }}
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
15
|
-
- uses: actions/setup-node@
|
|
14
|
+
- uses: actions/checkout@v6
|
|
15
|
+
- uses: actions/setup-node@v6
|
|
16
16
|
with:
|
|
17
17
|
node-version: '20'
|
|
18
18
|
- run: npm install -g --force commitlint @commitlint/cli commitlint-plugin-cleanfeet
|
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
min_versions: "min_versions"
|
|
25
25
|
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
28
|
- name: Set up Python ${{ matrix.python-version }}
|
|
29
29
|
uses: actions/setup-python@v6
|
|
30
30
|
with:
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
run: |
|
|
37
37
|
sudo apt-get install -y poppler-utils imagemagick
|
|
38
38
|
- name: Cache tox and precommit environments
|
|
39
|
-
uses: actions/cache@
|
|
39
|
+
uses: actions/cache@v5
|
|
40
40
|
with:
|
|
41
41
|
path: |
|
|
42
42
|
.tox
|
|
@@ -58,7 +58,7 @@ jobs:
|
|
|
58
58
|
pip install tox
|
|
59
59
|
tox run -e min_versions
|
|
60
60
|
- name: JUnit Report Action
|
|
61
|
-
uses: mikepenz/action-junit-report@
|
|
61
|
+
uses: mikepenz/action-junit-report@v6
|
|
62
62
|
if: always() # always run even if the previous step fails
|
|
63
63
|
with:
|
|
64
64
|
report_paths: 'reports/pytest-*.xml'
|
|
@@ -81,7 +81,7 @@ jobs:
|
|
|
81
81
|
env:
|
|
82
82
|
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
83
83
|
- name: Upload test artifacts
|
|
84
|
-
uses: actions/upload-artifact@
|
|
84
|
+
uses: actions/upload-artifact@v6
|
|
85
85
|
if: always()
|
|
86
86
|
with:
|
|
87
87
|
name: tests-${{ matrix.python-version }}-${{ matrix.min_versions }}
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.14.1](https://github.com/BlueBrain/dir-content-diff/compare/1.14.0..1.14.1)
|
|
4
|
+
|
|
5
|
+
> 15 January 2026
|
|
6
|
+
|
|
7
|
+
### Chores And Housekeeping
|
|
8
|
+
|
|
9
|
+
- Bump copyright (Adrien Berchet - [#99](https://github.com/BlueBrain/dir-content-diff/pull/99))
|
|
10
|
+
|
|
11
|
+
### Documentation Changes
|
|
12
|
+
|
|
13
|
+
- Change theme to Furo because BBP theme is deprecated (Adrien Berchet - [#100](https://github.com/BlueBrain/dir-content-diff/pull/100))
|
|
14
|
+
|
|
15
|
+
## [1.14.0](https://github.com/BlueBrain/dir-content-diff/compare/1.13.0..1.14.0)
|
|
16
|
+
|
|
17
|
+
> 13 September 2025
|
|
18
|
+
|
|
19
|
+
### New Features
|
|
20
|
+
|
|
21
|
+
- Add parallel iteration over compared files (Adrien Berchet - [#89](https://github.com/BlueBrain/dir-content-diff/pull/89))
|
|
22
|
+
|
|
23
|
+
### Documentation Changes
|
|
24
|
+
|
|
25
|
+
- Improve README to describe parallel execution (Adrien Berchet - [#91](https://github.com/BlueBrain/dir-content-diff/pull/91))
|
|
26
|
+
|
|
27
|
+
### Refactoring and Updates
|
|
28
|
+
|
|
29
|
+
- Reorganize the code (Adrien Berchet - [#90](https://github.com/BlueBrain/dir-content-diff/pull/90))
|
|
30
|
+
|
|
3
31
|
## [1.13.0](https://github.com/BlueBrain/dir-content-diff/compare/1.12.1..1.13.0)
|
|
4
32
|
|
|
5
33
|
> 12 September 2025
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dir-content-diff
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.14.1
|
|
4
4
|
Summary: Simple tool to compare directory contents.
|
|
5
5
|
Author: Blue Brain Project, EPFL
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -40,7 +40,7 @@ Requires-Dist: pynrrd<1.1,>=0.4; extra == "all-comparators"
|
|
|
40
40
|
Provides-Extra: docs
|
|
41
41
|
Requires-Dist: myst_parser; extra == "docs"
|
|
42
42
|
Requires-Dist: sphinx; extra == "docs"
|
|
43
|
-
Requires-Dist:
|
|
43
|
+
Requires-Dist: furo; extra == "docs"
|
|
44
44
|
Provides-Extra: test
|
|
45
45
|
Requires-Dist: dicttoxml>=1.7.16; extra == "test"
|
|
46
46
|
Requires-Dist: matplotlib>=3.4; extra == "test"
|
|
@@ -76,7 +76,7 @@ Dynamic: provides-extra
|
|
|
76
76
|
This project provides simple tools to compare the content of a directory against a reference
|
|
77
77
|
directory.
|
|
78
78
|
|
|
79
|
-
This is useful to check the results of a process that
|
|
79
|
+
This is useful to check the results of a process that generates several files, like a luigi
|
|
80
80
|
workflow for example.
|
|
81
81
|
|
|
82
82
|
|
|
@@ -102,6 +102,8 @@ the files, so it is not able to report which values are different.
|
|
|
102
102
|
|
|
103
103
|
### Compare two directories
|
|
104
104
|
|
|
105
|
+
#### Basic Directory Comparison
|
|
106
|
+
|
|
105
107
|
Let's compare two directories with the following structures:
|
|
106
108
|
|
|
107
109
|
```bash
|
|
@@ -142,6 +144,8 @@ was detected. As mentioned previously, this is because `dir-content-diff` is onl
|
|
|
142
144
|
in the compared directory that are also present in the reference directory, so the file
|
|
143
145
|
`sub_file_3.b` is just ignored in this case.
|
|
144
146
|
|
|
147
|
+
#### Using Custom Comparators
|
|
148
|
+
|
|
145
149
|
If ``reference_dir/file_1.c`` is the following JSON-like file:
|
|
146
150
|
|
|
147
151
|
```json
|
|
@@ -183,6 +187,8 @@ The previous code will output the following dictionary:
|
|
|
183
187
|
}
|
|
184
188
|
```
|
|
185
189
|
|
|
190
|
+
#### Assertion-based Comparison
|
|
191
|
+
|
|
186
192
|
It is also possible to check whether the two directories are equal or not with the following code:
|
|
187
193
|
|
|
188
194
|
```python
|
|
@@ -201,7 +207,9 @@ Changed the value of '[a]' from 1 to 2.
|
|
|
201
207
|
Changed the value of '[b][0]' from 1 to 10.
|
|
202
208
|
```
|
|
203
209
|
|
|
204
|
-
|
|
210
|
+
#### Advanced Configuration Options
|
|
211
|
+
|
|
212
|
+
The comparators have parameters that can be passed either to be used for all files of a
|
|
205
213
|
given extension or only for a specific file:
|
|
206
214
|
|
|
207
215
|
```python
|
|
@@ -229,6 +237,8 @@ dir_content_diff.assert_equal_trees(
|
|
|
229
237
|
|
|
230
238
|
Each comparator has different arguments that are detailed in the documentation.
|
|
231
239
|
|
|
240
|
+
##### File-specific Comparators
|
|
241
|
+
|
|
232
242
|
It's also possible to specify a arbitrary comparator for a specific file:
|
|
233
243
|
|
|
234
244
|
```python
|
|
@@ -240,6 +250,8 @@ specific_args = {
|
|
|
240
250
|
}
|
|
241
251
|
```
|
|
242
252
|
|
|
253
|
+
##### Pattern-based Configuration
|
|
254
|
+
|
|
243
255
|
Another possibility is to use regular expressions to associate specific arguments to
|
|
244
256
|
a set of files:
|
|
245
257
|
|
|
@@ -252,7 +264,9 @@ specific_args = {
|
|
|
252
264
|
}
|
|
253
265
|
```
|
|
254
266
|
|
|
255
|
-
|
|
267
|
+
##### File Filtering
|
|
268
|
+
|
|
269
|
+
Last but not least, it's possible to filter files from the reference directory (for example
|
|
256
270
|
because the reference directory contains temporary files that should not be compared). For
|
|
257
271
|
example, the following code will ignore all files whose name does not start with `file_` and does
|
|
258
272
|
not ends with `_tmp.yaml`:
|
|
@@ -269,6 +283,73 @@ dir_content_diff.compare_trees(
|
|
|
269
283
|
```
|
|
270
284
|
|
|
271
285
|
|
|
286
|
+
### Parallel Execution
|
|
287
|
+
|
|
288
|
+
By default, `dir-content-diff` runs file comparisons sequentially. However, for improved performance when comparing large numbers of files, parallel execution is available using either thread-based or process-based concurrency.
|
|
289
|
+
|
|
290
|
+
#### Configuration Options
|
|
291
|
+
|
|
292
|
+
Parallel execution can be configured using the following parameters:
|
|
293
|
+
|
|
294
|
+
- **`executor_type`**: Controls the type of parallel execution:
|
|
295
|
+
- `"sequential"` (default): No parallel execution, files are compared one by one
|
|
296
|
+
- `"thread"`: Uses `ThreadPoolExecutor` (recommended for I/O-bound tasks)
|
|
297
|
+
- `"process"`: Uses `ProcessPoolExecutor` (recommended for CPU-intensive comparisons)
|
|
298
|
+
|
|
299
|
+
- **`max_workers`**: Maximum number of worker threads/processes. If `None` (default), it defaults to `min(32, (os.cpu_count() or 1) + 4)`.
|
|
300
|
+
|
|
301
|
+
#### Usage Examples
|
|
302
|
+
|
|
303
|
+
Enable thread-based parallel execution:
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
import dir_content_diff
|
|
307
|
+
|
|
308
|
+
dir_content_diff.compare_trees(
|
|
309
|
+
"reference_dir",
|
|
310
|
+
"compared_dir",
|
|
311
|
+
executor_type="thread",
|
|
312
|
+
max_workers=8
|
|
313
|
+
)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Enable process-based parallel execution with automatic worker count:
|
|
317
|
+
|
|
318
|
+
```python
|
|
319
|
+
import dir_content_diff
|
|
320
|
+
|
|
321
|
+
dir_content_diff.compare_trees(
|
|
322
|
+
"reference_dir",
|
|
323
|
+
"compared_dir",
|
|
324
|
+
executor_type="process"
|
|
325
|
+
)
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Using a configuration object:
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
import dir_content_diff
|
|
332
|
+
|
|
333
|
+
config = dir_content_diff.ComparisonConfig(
|
|
334
|
+
executor_type="thread",
|
|
335
|
+
max_workers=4
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
dir_content_diff.compare_trees(
|
|
339
|
+
"reference_dir",
|
|
340
|
+
"compared_dir",
|
|
341
|
+
config=config
|
|
342
|
+
)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Performance Considerations
|
|
346
|
+
|
|
347
|
+
- **Thread-based execution** (`executor_type="thread"`) is generally recommended for most use cases as file comparisons are typically I/O-bound operations
|
|
348
|
+
- **Process-based execution** (`executor_type="process"`) may be beneficial when using computationally intensive comparators or when dealing with very large files
|
|
349
|
+
- Parallel execution is automatically disabled for single file comparisons and falls back to sequential execution when only one file needs to be compared
|
|
350
|
+
- The optimal number of workers depends on your system's capabilities and the nature of your files; too many workers may actually decrease performance due to overhead
|
|
351
|
+
|
|
352
|
+
|
|
272
353
|
### Export formatted data
|
|
273
354
|
|
|
274
355
|
Some comparators have to format the data before comparing them. For example, if one wants to
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
This project provides simple tools to compare the content of a directory against a reference
|
|
11
11
|
directory.
|
|
12
12
|
|
|
13
|
-
This is useful to check the results of a process that
|
|
13
|
+
This is useful to check the results of a process that generates several files, like a luigi
|
|
14
14
|
workflow for example.
|
|
15
15
|
|
|
16
16
|
|
|
@@ -36,6 +36,8 @@ the files, so it is not able to report which values are different.
|
|
|
36
36
|
|
|
37
37
|
### Compare two directories
|
|
38
38
|
|
|
39
|
+
#### Basic Directory Comparison
|
|
40
|
+
|
|
39
41
|
Let's compare two directories with the following structures:
|
|
40
42
|
|
|
41
43
|
```bash
|
|
@@ -76,6 +78,8 @@ was detected. As mentioned previously, this is because `dir-content-diff` is onl
|
|
|
76
78
|
in the compared directory that are also present in the reference directory, so the file
|
|
77
79
|
`sub_file_3.b` is just ignored in this case.
|
|
78
80
|
|
|
81
|
+
#### Using Custom Comparators
|
|
82
|
+
|
|
79
83
|
If ``reference_dir/file_1.c`` is the following JSON-like file:
|
|
80
84
|
|
|
81
85
|
```json
|
|
@@ -117,6 +121,8 @@ The previous code will output the following dictionary:
|
|
|
117
121
|
}
|
|
118
122
|
```
|
|
119
123
|
|
|
124
|
+
#### Assertion-based Comparison
|
|
125
|
+
|
|
120
126
|
It is also possible to check whether the two directories are equal or not with the following code:
|
|
121
127
|
|
|
122
128
|
```python
|
|
@@ -135,7 +141,9 @@ Changed the value of '[a]' from 1 to 2.
|
|
|
135
141
|
Changed the value of '[b][0]' from 1 to 10.
|
|
136
142
|
```
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
#### Advanced Configuration Options
|
|
145
|
+
|
|
146
|
+
The comparators have parameters that can be passed either to be used for all files of a
|
|
139
147
|
given extension or only for a specific file:
|
|
140
148
|
|
|
141
149
|
```python
|
|
@@ -163,6 +171,8 @@ dir_content_diff.assert_equal_trees(
|
|
|
163
171
|
|
|
164
172
|
Each comparator has different arguments that are detailed in the documentation.
|
|
165
173
|
|
|
174
|
+
##### File-specific Comparators
|
|
175
|
+
|
|
166
176
|
It's also possible to specify a arbitrary comparator for a specific file:
|
|
167
177
|
|
|
168
178
|
```python
|
|
@@ -174,6 +184,8 @@ specific_args = {
|
|
|
174
184
|
}
|
|
175
185
|
```
|
|
176
186
|
|
|
187
|
+
##### Pattern-based Configuration
|
|
188
|
+
|
|
177
189
|
Another possibility is to use regular expressions to associate specific arguments to
|
|
178
190
|
a set of files:
|
|
179
191
|
|
|
@@ -186,7 +198,9 @@ specific_args = {
|
|
|
186
198
|
}
|
|
187
199
|
```
|
|
188
200
|
|
|
189
|
-
|
|
201
|
+
##### File Filtering
|
|
202
|
+
|
|
203
|
+
Last but not least, it's possible to filter files from the reference directory (for example
|
|
190
204
|
because the reference directory contains temporary files that should not be compared). For
|
|
191
205
|
example, the following code will ignore all files whose name does not start with `file_` and does
|
|
192
206
|
not ends with `_tmp.yaml`:
|
|
@@ -203,6 +217,73 @@ dir_content_diff.compare_trees(
|
|
|
203
217
|
```
|
|
204
218
|
|
|
205
219
|
|
|
220
|
+
### Parallel Execution
|
|
221
|
+
|
|
222
|
+
By default, `dir-content-diff` runs file comparisons sequentially. However, for improved performance when comparing large numbers of files, parallel execution is available using either thread-based or process-based concurrency.
|
|
223
|
+
|
|
224
|
+
#### Configuration Options
|
|
225
|
+
|
|
226
|
+
Parallel execution can be configured using the following parameters:
|
|
227
|
+
|
|
228
|
+
- **`executor_type`**: Controls the type of parallel execution:
|
|
229
|
+
- `"sequential"` (default): No parallel execution, files are compared one by one
|
|
230
|
+
- `"thread"`: Uses `ThreadPoolExecutor` (recommended for I/O-bound tasks)
|
|
231
|
+
- `"process"`: Uses `ProcessPoolExecutor` (recommended for CPU-intensive comparisons)
|
|
232
|
+
|
|
233
|
+
- **`max_workers`**: Maximum number of worker threads/processes. If `None` (default), it defaults to `min(32, (os.cpu_count() or 1) + 4)`.
|
|
234
|
+
|
|
235
|
+
#### Usage Examples
|
|
236
|
+
|
|
237
|
+
Enable thread-based parallel execution:
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
import dir_content_diff
|
|
241
|
+
|
|
242
|
+
dir_content_diff.compare_trees(
|
|
243
|
+
"reference_dir",
|
|
244
|
+
"compared_dir",
|
|
245
|
+
executor_type="thread",
|
|
246
|
+
max_workers=8
|
|
247
|
+
)
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Enable process-based parallel execution with automatic worker count:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
import dir_content_diff
|
|
254
|
+
|
|
255
|
+
dir_content_diff.compare_trees(
|
|
256
|
+
"reference_dir",
|
|
257
|
+
"compared_dir",
|
|
258
|
+
executor_type="process"
|
|
259
|
+
)
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Using a configuration object:
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
import dir_content_diff
|
|
266
|
+
|
|
267
|
+
config = dir_content_diff.ComparisonConfig(
|
|
268
|
+
executor_type="thread",
|
|
269
|
+
max_workers=4
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
dir_content_diff.compare_trees(
|
|
273
|
+
"reference_dir",
|
|
274
|
+
"compared_dir",
|
|
275
|
+
config=config
|
|
276
|
+
)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### Performance Considerations
|
|
280
|
+
|
|
281
|
+
- **Thread-based execution** (`executor_type="thread"`) is generally recommended for most use cases as file comparisons are typically I/O-bound operations
|
|
282
|
+
- **Process-based execution** (`executor_type="process"`) may be beneficial when using computationally intensive comparators or when dealing with very large files
|
|
283
|
+
- Parallel execution is automatically disabled for single file comparisons and falls back to sequential execution when only one file needs to be compared
|
|
284
|
+
- The optimal number of workers depends on your system's capabilities and the nature of your files; too many workers may actually decrease performance due to overhead
|
|
285
|
+
|
|
286
|
+
|
|
206
287
|
### Export formatted data
|
|
207
288
|
|
|
208
289
|
Some comparators have to format the data before comparing them. For example, if one wants to
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""dir-content-diff package.
|
|
2
|
+
|
|
3
|
+
Simple tool to compare directory contents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# LICENSE HEADER MANAGED BY add-license-header
|
|
7
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
8
|
+
#
|
|
9
|
+
# This file is part of dir-content-diff.
|
|
10
|
+
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
11
|
+
#
|
|
12
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
13
|
+
# LICENSE HEADER MANAGED BY add-license-header
|
|
14
|
+
|
|
15
|
+
import importlib.metadata
|
|
16
|
+
|
|
17
|
+
# Import base comparators
|
|
18
|
+
from dir_content_diff.base_comparators import BaseComparator
|
|
19
|
+
from dir_content_diff.base_comparators import DefaultComparator
|
|
20
|
+
|
|
21
|
+
# Import core comparison functionality
|
|
22
|
+
from dir_content_diff.config import ComparisonConfig
|
|
23
|
+
from dir_content_diff.core import ComparatorType
|
|
24
|
+
from dir_content_diff.core import assert_equal_trees
|
|
25
|
+
from dir_content_diff.core import compare_files
|
|
26
|
+
from dir_content_diff.core import compare_trees
|
|
27
|
+
from dir_content_diff.core import export_formatted_file
|
|
28
|
+
from dir_content_diff.core import pick_comparator
|
|
29
|
+
|
|
30
|
+
# Import comparator registry functionality
|
|
31
|
+
from dir_content_diff.registry import get_comparators
|
|
32
|
+
from dir_content_diff.registry import register_comparator
|
|
33
|
+
from dir_content_diff.registry import reset_comparators
|
|
34
|
+
from dir_content_diff.registry import unregister_comparator
|
|
35
|
+
|
|
36
|
+
__version__ = importlib.metadata.version("dir-content-diff")
|
|
37
|
+
|
|
38
|
+
# For backward compatibility, ensure all public functions are available
|
|
39
|
+
__all__ = [
|
|
40
|
+
"ComparisonConfig",
|
|
41
|
+
"ComparatorType",
|
|
42
|
+
"assert_equal_trees",
|
|
43
|
+
"compare_files",
|
|
44
|
+
"compare_trees",
|
|
45
|
+
"export_formatted_file",
|
|
46
|
+
"pick_comparator",
|
|
47
|
+
"get_comparators",
|
|
48
|
+
"register_comparator",
|
|
49
|
+
"reset_comparators",
|
|
50
|
+
"unregister_comparator",
|
|
51
|
+
"BaseComparator",
|
|
52
|
+
"DefaultComparator",
|
|
53
|
+
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Module containing the base comparators."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
@@ -513,7 +513,7 @@ class XmlComparator(DictComparator):
|
|
|
513
513
|
elif str(text).lower() == "false":
|
|
514
514
|
res = False
|
|
515
515
|
else:
|
|
516
|
-
raise ValueError("
|
|
516
|
+
raise ValueError("Boolean attributes expect 'true' or 'false'.")
|
|
517
517
|
elif value_type == "list":
|
|
518
518
|
res = []
|
|
519
519
|
elif value_type == "dict":
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Main entry point of the Command Line Interface for the dir-content-diff package."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
@@ -13,15 +13,17 @@ import json
|
|
|
13
13
|
import logging
|
|
14
14
|
import sys
|
|
15
15
|
from pathlib import Path
|
|
16
|
+
from typing import Optional
|
|
17
|
+
from typing import Union
|
|
16
18
|
|
|
17
19
|
import click
|
|
18
20
|
from yaml import safe_load
|
|
19
21
|
|
|
20
|
-
from dir_content_diff import _DEFAULT_EXPORT_SUFFIX
|
|
21
22
|
from dir_content_diff import compare_files
|
|
22
23
|
from dir_content_diff import compare_trees
|
|
23
24
|
from dir_content_diff import export_formatted_file
|
|
24
25
|
from dir_content_diff import pick_comparator
|
|
26
|
+
from dir_content_diff.core import _DEFAULT_EXPORT_SUFFIX
|
|
25
27
|
from dir_content_diff.util import LOGGER
|
|
26
28
|
|
|
27
29
|
|
|
@@ -102,6 +104,19 @@ def load_config(ctx, param, value): # pylint: disable=unused-argument
|
|
|
102
104
|
default=False,
|
|
103
105
|
help="Sort the differences by file name.",
|
|
104
106
|
)
|
|
107
|
+
@click.option(
|
|
108
|
+
"--executor-type",
|
|
109
|
+
type=click.Choice(["sequential", "thread", "process"]),
|
|
110
|
+
default="sequential",
|
|
111
|
+
help="Type of executor for execution. 'sequential' for single-threaded, "
|
|
112
|
+
"'thread' for I/O-bound tasks, 'process' for CPU-bound tasks.",
|
|
113
|
+
)
|
|
114
|
+
@click.option(
|
|
115
|
+
"--max-workers",
|
|
116
|
+
type=int,
|
|
117
|
+
help="Maximum number of worker threads/processes for parallel execution. "
|
|
118
|
+
"Only used with 'thread' or 'process' executor types.",
|
|
119
|
+
)
|
|
105
120
|
@click.version_option()
|
|
106
121
|
@click.pass_context
|
|
107
122
|
def main(ctx, *args, **kwargs):
|
|
@@ -120,16 +135,31 @@ def main(ctx, *args, **kwargs):
|
|
|
120
135
|
|
|
121
136
|
ref = Path(kwargs.pop("reference_input"))
|
|
122
137
|
comp = Path(kwargs.pop("compared_input"))
|
|
138
|
+
|
|
139
|
+
# Extract execution options
|
|
140
|
+
executor_type = kwargs.pop("executor_type", "sequential")
|
|
141
|
+
max_workers = kwargs.pop("max_workers", None)
|
|
142
|
+
|
|
123
143
|
input_diff(
|
|
124
144
|
ref,
|
|
125
145
|
comp,
|
|
126
146
|
ctx.config,
|
|
127
147
|
kwargs.pop("export_formatted_files", False),
|
|
128
148
|
kwargs.pop("sort_diffs", False),
|
|
149
|
+
executor_type,
|
|
150
|
+
max_workers,
|
|
129
151
|
)
|
|
130
152
|
|
|
131
153
|
|
|
132
|
-
def input_diff(
|
|
154
|
+
def input_diff(
|
|
155
|
+
ref: Union[str, Path],
|
|
156
|
+
comp: Union[str, Path],
|
|
157
|
+
config,
|
|
158
|
+
export_formatted_files: Union[bool, str] = False,
|
|
159
|
+
sort_diffs: bool = False,
|
|
160
|
+
executor_type: str = "sequential",
|
|
161
|
+
max_workers: Optional[int] = None,
|
|
162
|
+
):
|
|
133
163
|
"""Compute and display differences from given inputs."""
|
|
134
164
|
ref = Path(ref)
|
|
135
165
|
comp = Path(comp)
|
|
@@ -145,6 +175,8 @@ def input_diff(ref, comp, config, export_formatted_files=False, sort_diffs=False
|
|
|
145
175
|
comp,
|
|
146
176
|
specific_args=config,
|
|
147
177
|
export_formatted_files=export_formatted_files,
|
|
178
|
+
executor_type=executor_type,
|
|
179
|
+
max_workers=max_workers,
|
|
148
180
|
)
|
|
149
181
|
else:
|
|
150
182
|
comparator_name = config.pop("comparator", None)
|
{dir_content_diff-1.13.0 → dir_content_diff-1.14.1}/dir_content_diff/comparators/__init__.py
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Sub-package of dir-content-diff for specific comparators."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Extension module to process morphology files with MorphIO and morph-tool."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Extension module to process files with Pandas."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Extension module to process files with Voxcell."""
|
|
2
2
|
|
|
3
3
|
# LICENSE HEADER MANAGED BY add-license-header
|
|
4
|
-
# Copyright (c) 2023-
|
|
4
|
+
# Copyright (c) 2023-2026 Blue Brain Project, EPFL.
|
|
5
5
|
#
|
|
6
6
|
# This file is part of dir-content-diff.
|
|
7
7
|
# See https://github.com/BlueBrain/dir-content-diff for further info.
|