[minor] Add runtime-checkable Protocol typing to public interfaces #57

Merged
brian merged 3 commits from cursor/protocol-abc-interfaces into main 2026-07-11 10:56:03 +02:00
Owner

Summary

  • Convert all four public interfaces (JsonRepositoryInterface, ObjectRepositoryInterface, ConnectionAwareInterface, ContextAwareInterface) to @runtime_checkable Protocol classes with @abstractmethod members
  • Reorder adapter inheritance so concrete bases come before Protocol interfaces (ConnectionAwareAdapter first), preserving super().__init__() behavior
  • Add structural typing unit tests for duck-typed implementations without inheritance
  • Document nominal (subclass adapter) vs structural (type-annotate against interface) usage in README

Notes

  • class X(Protocol, ABC) is invalid at runtime in Python; Protocol with @abstractmethod provides the intended behavior (structural typing + instantiation guards for explicit subclasses)
  • No breaking changes for existing adapter subclasses; scan_keys default remains for nominal implementors

Test plan

  • uv run pytest tests/unit/ -v (99 passed)
  • uv run mypy python_repositories tests
  • uv run ruff check / ruff format
## Summary - Convert all four public interfaces (`JsonRepositoryInterface`, `ObjectRepositoryInterface`, `ConnectionAwareInterface`, `ContextAwareInterface`) to `@runtime_checkable` `Protocol` classes with `@abstractmethod` members - Reorder adapter inheritance so concrete bases come before Protocol interfaces (`ConnectionAwareAdapter` first), preserving `super().__init__()` behavior - Add structural typing unit tests for duck-typed implementations without inheritance - Document nominal (subclass adapter) vs structural (type-annotate against interface) usage in README ## Notes - `class X(Protocol, ABC)` is invalid at runtime in Python; `Protocol` with `@abstractmethod` provides the intended behavior (structural typing + instantiation guards for explicit subclasses) - No breaking changes for existing adapter subclasses; `scan_keys` default remains for nominal implementors ## Test plan - [x] `uv run pytest tests/unit/ -v` (99 passed) - [x] `uv run mypy python_repositories tests` - [x] `uv run ruff check` / `ruff format`
brian added 1 commit 2026-07-11 09:46:24 +02:00
Add runtime-checkable Protocol typing to all public interfaces.
PR Title Check / check-title (pull_request) Successful in 7s
Test Python Package / unit-tests (pull_request) Successful in 9s
Code Quality Pipeline / code-quality (pull_request) Successful in 22s
Test Python Package / integration-tests (pull_request) Successful in 24s
Test Python Package / coverage-report (pull_request) Successful in 8s
f6ee9a3724
Enables structural subtyping for consumers while preserving nominal adapter inheritance, instantiation guards, and scan_keys defaults.

Co-authored-by: Cursor <cursoragent@cursor.com>
Member

Test Coverage Report:

Name                                                            Stmts   Miss    Cover   Missing
-----------------------------------------------------------------------------------------------
python_repositories/__init__.py                                    12      0  100.00%
python_repositories/adapters/__init__.py                           13      0  100.00%
python_repositories/adapters/connection_aware_adapter.py           61      0  100.00%
python_repositories/adapters/minio_adapter.py                     117      0  100.00%
python_repositories/adapters/redis_adapter.py                     105      0  100.00%
python_repositories/config/__init__.py                              4      0  100.00%
python_repositories/config/dotenv_loader.py                         7      0  100.00%
python_repositories/config/env_bool.py                             14      0  100.00%
python_repositories/config/minio_config.py                         21      0  100.00%
python_repositories/config/redis_config.py                         14      0  100.00%
python_repositories/examples/__init__.py                            0      0  100.00%
python_repositories/examples/artifact_object_repository.py          9      0  100.00%
python_repositories/examples/user_json_repository.py               11      0  100.00%
python_repositories/interfaces/__init__.py                          5      0  100.00%
python_repositories/interfaces/connection_aware_interface.py       10      0  100.00%
python_repositories/interfaces/context_aware_interface.py           9      0  100.00%
python_repositories/interfaces/json_repository_interface.py        16      0  100.00%
python_repositories/interfaces/object_repository_interface.py      13      0  100.00%
-----------------------------------------------------------------------------------------------
TOTAL                                                             441      0  100.00%

**Test Coverage Report:** ``` Name Stmts Miss Cover Missing ----------------------------------------------------------------------------------------------- python_repositories/__init__.py 12 0 100.00% python_repositories/adapters/__init__.py 13 0 100.00% python_repositories/adapters/connection_aware_adapter.py 61 0 100.00% python_repositories/adapters/minio_adapter.py 117 0 100.00% python_repositories/adapters/redis_adapter.py 105 0 100.00% python_repositories/config/__init__.py 4 0 100.00% python_repositories/config/dotenv_loader.py 7 0 100.00% python_repositories/config/env_bool.py 14 0 100.00% python_repositories/config/minio_config.py 21 0 100.00% python_repositories/config/redis_config.py 14 0 100.00% python_repositories/examples/__init__.py 0 0 100.00% python_repositories/examples/artifact_object_repository.py 9 0 100.00% python_repositories/examples/user_json_repository.py 11 0 100.00% python_repositories/interfaces/__init__.py 5 0 100.00% python_repositories/interfaces/connection_aware_interface.py 10 0 100.00% python_repositories/interfaces/context_aware_interface.py 9 0 100.00% python_repositories/interfaces/json_repository_interface.py 16 0 100.00% python_repositories/interfaces/object_repository_interface.py 13 0 100.00% ----------------------------------------------------------------------------------------------- TOTAL 441 0 100.00% ```
brian added 1 commit 2026-07-11 10:32:22 +02:00
Move structural typing tests into interface unit test files.
Code Quality Pipeline / code-quality (pull_request) Successful in 24s
PR Title Check / check-title (pull_request) Successful in 35s
Test Python Package / coverage-report (pull_request) Successful in 11s
Test Python Package / unit-tests (pull_request) Successful in 12s
Test Python Package / integration-tests (pull_request) Successful in 26s
44b15cb21a
Align test layout with the one-test-file-per-interface convention by removing structural_typing_test.py.

Co-authored-by: Cursor <cursoragent@cursor.com>
Member

Test Coverage Report:

Name                                                            Stmts   Miss    Cover   Missing
-----------------------------------------------------------------------------------------------
python_repositories/__init__.py                                    12      0  100.00%
python_repositories/adapters/__init__.py                           13      0  100.00%
python_repositories/adapters/connection_aware_adapter.py           61      0  100.00%
python_repositories/adapters/minio_adapter.py                     117      0  100.00%
python_repositories/adapters/redis_adapter.py                     105      0  100.00%
python_repositories/config/__init__.py                              4      0  100.00%
python_repositories/config/dotenv_loader.py                         7      0  100.00%
python_repositories/config/env_bool.py                             14      0  100.00%
python_repositories/config/minio_config.py                         21      0  100.00%
python_repositories/config/redis_config.py                         14      0  100.00%
python_repositories/examples/__init__.py                            0      0  100.00%
python_repositories/examples/artifact_object_repository.py          9      0  100.00%
python_repositories/examples/user_json_repository.py               11      0  100.00%
python_repositories/interfaces/__init__.py                          5      0  100.00%
python_repositories/interfaces/connection_aware_interface.py       10      0  100.00%
python_repositories/interfaces/context_aware_interface.py           9      0  100.00%
python_repositories/interfaces/json_repository_interface.py        16      0  100.00%
python_repositories/interfaces/object_repository_interface.py      13      0  100.00%
-----------------------------------------------------------------------------------------------
TOTAL                                                             441      0  100.00%

**Test Coverage Report:** ``` Name Stmts Miss Cover Missing ----------------------------------------------------------------------------------------------- python_repositories/__init__.py 12 0 100.00% python_repositories/adapters/__init__.py 13 0 100.00% python_repositories/adapters/connection_aware_adapter.py 61 0 100.00% python_repositories/adapters/minio_adapter.py 117 0 100.00% python_repositories/adapters/redis_adapter.py 105 0 100.00% python_repositories/config/__init__.py 4 0 100.00% python_repositories/config/dotenv_loader.py 7 0 100.00% python_repositories/config/env_bool.py 14 0 100.00% python_repositories/config/minio_config.py 21 0 100.00% python_repositories/config/redis_config.py 14 0 100.00% python_repositories/examples/__init__.py 0 0 100.00% python_repositories/examples/artifact_object_repository.py 9 0 100.00% python_repositories/examples/user_json_repository.py 11 0 100.00% python_repositories/interfaces/__init__.py 5 0 100.00% python_repositories/interfaces/connection_aware_interface.py 10 0 100.00% python_repositories/interfaces/context_aware_interface.py 9 0 100.00% python_repositories/interfaces/json_repository_interface.py 16 0 100.00% python_repositories/interfaces/object_repository_interface.py 13 0 100.00% ----------------------------------------------------------------------------------------------- TOTAL 441 0 100.00% ```
brian added 1 commit 2026-07-11 10:50:56 +02:00
Document test organization and add Cursor workflow rules.
PR Title Check / check-title (pull_request) Successful in 8s
Test Python Package / unit-tests (pull_request) Successful in 13s
Code Quality Pipeline / code-quality (pull_request) Successful in 23s
Test Python Package / integration-tests (pull_request) Successful in 1m14s
Test Python Package / coverage-report (pull_request) Successful in 12s
a0e5c9dcca
Record the one-to-one unit test file convention in README and add rules for test placement and copy-ready PR text after first push.

Co-authored-by: Cursor <cursoragent@cursor.com>
Member

Test Coverage Report:

Name                                                            Stmts   Miss    Cover   Missing
-----------------------------------------------------------------------------------------------
python_repositories/__init__.py                                    12      0  100.00%
python_repositories/adapters/__init__.py                           13      0  100.00%
python_repositories/adapters/connection_aware_adapter.py           61      0  100.00%
python_repositories/adapters/minio_adapter.py                     117      0  100.00%
python_repositories/adapters/redis_adapter.py                     105      0  100.00%
python_repositories/config/__init__.py                              4      0  100.00%
python_repositories/config/dotenv_loader.py                         7      0  100.00%
python_repositories/config/env_bool.py                             14      0  100.00%
python_repositories/config/minio_config.py                         21      0  100.00%
python_repositories/config/redis_config.py                         14      0  100.00%
python_repositories/examples/__init__.py                            0      0  100.00%
python_repositories/examples/artifact_object_repository.py          9      0  100.00%
python_repositories/examples/user_json_repository.py               11      0  100.00%
python_repositories/interfaces/__init__.py                          5      0  100.00%
python_repositories/interfaces/connection_aware_interface.py       10      0  100.00%
python_repositories/interfaces/context_aware_interface.py           9      0  100.00%
python_repositories/interfaces/json_repository_interface.py        16      0  100.00%
python_repositories/interfaces/object_repository_interface.py      13      0  100.00%
-----------------------------------------------------------------------------------------------
TOTAL                                                             441      0  100.00%

**Test Coverage Report:** ``` Name Stmts Miss Cover Missing ----------------------------------------------------------------------------------------------- python_repositories/__init__.py 12 0 100.00% python_repositories/adapters/__init__.py 13 0 100.00% python_repositories/adapters/connection_aware_adapter.py 61 0 100.00% python_repositories/adapters/minio_adapter.py 117 0 100.00% python_repositories/adapters/redis_adapter.py 105 0 100.00% python_repositories/config/__init__.py 4 0 100.00% python_repositories/config/dotenv_loader.py 7 0 100.00% python_repositories/config/env_bool.py 14 0 100.00% python_repositories/config/minio_config.py 21 0 100.00% python_repositories/config/redis_config.py 14 0 100.00% python_repositories/examples/__init__.py 0 0 100.00% python_repositories/examples/artifact_object_repository.py 9 0 100.00% python_repositories/examples/user_json_repository.py 11 0 100.00% python_repositories/interfaces/__init__.py 5 0 100.00% python_repositories/interfaces/connection_aware_interface.py 10 0 100.00% python_repositories/interfaces/context_aware_interface.py 9 0 100.00% python_repositories/interfaces/json_repository_interface.py 16 0 100.00% python_repositories/interfaces/object_repository_interface.py 13 0 100.00% ----------------------------------------------------------------------------------------------- TOTAL 441 0 100.00% ```
brian merged commit 1cbcc1c19b into main 2026-07-11 10:56:03 +02:00
brian deleted branch cursor/protocol-abc-interfaces 2026-07-11 10:56:03 +02:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lille-vemmelund/python-repositories#57