D-SafeLogger 0.2.1__tar.gz → 0.2.2__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.
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/CHANGELOG.md +34 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/CONTRIBUTING.md +8 -2
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/PKG-INFO +9 -4
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/README.md +8 -3
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/README_ja.md +8 -3
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/TESTING.md +63 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__color.md +1 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__formatter.md +1 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__handler.md +12 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp_attach.md +1 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__pipeline.md +7 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D-SafeLogger_DetailedDesign_v23j.md +1 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D-SafeLogger_TestDesign_v23j.md +24 -2
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D-SafeLogger_v23j_WhitePaper.md +6 -4
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D-SafeLogger_v23j_WhitePaper_en.md +5 -3
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D_SafeLogger_Specification_v23j_full.md +4 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D_SafeLogger_Specification_v23j_full_en.md +4 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/pyproject.toml +10 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/D_SafeLogger.egg-info/PKG-INFO +9 -4
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/D_SafeLogger.egg-info/SOURCES.txt +3 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/__init__.py +9 -6
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_async.py +7 -7
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_cli.py +1 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_color.py +2 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_formatter.py +7 -7
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_handler.py +18 -4
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_levels.py +3 -2
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_mp_attach.py +18 -8
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_mp_protocol.py +9 -9
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_mp_queue.py +10 -7
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_mp_runtime.py +3 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_pipeline.py +6 -4
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_routing.py +1 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_transport.py +2 -2
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_writer_formatter.py +1 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/mp/__init__.py +2 -2
- d_safelogger-0.2.2/tests/typing_smoke/__init__.py +0 -0
- d_safelogger-0.2.2/tests/typing_smoke/public_api_smoke.py +35 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/uv.lock +213 -1
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/BENCHMARK.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/LICENSE +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/MANIFEST.in +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/SECURITY.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/_benchmark_report.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmark_20260506_180018/summary.json +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmark_20260506_180018/summary.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_integ_20260506_185947/summary.json +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_integ_20260506_185947/summary.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_perf_20260506_190518/summary.json +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_perf_20260506_190518/summary.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_resilience_20260506_211129/summary.json +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/results/benchmarks_multi_resilience_20260506_211129/summary.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/index.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/manifest.json +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/multiprocess_integrity.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/multiprocess_performance.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/multiprocess_resilience.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/summary/single_process.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/benchmarks/update_summary.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__async.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__cli.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__config_validation.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__constants.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__context.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__env_parser.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__ini_loader.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__integrity.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__levels.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__logger.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp_control.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp_protocol.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp_queue.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__mp_runtime.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__purge.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__routing.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__sink.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__transport.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__validator.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/dsafelogger__writer_formatter.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/api/index.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/01_quick_start.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/02_configuration_guide.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/03_migration_from_stdlib.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/04_stdlib_ecosystem_coexistence.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/05_windows_service_and_scheduled_batch.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/06_web_api_logging.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/07_long_running_service.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/08_compliance_audit.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/09_debugging_production.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/10_incident_response_bundle.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/11_async_performance.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/12_multiprocess_logging.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/13_external_rotation_reopen.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/14_cli_operations.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/15_opentelemetry_logging.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/16_structlog_coexistence.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/examples/17_container_collector_coexistence.md +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/setup.cfg +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/D_SafeLogger.egg-info/dependency_links.txt +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/D_SafeLogger.egg-info/entry_points.txt +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/D_SafeLogger.egg-info/top_level.txt +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_config_validation.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_constants.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_context.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_env_parser.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_ini_loader.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_integrity.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_logger.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_mp_control.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_purge.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_sink.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/_validator.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/src/dsafelogger/py.typed +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/conftest.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_03_migration_from_stdlib.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_04_stdlib_ecosystem_coexistence.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_05_windows_service_and_scheduled_batch.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_06_web_api_logging.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_07_long_running_service.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_08_compliance_audit.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_09_debugging_production.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_10_incident_response_bundle.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_11_async_performance.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_12_multiprocess_logging.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_13_external_rotation_reopen.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_14_cli_operations.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_15_opentelemetry_logging.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_16_structlog_coexistence.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/examples/test_17_container_collector_coexistence.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_async.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_cli.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_color.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_configure.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_context.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_coverage_boost.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_diagnose.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_env_parser.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_formatter.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_getlogger.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_handler.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_ini_loader.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_integration.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_integrity.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_levels.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_logger.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_merge.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_attach.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_configure.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_control.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_fork.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_formatter.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_integration.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_runtime.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_mp_spawn_windows.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_opentelemetry.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_pipeline.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_purge.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_reopen.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_routing.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_structlog.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_transport.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_validator.py +0 -0
- {d_safelogger-0.2.1 → d_safelogger-0.2.2}/tests/test_version.py +0 -0
|
@@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.2.2] - 2026-05-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Type validation as a CI quality gate: `mypy` and `pyright` are now required dev dependencies; `publication-checks` runs `uv run mypy src` and `uv run pyright src` on every push.
|
|
14
|
+
- `scripts/install_built_wheel.py` — helper for installing the freshly built wheel into the uv-managed venv before running `pyright --verifytypes` against the packaged module (rather than the editable source tree).
|
|
15
|
+
- `scripts/check_type_completeness.py` — threshold gate for `pyright --verifytypes dsafelogger --ignoreexternal`; CI now requires 100% public type completeness from the built wheel.
|
|
16
|
+
- `scripts/check_distribution_contents.py` — standalone script replacing the inline heredoc in `publish.yml`; adds `dsafelogger/py.typed` (wheel) and `src/dsafelogger/py.typed` (sdist) to required-path checks. Also wired into `ci.yml` `publication-checks`.
|
|
17
|
+
- `tests/typing_smoke/public_api_smoke.py` — pyright-only smoke test covering `ConfigureLogger`, `GetLogger`, `contextualize`, and `mp.ConfigureLogger` / `mp.GetWorkerInitializer` from a user import perspective. The directory is named `typing_smoke` (not `typing`) to avoid shadowing the stdlib `typing` module in spawn child processes. Not collected by pytest (filename does not match `test_*.py`); checked by `uv run pyright tests/typing_smoke` in `publication-checks`.
|
|
18
|
+
- `dsafelogger._handler.ReopenableHandler` — `@runtime_checkable` Protocol that narrows `logging.Handler` references to those exposing `reopen()`; replaces internal `hasattr(h, 'reopen')` checks for static type checking.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- `dsafelogger._pipeline.ResolvedConfig.sensitive_keywords` now defaults to `BUILTIN_SENSITIVE_KEYWORDS` directly (previously `field(default_factory=frozenset)`). Behaviour is preserved by the existing `or BUILTIN_SENSITIVE_KEYWORDS` consumer fallback; the API docs now show the concrete default value rather than `<factory>`.
|
|
22
|
+
- `dsafelogger._mp_protocol.LogEvent` TypedDict fields `process`, `processName`, `thread`, `threadName` are now `int | None` / `str | None`, aligning with stdlib `logging.LogRecord` semantics (None is a legal value for these attributes).
|
|
23
|
+
- `dsafelogger._formatter.DSafeFormatter.__init__` `style` parameter is now typed `Literal['%', '{', '$']` instead of `str`, matching `logging.Formatter`.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- `dsafelogger._routing.NoneStrategy.advance()` now returns the current path instead of implicitly returning `None`, satisfying its `Path` return-type contract (no observable behaviour change; `should_switch()` always returns `False` so the method is unreachable in production).
|
|
27
|
+
- `dsafelogger._cli` tail follow loop asserts that the open file handle is non-`None` before reuse (defensive narrowing; the assert is unreachable in normal execution).
|
|
28
|
+
- `dsafelogger._shutdown()` acquires the root logger reference before the `try` block so the `finally` block always has it available, even if an exception is raised before the original assignment site.
|
|
29
|
+
|
|
30
|
+
### Internal
|
|
31
|
+
- Removed 19 stale `# type: ignore[...]` comments that mypy 2.1 no longer requires.
|
|
32
|
+
- Annotated 4 previously untyped functions (`_levels._make_log_method`, `_color.ColorStreamHandler.__init__`, `_transport.TransportFactory.create`).
|
|
33
|
+
- `dsafelogger._mp_queue.TrackedQueue.__getstate__` / `__setstate__` are now explicitly marked `# type: ignore[override]` with a comment documenting the intentional `_QueueState` extension; cross-platform `qsize()` and `empty()` are coerced via `int(...)` / `bool(...)` to satisfy `warn_return_any`.
|
|
34
|
+
- `dsafelogger._mp_attach._validate_attach_ack` and `dsafelogger.mp._validate_bootstrap_ready_ack` now accept `ControlAck` TypedDict directly (previously `dict[str, Any]` / `dict[str, object]`).
|
|
35
|
+
- `pyproject.toml` adds `[tool.pyright]` (basic mode, `include = ["src"]`).
|
|
36
|
+
- `TESTING.md` gains a Type Validation section describing the local-green-before-push policy, recorded versions, and the private module surface rule.
|
|
37
|
+
- `README.md` / `README_ja.md` typing bullet updated to mention the CI type-check gate.
|
|
38
|
+
- `CONTRIBUTING.md` adds `uv run mypy src` / `uv run pyright src` to the required PR pre-flight commands and documents the private module surface policy.
|
|
39
|
+
- Public v23j design documents now describe the 0.2.2 type-validation gate, including source typing, `tests/typing_smoke`, built-wheel verifytypes, and the stdlib `typing` shadowing guard.
|
|
40
|
+
- API docs regenerated for `_color`, `_formatter`, `_handler`, `_mp_attach`, `_pipeline`.
|
|
41
|
+
|
|
8
42
|
## [0.2.1] - 2026-05-20
|
|
9
43
|
|
|
10
44
|
### Fixed
|
|
@@ -51,6 +51,9 @@ cd D-SafeLogger
|
|
|
51
51
|
uv sync --group dev
|
|
52
52
|
uv run pytest tests/ -v
|
|
53
53
|
uv run ruff check src/ tests/
|
|
54
|
+
uv run mypy src
|
|
55
|
+
uv run pyright src
|
|
56
|
+
uv run pyright tests/typing_smoke
|
|
54
57
|
```
|
|
55
58
|
|
|
56
59
|
## 6. Code Style
|
|
@@ -58,14 +61,17 @@ uv run ruff check src/ tests/
|
|
|
58
61
|
- **PEP 8**, max **100** characters per line.
|
|
59
62
|
- **ruff** for linting (`uv run ruff check src/ tests/`).
|
|
60
63
|
- **Type hints required** — use Python 3.11+ `X | Y` union syntax.
|
|
64
|
+
- **Typing must stay green**: `uv run mypy src`, `uv run pyright src`, and `uv run pyright tests/typing_smoke` must report `0 errors` locally before opening a PR. CI also enforces 100% public type completeness with `pyright --verifytypes` against the built wheel.
|
|
65
|
+
- Private module surface (names starting with `_`, e.g. `dsafelogger._constants.MASK_STRING`) is **not** part of the public API even though `py.typed` exposes it to user type checkers. Do not encourage external dependence on these names; rename / reshape freely as needed.
|
|
61
66
|
|
|
62
67
|
## 7. Pull Request Process
|
|
63
68
|
|
|
64
69
|
1. Create a feature branch from `main`.
|
|
65
70
|
2. Add tests for new functionality.
|
|
66
71
|
3. Ensure **all** tests pass: `uv run pytest tests/ -v`.
|
|
67
|
-
4.
|
|
68
|
-
5.
|
|
72
|
+
4. Verify type checks pass: `uv run mypy src`, `uv run pyright src`, and `uv run pyright tests/typing_smoke` (all must report `0 errors`).
|
|
73
|
+
5. Update documentation if needed.
|
|
74
|
+
6. Submit a PR with a clear description referencing the accepted issue.
|
|
69
75
|
|
|
70
76
|
## License
|
|
71
77
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: D-SafeLogger
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Zero-dependency, thread-safe, append-only logging library for Python with 3-layer config pipeline
|
|
5
5
|
Author: D
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -182,11 +182,12 @@ Notes:
|
|
|
182
182
|
- **Centralized setup:** replace common `basicConfig()`, `dictConfig()`, formatter, handler, and rotating-file boilerplate with `ConfigureLogger()`.
|
|
183
183
|
- **Fail-fast initialization:** invalid configuration and unwritable log destinations fail during setup instead of degrading silently.
|
|
184
184
|
- **Append-only file routing:** the routing layer opens the next destination instead of renaming or truncating the active log file. This avoids the common Windows failure mode where active log files cannot be renamed, and it avoids the POSIX case where a writer may continue writing to the previous file after a successful rename.
|
|
185
|
+
- **Retention for routed files:** routed files can be kept by `backup_count`; older files can be deleted by the purge worker or ZIP-archived with `archive_mode=True`.
|
|
185
186
|
- **Classified delivery state:** loss, reject, and drop events are not treated as invisible file gaps. When records cannot be delivered, the runtime classifies the outcome as known-rejected, known-dropped, or unexplained-lost where applicable.
|
|
186
187
|
- **Bounded logging path:** D-SafeLogger uses bounded queues, explicit timeouts, and explicit rejection paths to avoid unbounded logging-side waits in the host process.
|
|
187
188
|
- **Structured JSON Lines:** emit log records as JSON fields for log collectors and observability pipelines.
|
|
188
189
|
- **Contextual logging:** attach request IDs, user IDs, job IDs, or other context with thread-safe and async-safe propagation. Producer-side context snapshots are taken at hand-off so listeners and Writers do not look up live `contextvars`.
|
|
189
|
-
- **Integrity sidecars:** generate SHA-256 sidecars and optional manifest entries for routed log files.
|
|
190
|
+
- **Integrity sidecars:** generate SHA-256 sidecars and optional manifest entries for routed log files. This is tamper-evidence for closed files, not an access-control or compliance system.
|
|
190
191
|
- **Operational overrides:** change log level, module routing, console output, color, hashing, config file path, and queue/timeout parameters through environment variables, typically to raise diagnostics in production without code changes.
|
|
191
192
|
- **Environment-only diagnostic mode:** opt in via `D_LOG_DIAGNOSE=1` for `f_locals` expansion of selected frames; deliberately not exposed through INI or arguments, so it cannot be enabled by an unowned configuration file.
|
|
192
193
|
- **Async transport:** opt in to queue-backed logging when application threads should avoid direct sink writes.
|
|
@@ -200,6 +201,8 @@ Notes:
|
|
|
200
201
|
|
|
201
202
|
In this mode, a parent-side Writer owns the file sinks. Workers attach to the Writer and submit log records through IPC. This centralizes file ownership and exposes delivery-state counters such as accepted, delivered, rejected, dropped, and unexplained-lost.
|
|
202
203
|
|
|
204
|
+
The Writer shutdown path is bounded: it attempts to drain and join within a timeout, emits a visible warning if drain is incomplete, and avoids hanging the host process indefinitely.
|
|
205
|
+
|
|
203
206
|
For setup code, the `multiprocessing` context rules, pool initializer, `ProcessPoolExecutor` integration, Windows spawn caveats, custom log levels, attach/detach lifecycle, environment-variable knobs, and shutdown handling, see [`examples/12_multiprocess_logging.md`](examples/12_multiprocess_logging.md).
|
|
204
207
|
|
|
205
208
|
Public API in `dsafelogger.mp`: `ConfigureLogger`, `AttachCurrentProcess`, `DetachCurrentProcess`, `GetLogger`, `GetWorkerInitializer`, `ReopenLogFiles`.
|
|
@@ -256,11 +259,13 @@ Suggested reading paths:
|
|
|
256
259
|
|
|
257
260
|
D-SafeLogger is competitive in the selected single-process async benchmark runs. In multiprocess benchmarks, raw throughput is not the differentiator; parent-side file output and classified delivery-state accounting are.
|
|
258
261
|
|
|
262
|
+
The benchmark suite also includes multiprocess resilience profiles, such as sink-unavailable, burst backpressure, worker crash, mixed worker behavior, and shutdown behavior. These runs are not throughput claims; they check whether attempted records can be accounted for as delivered, known-rejected, known-dropped, or unexplained-lost.
|
|
263
|
+
|
|
259
264
|
See [BENCHMARK.md](BENCHMARK.md) for the selected runs, methodology, and the explicit "what to claim / what not to claim" boundaries, and [`benchmarks/summary/`](benchmarks/summary/) for the published summaries.
|
|
260
265
|
|
|
261
266
|
## Testing / Quality
|
|
262
267
|
|
|
263
|
-
The release gate runs the full dev test suite across Windows, macOS, and Linux on Python 3.11-3.14. Publication checks also verify generated API docs, public design documents, benchmark summaries, and package build output.
|
|
268
|
+
The release gate runs the full dev test suite across Windows, macOS, and Linux on Python 3.11-3.14. CI also runs Ubuntu free-threaded CPython `3.13t` and `3.14t` compatibility jobs with `PYTHON_GIL=0`. Publication checks also verify generated API docs, public design documents, benchmark summaries, and package build output.
|
|
264
269
|
|
|
265
270
|
See [TESTING.md](TESTING.md) for details.
|
|
266
271
|
|
|
@@ -269,7 +274,7 @@ See [TESTING.md](TESTING.md) for details.
|
|
|
269
274
|
- Python: 3.11 or newer.
|
|
270
275
|
- OS: Windows, macOS, and Linux.
|
|
271
276
|
- Runtime dependencies: none.
|
|
272
|
-
- Typing: includes `py.typed`.
|
|
277
|
+
- Typing: includes `py.typed`; CI checks `mypy`, `pyright`, typing smoke tests, and 100% public type completeness with `pyright --verifytypes`. See [TESTING.md](TESTING.md).
|
|
273
278
|
- API docs: [`docs/api/`](docs/api/).
|
|
274
279
|
- Design docs: [`docs/design/`](docs/design/).
|
|
275
280
|
- Distribution name is `d-safelogger` (with hyphen); import name is `dsafelogger` (no separator).
|
|
@@ -155,11 +155,12 @@ Notes:
|
|
|
155
155
|
- **Centralized setup:** replace common `basicConfig()`, `dictConfig()`, formatter, handler, and rotating-file boilerplate with `ConfigureLogger()`.
|
|
156
156
|
- **Fail-fast initialization:** invalid configuration and unwritable log destinations fail during setup instead of degrading silently.
|
|
157
157
|
- **Append-only file routing:** the routing layer opens the next destination instead of renaming or truncating the active log file. This avoids the common Windows failure mode where active log files cannot be renamed, and it avoids the POSIX case where a writer may continue writing to the previous file after a successful rename.
|
|
158
|
+
- **Retention for routed files:** routed files can be kept by `backup_count`; older files can be deleted by the purge worker or ZIP-archived with `archive_mode=True`.
|
|
158
159
|
- **Classified delivery state:** loss, reject, and drop events are not treated as invisible file gaps. When records cannot be delivered, the runtime classifies the outcome as known-rejected, known-dropped, or unexplained-lost where applicable.
|
|
159
160
|
- **Bounded logging path:** D-SafeLogger uses bounded queues, explicit timeouts, and explicit rejection paths to avoid unbounded logging-side waits in the host process.
|
|
160
161
|
- **Structured JSON Lines:** emit log records as JSON fields for log collectors and observability pipelines.
|
|
161
162
|
- **Contextual logging:** attach request IDs, user IDs, job IDs, or other context with thread-safe and async-safe propagation. Producer-side context snapshots are taken at hand-off so listeners and Writers do not look up live `contextvars`.
|
|
162
|
-
- **Integrity sidecars:** generate SHA-256 sidecars and optional manifest entries for routed log files.
|
|
163
|
+
- **Integrity sidecars:** generate SHA-256 sidecars and optional manifest entries for routed log files. This is tamper-evidence for closed files, not an access-control or compliance system.
|
|
163
164
|
- **Operational overrides:** change log level, module routing, console output, color, hashing, config file path, and queue/timeout parameters through environment variables, typically to raise diagnostics in production without code changes.
|
|
164
165
|
- **Environment-only diagnostic mode:** opt in via `D_LOG_DIAGNOSE=1` for `f_locals` expansion of selected frames; deliberately not exposed through INI or arguments, so it cannot be enabled by an unowned configuration file.
|
|
165
166
|
- **Async transport:** opt in to queue-backed logging when application threads should avoid direct sink writes.
|
|
@@ -173,6 +174,8 @@ Notes:
|
|
|
173
174
|
|
|
174
175
|
In this mode, a parent-side Writer owns the file sinks. Workers attach to the Writer and submit log records through IPC. This centralizes file ownership and exposes delivery-state counters such as accepted, delivered, rejected, dropped, and unexplained-lost.
|
|
175
176
|
|
|
177
|
+
The Writer shutdown path is bounded: it attempts to drain and join within a timeout, emits a visible warning if drain is incomplete, and avoids hanging the host process indefinitely.
|
|
178
|
+
|
|
176
179
|
For setup code, the `multiprocessing` context rules, pool initializer, `ProcessPoolExecutor` integration, Windows spawn caveats, custom log levels, attach/detach lifecycle, environment-variable knobs, and shutdown handling, see [`examples/12_multiprocess_logging.md`](examples/12_multiprocess_logging.md).
|
|
177
180
|
|
|
178
181
|
Public API in `dsafelogger.mp`: `ConfigureLogger`, `AttachCurrentProcess`, `DetachCurrentProcess`, `GetLogger`, `GetWorkerInitializer`, `ReopenLogFiles`.
|
|
@@ -229,11 +232,13 @@ Suggested reading paths:
|
|
|
229
232
|
|
|
230
233
|
D-SafeLogger is competitive in the selected single-process async benchmark runs. In multiprocess benchmarks, raw throughput is not the differentiator; parent-side file output and classified delivery-state accounting are.
|
|
231
234
|
|
|
235
|
+
The benchmark suite also includes multiprocess resilience profiles, such as sink-unavailable, burst backpressure, worker crash, mixed worker behavior, and shutdown behavior. These runs are not throughput claims; they check whether attempted records can be accounted for as delivered, known-rejected, known-dropped, or unexplained-lost.
|
|
236
|
+
|
|
232
237
|
See [BENCHMARK.md](BENCHMARK.md) for the selected runs, methodology, and the explicit "what to claim / what not to claim" boundaries, and [`benchmarks/summary/`](benchmarks/summary/) for the published summaries.
|
|
233
238
|
|
|
234
239
|
## Testing / Quality
|
|
235
240
|
|
|
236
|
-
The release gate runs the full dev test suite across Windows, macOS, and Linux on Python 3.11-3.14. Publication checks also verify generated API docs, public design documents, benchmark summaries, and package build output.
|
|
241
|
+
The release gate runs the full dev test suite across Windows, macOS, and Linux on Python 3.11-3.14. CI also runs Ubuntu free-threaded CPython `3.13t` and `3.14t` compatibility jobs with `PYTHON_GIL=0`. Publication checks also verify generated API docs, public design documents, benchmark summaries, and package build output.
|
|
237
242
|
|
|
238
243
|
See [TESTING.md](TESTING.md) for details.
|
|
239
244
|
|
|
@@ -242,7 +247,7 @@ See [TESTING.md](TESTING.md) for details.
|
|
|
242
247
|
- Python: 3.11 or newer.
|
|
243
248
|
- OS: Windows, macOS, and Linux.
|
|
244
249
|
- Runtime dependencies: none.
|
|
245
|
-
- Typing: includes `py.typed`.
|
|
250
|
+
- Typing: includes `py.typed`; CI checks `mypy`, `pyright`, typing smoke tests, and 100% public type completeness with `pyright --verifytypes`. See [TESTING.md](TESTING.md).
|
|
246
251
|
- API docs: [`docs/api/`](docs/api/).
|
|
247
252
|
- Design docs: [`docs/design/`](docs/design/).
|
|
248
253
|
- Distribution name is `d-safelogger` (with hyphen); import name is `dsafelogger` (no separator).
|
|
@@ -155,11 +155,12 @@ D-SafeLogger は、active file を後から動かす代わりに、書き込み
|
|
|
155
155
|
- **中央初期化:** `basicConfig()`、`dictConfig()`、formatter、handler、rotation 設定の boilerplate を `ConfigureLogger()` に集約できます。
|
|
156
156
|
- **fail-fast 初期化:** 不正な設定値や書き込めないログ出力先は初期化時に失敗させ、あとから気づきにくい形で動作が崩れることを避けます。
|
|
157
157
|
- **追記専用のファイルルーティング:** ルーティング層は、使用中のログファイルを rename / truncate せず、境界到達時に次の出力先を開きます。Windows の active file rename 失敗だけでなく、POSIX 系で rename が成功したまま writer が旧世代へ書き続ける問題も避けられます。
|
|
158
|
+
- **ルーティング済みファイルの保持管理:** ルーティング済みファイルは `backup_count` に基づいて保持できます。古いファイルは purge worker による削除、または `archive_mode=True` による ZIP archive 化が可能です。
|
|
158
159
|
- **配送状態の分類:** 失われたレコードをファイル上の見えない欠損として扱わず、可能な範囲で known-rejected / known-dropped / unexplained-lost に分類します。
|
|
159
160
|
- **境界をもった logging 経路:** 上限つきキュー、明示的な timeout、明示的な拒否経路を使うことで、logging 処理が本体プロセス側で無制限に待ち続ける設計を避けます。
|
|
160
161
|
- **JSON Lines 出力:** ログ収集基盤や監視基盤へ渡しやすい JSON 形式で出力できます。
|
|
161
162
|
- **コンテキスト付与:** request ID、user ID、job ID などを、スレッドや非同期境界をまたいでログへ付与できます。`contextvars` の snapshot は producer 側で取り、Writer 側では live な `contextvars` を参照しません。
|
|
162
|
-
- **整合性 sidecar:** ルーティング済みログファイルに対して SHA-256 sidecar と、任意で manifest
|
|
163
|
+
- **整合性 sidecar:** ルーティング済みログファイルに対して SHA-256 sidecar と、任意で manifest を出力できます。これは closed file の改ざんや破損を後から検出しやすくするためのもので、access-control system や compliance system ではありません。
|
|
163
164
|
- **運用時の上書き:** ログレベル、モジュール別ルーティング、コンソール出力、色、ハッシュ、設定ファイルパス、キュー / timeout 関連を環境変数で変更できます。本番障害時にコードを変更せず診断レベルを上げる用途を主に想定しています。
|
|
164
165
|
- **環境変数限定の診断モード:** `D_LOG_DIAGNOSE=1` を有効にすると、選択フレームの `f_locals` を展開できます。INI や引数からは意図的に有効化できないため、由来のわからない設定ファイルから ON にされることがありません。
|
|
165
166
|
- **非同期出力:** アプリケーションスレッドが直接ファイル出力を待たないよう、キューを介した logging を選べます。
|
|
@@ -173,6 +174,8 @@ D-SafeLogger は、active file を後から動かす代わりに、書き込み
|
|
|
173
174
|
|
|
174
175
|
このモードでは、親プロセス側の Writer がファイル出力先を所有します。worker は Writer に attach し、IPC 経由でログレコードを送ります。これによりファイル所有が一箇所に集約され、accepted / delivered / rejected / dropped / unexplained-lost といった配送状態のカウンターが公開されます。
|
|
175
176
|
|
|
177
|
+
Writer の終了処理では上限つきの待機を行います。timeout 内で drain と join を試み、drain が完了しない場合は warning を出し、host process が無期限に hang し続けることを避けます。
|
|
178
|
+
|
|
176
179
|
具体的なコード、`multiprocessing` の context ルール、Pool initializer、`ProcessPoolExecutor` 連携、Windows での spawn の注意、カスタムログレベル、attach / detach のライフサイクル、環境変数のチューニング、終了処理は [`examples/12_multiprocess_logging.md`](examples/12_multiprocess_logging.md) を参照してください。
|
|
177
180
|
|
|
178
181
|
`dsafelogger.mp` の公開 API: `ConfigureLogger`, `AttachCurrentProcess`, `DetachCurrentProcess`, `GetLogger`, `GetWorkerInitializer`, `ReopenLogFiles`。
|
|
@@ -229,11 +232,13 @@ INI ファイル、dict 設定、モジュール別ルーティング、優先
|
|
|
229
232
|
|
|
230
233
|
D-SafeLogger は、採用済みの単一プロセス async ベンチマークでは競争力があります。マルチプロセスでは、単純な throughput ではなく、親プロセス側 Writer によるファイル出力と配送状態の分類が主な価値です。
|
|
231
234
|
|
|
235
|
+
ベンチマークには、sink-unavailable、burst backpressure、worker crash、mixed worker behavior、shutdown behavior などの multiprocess resilience profile も含まれます。これらは throughput claim ではなく、attempted record を delivered / known-rejected / known-dropped / unexplained-lost として説明できるかを確認するものです。
|
|
236
|
+
|
|
232
237
|
採用 run、計測条件、主張できる範囲は [BENCHMARK.md](BENCHMARK.md) を、公開済みの summary は [`benchmarks/summary/`](benchmarks/summary/) を参照してください。
|
|
233
238
|
|
|
234
239
|
## テスト / 品質
|
|
235
240
|
|
|
236
|
-
リリースゲートでは、Windows / macOS / Linux と Python 3.11-3.14 の組み合わせで dev 依存を含む full test suite
|
|
241
|
+
リリースゲートでは、Windows / macOS / Linux と Python 3.11-3.14 の組み合わせで dev 依存を含む full test suite を実行します。CI では Ubuntu free-threaded CPython `3.13t` / `3.14t` の互換性ジョブも `PYTHON_GIL=0` で実行します。公開前チェックでは、生成済み API docs、公開設計書、ベンチマークサマリー、パッケージ build も検証します。
|
|
237
242
|
|
|
238
243
|
詳しくは [TESTING.md](TESTING.md) を参照してください。
|
|
239
244
|
|
|
@@ -242,7 +247,7 @@ D-SafeLogger は、採用済みの単一プロセス async ベンチマークで
|
|
|
242
247
|
- Python: 3.11 以上。
|
|
243
248
|
- OS: Windows, macOS, Linux。
|
|
244
249
|
- 実行時依存: なし。
|
|
245
|
-
- 型情報: `py.typed` を同梱。
|
|
250
|
+
- 型情報: `py.typed` を同梱。CI で `mypy` / `pyright`、typing smoke test、`pyright --verifytypes` による public type completeness 100% gate を検証。詳細は [TESTING.md](TESTING.md)。
|
|
246
251
|
- API docs: [`docs/api/`](docs/api/)。
|
|
247
252
|
- Design docs: [`docs/design/`](docs/design/)。
|
|
248
253
|
- 配布パッケージ名は `d-safelogger` (ハイフン)、import 名は `dsafelogger` (区切りなし) です。
|
|
@@ -129,6 +129,60 @@ Important expectations:
|
|
|
129
129
|
- Tests must not rely on `multiprocessing.Queue.empty()` for correctness. Use timeout-based `get()` or fake/recording queues instead.
|
|
130
130
|
- CloseMarker drain, control-plane ACKs, backpressure, reject counters, partial delivery, and bounded shutdown warning paths are covered by MP tests.
|
|
131
131
|
|
|
132
|
+
## Type Validation
|
|
133
|
+
|
|
134
|
+
`D-SafeLogger` ships with `py.typed` (PEP 561), so source typing and public type completeness are part of the standard quality gate. CI runs `mypy`, `pyright`, a typing smoke test, and a 100% `pyright --verifytypes` gate on every push.
|
|
135
|
+
|
|
136
|
+
### Tooling
|
|
137
|
+
|
|
138
|
+
- `mypy>=2.1` — strict-ish config (`disallow_untyped_defs = true`, `warn_unused_ignores = true`, `warn_return_any = true`).
|
|
139
|
+
- `pyright>=1.1.409` — `typeCheckingMode = "basic"` with `include = ["src"]`.
|
|
140
|
+
|
|
141
|
+
### Required commands (PR pre-flight)
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
uv sync --group dev
|
|
145
|
+
uv run pyright --version # record first
|
|
146
|
+
uv run mypy src # → 0 errors
|
|
147
|
+
uv run pyright src # → 0 errors
|
|
148
|
+
uv run pyright tests/typing_smoke # → 0 errors
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Local green (`0 errors` from both tools) is the precondition for pushing. CI runs the same commands and treats any error as a hard fail.
|
|
152
|
+
|
|
153
|
+
Package-level type completeness is checked from the built wheel, not the editable source tree:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
uv build
|
|
157
|
+
uv run python scripts/install_built_wheel.py
|
|
158
|
+
uv run --no-sync python scripts/check_type_completeness.py --min-score 100
|
|
159
|
+
uv sync --reinstall
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Use `uv run --no-sync` for the completeness check so the wheel install is not replaced by the editable project before `pyright --verifytypes` runs.
|
|
163
|
+
|
|
164
|
+
### Latest local validation (2026-05-21 / Python 3.14.3 / Windows)
|
|
165
|
+
|
|
166
|
+
| Tool | Version | Result |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| `mypy` | 2.1.0 | `Success: no issues found in 27 source files` |
|
|
169
|
+
| `pyright` | 1.1.409 | `0 errors, 0 warnings, 0 informations` |
|
|
170
|
+
| `pyright --verifytypes dsafelogger --ignoreexternal` | 1.1.409 | `Type completeness score: 100%` (10 public symbols, 23 referenced internal symbols — all known type) |
|
|
171
|
+
|
|
172
|
+
### Package name vs. type checker target
|
|
173
|
+
|
|
174
|
+
D-SafeLogger uses three name forms — be careful when invoking type tools:
|
|
175
|
+
|
|
176
|
+
- PyPI metadata: `D-SafeLogger`
|
|
177
|
+
- Python import / `verifytypes` target: `dsafelogger`
|
|
178
|
+
- Wheel filename: `d_safelogger-*.whl`
|
|
179
|
+
|
|
180
|
+
For `pyright --verifytypes`, always pass `dsafelogger` (the import name).
|
|
181
|
+
|
|
182
|
+
### Private module surface policy
|
|
183
|
+
|
|
184
|
+
Names starting with a leading underscore (`_constants.MASK_STRING`, `_constants._resolved_sensitive_keywords`, `_pipeline.ResolvedConfig`, `_async.DSafeQueueHandler`, etc.) are **private** even though `py.typed` exposes them to user type checkers. Library consumers MUST NOT depend on private symbols; they may change without notice in PATCH or MINOR releases. Only names re-exported from `dsafelogger` / `dsafelogger.mp` `__init__.py` are public.
|
|
185
|
+
|
|
132
186
|
## Free-Threaded Python
|
|
133
187
|
|
|
134
188
|
GitHub Actions runs Ubuntu free-threaded CPython `3.13t` and `3.14t` jobs with `PYTHON_GIL=0`.
|
|
@@ -166,13 +220,21 @@ See [`.github/workflows/ci.yml`](.github/workflows/ci.yml).
|
|
|
166
220
|
The CI workflow also runs publication checks on Ubuntu/Python 3.13:
|
|
167
221
|
|
|
168
222
|
```bash
|
|
223
|
+
uv run pyright --version
|
|
224
|
+
uv run mypy src
|
|
225
|
+
uv run pyright src
|
|
226
|
+
uv run pyright tests/typing_smoke
|
|
169
227
|
uv run python scripts/generate_api_docs.py --check
|
|
170
228
|
uv run python scripts/check_design_docs_sync.py
|
|
171
229
|
uv run python benchmarks/update_summary.py --check
|
|
172
230
|
uv build
|
|
231
|
+
uv run python scripts/check_distribution_contents.py
|
|
232
|
+
uv run python scripts/install_built_wheel.py
|
|
233
|
+
uv run --no-sync python scripts/check_type_completeness.py --min-score 100
|
|
234
|
+
uv sync --reinstall --group dev
|
|
173
235
|
```
|
|
174
236
|
|
|
175
|
-
The publish workflow repeats
|
|
237
|
+
The publish workflow repeats release document, benchmark, build, distribution-content, metadata, and full-suite checks, verifies the git tag matches the package version, and only then publishes.
|
|
176
238
|
|
|
177
239
|
## Documentation Checks
|
|
178
240
|
|
|
@@ -12,7 +12,7 @@ Enable ANSI escape sequences on Windows 10+.
|
|
|
12
12
|
|
|
13
13
|
## Classes
|
|
14
14
|
|
|
15
|
-
### `ColorStreamHandler(stream=None, color_enabled: 'bool' = True, color_overrides: 'dict[str, str] | None' = None) -> 'None'`
|
|
15
|
+
### `ColorStreamHandler(stream: 'IO[str] | None' = None, color_enabled: 'bool' = True, color_overrides: 'dict[str, str] | None' = None) -> 'None'`
|
|
16
16
|
|
|
17
17
|
StreamHandler with ANSI color codes for log levels.
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ in high-throughput multi-threaded scenarios.
|
|
|
43
43
|
|
|
44
44
|
## Classes
|
|
45
45
|
|
|
46
|
-
### `DSafeFormatter(fmt: 'str | None' = None, datefmt: 'str | None' = None, style: '
|
|
46
|
+
### `DSafeFormatter(fmt: 'str | None' = None, datefmt: 'str | None' = None, style: "Literal['%', '{', '$']" = '%') -> 'None'`
|
|
47
47
|
|
|
48
48
|
Standard D-SafeLogger formatter with level abbreviation and context suffix.
|
|
49
49
|
|
|
@@ -24,3 +24,15 @@ Public methods:
|
|
|
24
24
|
- `emit(self, record: 'logging.LogRecord') -> 'None'`
|
|
25
25
|
- `flush(self) -> 'None'`
|
|
26
26
|
- `reopen(self) -> 'None'`
|
|
27
|
+
|
|
28
|
+
### `ReopenableHandler(*args, **kwargs)`
|
|
29
|
+
|
|
30
|
+
Protocol for logging handlers that support external rotation reopen.
|
|
31
|
+
|
|
32
|
+
`isinstance(h, ReopenableHandler)` narrows `logging.Handler` references
|
|
33
|
+
to those that implement `reopen()`, replacing `hasattr(h, 'reopen')`
|
|
34
|
+
for static type checking.
|
|
35
|
+
|
|
36
|
+
Public methods:
|
|
37
|
+
|
|
38
|
+
- `reopen(self) -> 'None'`
|
|
@@ -39,7 +39,7 @@ Restart pump threads that were lost due to a post-fork in the parent process.
|
|
|
39
39
|
|
|
40
40
|
### `_same_process_identity(state: 'MPProcessState') -> 'bool'`
|
|
41
41
|
|
|
42
|
-
### `_validate_attach_ack(ack: '
|
|
42
|
+
### `_validate_attach_ack(ack: 'ControlAck', *, expected_protocol_version: 'int', expected_registry_hash: 'str') -> 'None'`
|
|
43
43
|
|
|
44
44
|
### `_validate_bootstrap_context(ctx: 'BootstrapContext') -> 'None'`
|
|
45
45
|
|
|
@@ -41,6 +41,12 @@ Public methods:
|
|
|
41
41
|
|
|
42
42
|
- `build(self, config: 'ResolvedConfig') -> 'Pipeline'`
|
|
43
43
|
|
|
44
|
-
### `ResolvedConfig(pg_name: 'str', log_dir: 'Path', file_fmt: 'str | FormatterConfigDict | logging.Formatter', console_fmt: 'str | FormatterConfigDict | logging.Formatter', routing_mode: 'str', routing_kwargs: 'dict', backup_count: 'int', archive_mode: 'bool', enable_hash: 'bool', manifest_path: 'Path | None', encoding: 'str', diagnose: 'bool', max_level: 'str', console: 'bool', is_async: 'bool', queue_size: 'int', log_level: 'str', color_stream: 'bool', module_configs: 'dict[str, dict]', color_overrides: 'dict[str, str]', sensitive_keywords: 'frozenset[str]' =
|
|
44
|
+
### `ResolvedConfig(pg_name: 'str', log_dir: 'Path', file_fmt: 'str | FormatterConfigDict | logging.Formatter', console_fmt: 'str | FormatterConfigDict | logging.Formatter', routing_mode: 'str', routing_kwargs: 'dict', backup_count: 'int', archive_mode: 'bool', enable_hash: 'bool', manifest_path: 'Path | None', encoding: 'str', diagnose: 'bool', max_level: 'str', console: 'bool', is_async: 'bool', queue_size: 'int', log_level: 'str', color_stream: 'bool', module_configs: 'dict[str, dict]', color_overrides: 'dict[str, str]', sensitive_keywords: 'frozenset[str]' = frozenset({'access_key', 'api_key', 'apikey', 'auth', 'cookie', 'credential', 'passwd', 'password', 'private_key', 'secret', 'session_id', 'token'})) -> None`
|
|
45
45
|
|
|
46
46
|
Resolved configuration holding 3-layer merged parameters.
|
|
47
|
+
|
|
48
|
+
## Constants
|
|
49
|
+
|
|
50
|
+
| Name | Type | Value |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `BUILTIN_SENSITIVE_KEYWORDS` | `frozenset` | `frozenset({'access_key', 'api_key', 'apikey', 'auth', 'cookie', 'credential',...` |
|
|
@@ -4290,6 +4290,7 @@ ConfigureLogger 引数 ← デフォルト(第3層)
|
|
|
4290
4290
|
|---|---|---|
|
|
4291
4291
|
| v23j | 2026-05-05 | OSS公開前 review 対応として、実装動作は v23h から変更せず、公開運用と品質ゲートを固定した。`dsafelogger.mp` は preview / experimental ではなく正式 API として公開する判断を記録し、価値訴求を raw throughput ではなく Writer-owned sinks と classified delivery-state observability に置く。OpenTelemetry / structlog coexistence tests は `dev` dependency group の full test suite に含め、`optional_integration` marker は診断用選択 marker とする。spawn E2E は Writer IPC primitives と worker creation で同一 `multiprocessing` context を使う。`tests/` から `multiprocessing.Queue.empty()` 依存を排除した。benchmark runner は `BENCHMARK.md` を生成せず、`benchmarks/results/<session>/`、`benchmarks/summary/manifest.json`、`benchmarks/summary/*.md`、手動編集 `BENCHMARK.md` の4層 publication model を採用する。release version は `0.2.0` とし、`pyproject.toml` と `dsafelogger.__version__` を一致させる。 |
|
|
4292
4292
|
| v23j-publication-sync | 2026-05-06 | 公開前同期として、API docs 生成、design docs sync check、examples 更新、GitHub workflow gate、coverage 再生成を追加する。これらは detailed runtime design を変更しない公開成果物同期であり、`dsafelogger.mp` formal API、dev full-test policy、benchmark publication model、release version `0.2.0` の判断を維持する。 |
|
|
4293
|
+
| v23j-type-validation | 2026-05-21 | 0.2.2 向け公開前品質ゲートとして、`py.typed` 配布に対応する source typing / packaged typing 検証を CI に追加する。`mypy src`、`pyright src`、`pyright tests/typing_smoke`、built wheel に対する `pyright --verifytypes dsafelogger --ignoreexternal` 100% completeness gate を publication checks に含める。verifytypes は `scripts/install_built_wheel.py` で wheel を install した直後に `uv run --no-sync` で実行し、editable install への自動復元を避ける。smoke test は標準ライブラリ `typing` shadow を避けるため `tests/typing_smoke/` に配置する。runtime behavior は変更しない。 |
|
|
4293
4294
|
| v23 | 2026-04-25 | v22i 詳細設計書を v23 として複写。v23 系設計方針(Writer 不変条件・配送契約用語・Overload Policy)は基本設計書 §12 を参照。実装との差分棚卸しを private planning notes に記録した。挙動変更なし。 |
|
|
4294
4295
|
| v23b | 2026-04-25 | `_log_loop` の `Queue.empty()` 依存を廃止し、client close marker 機構を実装した(差分棚卸し #4 対応)。各 client は DETACH 前に `CloseMarker` を log_queue に投入する。Writer は全 ATTACH 済み client の `CloseMarker` 受信(または `close_marker_failed` 確認)を drain 完了条件とする。`is_async=True` は pump thread join 後に CloseMarker を送信し、ordering を保証する。`close_marker_failed` は silent にならず、degraded shutdown として `_close_marker_degraded` フラグと stderr に反映する。drain deadline(`WRITER_STOP_WAIT_TIMEOUT_SEC`)超過時は outstanding marker を警告しつつ終了する。変更対象: `_mp_protocol.py`(`CloseMarker`, `_is_close_marker`)、`_mp_runtime.py`(`_drain_complete`, `_record_close_marker`, `_expected_close_markers`, `_close_markers_received`, `_close_marker_failed_clients`, `_drain_deadline`)、`_mp_attach.py`(`send_close_marker`, `_do_detach` フェーズ再構築)、`_mp_control.py`(`_make_detach_request` の `close_marker_failed` 引数)。 |
|
|
4295
4296
|
| v23c | 2026-04-26 | queue サイズをユーザー設定可能にし、drop/reject カウンターを原因別に分離した(差分棚卸し #1・#5・#7 対応)。`mp.ConfigureLogger()` に `ipc_log_queue_maxsize: int | None` と `ipc_client_queue_maxsize: int | None` を追加。env var `{prefix}_IPC_LOG_QUEUE_MAXSIZE` / `{prefix}_IPC_CLIENT_QUEUE_MAXSIZE` で上書き可能。既定値は `ipc_log_queue_maxsize=1000`(v22i 実装値を継承)、`ipc_client_queue_maxsize` は未指定時 `ipc_log_queue_maxsize` に揃える。`BootstrapContext` に `ipc_client_queue_maxsize: int` フィールドを追加。`MPClientTransport` の process-local async queue を `ctx.ipc_client_queue_maxsize` で生成するよう変更。`MPClientTransport._drop()` に原因別カウンター(`_overload_shed`, `_transport_closed_drop`, `_writer_unavailable_drop`, `_timeout_drop`)を追加。`WriterRuntime` に `_writer_route_reject`, `_writer_event_reject` を追加し `STATUS` レスポンスに反映。制御 queue(256)は内部定数のまま維持(根拠不明を棚卸し #2 に記録済み)。 |
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
v23j は v23h 完了時点の OSS 公開前指摘に対するユーザー判断に基づく修正版である。v23h の sink 分類 / bounded shutdown 契約を維持した上で、公開前のテスト契約・MP E2E・benchmark 成果物管理を確定する。
|
|
11
11
|
|
|
12
|
-
現行 v23j のローカル検証 baseline は Python 3.14.3 / Windows 上の結果であり、`658 passed, 3 skipped`(`661` collected)である。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、OS によって skipped 数は変動し得る。
|
|
12
|
+
現行 v23j のローカル検証 baseline は Python 3.14.3 / Windows 上の結果であり、`658 passed, 3 skipped`(`661` collected)である。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、OS によって skipped 数は変動し得る。0.2.2 向けの公開前品質ゲートでは、これに加えて `mypy src` / `pyright src` / `pyright tests/typing_smoke` / built wheel に対する `pyright --verifytypes dsafelogger --ignoreexternal` 100% completeness gate を実行する。
|
|
13
13
|
|
|
14
14
|
v23h から継続する動作変更は以下:
|
|
15
15
|
|
|
@@ -34,6 +34,8 @@ v23j で追加する公開前方針は以下:
|
|
|
34
34
|
16. merge 後の設定正規化・検証を single-process / module-specific / multiprocess で共通化する
|
|
35
35
|
17. routing / 世代管理 / hash の無効組み合わせは warning 補正ではなく `ValueError` とする
|
|
36
36
|
18. `structured=True` と formatter 指定、未登録 level、数値範囲不正、Python API bool 型不正を fail-fast 検証する
|
|
37
|
+
19. `py.typed` 配布に対応し、source typing (`mypy src`, `pyright src`) と packaged typing (`pyright --verifytypes dsafelogger --ignoreexternal`) を公開前品質ゲートへ含める
|
|
38
|
+
20. 利用者視点の public API typing smoke test は `tests/typing_smoke/` に置き、`tests/typing/` という名前は標準ライブラリ `typing` shadow を避けるため使わない
|
|
37
39
|
|
|
38
40
|
---
|
|
39
41
|
|
|
@@ -71,6 +73,10 @@ v23j で追加する公開前方針は以下:
|
|
|
71
73
|
| DOD-v23j-28 | mp の validation は single-process と同じ共通検証を使い、`structured=True + file_fmt/console_fmt` も拒否する |
|
|
72
74
|
| DOD-v23j-29 | mp module-specific `level` は worker attach 側 logger level に反映する |
|
|
73
75
|
| DOD-v23j-30 | Python API bool 引数に `str` など bool 以外を渡した場合は `TypeError` |
|
|
76
|
+
| DOD-v23j-type-31 | `uv run mypy src` と `uv run pyright src` が 0 errors で完了する |
|
|
77
|
+
| DOD-v23j-type-32 | `uv run pyright tests/typing_smoke` が 0 errors で完了し、`tests/typing_smoke/public_api_smoke.py` は pytest default collection に含まれない |
|
|
78
|
+
| DOD-v23j-type-33 | built wheel install 後、`uv run --no-sync python scripts/check_type_completeness.py --min-score 100` が `pyright --verifytypes dsafelogger --ignoreexternal` の 100% completeness を確認する |
|
|
79
|
+
| DOD-v23j-type-34 | `tests/typing_smoke/` の名称により spawn worker で stdlib `typing` を shadow しない |
|
|
74
80
|
|
|
75
81
|
---
|
|
76
82
|
|
|
@@ -108,6 +114,10 @@ v23j で追加する公開前方針は以下:
|
|
|
108
114
|
| DOD-v23j-28 | `tests/test_mp_configure.py::TestMpConfigureLogger::test_structured_and_file_fmt_mutual_exclusion`、`test_config_dict_invalid_default_level_raises` |
|
|
109
115
|
| DOD-v23j-29 | `tests/test_mp_configure.py::TestMpConfigureLogger::test_module_level_propagates_to_attached_logger` |
|
|
110
116
|
| DOD-v23j-30 | `tests/test_coverage_boost.py::TestConfigureAdvanced::test_enable_hash_wrong_type` と追加 bool 型検査 |
|
|
117
|
+
| DOD-v23j-type-31 | `uv run mypy src` / `uv run pyright src` |
|
|
118
|
+
| DOD-v23j-type-32 | `uv run pyright tests/typing_smoke` / `uv run pytest tests --collect-only -q` |
|
|
119
|
+
| DOD-v23j-type-33 | `scripts/install_built_wheel.py` / `scripts/check_type_completeness.py --min-score 100` |
|
|
120
|
+
| DOD-v23j-type-34 | `tests/typing_smoke/public_api_smoke.py` の配置と spawn 系 MP tests (`tests/test_mp_integration.py`, `tests/test_mp_spawn_windows.py`) |
|
|
111
121
|
|
|
112
122
|
---
|
|
113
123
|
|
|
@@ -118,6 +128,18 @@ v23j で追加する公開前方針は以下:
|
|
|
118
128
|
```bash
|
|
119
129
|
uv sync --group dev
|
|
120
130
|
uv run pytest tests -v
|
|
131
|
+
uv run mypy src
|
|
132
|
+
uv run pyright src
|
|
133
|
+
uv run pyright tests/typing_smoke
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
packaged typing の completeness は built wheel を対象に検証する。`install_built_wheel.py` 実行後の verifytypes は editable install へ戻らないよう `uv run --no-sync` を使う。
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
uv build
|
|
140
|
+
uv run python scripts/install_built_wheel.py
|
|
141
|
+
uv run --no-sync python scripts/check_type_completeness.py --min-score 100
|
|
142
|
+
uv sync --reinstall
|
|
121
143
|
```
|
|
122
144
|
|
|
123
145
|
補助的な切り分け用途として以下を許可するが、release 判定の代替にはしない。
|
|
@@ -140,7 +162,7 @@ v23j では benchmark 公開成果物の管理方式を変更する。runner は
|
|
|
140
162
|
|
|
141
163
|
### v23j Publication Sync Addendum
|
|
142
164
|
|
|
143
|
-
公開前同期の追加 DOD として、coverage 再生成、API docs `--check`、design docs sync check、GitHub CI / publish preflight、examples の formal MP / external rotation
|
|
165
|
+
公開前同期の追加 DOD として、coverage 再生成、API docs `--check`、design docs sync check、GitHub CI / publish preflight、examples の formal MP / external rotation 追加を検証対象に含める。0.2.2 向けにはさらに source typing、typing smoke、built wheel に対する verifytypes 100% completeness gate を追加する。これらは runtime behavior を変更せず、公開成果物と品質ゲートを同期するための補助検証である。
|
|
144
166
|
|
|
145
167
|
---
|
|
146
168
|
|
|
@@ -243,7 +243,7 @@ D-SafeLogger は、**Python 標準ライブラリ `logging` の上に構築さ
|
|
|
243
243
|
- 対象 Python: 3.11 以上(CPython 3.13 以上の **free-threaded build** を設計対象に含む)
|
|
244
244
|
- 対象 OS: Windows / macOS / Linux
|
|
245
245
|
- ランタイム依存: なし(Python 標準ライブラリのみ)
|
|
246
|
-
- 型情報: `py.typed`
|
|
246
|
+
- 型情報: `py.typed` を同梱。CI では `mypy` / `pyright` / typing smoke test / `pyright --verifytypes` 100% public type completeness gate を検証する
|
|
247
247
|
|
|
248
248
|
#### 1.1.2 ポジショニング
|
|
249
249
|
|
|
@@ -4770,7 +4770,7 @@ D-SafeLogger の 3 層パイプラインは次の点で観測可能な差別化
|
|
|
4770
4770
|
|
|
4771
4771
|
| 項目 | D-SafeLogger v23j | stdlib `logging` | Loguru 0.7.3 | structlog 25.5.0 | picologging 0.9.3 | Eliot 1.18.0 | Logbook 1.9.2 | logfire 4.32.1 | OTel SDK 1.41.1 |
|
|
4772
4772
|
|---|---|---|---|---|---|---|---|---|---|
|
|
4773
|
-
| 最新 release 日 | (v23j / 0.2.
|
|
4773
|
+
| 最新 release 日 | (v23j / 0.2.1、本レポート時点) | Python 3.14 | 2024-12-06 | 2025-10-27 | 2024-09-13(GitHub) | 2026-05-07 | — | (4.32.1) | (1.41.1) |
|
|
4774
4774
|
| ライセンス | Apache 2.0 | PSF | MIT | MIT or Apache-2.0 | MIT | Apache 2.0 | BSD-3-Clause | MIT | Apache-2.0 |
|
|
4775
4775
|
| Python 要件 | >=3.11 | (Python 自体) | >=3.5,<4 | >=3.8 | >=3.7 | >=3.10.0 | >=3.9 | >=3.9 | >=3.9 |
|
|
4776
4776
|
| ランタイム依存数 | **0** | 0 | 3(条件付き) | 1(条件付き) | 0 | 4 | 1 | 8 | 3 |
|
|
@@ -5342,6 +5342,7 @@ OSS 公開時には国内・海外双方からの評価軸が想定されるが
|
|
|
5342
5342
|
- skipped 数は OS 依存。fork E2E は POSIX-only、Windows spawn E2E は Windows-only であるため、CI matrix では OS により skipped 数が変動し得る。
|
|
5343
5343
|
- カバレッジ: terminal total **87%**, XML line-rate **88.97%**, branch-rate **81.46%**
|
|
5344
5344
|
- multiprocess tests / OTel・structlog coexistence tests は公式品質ゲートに含まれる
|
|
5345
|
+
- 型検証: `mypy src` / `pyright src` / `pyright tests/typing_smoke` / built wheel に対する `pyright --verifytypes dsafelogger --ignoreexternal` 100% completeness gate を公開前検証に含める。smoke test ディレクトリは標準ライブラリ `typing` shadow を避けるため `tests/typing_smoke/` とする。
|
|
5345
5346
|
- free-threaded build テスト: `PYTHON_GIL=0 uvx --python cpython-3.13+freethreaded --from pytest pytest tests -v`
|
|
5346
5347
|
|
|
5347
5348
|
#### 7.10.4 リリース管理
|
|
@@ -5709,6 +5710,7 @@ structlog(2 パターンで共存)/ OpenTelemetry Python(`LoggingHandler`
|
|
|
5709
5710
|
- 公式テスト baseline: 658 passed / 3 skipped(収集 661、`uv run pytest tests -v`、Python 3.14.3 / Windows)。fork E2E は POSIX-only、Windows spawn E2E は Windows-only のため、OS によって skipped 数は変動し得る。
|
|
5710
5711
|
- カバレッジ: terminal total 87%, XML line-rate 88.97%, branch-rate 81.46%
|
|
5711
5712
|
- multiprocess tests / OTel・structlog coexistence tests は公式品質ゲートに含まれる
|
|
5713
|
+
- 型検証: `mypy src` / `pyright src` / `pyright tests/typing_smoke` / built wheel に対する `pyright --verifytypes dsafelogger --ignoreexternal` 100% completeness gate を公開前検証に含める
|
|
5712
5714
|
- free-threaded build テスト手順あり(`PYTHON_GIL=0 uvx ...`)
|
|
5713
5715
|
- `scripts/check_design_docs_sync.py` および `scripts/generate_api_docs.py --check` で内部同期検証
|
|
5714
5716
|
- `benchmarks/summary/manifest.json` で公開代表セッションを固定
|
|
@@ -5760,7 +5762,7 @@ structlog(2 パターンで共存)/ OpenTelemetry Python(`LoggingHandler`
|
|
|
5760
5762
|
|
|
5761
5763
|
#### 8.8.5 ドキュメント・品質運用
|
|
5762
5764
|
|
|
5763
|
-
10. **品質ゲートと内部同期検証スクリプトが整備されている**: Python 3.14.3 / Windows で 658 passed / 3 skipped(収集 661)、カバレッジ 87%、`scripts/check_design_docs_sync.py` と `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による公開代表セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
|
|
5765
|
+
10. **品質ゲートと内部同期検証スクリプトが整備されている**: Python 3.14.3 / Windows で 658 passed / 3 skipped(収集 661)、カバレッジ 87%、`mypy` / `pyright` / typing smoke / `pyright --verifytypes` 100% completeness gate、`scripts/check_design_docs_sync.py` と `scripts/generate_api_docs.py --check` による内部同期検証、`benchmarks/summary/manifest.json` による公開代表セッション固定。skipped 数は OS 依存で変動し得る。これらは導入候補ライブラリの評価時に観測可能な品質指標として記録される。
|
|
5764
5766
|
|
|
5765
5767
|
---
|
|
5766
5768
|
|
|
@@ -5772,7 +5774,7 @@ D-SafeLogger v23j は次の総合像として整理できる:
|
|
|
5772
5774
|
2. **8 軸の設計姿勢がライブラリ全体を貫いて一貫している**: 構造的に排除 / 責務分離 / 失敗分類 / 絶対防衛線 / opt-in 境界の明示 / 境界の能動的明示 / standardness 維持 / 責務委譲。
|
|
5773
5775
|
3. **エコシステム上の位置は 4 命題に集約される**: 直接競合は観測されない / stdlib 拡張型 × 機能差別化のニッチを占める / stdlib 公式の既知制約への直接応答 / 競合ではなく共存を志向。
|
|
5774
5776
|
4. **ベンチマーク観測事実は raw throughput ではなく観測性に主張軸が置かれる**: 単一プロセス async は競争力ある数値、multiprocess は raw throughput では stdlib に劣るが配送状態の説明可能性で固有の観測性を提供。
|
|
5775
|
-
5. **ドキュメント・運用構造は内部同期検証と境界の能動的明示で整備されている**: 公開設計書 + 自動生成 API + 多言語 README + manifest 固定 benchmark +
|
|
5777
|
+
5. **ドキュメント・運用構造は内部同期検証と境界の能動的明示で整備されている**: 公開設計書 + 自動生成 API + 多言語 README + manifest 固定 benchmark + 品質ゲートのテストマトリックス + 型検証 gate。
|
|
5776
5778
|
|
|
5777
5779
|
これらは設計書 §1 の絶対条件「標準ライブラリへの完全な準拠を絶対条件としつつ、サードパーティ製ライブラリ(Loguru 等)を凌駕する診断能力と、Windows 環境での致命的なファイルロック問題を回避する堅牢性を外部依存ゼロで実現する」が、v23j 時点で**仕様・設計・実装・テスト・ドキュメント・ベンチマークの全層で一貫した形に到達している**ことを示す観測事実の集約である。
|
|
5778
5780
|
|
|
@@ -224,7 +224,7 @@ D-SafeLogger is a logging platform built on the Python standard library `logging
|
|
|
224
224
|
- Target Python: 3.11 or higher (including **free-threaded build** of CPython 3.13 or higher)
|
|
225
225
|
- Target OS: Windows / macOS / Linux
|
|
226
226
|
- Runtime dependencies: None (Python standard library only)
|
|
227
|
-
- Type information: Includes `py.typed`
|
|
227
|
+
- Type information: Includes `py.typed`; CI verifies `mypy`, `pyright`, a typing smoke test, and a 100% public type-completeness gate with `pyright --verifytypes`
|
|
228
228
|
#### 1.1.2 Positioning
|
|
229
229
|
Official design document §1 defines the position of this module as follows.
|
|
230
230
|
> This module is a lightweight, fast, and highly functional logging platform that is commonly used by all projects in the various Python ecosystems (D-Settings, DPySide, D-MessageRouter, etc.) provided by `D`. **The premise is that it will be released as a standalone OSS, but the top priority will be to operate it as a common platform for the "D Ecosystem" rather than to widely disseminate it**.
|
|
@@ -3473,7 +3473,7 @@ D-SafeLogger's three-layer pipeline has observable differentiation in the follow
|
|
|
3473
3473
|
### 6.12 Latest status summary by library
|
|
3474
3474
|
| Item | D-SafeLogger v23j | stdlib `logging` | Loguru 0.7.3 | structlog 25.5.0 | picologging 0.9.3 | Eliot 1.18.0 | Logbook 1.9.2 | logfire 4.32.1 | OTel SDK 1.41.1 |
|
|
3475
3475
|
|---|---|---|---|---|---|---|---|---|---|
|
|
3476
|
-
| Latest release date | (v23j/0.2.
|
|
3476
|
+
| Latest release date | (v23j/0.2.1, as of this report) | Python 3.14 | 2024-12-06 | 2025-10-27 | 2024-09-13 (GitHub) | 2026-05-07 | — | (4.32.1) | (1.41.1) |
|
|
3477
3477
|
| License | Apache 2.0 | PSF | MIT | MIT or Apache-2.0 | MIT | Apache 2.0 | BSD-3-Clause | MIT | Apache-2.0 |
|
|
3478
3478
|
| Python requirements | >=3.11 | (Python itself) | >=3.5,<4 | >=3.8 | >=3.7 | >=3.10.0 | >=3.9 | >=3.9 | >=3.9 |
|
|
3479
3479
|
| Number of runtime dependencies | **0** | 0 | 3 (conditional) | 1 (conditional) | 0 | 4 | 1 | 8 | 3 |
|
|
@@ -3872,6 +3872,7 @@ Facts that can be confirmed from `pyproject.toml` and `MANIFEST.in`:
|
|
|
3872
3872
|
- The skipped count is platform-dependent because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
|
|
3873
3873
|
- Coverage: terminal total **87%**, XML line-rate **88.97%**, branch-rate **81.46%**
|
|
3874
3874
|
- multiprocess tests / OTel/structlog coexistence tests are included in the official quality gate
|
|
3875
|
+
- Type validation: public validation includes `mypy src`, `pyright src`, `pyright tests/typing_smoke`, and a 100% `pyright --verifytypes dsafelogger --ignoreexternal` completeness gate against the built wheel. The smoke-test directory is named `tests/typing_smoke/` to avoid shadowing the standard-library `typing` module.
|
|
3875
3876
|
- free-threaded build test: `PYTHON_GIL=0 uvx --python cpython-3.13+freethreaded --from pytest pytest tests -v`
|
|
3876
3877
|
#### 7.10.4 Release Management
|
|
3877
3878
|
Public validation procedures:
|
|
@@ -4134,6 +4135,7 @@ Boundaries that public bench analysis actively enumerates:
|
|
|
4134
4135
|
- Official test baseline: 658 passed / 3 skipped (661 collected, `uv run pytest tests -v`, Python 3.14.3 / Windows). The skipped count can vary by OS because fork E2E tests are POSIX-only and Windows spawn E2E tests are Windows-only.
|
|
4135
4136
|
- Coverage: terminal total 87%, XML line-rate 88.97%, branch-rate 81.46%
|
|
4136
4137
|
- multiprocess tests / OTel/structlog coexistence tests are included in the official quality gate
|
|
4138
|
+
- Type validation: public validation includes `mypy src`, `pyright src`, `pyright tests/typing_smoke`, and a 100% `pyright --verifytypes dsafelogger --ignoreexternal` completeness gate against the built wheel
|
|
4137
4139
|
- free-threaded build test procedure included (`PYTHON_GIL=0 uvx ...`)
|
|
4138
4140
|
- Internal synchronization verification on `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`
|
|
4139
4141
|
- Fixed public representative session with `benchmarks/summary/manifest.json`
|
|
@@ -4168,7 +4170,7 @@ Based on the observed facts in this report as a whole, we have summarized the ob
|
|
|
4168
4170
|
8. **Multiprocess raw throughput is led by stdlib logging**: In `root_p8`, D-SafeLogger reaches 63-75% of stdlib throughput. `BENCHMARK.md` states this clearly as a design tradeoff reflecting fixed costs in the specification (IPC + Writer dispatch). The multiprocess value of this library is not raw throughput, but delivery-state observability.
|
|
4169
4171
|
9. **Classifies and explains 12/12 rows in the multiprocess resilience profile**: stdlib / loguru rows are marked with `observability_gap`. Delivery-state explainability is recorded as observability specific to this library.
|
|
4170
4172
|
#### 8.8.5 Documentation/quality operations
|
|
4171
|
-
10. **Quality gate and internal synchronization verification scripts are in place**: 658 passed / 3 skipped on Python 3.14.3 / Windows (661 collected), coverage 87%, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, public representative session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
|
|
4173
|
+
10. **Quality gate and internal synchronization verification scripts are in place**: 658 passed / 3 skipped on Python 3.14.3 / Windows (661 collected), coverage 87%, `mypy` / `pyright` / typing smoke / `pyright --verifytypes` 100% completeness gate, internal synchronization verification by `scripts/check_design_docs_sync.py` and `scripts/generate_api_docs.py --check`, public representative session fixation by `benchmarks/summary/manifest.json`. The skipped count can vary by OS. These are recorded as observable quality indicators when evaluating candidate libraries for introduction.
|
|
4172
4174
|
---
|
|
4173
4175
|
|
|
4174
4176
|
### 8.9 Summary of this chapter
|
{d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D_SafeLogger_Specification_v23j_full.md
RENAMED
|
@@ -2496,3 +2496,7 @@ bounded wait (≤ timeout) -> visible warning (drain incomplete を可視化) ->
|
|
|
2496
2496
|
### v23j Publication Sync Addendum
|
|
2497
2497
|
|
|
2498
2498
|
公開前同期として、coverage 再生成、API docs 再生成、examples の formal MP / external rotation 追加、GitHub workflow gate 強化、`docs/design/` 公開設計書の readiness check を対象に含める。これらは runtime behavior を変更しない公開成果物同期であり、release version は `0.2.0` のまま維持する。
|
|
2499
|
+
|
|
2500
|
+
### v23j Type Validation CI Addendum
|
|
2501
|
+
|
|
2502
|
+
0.2.2 向けの公開前品質ゲートとして、`py.typed` 配布に対応する型検証を CI に追加する。source typing は `mypy src` と `pyright src`、利用者視点の smoke test は `pyright tests/typing_smoke`、packaged typing は built wheel を install した上で `pyright --verifytypes dsafelogger --ignoreexternal` を 100% completeness threshold で検証する。verifytypes 実行時は editable install へ戻らないよう `uv run --no-sync` を使う。smoke test ディレクトリは spawn worker で標準ライブラリ `typing` を shadow しないよう `tests/typing_smoke/` とし、`tests/typing/` は使わない。これらは runtime behavior を変更しない公開品質ゲートの追加であり、release version bump は release readiness 確定時に行う。
|
{d_safelogger-0.2.1 → d_safelogger-0.2.2}/docs/design/D_SafeLogger_Specification_v23j_full_en.md
RENAMED
|
@@ -2479,3 +2479,7 @@ This design prevents the host process from permanently blocking even if an unkno
|
|
|
2479
2479
|
### v23j Publication Sync Addendum
|
|
2480
2480
|
|
|
2481
2481
|
Pre-publication synchronization includes coverage regeneration, API docs regeneration, addition of formal MP/external rotation for examples, enhancement of GitHub workflow gate, and readiness check of `docs/design/` publication design document. These are public artifact synchronizations that do not change the runtime behavior and keep the release version as `0.2.0`.
|
|
2482
|
+
|
|
2483
|
+
### v23j Type Validation CI Addendum
|
|
2484
|
+
|
|
2485
|
+
For the 0.2.2 pre-publication quality gate, CI adds type validation for the `py.typed` distribution. Source typing is checked with `mypy src` and `pyright src`, user-perspective smoke typing is checked with `pyright tests/typing_smoke`, and packaged typing is checked from the installed built wheel with `pyright --verifytypes dsafelogger --ignoreexternal` at a 100% completeness threshold. The verifytypes step uses `uv run --no-sync` so the wheel install is not replaced by the editable install before verification. The smoke-test directory is named `tests/typing_smoke/`, not `tests/typing/`, to avoid shadowing the standard-library `typing` module in spawn workers. These additions change only the public quality gate, not runtime behavior; the release-version bump is deferred until release readiness is confirmed.
|