You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Python SDK averages 52.2% test coverage against a 95% target. The test infrastructure is solid (280 functions across 15 files), but coverage of the public client APIs, compatibility checking, and core types is critically low. The largest gaps are client.py and async_client.py at ~44%, missing constructor variants, write methods, context manager protocol, and lazy version checking.
Constructor matrix: TLS with token (composite credentials), TLS without token, insecure with token (UserWarning), insecure without token — both sync and async variants
Lazy version checking: check_version=True triggers check on first RPC, result is cached, incompatible version raises IncompatibleServerError
Context manager protocol: __enter__/__exit__ (sync) and __aenter__/__aexit__ (async)
All get() type variants: int, float, bool, timedelta, nullable str
Write methods: set() with and without idempotency_key, set_many(), set_null()
RPC error mapping for all gRPC status codes
_compat.py (39.3%)
_parse_version() with non-semver inputs ("dev", "main", "", "v1.2.3", pre-releases)
_satisfies() with single and compound constraints
fetch_server_version() / async_fetch_server_version() with mocked stub
Frozen/slotted immutability (FrozenInstanceError on mutation), equality and hashing, optional field defaults for Change, FieldUpdate, ServerVersion.
Cross-cutting gaps
Timeout budget exhaustion in _retry.py — total_timeout path not exercised
Async lifecycle edge cases: cancellation and resource cleanup on exception
Duration parsing compound forms in _convert.py ("1h30m", microsecond/nanosecond units)
Acceptance criteria
client.py + async_client.py ≥ 80%: constructor matrix (TLS/insecure × token/no-token), context manager protocol, all get() type variants, set()/set_many()/set_null() with and without idempotency_key, lazy version checking lifecycle, RPC error mapping for all gRPC status codes
_compat.py ≥ 80%: _parse_version() with non-semver inputs, _satisfies() with compound constraints, fetch_server_version() with mocked stub, check_version_compatible() raising IncompatibleServerError
types.py ≥ 80%: frozen/slotted immutability (FrozenInstanceError on mutation), equality and hashing, optional field defaults
__init__.py ≥ 80%: all __all__ items importable, version constants are correct strings
_retry.py: timeout budget exhaustion path covered
async_watcher.py + watcher.py: error recovery and lifecycle paths covered
_convert.py: compound duration parsing ("1h30m") and JSON/dict edge cases covered
make test passes with no regressions; overall SDK coverage ≥ 85% (stepping stone toward 95%)
Description
The Python SDK averages 52.2% test coverage against a 95% target. The test infrastructure is solid (280 functions across 15 files), but coverage of the public client APIs, compatibility checking, and core types is critically low. The largest gaps are
client.pyandasync_client.pyat ~44%, missing constructor variants, write methods, context manager protocol, and lazy version checking.Coverage by module:
__init__.py_compat.pyfetch_server_version(),check_version_compatible(),_parse_version(),_satisfies()types.pyChange,FieldUpdate,ServerVersiondataclass invariantsasync_client.pycheck_compatibility(),watch(), version-check pathclient.pycheck_compatibility(),watch(), version-check path_stubs.pyensure_stubs(),make_string_typed_value(),process_get_response()async_watcher.pywatcher.pyerrors.py_parse_retry_after(), error mapping paths_retry.py_channel.py_convert.py_parse_timedelta()edge cases, JSON/dict conversion_interceptors.py_watcher_base.pyclient.py + async_client.py (44% — highest impact)
UserWarning), insecure without token — both sync and async variantscheck_version=Truetriggers check on first RPC, result is cached, incompatible version raisesIncompatibleServerError__enter__/__exit__(sync) and__aenter__/__aexit__(async)get()type variants: int, float, bool, timedelta, nullable strset()with and withoutidempotency_key,set_many(),set_null()_compat.py (39.3%)
_parse_version()with non-semver inputs ("dev", "main", "", "v1.2.3", pre-releases)_satisfies()with single and compound constraintsfetch_server_version()/async_fetch_server_version()with mocked stubcheck_version_compatible()— compatible versions pass, incompatible raiseIncompatibleServerErrortypes.py (39.7%)
Frozen/slotted immutability (
FrozenInstanceErroron mutation), equality and hashing, optional field defaults forChange,FieldUpdate,ServerVersion.Cross-cutting gaps
_retry.py—total_timeoutpath not exercised_convert.py("1h30m", microsecond/nanosecond units)Acceptance criteria
client.py+async_client.py≥ 80%: constructor matrix (TLS/insecure × token/no-token), context manager protocol, allget()type variants,set()/set_many()/set_null()with and withoutidempotency_key, lazy version checking lifecycle, RPC error mapping for all gRPC status codes_compat.py≥ 80%:_parse_version()with non-semver inputs,_satisfies()with compound constraints,fetch_server_version()with mocked stub,check_version_compatible()raisingIncompatibleServerErrortypes.py≥ 80%: frozen/slotted immutability (FrozenInstanceErroron mutation), equality and hashing, optional field defaults__init__.py≥ 80%: all__all__items importable, version constants are correct strings_retry.py: timeout budget exhaustion path coveredasync_watcher.py+watcher.py: error recovery and lifecycle paths covered_convert.py: compound duration parsing ("1h30m") and JSON/dict edge cases coveredmake testpasses with no regressions; overall SDK coverage ≥ 85% (stepping stone toward 95%)