From d44b829735a379ddbb182e747b213c91c7736122 Mon Sep 17 00:00:00 2001 From: Daniel Sanche Date: Thu, 12 Sep 2024 17:28:40 -0700 Subject: [PATCH] made drop_method into drop, with support for classes --- .cross_sync/README.md | 4 ++-- .cross_sync/transformers.py | 12 +++++------- .../data/_sync/cross_sync/_decorators.py | 6 +++--- .../data/_sync/cross_sync/cross_sync.py | 4 ++-- .../test_cases/cross_sync_files.yaml | 18 ++++++++++++++++-- .../data/_sync/test_cross_sync_decorators.py | 6 +++--- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.cross_sync/README.md b/.cross_sync/README.md index e02497a80..a2f193985 100644 --- a/.cross_sync/README.md +++ b/.cross_sync/README.md @@ -51,8 +51,8 @@ CrossSync provides a set of annotations to mark up async classes, to guide the g - if add_mapping is included, the async and sync classes can be accessed using a shared CrossSync.X alias - `@CrossSync.convert` - marks async functions for conversion. Unmarked methods will be copied as-is -- `@CrossSync.drop_method` - - marks functions that should not be included in sync output +- `@CrossSync.drop` + - marks functions or classes that should not be included in sync output - `@CrossSync.pytest` - marks test functions. Test functions automatically have all async keywords stripped (i.e., rm_aio is unneeded) - `CrossSync.add_mapping` diff --git a/.cross_sync/transformers.py b/.cross_sync/transformers.py index b4ffe7ba6..a780f2bb9 100644 --- a/.cross_sync/transformers.py +++ b/.cross_sync/transformers.py @@ -240,18 +240,16 @@ def visit_ClassDef(self, node): Called for each class in file. If class has a CrossSync decorator, it will be transformed according to the decorator arguments. Otherwise, class is returned unchanged """ - for decorator in node.decorator_list: + orig_decorators = node.decorator_list + for decorator in orig_decorators: try: handler = AstDecorator.get_for_node(decorator) - if isinstance(handler, ExportSync): - # transformation is handled in sync_ast_transform method of the decorator - after_export = handler.sync_ast_transform(node, globals()) - return self.generic_visit(after_export) + # transformation is handled in sync_ast_transform method of the decorator + node = handler.sync_ast_transform(node, globals()) except ValueError: # not cross_sync decorator continue - # cross_sync decorator not found. Drop from sync version - return None + return self.generic_visit(node) if node else None def visit_If(self, node): """ diff --git a/google/cloud/bigtable/data/_sync/cross_sync/_decorators.py b/google/cloud/bigtable/data/_sync/cross_sync/_decorators.py index 965765161..8f90efce0 100644 --- a/google/cloud/bigtable/data/_sync/cross_sync/_decorators.py +++ b/google/cloud/bigtable/data/_sync/cross_sync/_decorators.py @@ -342,14 +342,14 @@ def sync_ast_transform(self, wrapped_node, transformers_globals): return super().sync_ast_transform(converted, transformers_globals) -class DropMethod(AstDecorator): +class Drop(AstDecorator): """ - Method decorator to drop async methods from the sync output + Method decorator to drop methods or classes from the sync output """ def sync_ast_transform(self, wrapped_node, transformers_globals): """ - Drop method from sync output + Drop from sync output """ return None diff --git a/google/cloud/bigtable/data/_sync/cross_sync/cross_sync.py b/google/cloud/bigtable/data/_sync/cross_sync/cross_sync.py index dceff5a62..2433562cf 100644 --- a/google/cloud/bigtable/data/_sync/cross_sync/cross_sync.py +++ b/google/cloud/bigtable/data/_sync/cross_sync/cross_sync.py @@ -62,7 +62,7 @@ async def async_func(self, arg: int) -> int: from ._decorators import ( ExportSync, Convert, - DropMethod, + Drop, Pytest, PytestFixture, ) @@ -99,7 +99,7 @@ class CrossSync(metaclass=MappingMeta): # decorators export_sync = ExportSync.decorator # decorate classes to convert convert = Convert.decorator # decorate methods to convert from async to sync - drop_method = DropMethod.decorator # decorate methods to remove from sync version + drop = Drop.decorator # decorate methods to remove from sync version pytest = Pytest.decorator # decorate test methods to run with pytest-asyncio pytest_fixture = ( PytestFixture.decorator diff --git a/tests/system/cross_sync/test_cases/cross_sync_files.yaml b/tests/system/cross_sync/test_cases/cross_sync_files.yaml index 9c8627657..3eca767ec 100644 --- a/tests/system/cross_sync/test_cases/cross_sync_files.yaml +++ b/tests/system/cross_sync/test_cases/cross_sync_files.yaml @@ -87,7 +87,7 @@ tests: async with self.base.connection(): return await self.base.my_method() - @CrossSync.drop_method + @CrossSync.drop async def async_only_method(self): await self.async_operation() @@ -120,6 +120,7 @@ tests: __CROSS_SYNC_OUTPUT__ = "out.path" @CrossSync.export_sync(sync_name="MyClass") class MyAsyncClass: + @CrossSync.drop class NestedAsyncClass: async def nested_method(self, base: AsyncBase): pass @@ -263,7 +264,7 @@ tests: def keep_method(self): pass - @CrossSync.drop_method + @CrossSync.drop async def async_only_method(self): await self.async_operation() transformers: [CrossSyncFileProcessor] @@ -271,6 +272,19 @@ tests: def keep_method(self): pass + - description: "Drop class from sync version" + before: | + __CROSS_SYNC_OUTPUT__ = "out.path" + @CrossSync.drop + class DropMe: + pass + class Keeper: + pass + transformers: [CrossSyncFileProcessor] + after: | + class Keeper: + pass + - description: "Convert.pytest" before: | __CROSS_SYNC_OUTPUT__ = "out.path" diff --git a/tests/unit/data/_sync/test_cross_sync_decorators.py b/tests/unit/data/_sync/test_cross_sync_decorators.py index 727d5a599..bc9a92917 100644 --- a/tests/unit/data/_sync/test_cross_sync_decorators.py +++ b/tests/unit/data/_sync/test_cross_sync_decorators.py @@ -20,7 +20,7 @@ from google.cloud.bigtable.data._sync.cross_sync._decorators import ( ExportSync, Convert, - DropMethod, + Drop, Pytest, PytestFixture, ) @@ -412,9 +412,9 @@ def test_sync_ast_transform_add_docstring_format( assert result.body[0].value.value == expected -class TestDropMethodDecorator: +class TestDropDecorator: def _get_class(self): - return DropMethod + return Drop def test_decorator_functionality(self): """