Skip to content

Release v0.0.34

Choose a tag to compare

@sebastienrousseau sebastienrousseau released this 10 Jan 01:29

Release v0.0.34 - 2026-01-10

Pain001: Enterprise Quality & Compliance Release

Pain001 banner

Overview

Pain001 is an open-source Python Library that you can use to create
ISO 20022-Compliant Payment Files directly from your CSV or SQLite
Data Files.

🎯 Release Focus

This release delivers enterprise-grade quality standards through the PySentinel compliance framework. We've achieved complete type safety, deterministic testing, and eliminated all unused dependencies while maintaining 100% backward compatibility.

✨ Highlights

🏆 PySentinel Compliance Achievement

We're proud to announce that Pain001 now meets enterprise-grade quality standards:

  • Type Safety: 100% mypy strict mode ✅
  • Test Coverage: 98.94% (173/173 tests passing) ✅
  • Mock Isolation: 18+ autospec mocks preventing interface drift ✅
  • Determinism: Zero non-deterministic testing patterns ✅
  • Dependency Health: 33% reduction (10 direct dependencies) ✅
Quality Metrics Summary:
─────────────────────────────────────────────────────────────
Type Coverage:         100% (20+ files fully annotated)
Test Coverage:         98.94% (exceeds 95% baseline)
Mock Isolation:        18+ with autospec=True
Unused Dependencies:   0 (all purged)
Linting (Ruff):        100% passing
Mypy Strict:           0 errors
Bandit Security:       0 issues

🔒 Complete Type Safety

All production code now enforces strict type annotations:

Type-Annotated Modules:

  1. pain001/xml/ - All 11 generation functions fully typed
  2. pain001/cli/cli.py - CLI functions with strict Optional handling
  3. pain001/core/core.py - Core processing with complete signatures
  4. pain001/csv/validate_csv_data.py - Validation with stdlib datetime
  5. All modules resolved with mypy strict mode

Configuration:

[tool.mypy]
python_version = "3.9"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

🧪 Deterministic Test Suite

Eliminated all non-deterministic testing patterns:

Mock Isolation Improvements:

  • All mock.patch() calls use autospec=True
  • 18+ mock objects prevent interface drift
  • MagicMock instances properly spec'd with spec= parameter
  • No datetime.now() calls in test suite (100% deterministic)
  • Proper fixture-based dependency injection

Test Files Enhanced:

test_cli.py              8 patches with autospec
test_core.py             7 patches with autospec
test_main.py             1 patch with autospec
test_data_loader.py      2 patches with autospec
test_validate_db_data.py 1 patch with autospec
test_validate_via_xsd.py 1 patch + MagicMock spec
test_generate_xml.py     1 patch with autospec

🧹 Dependency Optimization

Reduced external dependencies from 15 to 10 (-33%):

Removed Packages:

  1. datetime 5.5 - CRITICAL FIX: Zope package conflicting with stdlib
  2. requests 2.32.5 - Unused HTTP library
  3. urllib3 2.6.3 - Unused networking library
  4. setuptools 78.1.1 - Not needed as explicit dependency
  5. elementpath 4.4.0 - Transitive dependency only

Impact:

  • Eliminated stdlib naming conflict (datetime)
  • Reduced attack surface (fewer packages = fewer vulnerabilities)
  • Cleaner supply chain with only active dependencies
  • Proper transitive dependency management through Poetry

Remaining Core Dependencies:

✓ click 8.1.7          - CLI framework
✓ defusedxml 0.7.1     - Secure XML parsing
✓ jinja2 3.1.6         - Template rendering
✓ python ^3.9          - Runtime
✓ rich 13.7.1          - Terminal formatting
✓ xmlschema 3.3.1      - XSD validation

✅ What's New in v0.0.34

🔐 Critical Fix: Stdlib Conflict Resolution

Issue: Project declared Zope's datetime package (v5.5) instead of using Python's built-in stdlib
Impact: Code accidentally used Zope DateTime instead of stdlib datetime
Solution: Updated to from datetime import datetime in validate_csv_data.py

# BEFORE (Zope datetime)
import datetime
datetime.datetime.fromisoformat(value)

# AFTER (Stdlib datetime)
from datetime import datetime
datetime.fromisoformat(value)

This was a critical issue that could have caused subtle bugs in datetime handling. The fix ensures all datetime operations use the standard library.

📝 Type Annotations Added

20+ Production Files Enhanced:

pain001/__main__.py                    ✅ Typed
pain001/cli/cli.py                     ✅ Typed with Optional handling
pain001/context/context.py             ✅ Typed
pain001/core/core.py                   ✅ Typed with proper returns
pain001/csv/validate_csv_data.py       ✅ Typed + stdlib datetime
pain001/db/load_db_data.py             ✅ Typed
pain001/xml/create_common_elements.py  ✅ Typed
pain001/xml/create_root_element.py     ✅ Typed
pain001/xml/create_xml_element.py      ✅ Typed
pain001/xml/create_xml_v3.py           ✅ Typed
pain001/xml/create_xml_v4.py           ✅ Typed
pain001/xml/create_xml_v5.py           ✅ Typed
pain001/xml/create_xml_v6.py           ✅ Typed
pain001/xml/create_xml_v7.py           ✅ Typed
pain001/xml/create_xml_v8.py           ✅ Typed
pain001/xml/create_xml_v9.py           ✅ Typed
pain001/xml/generate_updated_xml_file_path.py  ✅ Typed
pain001/xml/generate_xml.py            ✅ Typed
pain001/xml/register_namespaces.py     ✅ Typed
pain001/xml/write_xml_to_file.py       ✅ Typed

🧪 Mock Isolation Hardening

8 Test Files Updated with autospec=True:

All mock objects now enforce interface specifications:

# BEFORE (Interface not enforced)
with patch("pain001.cli.cli.process_files") as mock:
    mock.assert_called_once()

# AFTER (Interface enforced)
with patch("pain001.cli.cli.process_files", autospec=True) as mock:
    mock.assert_called_once()

Benefits:

  • Catches interface changes that tests should know about
  • Prevents silent test failures from mocked object changes
  • Type-safe mock interactions
  • Spec enforcement at runtime

📊 Quality Metrics

Category Value Status
Type Coverage 100% ✅ Mypy strict
Test Coverage 98.94% ✅ Exceeds 95%
Tests Passing 173/173 ✅ All pass
Mock Objects 18+ with autospec ✅ Interface safe
Dependencies 10 (down from 15) ✅ Optimized
Unused Packages 0 ✅ All removed
Linting 100% passing ✅ Ruff clean
Security 0 vulnerabilities ✅ Bandit clean

🔄 Backward Compatibility

✅ 100% Backward Compatible

  • No breaking changes to public APIs
  • All existing code continues to work
  • Internal changes only (datetime import, type annotations)
  • Dependency removal is transparent to users
  • All documented examples tested and verified

📋 Files Modified

Core Changes

  • pyproject.toml - Version bump + dependency cleanup
  • pain001/__init__.py - Version update
  • CHANGELOG.md - New v0.0.34 entry
  • RELEASE_NOTES.md - Release documentation

Type Annotations (20+ files)

  • All XML generation modules
  • CLI functions
  • CSV validation
  • Core processing functions

Test Enhancements (8 files)

  • test_cli.py - autospec enforcement
  • test_core.py - autospec enforcement
  • test_main.py - autospec enforcement
  • test_data_loader.py - autospec enforcement
  • test_validate_db_data.py - autospec enforcement
  • test_validate_via_xsd.py - autospec enforcement
  • test_generate_xml.py - autospec enforcement
  • test_validate_csv_data.py - Updated datetime usage

Configuration Updates

  • poetry.lock - Regenerated with 5 packages removed
  • .mypy - Strict mode configuration added

🧪 Testing & Validation

All tests pass with comprehensive validation:

$ poetry run pytest tests/ -v
============================= 173 passed in 7.95s ==========================
Coverage: 98.94%

All quality gates passing:

  • ✅ pytest: 173/173 tests
  • ✅ mypy: strict mode, 0 errors
  • ✅ ruff: 0 linting issues
  • ✅ black: formatting verified
  • ✅ pylint: 10/10 quality score
  • ✅ bandit: 0 security issues

🚀 Installation

Fresh Installation

pip install pain001==0.0.34

Upgrade from Earlier Versions

pip install -U pain001

Verify Installation

python -c "import pain001; print(f'Pain001 v{pain001.__version__} is ready!')"
# Output: Pain001 v0.0.34 is ready!

📚 Documentation

🔗 Related

---

Pain001 v0.0.34 is production-ready and fully compliant with enterprise quality standards. 🚀

Thank you for using Pain001!