From 076908e667527a189ca891dbaed89665420afe34 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 09:57:12 +0200 Subject: [PATCH 01/19] use enum instead of bool for contribution variant --- .../extract_usd_layer_contributions.py | 82 +++++++++++++++---- server/settings/publish_plugins.py | 30 ++++--- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 6f370b4b38d..f78b11be017 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -74,7 +74,14 @@ class VariantContribution(_BaseContribution): # Variant variant_set_name: str variant_name: str - variant_is_default: bool # Whether to author variant selection opinion + variant_default_policy: str # Policy controlling variant selection opinion + + +CONTRIBUTION_VARIANT_DEFAULT_POLICY = { + "if_missing": "Set as default if no current default", + "always": "Set as default", + "never": "Do not set" +} def get_representation_path_in_publish_context( @@ -349,13 +356,25 @@ def process(self, instance): # Define contribution in_layer_order: int = attr_values.get("contribution_in_layer_order", 0) if attr_values["contribution_apply_as_variant"]: + variant_default_policy = attr_values.get( + "contribution_variant_default_policy" + ) + if variant_default_policy is None: + # Support data created before the boolean was replaced by the + # policy enum. + variant_default_policy = CONTRIBUTION_VARIANT_DEFAULT_POLICY[ + "always" + if attr_values.get("contribution_variant_is_default", False) + else "if_missing" + ] + contribution = VariantContribution( instance=instance, layer_id=attr_values["contribution_layer"], target_product=attr_values["contribution_target_product"], variant_set_name=attr_values["contribution_variant_set_name"], variant_name=attr_values["contribution_variant"], - variant_is_default=attr_values["contribution_variant_is_default"], # noqa: E501 + variant_default_policy=variant_default_policy, order=in_layer_order ) else: @@ -536,6 +555,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): "task_names": create_context.get_current_task_name() } profile = filter_profiles(cls.profiles, filtering_criteria) + if not profile: profile = { "contribution_enabled": True, @@ -544,8 +564,20 @@ def get_attr_defs_for_instance(cls, create_context, instance): "contribution_apply_as_variant": False, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], } + elif "contribution_variant_default_policy" not in profile: + # Support profiles created before the boolean was replaced by the + # policy enum. + profile = profile.copy() + profile["contribution_variant_default_policy"] = ( + CONTRIBUTION_VARIANT_DEFAULT_POLICY[ + "always" + if profile.get("contribution_variant_is_default", False) + else "if_missing" + ] + ) # Define defaults default_target_product: str = profile["contribution_target_product"] @@ -654,18 +686,27 @@ def get_attr_defs_for_instance(cls, create_context, instance): label="Variant Name", default=profile["contribution_variant"], visible=variant_visible), - BoolDef("contribution_variant_is_default", - label="Set as default variant selection", - tooltip=( - "Whether to set this instance's variant name as the " - "default selected variant name for the variant set.\n" - "It is always expected to be enabled for only one " - "variant name in the variant set.\n" - "The behavior is unpredictable if multiple instances " - "for the same variant set have this enabled." - ), - default=profile["contribution_variant_is_default"], - visible=variant_visible), + EnumDef( + "contribution_variant_default_policy", + label="Set as default variant selection", + tooltip=( + "Controls whether this contribution's variant name is " + "authored as the selected default for the variant set.\n" + "'Do not set' leaves the variant selection unchanged.\n" + "'Set as default if no current default' sets it only when " + "the variant set has no default selection yet.\n" + "'Set as default' always sets it as the default and may " + "override a selection authored by another contribution.\n" + "When multiple contributions use 'Set as default', " + "the final result depends on their contribution order." + ), + items=CONTRIBUTION_VARIANT_DEFAULT_POLICY.values(), + default=profile.get( + "contribution_variant_default_policy", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + ), + visible=variant_visible, + ), UISeparatorDef("usd_container_settings3"), ] @@ -790,8 +831,15 @@ def process(self, instance): # Set default variant selection variant_set_name = contribution.variant_set_name variant_name = contribution.variant_name - if contribution.variant_is_default or \ - variant_set_name not in prim_spec.variantSelections: + if ( + contribution.variant_default_policy + == CONTRIBUTION_VARIANT_DEFAULT_POLICY["always"] + or ( + contribution.variant_default_policy + == CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"] + and variant_set_name not in prim_spec.variantSelections + ) + ): prim_spec.variantSelections[variant_set_name] = variant_name # noqa: E501 elif isinstance(contribution, SublayerContribution): diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index dba9a0bd54f..6f87b4caa58 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -261,16 +261,15 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): "The default variant name for instances matching this profile." ), ) - contribution_variant_is_default: bool = SettingsField( - False, + contribution_variant_default_policy: str = SettingsField( + "Set as default if no current default", title="Set as default variant selection", description=( - "Whether to set this instance's variant name as the " - "default selected variant name for the variant set.\n" - "It is always expected to be enabled for only one " - "variant name in the variant set.\n" - "The behavior is unpredictable if multiple instances " - "for the same variant set have this enabled." + "Controls whether this contribution's variant name is authored " + "as the selected default for the variant set. Use 'Do not set' " + "to leave the variant selection unchanged, 'Set as default if " + "no current default' to set it only when no selection exists, " + "or 'Set as default' to always override the current selection." ), ) @@ -1656,7 +1655,8 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_apply_as_variant": True, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + "Set as default if no current default", }, { "product_base_types": ["look"], @@ -1668,7 +1668,8 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_apply_as_variant": True, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + "Set as default if no current default", }, { "product_base_types": ["groom"], @@ -1680,7 +1681,8 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_apply_as_variant": True, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + "Set as default if no current default", }, { "product_base_types": ["rig"], @@ -1692,7 +1694,8 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_apply_as_variant": True, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + "Set as default if no current default", }, { "product_base_types": ["usd"], @@ -1704,7 +1707,8 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_apply_as_variant": False, "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", - "contribution_variant_is_default": False, + "contribution_variant_default_policy": + "Set as default if no current default", }, ] }, From e94ca795b35e61ff9b44775532fc263878c21ba0 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 10:08:02 +0200 Subject: [PATCH 02/19] str -> enum in settings, use dict with defined labels also in tooltips --- .../extract_usd_layer_contributions.py | 12 ++++-- server/settings/publish_plugins.py | 39 ++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index f78b11be017..3ae6387d56d 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -692,12 +692,16 @@ def get_attr_defs_for_instance(cls, create_context, instance): tooltip=( "Controls whether this contribution's variant name is " "authored as the selected default for the variant set.\n" - "'Do not set' leaves the variant selection unchanged.\n" - "'Set as default if no current default' sets it only when " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['never']}' leaves " + "the variant selection unchanged.\n" + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_missing']}' " + "sets it only when " "the variant set has no default selection yet.\n" - "'Set as default' always sets it as the default and may " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' always " + "sets it as the default and may " "override a selection authored by another contribution.\n" - "When multiple contributions use 'Set as default', " + f"When multiple contributions use " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}', " "the final result depends on their contribution order." ), items=CONTRIBUTION_VARIANT_DEFAULT_POLICY.values(), diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 6f87b4caa58..7731983d5f8 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -26,6 +26,21 @@ StatusesEnumResolver = None +CONTRIBUTION_VARIANT_DEFAULT_POLICY = { + "if_missing": "Set as default if no current default", + "always": "Set as default", + "never": "Do not set", +} + + +def contribution_variant_default_policy_enum(): + """Return the available variant default policies for the settings UI.""" + return [ + {"value": label, "label": label} + for label in CONTRIBUTION_VARIANT_DEFAULT_POLICY.values() + ] + + async def _get_anatomy(project_name: str | None = None) -> Anatomy: if project_name: return await get_project_anatomy(project_name) @@ -262,14 +277,18 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): ), ) contribution_variant_default_policy: str = SettingsField( - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], title="Set as default variant selection", + enum_resolver=contribution_variant_default_policy_enum, description=( "Controls whether this contribution's variant name is authored " - "as the selected default for the variant set. Use 'Do not set' " - "to leave the variant selection unchanged, 'Set as default if " - "no current default' to set it only when no selection exists, " - "or 'Set as default' to always override the current selection." + "as the selected default for the variant set. Use " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['never']}' to leave the " + "variant selection unchanged, " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_missing']}' to set " + "it only when no selection exists, or " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' to always " + "override the current selection." ), ) @@ -1656,7 +1675,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], }, { "product_base_types": ["look"], @@ -1669,7 +1688,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], }, { "product_base_types": ["groom"], @@ -1682,7 +1701,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], }, { "product_base_types": ["rig"], @@ -1695,7 +1714,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], }, { "product_base_types": ["usd"], @@ -1708,7 +1727,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "Set as default if no current default", + CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], }, ] }, From 7f9b7017ccf3e1708ee480acf7a2bd8370944dad Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 10:17:43 +0200 Subject: [PATCH 03/19] add conversion from old settings --- server/settings/conversion.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/server/settings/conversion.py b/server/settings/conversion.py index 6e44cceafa7..54780dc1788 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -5,7 +5,10 @@ from semver import VersionInfo -from .publish_plugins import DEFAULT_PUBLISH_VALUES +from .publish_plugins import ( + CONTRIBUTION_VARIANT_DEFAULT_POLICY, + DEFAULT_PUBLISH_VALUES, +) PRODUCT_NAME_REPL_REGEX = re.compile(r"[^<>{}\[\]a-zA-Z0-9_.]") @@ -287,11 +290,36 @@ def _convert_oiio_transcode_0_4_5(publish_overrides): } +def _convert_usd_contribution_variant_default_policy(overrides): + """Convert the USD contribution default boolean to a policy enum.""" + profiles = ( + overrides + .get("publish", {}) + .get("CollectUSDLayerContributions", {}) + .get("profiles", []) + ) + + for profile in profiles: + if "contribution_variant_default_policy" in profile: + continue + + if "contribution_variant_is_default" not in profile: + continue + + is_default = profile.pop("contribution_variant_is_default") + profile["contribution_variant_default_policy"] = ( + CONTRIBUTION_VARIANT_DEFAULT_POLICY[ + "always" if is_default else "if_missing" + ] + ) + + def _convert_publish_plugins(overrides): if "publish" not in overrides: return _convert_validate_version_0_3_3(overrides["publish"]) _convert_oiio_transcode_0_4_5(overrides["publish"]) + _convert_usd_contribution_variant_default_policy(overrides) def _convert_extract_thumbnail(overrides, version: VersionInfo): From 53c0093aa84950177985cdf3243004007146838b Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 10:21:49 +0200 Subject: [PATCH 04/19] linting --- .../plugins/publish/extract_usd_layer_contributions.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 3ae6387d56d..e6c19aea30d 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -364,7 +364,9 @@ def process(self, instance): # policy enum. variant_default_policy = CONTRIBUTION_VARIANT_DEFAULT_POLICY[ "always" - if attr_values.get("contribution_variant_is_default", False) + if attr_values.get( + "contribution_variant_is_default", False + ) else "if_missing" ] @@ -697,8 +699,8 @@ def get_attr_defs_for_instance(cls, create_context, instance): f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_missing']}' " "sets it only when " "the variant set has no default selection yet.\n" - f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' always " - "sets it as the default and may " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' always" + " sets it as the default and may " "override a selection authored by another contribution.\n" f"When multiple contributions use " f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}', " From de9c0157a578113282262e21afdb45613dff153d Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 13:57:12 +0200 Subject: [PATCH 05/19] fix: convert the values to list --- .../plugins/publish/extract_usd_layer_contributions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index e6c19aea30d..68d47ad9a62 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -706,7 +706,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}', " "the final result depends on their contribution order." ), - items=CONTRIBUTION_VARIANT_DEFAULT_POLICY.values(), + items=list(CONTRIBUTION_VARIANT_DEFAULT_POLICY.values()), default=profile.get( "contribution_variant_default_policy", CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], From c2e6d1e72f91e74775fb7ed2274c7427215c409d Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Wed, 12 Aug 2026 15:22:35 +0200 Subject: [PATCH 06/19] fix: store the labels and values in the enum correctly --- .../extract_usd_layer_contributions.py | 22 +++++++++---------- server/settings/conversion.py | 9 ++------ server/settings/publish_plugins.py | 16 +++++++------- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 68d47ad9a62..5f22332a9b5 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -362,13 +362,13 @@ def process(self, instance): if variant_default_policy is None: # Support data created before the boolean was replaced by the # policy enum. - variant_default_policy = CONTRIBUTION_VARIANT_DEFAULT_POLICY[ + variant_default_policy = ( "always" if attr_values.get( "contribution_variant_is_default", False ) else "if_missing" - ] + ) contribution = VariantContribution( instance=instance, @@ -567,18 +567,16 @@ def get_attr_defs_for_instance(cls, create_context, instance): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", } elif "contribution_variant_default_policy" not in profile: # Support profiles created before the boolean was replaced by the # policy enum. profile = profile.copy() profile["contribution_variant_default_policy"] = ( - CONTRIBUTION_VARIANT_DEFAULT_POLICY[ - "always" - if profile.get("contribution_variant_is_default", False) - else "if_missing" - ] + "always" + if profile.get("contribution_variant_is_default", False) + else "if_missing" ) # Define defaults @@ -706,10 +704,10 @@ def get_attr_defs_for_instance(cls, create_context, instance): f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}', " "the final result depends on their contribution order." ), - items=list(CONTRIBUTION_VARIANT_DEFAULT_POLICY.values()), + items=CONTRIBUTION_VARIANT_DEFAULT_POLICY, default=profile.get( "contribution_variant_default_policy", - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", ), visible=variant_visible, ), @@ -839,10 +837,10 @@ def process(self, instance): variant_name = contribution.variant_name if ( contribution.variant_default_policy - == CONTRIBUTION_VARIANT_DEFAULT_POLICY["always"] + == "always" or ( contribution.variant_default_policy - == CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"] + == "if_missing" and variant_set_name not in prim_spec.variantSelections ) ): diff --git a/server/settings/conversion.py b/server/settings/conversion.py index 54780dc1788..62375ce71ee 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -5,10 +5,7 @@ from semver import VersionInfo -from .publish_plugins import ( - CONTRIBUTION_VARIANT_DEFAULT_POLICY, - DEFAULT_PUBLISH_VALUES, -) +from .publish_plugins import DEFAULT_PUBLISH_VALUES PRODUCT_NAME_REPL_REGEX = re.compile(r"[^<>{}\[\]a-zA-Z0-9_.]") @@ -308,9 +305,7 @@ def _convert_usd_contribution_variant_default_policy(overrides): is_default = profile.pop("contribution_variant_is_default") profile["contribution_variant_default_policy"] = ( - CONTRIBUTION_VARIANT_DEFAULT_POLICY[ - "always" if is_default else "if_missing" - ] + "always" if is_default else "if_missing" ) diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 7731983d5f8..14cc1396bc6 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -36,8 +36,8 @@ def contribution_variant_default_policy_enum(): """Return the available variant default policies for the settings UI.""" return [ - {"value": label, "label": label} - for label in CONTRIBUTION_VARIANT_DEFAULT_POLICY.values() + {"value": value, "label": label} + for value, label in CONTRIBUTION_VARIANT_DEFAULT_POLICY.items() ] @@ -277,7 +277,7 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): ), ) contribution_variant_default_policy: str = SettingsField( - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", title="Set as default variant selection", enum_resolver=contribution_variant_default_policy_enum, description=( @@ -1675,7 +1675,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", }, { "product_base_types": ["look"], @@ -1688,7 +1688,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", }, { "product_base_types": ["groom"], @@ -1701,7 +1701,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", }, { "product_base_types": ["rig"], @@ -1714,7 +1714,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", }, { "product_base_types": ["usd"], @@ -1727,7 +1727,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - CONTRIBUTION_VARIANT_DEFAULT_POLICY["if_missing"], + "if_missing", }, ] }, From 8095e075b83132f8842666b10160870c8d7fa43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Thu, 13 Aug 2026 09:34:22 +0200 Subject: [PATCH 07/19] readability improvement Co-authored-by: Roy Nieterau --- .../plugins/publish/extract_usd_layer_contributions.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 5f22332a9b5..2e12170321a 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -835,12 +835,10 @@ def process(self, instance): # Set default variant selection variant_set_name = contribution.variant_set_name variant_name = contribution.variant_name - if ( - contribution.variant_default_policy - == "always" + policy = contribution.variant_default_policy + if (policy == "always" or ( - contribution.variant_default_policy - == "if_missing" + policy == "if_missing" and variant_set_name not in prim_spec.variantSelections ) ): From faf7b6521a8acc140cd57d14c266b3cdd142a2ab Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Thu, 13 Aug 2026 09:36:54 +0200 Subject: [PATCH 08/19] if_missing -> if_not_set --- .../publish/extract_usd_layer_contributions.py | 14 +++++++------- server/settings/conversion.py | 2 +- server/settings/publish_plugins.py | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 2e12170321a..240d18a567d 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -78,7 +78,7 @@ class VariantContribution(_BaseContribution): CONTRIBUTION_VARIANT_DEFAULT_POLICY = { - "if_missing": "Set as default if no current default", + "if_not_set": "Set as default if no current default", "always": "Set as default", "never": "Do not set" } @@ -367,7 +367,7 @@ def process(self, instance): if attr_values.get( "contribution_variant_is_default", False ) - else "if_missing" + else "if_not_set" ) contribution = VariantContribution( @@ -567,7 +567,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", } elif "contribution_variant_default_policy" not in profile: # Support profiles created before the boolean was replaced by the @@ -576,7 +576,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): profile["contribution_variant_default_policy"] = ( "always" if profile.get("contribution_variant_is_default", False) - else "if_missing" + else "if_not_set" ) # Define defaults @@ -694,7 +694,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): "authored as the selected default for the variant set.\n" f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['never']}' leaves " "the variant selection unchanged.\n" - f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_missing']}' " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_not_set']}' " "sets it only when " "the variant set has no default selection yet.\n" f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' always" @@ -707,7 +707,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): items=CONTRIBUTION_VARIANT_DEFAULT_POLICY, default=profile.get( "contribution_variant_default_policy", - "if_missing", + "if_not_set", ), visible=variant_visible, ), @@ -838,7 +838,7 @@ def process(self, instance): policy = contribution.variant_default_policy if (policy == "always" or ( - policy == "if_missing" + policy == "if_not_set" and variant_set_name not in prim_spec.variantSelections ) ): diff --git a/server/settings/conversion.py b/server/settings/conversion.py index 62375ce71ee..357164bba54 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -305,7 +305,7 @@ def _convert_usd_contribution_variant_default_policy(overrides): is_default = profile.pop("contribution_variant_is_default") profile["contribution_variant_default_policy"] = ( - "always" if is_default else "if_missing" + "always" if is_default else "if_not_set" ) diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 14cc1396bc6..f700bdcd8e3 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -27,7 +27,7 @@ CONTRIBUTION_VARIANT_DEFAULT_POLICY = { - "if_missing": "Set as default if no current default", + "if_not_set": "Set as default if no current default", "always": "Set as default", "never": "Do not set", } @@ -277,7 +277,7 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): ), ) contribution_variant_default_policy: str = SettingsField( - "if_missing", + "if_not_set", title="Set as default variant selection", enum_resolver=contribution_variant_default_policy_enum, description=( @@ -285,7 +285,7 @@ class CollectUSDLayerContributionsProfileModel(BaseSettingsModel): "as the selected default for the variant set. Use " f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['never']}' to leave the " "variant selection unchanged, " - f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_missing']}' to set " + f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['if_not_set']}' to set " "it only when no selection exists, or " f"'{CONTRIBUTION_VARIANT_DEFAULT_POLICY['always']}' to always " "override the current selection." @@ -1675,7 +1675,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", }, { "product_base_types": ["look"], @@ -1688,7 +1688,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", }, { "product_base_types": ["groom"], @@ -1701,7 +1701,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", }, { "product_base_types": ["rig"], @@ -1714,7 +1714,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", }, { "product_base_types": ["usd"], @@ -1727,7 +1727,7 @@ class PublishPuginsModel(BaseSettingsModel): "contribution_variant_set_name": "{layer}", "contribution_variant": "{variant}", "contribution_variant_default_policy": - "if_missing", + "if_not_set", }, ] }, From f70635ef2aa5a41d88256451ef70e668a243e010 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Thu, 13 Aug 2026 09:41:28 +0200 Subject: [PATCH 09/19] add Literal type hint --- .../plugins/publish/extract_usd_layer_contributions.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 240d18a567d..e51be3383de 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -4,7 +4,7 @@ import platform from collections import defaultdict from operator import attrgetter -from typing import Any, Dict, List +from typing import Any, Dict, List, Literal import pyblish.api try: @@ -74,7 +74,9 @@ class VariantContribution(_BaseContribution): # Variant variant_set_name: str variant_name: str - variant_default_policy: str # Policy controlling variant selection opinion + variant_default_policy: Literal[ + "if_not_set", "always", "never" + ] # Policy controlling variant selection opinion CONTRIBUTION_VARIANT_DEFAULT_POLICY = { From 09755522235f4cb7a6a6a0f3351455fa159057c4 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Mon, 17 Aug 2026 09:32:10 +0200 Subject: [PATCH 10/19] remove unnecessary check --- .../plugins/publish/extract_usd_layer_contributions.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 8fb72e98446..8fbbe2ba4bd 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -361,16 +361,6 @@ def process(self, instance): variant_default_policy = attr_values.get( "contribution_variant_default_policy" ) - if variant_default_policy is None: - # Support data created before the boolean was replaced by the - # policy enum. - variant_default_policy = ( - "always" - if attr_values.get( - "contribution_variant_is_default", False - ) - else "if_not_set" - ) contribution = VariantContribution( instance=instance, From 85fdcc7844b9833709ed68ac3834c56ad103247b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:35:36 +0200 Subject: [PATCH 11/19] remove unnecessary condition Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../plugins/publish/extract_usd_layer_contributions.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 8fbbe2ba4bd..1f81b38a0c8 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -561,15 +561,6 @@ def get_attr_defs_for_instance(cls, create_context, instance): "contribution_variant_default_policy": "if_not_set", } - elif "contribution_variant_default_policy" not in profile: - # Support profiles created before the boolean was replaced by the - # policy enum. - profile = profile.copy() - profile["contribution_variant_default_policy"] = ( - "always" - if profile.get("contribution_variant_is_default", False) - else "if_not_set" - ) # Define defaults default_target_product: str = profile["contribution_target_product"] From c48cd789d0ebdaf4d5455e90181640353ff4c9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:36:01 +0200 Subject: [PATCH 12/19] formating adjustment Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../plugins/publish/extract_usd_layer_contributions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 1f81b38a0c8..1b8f86be6d1 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -819,7 +819,8 @@ def process(self, instance): variant_set_name = contribution.variant_set_name variant_name = contribution.variant_name policy = contribution.variant_default_policy - if (policy == "always" + if ( + policy == "always" or ( policy == "if_not_set" and variant_set_name not in prim_spec.variantSelections From c41accc7542dffe63481ff6b8ab6c644c0849d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:36:26 +0200 Subject: [PATCH 13/19] return if no profiles Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/conversion.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/settings/conversion.py b/server/settings/conversion.py index 357164bba54..d9127a53e06 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -293,8 +293,10 @@ def _convert_usd_contribution_variant_default_policy(overrides): overrides .get("publish", {}) .get("CollectUSDLayerContributions", {}) - .get("profiles", []) + .get("profiles") ) + if not profiles: + return for profile in profiles: if "contribution_variant_default_policy" in profile: From 75bb83f88e83eba07336adeeb449617612181520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:37:02 +0200 Subject: [PATCH 14/19] include version number in convert func name Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/conversion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/settings/conversion.py b/server/settings/conversion.py index d9127a53e06..457e5863bd3 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -316,7 +316,7 @@ def _convert_publish_plugins(overrides): return _convert_validate_version_0_3_3(overrides["publish"]) _convert_oiio_transcode_0_4_5(overrides["publish"]) - _convert_usd_contribution_variant_default_policy(overrides) + _convert_usd_contribution_variant_default_policy_1_9_11(overrides) def _convert_extract_thumbnail(overrides, version: VersionInfo): From db4ef066768378dfd7e75746c00c4ee298e6d0da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:37:22 +0200 Subject: [PATCH 15/19] include version number in convert func name 2 Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- server/settings/conversion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/settings/conversion.py b/server/settings/conversion.py index 457e5863bd3..66273ab2d68 100644 --- a/server/settings/conversion.py +++ b/server/settings/conversion.py @@ -287,7 +287,7 @@ def _convert_oiio_transcode_0_4_5(publish_overrides): } -def _convert_usd_contribution_variant_default_policy(overrides): +def _convert_usd_contribution_variant_default_policy_1_9_11(overrides): """Convert the USD contribution default boolean to a policy enum.""" profiles = ( overrides From 9f929ac8fed13600bcf63e973934ea41c8768f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:38:10 +0200 Subject: [PATCH 16/19] convert of old values Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- .../plugins/publish/extract_usd_layer_contributions.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 1b8f86be6d1..22324ce340a 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -574,6 +574,16 @@ def get_attr_defs_for_instance(cls, create_context, instance): # Attributes logic publish_attributes = instance["publish_attributes"].get( cls.__name__, {}) + if "contribution_variant_is_default" in publish_attributes: + contribution_variant_is_default = publish_attributes.pop( + "contribution_variant_is_default" + ) + + publish_attributes["contribution_variant_default_policy"] = ( + "always" + if contribution_variant_is_default + else "if_not_set" + ) visible = publish_attributes.get("contribution_enabled", True) variant_visible = visible and publish_attributes.get( From 492da26b2068c78723bb5f1a02b11086de361368 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Mon, 17 Aug 2026 13:39:36 +0200 Subject: [PATCH 17/19] fix incorrect formatting --- .../extract_usd_layer_contributions.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 22324ce340a..8cab39862cf 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -574,16 +574,17 @@ def get_attr_defs_for_instance(cls, create_context, instance): # Attributes logic publish_attributes = instance["publish_attributes"].get( cls.__name__, {}) - if "contribution_variant_is_default" in publish_attributes: - contribution_variant_is_default = publish_attributes.pop( - "contribution_variant_is_default" - ) - publish_attributes["contribution_variant_default_policy"] = ( - "always" - if contribution_variant_is_default - else "if_not_set" - ) + if "contribution_variant_is_default" in publish_attributes: + contribution_variant_is_default = publish_attributes.pop( + "contribution_variant_is_default" + ) + + publish_attributes["contribution_variant_default_policy"] = ( + "always" + if contribution_variant_is_default + else "if_not_set" + ) visible = publish_attributes.get("contribution_enabled", True) variant_visible = visible and publish_attributes.get( From 81a9c597f0feee1224d6b57739654b3d5fe2b78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tade=C3=A1=C5=A1=20Hejnic?= <65614308+tadeas-hejnic@users.noreply.github.com> Date: Tue, 18 Aug 2026 10:22:52 +0200 Subject: [PATCH 18/19] Add comment Co-authored-by: Roy Nieterau --- .../ayon_core/plugins/publish/extract_usd_layer_contributions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index 8cab39862cf..e937eb6d413 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -575,6 +575,7 @@ def get_attr_defs_for_instance(cls, create_context, instance): publish_attributes = instance["publish_attributes"].get( cls.__name__, {}) + # Convert legacy attribute value if "contribution_variant_is_default" in publish_attributes: contribution_variant_is_default = publish_attributes.pop( "contribution_variant_is_default" From 74d69f7147f7b0b7861139179aa5c4f82c613bc5 Mon Sep 17 00:00:00 2001 From: Tadeas Hejnic Date: Tue, 18 Aug 2026 10:27:36 +0200 Subject: [PATCH 19/19] use direct index instead of .get --- .../plugins/publish/extract_usd_layer_contributions.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py index e937eb6d413..efe0ff014c4 100644 --- a/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py +++ b/client/ayon_core/plugins/publish/extract_usd_layer_contributions.py @@ -358,9 +358,8 @@ def process(self, instance): # Define contribution in_layer_order: int = attr_values.get("contribution_in_layer_order", 0) if attr_values["contribution_apply_as_variant"]: - variant_default_policy = attr_values.get( - "contribution_variant_default_policy" - ) + variant_default_policy = attr_values[ + "contribution_variant_default_policy"] contribution = VariantContribution( instance=instance,