From e61d1b75b1e6d29a9ba61dbf03455c57c64c1333 Mon Sep 17 00:00:00 2001 From: Vitaly Terentyev Date: Thu, 26 Feb 2026 17:07:19 +0400 Subject: [PATCH] Stabilize test_check_standard_external_transforms_config_in_sync --- .../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 2f23c5df5983..e86beab563bb 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 @@ def test_check_standard_external_transforms_config_in_sync(self): '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 335fc2ee395b..3176b74e836a 100644 --- a/sdks/python/gen_xlang_wrappers.py +++ b/sdks/python/gen_xlang_wrappers.py @@ -137,7 +137,8 @@ class name. This can be overriden by manually providing a name. # 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 @@ class name. This can be overriden by manually providing a name. 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,