♻️ refactor filtering and add some tests

This commit is contained in:
Ondrej Samohel 2025-06-20 16:13:07 +02:00
parent 16ac7e2028
commit deacb2853e
No known key found for this signature in database
GPG key ID: 02376E18990A97C6
2 changed files with 103 additions and 5 deletions

View file

@ -129,6 +129,10 @@ class LoaderPlugin(list):
plugin_repre_names = cls.get_representations() plugin_repre_names = cls.get_representations()
plugin_product_types = cls.product_types plugin_product_types = cls.product_types
plugin_product_base_types = cls.product_base_types plugin_product_base_types = cls.product_base_types
# If product type isn't defined on the loader plugin,
# then we will use the product types.
plugin_product_filter = (
plugin_product_base_types or plugin_product_types)
repre_entity = context.get("representation") repre_entity = context.get("representation")
product_entity = context["product"] product_entity = context["product"]
@ -136,8 +140,8 @@ class LoaderPlugin(list):
# then loader is not compatible with any context. # then loader is not compatible with any context.
if ( if (
not plugin_repre_names not plugin_repre_names
or (not plugin_product_types and not plugin_product_base_types) and not plugin_product_filter
or not cls.extensions and not cls.extensions
): ):
return False return False
@ -148,7 +152,7 @@ class LoaderPlugin(list):
# Check the compatibility with the representation names. # Check the compatibility with the representation names.
plugin_repre_names = set(plugin_repre_names) plugin_repre_names = set(plugin_repre_names)
if not plugin_repre_names or ( if (
"*" not in plugin_repre_names "*" not in plugin_repre_names
and repre_entity["name"] not in plugin_repre_names and repre_entity["name"] not in plugin_repre_names
): ):
@ -169,8 +173,6 @@ class LoaderPlugin(list):
if product_filter is None: if product_filter is None:
product_filter = product_type product_filter = product_type
# If no product type isn't defined on the loader plugin,
# then we will use the product types.
plugin_product_filter = ( plugin_product_filter = (
plugin_product_base_types or plugin_product_types) plugin_product_base_types or plugin_product_types)
@ -179,6 +181,14 @@ class LoaderPlugin(list):
if "*" in plugin_product_filter: if "*" in plugin_product_filter:
return True return True
# compatibility with legacy loader
if cls.product_base_types is None and product_base_type:
cls.log.error(
f"Loader {cls.__name__} is doesn't specify "
"`product_base_types` but product entity has "
f"`productBaseType` defined as `{product_base_type}`. "
)
return product_filter in plugin_product_filter return product_filter in plugin_product_filter
@classmethod @classmethod

View file

@ -0,0 +1,88 @@
"""Test loaders in the pipeline module."""
from ayon_core.pipeline.load import LoaderPlugin
def test_is_compatible_loader():
"""Test if a loader is compatible with a given representation."""
from ayon_core.pipeline.load import is_compatible_loader
# Create a mock representation context
context = {
"loader": "test_loader",
"representation": {"name": "test_representation"},
}
# Create a mock loader plugin
class MockLoader(LoaderPlugin):
name = "test_loader"
version = "1.0.0"
def is_compatible_loader(self, context):
return True
# Check compatibility
assert is_compatible_loader(MockLoader(), context) is True
def test_complex_is_compatible_loader():
"""Test if a loader is compatible with a complex representation."""
from ayon_core.pipeline.load import is_compatible_loader
# Create a mock complex representation context
context = {
"loader": "complex_loader",
"representation": {
"name": "complex_representation",
"extension": "exr"
},
"additional_data": {"key": "value"},
"product": {
"name": "complex_product",
"productType": "foo",
"productBaseType": "bar",
},
}
# Create a mock loader plugin
class ComplexLoaderA(LoaderPlugin):
name = "complex_loaderA"
# False because the loader doesn't specify any compatibility (missing
# wildcard for product type and product base type)
assert is_compatible_loader(ComplexLoaderA(), context) is False
class ComplexLoaderB(LoaderPlugin):
name = "complex_loaderB"
product_types = {"*"}
representations = {"*"}
# True, it is compatible with any product type
assert is_compatible_loader(ComplexLoaderB(), context) is True
class ComplexLoaderC(LoaderPlugin):
name = "complex_loaderC"
product_base_types = {"*"}
representations = {"*"}
# True, it is compatible with any product base type
assert is_compatible_loader(ComplexLoaderC(), context) is True
class ComplexLoaderD(LoaderPlugin):
name = "complex_loaderD"
product_types = {"foo"}
representations = {"*"}
# legacy loader defining compatibility only with product type
# is compatible provided the same product type is defined in context
assert is_compatible_loader(ComplexLoaderD(), context) is False
class ComplexLoaderE(LoaderPlugin):
name = "complex_loaderE"
product_types = {"foo"}
representations = {"*"}
# remove productBaseType from context to simulate legacy behavior
context["product"].pop("productBaseType", None)
assert is_compatible_loader(ComplexLoaderE(), context) is True