diff --git a/google/cloud/bigtable/data/_cross_sync/_decorators.py b/google/cloud/bigtable/data/_cross_sync/_decorators.py index 4e79331dd..2f4c8374f 100644 --- a/google/cloud/bigtable/data/_cross_sync/_decorators.py +++ b/google/cloud/bigtable/data/_cross_sync/_decorators.py @@ -201,7 +201,7 @@ def __init__( sync_name: str | None = None, *, replace_symbols: dict[str, str] | None = None, - docstring_format_vars: dict[str, tuple[str, str]] | None = None, + docstring_format_vars: dict[str, tuple[str | None, str | None]] | None = None, rm_aio: bool = False, add_mapping_for_name: str | None = None, ): @@ -209,10 +209,10 @@ def __init__( self.replace_symbols = replace_symbols docstring_format_vars = docstring_format_vars or {} self.async_docstring_format_vars = { - k: v[0] for k, v in docstring_format_vars.items() + k: v[0] or "" for k, v in docstring_format_vars.items() } self.sync_docstring_format_vars = { - k: v[1] for k, v in docstring_format_vars.items() + k: v[1] or "" for k, v in docstring_format_vars.items() } self.rm_aio = rm_aio self.add_mapping_for_name = add_mapping_for_name diff --git a/tests/unit/data/_cross_sync/test_cross_sync_decorators.py b/tests/unit/data/_cross_sync/test_cross_sync_decorators.py index fb35a5834..1f5bd4b0e 100644 --- a/tests/unit/data/_cross_sync/test_cross_sync_decorators.py +++ b/tests/unit/data/_cross_sync/test_cross_sync_decorators.py @@ -108,6 +108,10 @@ def test_class_decorator_adds_mapping(self): ["{A}", {"A": (1, 2)}, "1"], ["{A} {B}", {"A": (1, 2), "B": (3, 4)}, "1 3"], ["hello {world_var}", {"world_var": ("world", "moon")}, "hello world"], + ["{empty}", {"empty": ("", "")}, ""], + ["{empty}", {"empty": (None, None)}, ""], + ["maybe{empty}", {"empty": (None, "yes")}, "maybe"], + ["maybe{empty}", {"empty": (" no", None)}, "maybe no"] ], ) def test_class_decorator_docstring_update(self, docstring, format_vars, expected): @@ -123,8 +127,8 @@ class Class: assert Class.__doc__ == expected # check internal state instance = self._get_class()(sync_name="s", docstring_format_vars=format_vars) - async_replacements = {k: v[0] for k, v in format_vars.items()} - sync_replacements = {k: v[1] for k, v in format_vars.items()} + async_replacements = {k: v[0] or "" for k, v in format_vars.items()} + sync_replacements = {k: v[1] or "" for k, v in format_vars.items()} assert instance.async_docstring_format_vars == async_replacements assert instance.sync_docstring_format_vars == sync_replacements @@ -299,6 +303,10 @@ def test_async_decorator_no_docstring(self): ["{A}", {"A": (1, 2)}, "1"], ["{A} {B}", {"A": (1, 2), "B": (3, 4)}, "1 3"], ["hello {world_var}", {"world_var": ("world", "moon")}, "hello world"], + ["{empty}", {"empty": ("", "")}, ""], + ["{empty}", {"empty": (None, None)}, ""], + ["maybe{empty}", {"empty": (None, "yes")}, "maybe"], + ["maybe{empty}", {"empty": (" no", None)}, "maybe no"] ], ) def test_async_decorator_docstring_update(self, docstring, format_vars, expected): @@ -314,8 +322,8 @@ class Class: assert Class.__doc__ == expected # check internal state instance = self._get_class()(docstring_format_vars=format_vars) - async_replacements = {k: v[0] for k, v in format_vars.items()} - sync_replacements = {k: v[1] for k, v in format_vars.items()} + async_replacements = {k: v[0] or "" for k, v in format_vars.items()} + sync_replacements = {k: v[1] or "" for k, v in format_vars.items()} assert instance.async_docstring_format_vars == async_replacements assert instance.sync_docstring_format_vars == sync_replacements