This is an automated email from the ASF dual-hosted git repository.
yzheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new 6a335a1ec Fix monkey patching (#3016)
6a335a1ec is described below
commit 6a335a1ec9ae4deafc5e90bb0b6f040a710ecbd1
Author: Yong Zheng <[email protected]>
AuthorDate: Wed Nov 12 09:32:27 2025 -0600
Fix monkey patching (#3016)
---
client/python/apache_polaris/cli/polaris_cli.py | 42 ---------------------
client/python/generate_clients.py | 45 ++++++++++++++++++++++
client/python/integration_tests/conftest.py | 50 -------------------------
3 files changed, 45 insertions(+), 92 deletions(-)
diff --git a/client/python/apache_polaris/cli/polaris_cli.py
b/client/python/apache_polaris/cli/polaris_cli.py
index 8bd49d63d..b06286df0 100644
--- a/client/python/apache_polaris/cli/polaris_cli.py
+++ b/client/python/apache_polaris/cli/polaris_cli.py
@@ -46,50 +46,8 @@ class PolarisCli:
# Can be enabled if the client is able to authenticate directly without
first fetching a token
DIRECT_AUTHENTICATION_ENABLED = False
- @staticmethod
- def _patch_generated_models() -> None:
- """
- The OpenAPI generator creates an `api_client` that dynamically looks up
- model classes from the `apache_polaris.sdk.catalog.models` module
using `getattr()`.
- For example, when a response for a `create_policy` call is received,
the
- deserializer tries to find the `LoadPolicyResponse` class by looking
for
- `apache_polaris.sdk.catalog.models.LoadPolicyResponse`.
-
- However, the generator fails to add the necessary `import` statements
- to the `apache_polaris/sdk/catalog/models/__init__.py` file. This
means that even
- though the model files exist (e.g., `load_policy_response.py`), the
classes
- are not part of the `apache_polaris.sdk.catalog.models` namespace.
-
- This method works around the bug in the generated code without
modifying
- the source files. It runs once per CLI execution, before any commands,
and
- manually injects the missing response-side model classes into the
- `apache_polaris.sdk.catalog.models` namespace, allowing the
deserializer to find them.
- """
- import apache_polaris.sdk.catalog.models
- from apache_polaris.sdk.catalog.models.applicable_policy import
ApplicablePolicy
- from
apache_polaris.sdk.catalog.models.get_applicable_policies_response import
GetApplicablePoliciesResponse
- from apache_polaris.sdk.catalog.models.list_policies_response import
ListPoliciesResponse
- from apache_polaris.sdk.catalog.models.load_policy_response import
LoadPolicyResponse
- from apache_polaris.sdk.catalog.models.policy import Policy
- from apache_polaris.sdk.catalog.models.policy_attachment_target import
PolicyAttachmentTarget
- from apache_polaris.sdk.catalog.models.policy_identifier import
PolicyIdentifier
-
- models_to_patch = {
- "ApplicablePolicy": ApplicablePolicy,
- "GetApplicablePoliciesResponse": GetApplicablePoliciesResponse,
- "ListPoliciesResponse": ListPoliciesResponse,
- "LoadPolicyResponse": LoadPolicyResponse,
- "Policy": Policy,
- "PolicyAttachmentTarget": PolicyAttachmentTarget,
- "PolicyIdentifier": PolicyIdentifier,
- }
-
- for name, model_class in models_to_patch.items():
- setattr(apache_polaris.sdk.catalog.models, name, model_class)
-
@staticmethod
def execute(args=None):
- PolarisCli._patch_generated_models()
options = Parser.parse(args)
if options.command == Commands.PROFILES:
from apache_polaris.cli.command import Command
diff --git a/client/python/generate_clients.py
b/client/python/generate_clients.py
index 9aaa07fd8..0c7c1b5af 100644
--- a/client/python/generate_clients.py
+++ b/client/python/generate_clients.py
@@ -32,6 +32,7 @@ import fnmatch
import logging
import argparse
import shutil
+import ast
# Paths
CLIENT_DIR = Path(__file__).parent
@@ -306,9 +307,53 @@ def build() -> None:
generate_polaris_management_client()
generate_polaris_catalog_client()
generate_iceberg_catalog_client()
+ fix_catalog_models_init()
prepend_licenses()
+def fix_catalog_models_init() -> None:
+ """
+ Regenerate the `apache_polaris.sdk.catalog.models.__init__.py` file by
consolidating
+ imports for all model classes found under
`apache_polaris/sdk/catalog/models`.
+
+ This ensures that rerunning the OpenAPI Generator (which overwrites
`__init__.py`)
+ does not cause missing imports for earlier generated model files.
+ """
+ logger.info("Fixing catalog models __init__.py...")
+ models_dir = CLIENT_DIR / "apache_polaris" / "sdk" / "catalog" / "models"
+ init_py = models_dir / "__init__.py"
+
+ # Get all python files in the models directory except __init__.py
+ model_files = [
+ f for f in models_dir.glob("*.py") if f.is_file() and f.name !=
"__init__.py"
+ ]
+
+ # Generate import statements
+ imports = []
+ for model_file in sorted(model_files):
+ module_name = model_file.stem
+ with open(model_file, "r") as f:
+ tree = ast.parse(f.read())
+ class_name = None
+ for node in ast.walk(tree):
+ if isinstance(node, ast.ClassDef):
+ # Find the first class that doesn't start with an underscore
+ if not node.name.startswith("_"):
+ class_name = node.name
+ break
+ if class_name:
+ imports.append(
+ f"from apache_polaris.sdk.catalog.models.{module_name} import
{class_name}"
+ )
+ else:
+ logger.warning(f"Could not find a suitable class in {model_file}")
+
+ # Write the new __init__.py
+ with open(init_py, "w") as f:
+ f.write("\n".join(sorted(imports)))
+ logger.info("Catalog models __init__.py fixed.")
+
+
def main():
parser = argparse.ArgumentParser(description="Generate Polaris Python
clients.")
parser.add_argument(
diff --git a/client/python/integration_tests/conftest.py
b/client/python/integration_tests/conftest.py
index d448fb50e..12f72cbd6 100644
--- a/client/python/integration_tests/conftest.py
+++ b/client/python/integration_tests/conftest.py
@@ -375,53 +375,3 @@ def clear_namespace(
def format_namespace(namespace: List[str]) -> str:
return codecs.decode("1F", "hex").decode("UTF-8").join(namespace)
-
-
[email protected](scope="session", autouse=True)
-def _patch_generated_models() -> None:
- """
- The OpenAPI generator creates an `api_client` that dynamically looks up
- model classes from the `apache_polaris.sdk.catalog.models` module using
`getattr()`.
- For example, when a response for a `create_policy` call is received, the
- deserializer tries to find the `LoadPolicyResponse` class by looking for
- `apache_polaris.sdk.catalog.models.LoadPolicyResponse`.
-
- However, the generator fails to add the necessary `import` statements
- to the `apache_polaris/sdk/catalog/models/__init__.py` file. This means
that even
- though the model files exist (e.g., `load_policy_response.py`), the classes
- are not part of the `apache_polaris.sdk.catalog.models` namespace.
-
- This fixture works around the bug in the generated code without modifying
- the source files. It runs once per test session, before any tests, and
- manually injects the missing response-side model classes into the
- `apache_polaris.sdk.catalog.models` namespace, allowing the deserializer
to find them.
- """
- import apache_polaris.sdk.catalog.models
- from apache_polaris.sdk.catalog.models.applicable_policy import
ApplicablePolicy
- from apache_polaris.sdk.catalog.models.get_applicable_policies_response
import (
- GetApplicablePoliciesResponse,
- )
- from apache_polaris.sdk.catalog.models.list_policies_response import (
- ListPoliciesResponse,
- )
- from apache_polaris.sdk.catalog.models.load_policy_response import (
- LoadPolicyResponse,
- )
- from apache_polaris.sdk.catalog.models.policy import Policy
- from apache_polaris.sdk.catalog.models.policy_attachment_target import (
- PolicyAttachmentTarget,
- )
- from apache_polaris.sdk.catalog.models.policy_identifier import
PolicyIdentifier
-
- models_to_patch = {
- "ApplicablePolicy": ApplicablePolicy,
- "GetApplicablePoliciesResponse": GetApplicablePoliciesResponse,
- "ListPoliciesResponse": ListPoliciesResponse,
- "LoadPolicyResponse": LoadPolicyResponse,
- "Policy": Policy,
- "PolicyAttachmentTarget": PolicyAttachmentTarget,
- "PolicyIdentifier": PolicyIdentifier,
- }
-
- for name, model_class in models_to_patch.items():
- setattr(apache_polaris.sdk.catalog.models, name, model_class)