You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by vt...@apache.org on 2026/03/10 15:55:11 UTC
(beam) 01/01: Cherrypick #37717
This is an automated email from the ASF dual-hosted git repository.
vterentev pushed a commit to branch cp-37717
in repository https://gitbox.apache.org/repos/asf/beam.git
commit 9a30717f954a6ed8d66aba938b5dbfdc07ccf5e7
Author: Vitaly Terentyev <vi...@akvelon.com>
AuthorDate: Tue Mar 10 19:54:58 2026 +0400
Cherrypick #37717
---
.../transforms/external_transform_provider_it_test.py | 12 ++++++++++--
sdks/python/gen_xlang_wrappers.py | 6 ++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/sdks/python/apache_beam/transforms/external_transform_provider_it_test.py b/sdks/python/apache_beam/transforms/external_transform_provider_it_test.py
index 2f23c5df598..e86beab563b 100644
--- a/sdks/python/apache_beam/transforms/external_transform_provider_it_test.py
+++ b/sdks/python/apache_beam/transforms/external_transform_provider_it_test.py
@@ -392,9 +392,17 @@ class AutoGenerationScriptIT(unittest.TestCase):
'r') as f:
standard_config = yaml.safe_load(f)
+ def _normalize(cfg):
+ # Sort each transform's fields deterministically
+ for t in cfg:
+ if "fields" in t and isinstance(t["fields"], list):
+ t["fields"] = sorted(t["fields"], key=lambda f: f.get("name", ""))
+ # Sort transforms deterministically
+ return sorted(cfg, key=lambda t: t.get("identifier", ""))
+
self.assertEqual(
- test_config,
- standard_config,
+ _normalize(test_config),
+ _normalize(standard_config),
"The standard xlang transforms config file "
"\"standard_external_transforms.yaml\" is out of sync! Please update "
"by running './gradlew generateExternalTransformsConfig' "
diff --git a/sdks/python/gen_xlang_wrappers.py b/sdks/python/gen_xlang_wrappers.py
index 335fc2ee395..3176b74e836 100644
--- a/sdks/python/gen_xlang_wrappers.py
+++ b/sdks/python/gen_xlang_wrappers.py
@@ -137,7 +137,8 @@ def generate_transforms_config(input_services, output_file):
# use dynamic provider to discover and populate wrapper details
provider = ExternalTransformProvider(BeamJarExpansionService(target))
discovered: Dict[str, ExternalTransform] = provider.get_all()
- for identifier, wrapper in discovered.items():
+ for identifier in sorted(discovered.keys()):
+ wrapper = discovered[identifier]
if identifier in transforms_to_skip:
continue
@@ -153,7 +154,8 @@ def generate_transforms_config(input_services, output_file):
name = modified_transform.get('name', wrapper.__name__)
fields = []
- for param in wrapper.configuration_schema.values():
+ for param_name in sorted(wrapper.configuration_schema.keys()):
+ param = wrapper.configuration_schema[param_name]
(tp, nullable) = pretty_type(param.type)
field_info = {
'name': param.original_name,