diffmonkey 1.1.0__tar.gz → 1.1.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 (31) hide show
  1. {diffmonkey-1.1.0/src/diffmonkey.egg-info → diffmonkey-1.1.1}/PKG-INFO +4 -4
  2. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/pyproject.toml +4 -4
  3. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/__init__.py +1 -1
  4. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/comparators.py +2 -1
  5. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/compare.py +5 -3
  6. {diffmonkey-1.1.0 → diffmonkey-1.1.1/src/diffmonkey.egg-info}/PKG-INFO +4 -4
  7. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey.egg-info/requires.txt +3 -3
  8. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_review_fixes.py +38 -0
  9. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/LICENSE +0 -0
  10. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/README.md +0 -0
  11. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/setup.cfg +0 -0
  12. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/cli.py +0 -0
  13. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/formatters/__init__.py +0 -0
  14. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/formatters/csv_out.py +0 -0
  15. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/formatters/html.py +0 -0
  16. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/formatters/markdown.py +0 -0
  17. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/matching.py +0 -0
  18. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/models.py +0 -0
  19. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey/readers.py +0 -0
  20. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey.egg-info/SOURCES.txt +0 -0
  21. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey.egg-info/dependency_links.txt +0 -0
  22. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey.egg-info/entry_points.txt +0 -0
  23. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/src/diffmonkey.egg-info/top_level.txt +0 -0
  24. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_cli.py +0 -0
  25. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_comparators.py +0 -0
  26. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_compare.py +0 -0
  27. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_compare_properties.py +0 -0
  28. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_formatters.py +0 -0
  29. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_matching.py +0 -0
  30. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_models.py +0 -0
  31. {diffmonkey-1.1.0 → diffmonkey-1.1.1}/tests/test_readers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffmonkey
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Type-aware, key-based structural diffing of tabular datasets with human- and machine-readable reports.
5
5
  Author-email: RexBytes <pythonic@rexbytes.com>
6
6
  License: MIT License
@@ -40,9 +40,9 @@ Classifier: Topic :: Utilities
40
40
  Requires-Python: >=3.11
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
- Requires-Dist: cleanmonkey
44
- Requires-Dist: typemonkey
45
- Requires-Dist: datemonkey
43
+ Requires-Dist: cleanmonkey>=0.2.0
44
+ Requires-Dist: typemonkey>=1.2.0
45
+ Requires-Dist: datemonkey>=0.2.0
46
46
  Provides-Extra: excel
47
47
  Requires-Dist: openpyxl>=3.0; extra == "excel"
48
48
  Provides-Extra: dsv
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "diffmonkey"
7
- version = "1.1.0"
7
+ version = "1.1.1"
8
8
  description = "Type-aware, key-based structural diffing of tabular datasets with human- and machine-readable reports."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -23,9 +23,9 @@ classifiers = [
23
23
  "Topic :: Utilities",
24
24
  ]
25
25
  dependencies = [
26
- "cleanmonkey",
27
- "typemonkey",
28
- "datemonkey",
26
+ "cleanmonkey>=0.2.0",
27
+ "typemonkey>=1.2.0",
28
+ "datemonkey>=0.2.0",
29
29
  ]
30
30
 
31
31
  [project.optional-dependencies]
@@ -31,7 +31,7 @@ from .models import (
31
31
  )
32
32
  from .readers import read_csv, read_excel, read_table
33
33
 
34
- __version__ = "1.1.0"
34
+ __version__ = "1.1.1"
35
35
 
36
36
  __all__ = [
37
37
  "compare",
@@ -76,7 +76,8 @@ def _clean(value: Any, settings: CompareSettings) -> str:
76
76
  text = value if isinstance(value, str) else str(value)
77
77
  if settings.normalize_whitespace:
78
78
  # 'minimal' would skip whitespace collapsing; 'default' strips and
79
- # collapses runs and removes invisible characters exactly the
79
+ # collapses runs, removes invisible characters, and folds typographic
80
+ # variants (smart quotes→straight, dashes→'-', '…'→'...') — exactly the
80
81
  # false-diff sources we want gone. strip=True is safe for cell values.
81
82
  return cleanmonkey.clean(text, profile="default")
82
83
  return text
@@ -130,9 +130,11 @@ def compare(
130
130
  (``math.isclose``). Default ``1e-9``.
131
131
  abs_tol: Absolute floating-point tolerance for numeric columns. Default
132
132
  ``0.0`` — set this to compare values near zero.
133
- normalize_whitespace: Collapse/strip whitespace and drop invisible
134
- characters before comparing strings (via ``cleanmonkey``). Default
135
- True.
133
+ normalize_whitespace: Collapse/strip whitespace, drop invisible
134
+ characters, and fold typographic variants (smart quotes→straight,
135
+ dashes/minus→``-``, ``…``→``...``) before comparing strings (via
136
+ ``cleanmonkey``'s ``default`` profile), so cosmetic punctuation
137
+ differences are not reported as changes. Default True.
136
138
  null_equivalent: Treat all null spellings (``None``, ``""``,
137
139
  whitespace-only, ``"na"``, …) as one value, so two different nulls
138
140
  are equal and null↔value is a change. Default True.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diffmonkey
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: Type-aware, key-based structural diffing of tabular datasets with human- and machine-readable reports.
5
5
  Author-email: RexBytes <pythonic@rexbytes.com>
6
6
  License: MIT License
@@ -40,9 +40,9 @@ Classifier: Topic :: Utilities
40
40
  Requires-Python: >=3.11
41
41
  Description-Content-Type: text/markdown
42
42
  License-File: LICENSE
43
- Requires-Dist: cleanmonkey
44
- Requires-Dist: typemonkey
45
- Requires-Dist: datemonkey
43
+ Requires-Dist: cleanmonkey>=0.2.0
44
+ Requires-Dist: typemonkey>=1.2.0
45
+ Requires-Dist: datemonkey>=0.2.0
46
46
  Provides-Extra: excel
47
47
  Requires-Dist: openpyxl>=3.0; extra == "excel"
48
48
  Provides-Extra: dsv
@@ -1,6 +1,6 @@
1
- cleanmonkey
2
- typemonkey
3
- datemonkey
1
+ cleanmonkey>=0.2.0
2
+ typemonkey>=1.2.0
3
+ datemonkey>=0.2.0
4
4
 
5
5
  [dev]
6
6
  pytest>=7.0
@@ -524,3 +524,41 @@ def test_fractional_bare_number_not_a_date():
524
524
  assert c._as_date("1.2") is UNPARSEABLE
525
525
  # 8-digit compact ISO still parses (integer part >= 8 digits).
526
526
  assert c._as_date("20240301") is not UNPARSEABLE
527
+
528
+
529
+ # =====================================================================
530
+
531
+ # Panel 6 (dependency-upgrade verification: cleanmonkey 0.2.0 / typemonkey 1.2.0
532
+ # / datemonkey 0.2.0). sonnet flagged that cleanmonkey's "default" profile folds
533
+ # typographic variants (smart quotes, em/en-dashes, ellipsis) to ASCII, so e.g.
534
+ # "Best—seller" compares equal to "Best-seller". Adjudication: NOT a regression
535
+ # (cleanmonkey 0.1.0's "default" profile is byte-identical on these inputs) and
536
+ # the equivalence is intended false-diff removal (SKILL.md documents smart-quote
537
+ # equivalence); only the docstring/comment under-described it. These tests pin
538
+ # the now-documented contract and its opt-out so a future cleanmonkey change or
539
+ # a doc drift fails loudly.
540
+
541
+
542
+ def test_typographic_variants_fold_when_normalising():
543
+ # normalize_whitespace=True (default): cosmetic punctuation differences are
544
+ # not reported as changes.
545
+ old = [
546
+ {"id": "1", "t": "Best-seller"}, # ASCII hyphen
547
+ {"id": "2", "t": 'say "hi"'}, # straight quotes
548
+ {"id": "3", "t": "a...b"}, # ASCII ellipsis
549
+ ]
550
+ new = [
551
+ {"id": "1", "t": "Best—seller"}, # em-dash
552
+ {"id": "2", "t": "say “hi”"}, # smart quotes
553
+ {"id": "3", "t": "a…b"}, # ellipsis char
554
+ ]
555
+ assert compare(old, new, key="id").summary.changed == 0
556
+
557
+
558
+ def test_typographic_variants_preserved_when_not_normalising():
559
+ # normalize_whitespace=False: the raw bytes are compared, so the same pairs
560
+ # are reported as changes (intent-preserving opt-out).
561
+ old = [{"id": "1", "t": "Best-seller"}]
562
+ new = [{"id": "1", "t": "Best—seller"}]
563
+ summary = compare(old, new, key="id", normalize_whitespace=False).summary
564
+ assert summary.changed == 1
File without changes
File without changes
File without changes
File without changes