deidkit 0.1.3__tar.gz → 0.1.4__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 (73) hide show
  1. {deidkit-0.1.3/src/deidkit.egg-info → deidkit-0.1.4}/PKG-INFO +1 -1
  2. {deidkit-0.1.3 → deidkit-0.1.4}/pyproject.toml +1 -1
  3. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/pipeline.py +6 -1
  4. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/version.py +1 -1
  5. {deidkit-0.1.3 → deidkit-0.1.4/src/deidkit.egg-info}/PKG-INFO +1 -1
  6. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit.egg-info/SOURCES.txt +2 -1
  7. deidkit-0.1.4/tests/test_scoring.py +24 -0
  8. {deidkit-0.1.3 → deidkit-0.1.4}/LICENSE +0 -0
  9. {deidkit-0.1.3 → deidkit-0.1.4}/MANIFEST.in +0 -0
  10. {deidkit-0.1.3 → deidkit-0.1.4}/README.md +0 -0
  11. {deidkit-0.1.3 → deidkit-0.1.4}/examples/benchmark.py +0 -0
  12. {deidkit-0.1.3 → deidkit-0.1.4}/examples/make_sample.py +0 -0
  13. {deidkit-0.1.3 → deidkit-0.1.4}/examples/policy.example.yaml +0 -0
  14. {deidkit-0.1.3 → deidkit-0.1.4}/examples/policy.meridian.yaml +0 -0
  15. {deidkit-0.1.3 → deidkit-0.1.4}/examples/quickstart.md +0 -0
  16. {deidkit-0.1.3 → deidkit-0.1.4}/setup.cfg +0 -0
  17. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/__init__.py +0 -0
  18. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/__main__.py +0 -0
  19. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/api.py +0 -0
  20. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/cli.py +0 -0
  21. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/config.py +0 -0
  22. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/NOTICES.md +0 -0
  23. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/context_triggers_en.txt +0 -0
  24. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/context_triggers_es.txt +0 -0
  25. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/en_given_names.txt +0 -0
  26. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/en_surnames.txt +0 -0
  27. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/es_given_names.txt +0 -0
  28. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/es_surnames.txt +0 -0
  29. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/honorifics_en.txt +0 -0
  30. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/honorifics_es.txt +0 -0
  31. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/medical_stoplist_en.txt +0 -0
  32. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/medical_stoplist_es.txt +0 -0
  33. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/data/medical_vocab.txt +0 -0
  34. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/dates.py +0 -0
  35. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/__init__.py +0 -0
  36. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/checksums.py +0 -0
  37. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/context.py +0 -0
  38. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/gazetteer.py +0 -0
  39. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/patterns.py +0 -0
  40. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/spacy_ner.py +0 -0
  41. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/detect/types.py +0 -0
  42. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/engine.py +0 -0
  43. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/generators/__init__.py +0 -0
  44. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/generators/names.py +0 -0
  45. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/generators/surrogates.py +0 -0
  46. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/io.py +0 -0
  47. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/learn.py +0 -0
  48. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/mapping.py +0 -0
  49. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/report.py +0 -0
  50. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/resources.py +0 -0
  51. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/schema.py +0 -0
  52. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/secret.py +0 -0
  53. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit/textnorm.py +0 -0
  54. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit.egg-info/dependency_links.txt +0 -0
  55. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit.egg-info/entry_points.txt +0 -0
  56. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit.egg-info/requires.txt +0 -0
  57. {deidkit-0.1.3 → deidkit-0.1.4}/src/deidkit.egg-info/top_level.txt +0 -0
  58. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_api.py +0 -0
  59. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_checksums.py +0 -0
  60. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_dates.py +0 -0
  61. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_db.py +0 -0
  62. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_detect.py +0 -0
  63. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_engine.py +0 -0
  64. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_hardening.py +0 -0
  65. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_known_phi.py +0 -0
  66. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_learn.py +0 -0
  67. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_medical_vocab.py +0 -0
  68. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_names.py +0 -0
  69. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_ner_model_helpers.py +0 -0
  70. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_qa_fixes.py +0 -0
  71. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_qa_freetext_leaks.py +0 -0
  72. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_qa_hardening.py +0 -0
  73. {deidkit-0.1.3 → deidkit-0.1.4}/tests/test_schema_lang.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deidkit
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Schema-driven pseudonymization for clinical/tabular datasets: synthetic names, interval-preserving date shifting, multi-stage free-text PII detection, and before/after audit exports.
5
5
  Author: Meridian Data
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deidkit"
7
- version = "0.1.3"
7
+ version = "0.1.4"
8
8
  description = "Schema-driven pseudonymization for clinical/tabular datasets: synthetic names, interval-preserving date shifting, multi-stage free-text PII detection, and before/after audit exports."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -238,4 +238,9 @@ def _score_person(d: Detection) -> float:
238
238
  score += 0.10
239
239
  if len(methods) >= 2:
240
240
  score += 0.20
241
- return min(score, 0.99)
241
+ # Round to 2 dp: the score is built from 2-decimal weights, and the mode
242
+ # thresholds are 2-decimal (0.80 / 0.65 / 0.35). Without this, float dust
243
+ # (0.30 + 0.35 = 0.6499999…) drops a lone NER hit just under the 0.65
244
+ # "balanced" threshold, so balanced would never accept single-model NER hits
245
+ # as documented.
246
+ return round(min(score, 0.99), 2)
@@ -1,3 +1,3 @@
1
1
  """Single source of truth for the package version."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.1.4"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deidkit
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Schema-driven pseudonymization for clinical/tabular datasets: synthetic names, interval-preserving date shifting, multi-stage free-text PII detection, and before/after audit exports.
5
5
  Author: Meridian Data
6
6
  License: MIT
@@ -67,4 +67,5 @@ tests/test_ner_model_helpers.py
67
67
  tests/test_qa_fixes.py
68
68
  tests/test_qa_freetext_leaks.py
69
69
  tests/test_qa_hardening.py
70
- tests/test_schema_lang.py
70
+ tests/test_schema_lang.py
71
+ tests/test_scoring.py
@@ -0,0 +1,24 @@
1
+ """Person-score threshold behaviour.
2
+
3
+ A lone statistical-NER hit must score exactly at the 'balanced' threshold (0.65),
4
+ not 0.6499999… — otherwise balanced mode silently fails to accept single-model
5
+ NER hits (the documented behaviour) because of float dust.
6
+ """
7
+
8
+ from deidkit.detect.pipeline import _score_person, _THRESHOLDS
9
+ from deidkit.detect.types import Detection, PERSON
10
+
11
+
12
+ def test_lone_ner_hit_scores_exactly_at_balanced_threshold():
13
+ d = Detection(0, 15, "Yeimy Bocanegra", PERSON, {"ner"})
14
+ score = _score_person(d)
15
+ assert score == 0.65 # not 0.6499999999999999
16
+ assert score >= _THRESHOLDS["balanced"] # balanced (0.65) accepts it
17
+ assert score < _THRESHOLDS["conservative"] # conservative (0.80) -> review
18
+
19
+
20
+ def test_score_is_two_decimal_quantized():
21
+ # a mix that would accumulate float error still lands on a clean 2-dp value
22
+ d = Detection(0, 10, "X", PERSON, {"ner"}, meta={"run_len": 2})
23
+ s = _score_person(d)
24
+ assert round(s, 2) == s
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes