From d907b1e71c42efc0e54843877d4233d7e88d5f56 Mon Sep 17 00:00:00 2001 From: Dmitrii Safronov Date: Tue, 9 Dec 2025 17:50:28 +0400 Subject: [PATCH 1/4] feat: add type annotations and mypy support - Updated `pyproject.toml` to include "Typing :: Typed" in classifiers. - Introduced a new `py.typed` file to indicate type checking support for mypy. - Enhanced type annotations in `schema_applier.py` for better type safety. - Added comprehensive tests in `test_mypy_support.py` to verify mypy type checking and ensure correct type annotations in `SchemaLogger`. These changes improve type safety and support for static type checking in the logging framework. Signed-off-by: Dmitrii Safronov --- pyproject.toml | 3 +- src/logging_objects_with_schema/py.typed | 0 .../schema_applier.py | 2 +- tests/test_mypy_support.py | 107 ++++++++++++++++++ 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/logging_objects_with_schema/py.typed create mode 100644 tests/test_mypy_support.py diff --git a/pyproject.toml b/pyproject.toml index 485997c..93bff8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,8 @@ classifiers = [ "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3 :: Only", "Intended Audience :: Developers", - "Topic :: System :: Logging" + "Topic :: System :: Logging", + "Typing :: Typed" ] [[project.authors]] diff --git a/src/logging_objects_with_schema/py.typed b/src/logging_objects_with_schema/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/src/logging_objects_with_schema/schema_applier.py b/src/logging_objects_with_schema/schema_applier.py index 2f30e86..74ff80b 100644 --- a/src/logging_objects_with_schema/schema_applier.py +++ b/src/logging_objects_with_schema/schema_applier.py @@ -42,7 +42,7 @@ def _create_validation_error_json(field: str, error: str, value: Any) -> str: def _validate_list_value( - value: list, + value: list[Any], source: str, item_expected_type: type | None, ) -> _DataProblem | None: diff --git a/tests/test_mypy_support.py b/tests/test_mypy_support.py new file mode 100644 index 0000000..2c79a2a --- /dev/null +++ b/tests/test_mypy_support.py @@ -0,0 +1,107 @@ +"""Tests for mypy type checking support.""" + +from __future__ import annotations + +import subprocess # nosec B404 +import sys +from pathlib import Path + +import pytest + +from logging_objects_with_schema import SchemaLogger +from tests.helpers import _write_schema + + +def test_py_typed_file_exists() -> None: + """Verify that py.typed marker file exists in the package.""" + package_dir = Path(__file__).parent.parent / "src" / "logging_objects_with_schema" + py_typed = package_dir / "py.typed" + + assert py_typed.exists(), "py.typed marker file must exist for mypy support" + + +def test_mypy_type_checking() -> None: + """Verify that mypy can type-check the package without errors.""" + package_dir = Path(__file__).parent.parent / "src" / "logging_objects_with_schema" + + # Run mypy on the package directory + result = subprocess.run( # nosec B603 + [ + sys.executable, + "-m", + "mypy", + str(package_dir), + "--no-error-summary", + ], + capture_output=True, + text=True, + cwd=Path(__file__).parent.parent, + ) + + assert ( + result.returncode == 0 + ), f"mypy found type errors:\n{result.stdout}\n{result.stderr}" + + +def test_mypy_strict_type_checking() -> None: + """Verify that mypy can type-check the package in strict mode without errors.""" + package_dir = Path(__file__).parent.parent / "src" / "logging_objects_with_schema" + + # Run mypy in strict mode on the package directory + result = subprocess.run( # nosec B603 + [ + sys.executable, + "-m", + "mypy", + str(package_dir), + "--strict", + "--no-error-summary", + ], + capture_output=True, + text=True, + cwd=Path(__file__).parent.parent, + ) + + assert ( + result.returncode == 0 + ), f"mypy found type errors in strict mode:\n{result.stdout}\n{result.stderr}" + + +def test_schema_logger_type_annotations( + tmp_path: Path, + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Verify that SchemaLogger has correct type annotations for mypy.""" + # This test verifies that type annotations are correct by using them + # If mypy is run on this file, it should not find any errors + + monkeypatch.chdir(tmp_path) + _write_schema(tmp_path, {"ServicePayload": {}}) + + # Test that SchemaLogger can be typed correctly + logger: SchemaLogger = SchemaLogger("test-logger", forbidden_keys=None) + + # Test that __init__ signature accepts correct types + logger2: SchemaLogger = SchemaLogger( + name="test-logger-2", + level=10, + forbidden_keys={"key1", "key2"}, + ) + + # Test that SchemaLogger is compatible with logging.Logger + import logging + + def accept_logger(logger: logging.Logger) -> logging.Logger: + return logger + + # This should work without type errors + result: logging.Logger = accept_logger(logger) + assert isinstance(result, SchemaLogger) + + # Test that logger methods are accessible and typed + logger.info("test message") + logger.debug("debug message", extra={"key": "value"}) + logger.warning("warning message") + + # Verify logger2 was created successfully (test __init__ signature) + assert logger2.name == "test-logger-2" From d98a9490362d512d685feccf86675e8c73847835 Mon Sep 17 00:00:00 2001 From: Dmitrii Safronov Date: Tue, 9 Dec 2025 17:52:27 +0400 Subject: [PATCH 2/4] chore: update excluded directories in Bandit configuration - Modified the `exclude_dirs` in the Bandit tool configuration within `pyproject.toml` to include the `tests` directory, ensuring that test files are not analyzed for security issues. This change helps streamline security checks by focusing on relevant source code directories. Signed-off-by: Dmitrii Safronov --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 93bff8f..a86a2f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,8 +94,7 @@ warn_unreachable = true strict_equality = true [tool.bandit] -skips = [ "B101", "B601" ] -exclude_dirs = [ ".venv", "__pycache__", ".git", "htmlcov" ] +exclude_dirs = [ ".venv", "__pycache__", ".git", "htmlcov", "tests" ] [tool.coverage.run] source = [ "src" ] From afff55d4e9bb06b6319426c66cfafdaf575cf5f0 Mon Sep 17 00:00:00 2001 From: Dmitrii Safronov Date: Tue, 9 Dec 2025 17:53:03 +0400 Subject: [PATCH 3/4] test: clean up subprocess calls in mypy tests - Removed unnecessary comments from subprocess calls in `test_mypy_support.py` to improve code readability. - Ensured consistent formatting for subprocess invocations, enhancing maintainability of the test code. This change streamlines the test code while maintaining its functionality. Signed-off-by: Dmitrii Safronov --- tests/test_mypy_support.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_mypy_support.py b/tests/test_mypy_support.py index 2c79a2a..d342088 100644 --- a/tests/test_mypy_support.py +++ b/tests/test_mypy_support.py @@ -2,7 +2,7 @@ from __future__ import annotations -import subprocess # nosec B404 +import subprocess import sys from pathlib import Path @@ -25,7 +25,7 @@ def test_mypy_type_checking() -> None: package_dir = Path(__file__).parent.parent / "src" / "logging_objects_with_schema" # Run mypy on the package directory - result = subprocess.run( # nosec B603 + result = subprocess.run( [ sys.executable, "-m", @@ -48,7 +48,7 @@ def test_mypy_strict_type_checking() -> None: package_dir = Path(__file__).parent.parent / "src" / "logging_objects_with_schema" # Run mypy in strict mode on the package directory - result = subprocess.run( # nosec B603 + result = subprocess.run( [ sys.executable, "-m", From 4a21caf4f6ee5068e4e47a52b317dca18630ec7e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 9 Dec 2025 15:21:47 +0000 Subject: [PATCH 4/4] chore(release): 0.3.0-rc.1 ## [0.3.0-rc.1](https://github.com/disafronov/python-logging-objects-with-schema/compare/v0.2.0...v0.3.0-rc.1) (2025-12-09) ### Features * add type annotations and mypy support ([d907b1e](https://github.com/disafronov/python-logging-objects-with-schema/commit/d907b1e71c42efc0e54843877d4233d7e88d5f56)) Signed-off-by: semantic-release-bot --- CHANGELOG.md | 6 ++++++ pyproject.toml | 2 +- uv.lock | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9863707..b252ff5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## [0.3.0-rc.1](https://github.com/disafronov/python-logging-objects-with-schema/compare/v0.2.0...v0.3.0-rc.1) (2025-12-09) + +### Features + +* add type annotations and mypy support ([d907b1e](https://github.com/disafronov/python-logging-objects-with-schema/commit/d907b1e71c42efc0e54843877d4233d7e88d5f56)) + ## [0.2.0](https://github.com/disafronov/python-logging-objects-with-schema/compare/v0.1.4...v0.2.0) (2025-12-09) ### Features diff --git a/pyproject.toml b/pyproject.toml index a86a2f1..4ab6a91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "logging-objects-with-schema" -version = "0.2.0" +version = "0.3.0rc1" description = "Proxy logging wrapper that validates extra fields against a JSON schema." readme = "README.md" requires-python = ">=3.10" diff --git a/uv.lock b/uv.lock index 316b18b..9d108cf 100644 --- a/uv.lock +++ b/uv.lock @@ -1394,7 +1394,7 @@ version = "0.6.3" [[package]] name = "logging-objects-with-schema" -version = "0.2.0" +version = "0.3.0rc1" [package.source] editable = "."