Skip to content

Commit

Permalink
Merge pull request #366 from BigRoy/enhancement/create_context_typing
Browse files Browse the repository at this point in the history
Code: Improve type hints for Creators
  • Loading branch information
antirotor authored Jul 11, 2024
2 parents 590c612 + 3a1857a commit 6786363
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 35 deletions.
7 changes: 4 additions & 3 deletions client/ayon_core/pipeline/create/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import inspect
from uuid import uuid4
from contextlib import contextmanager
from typing import Optional

import pyblish.logic
import pyblish.api
Expand Down Expand Up @@ -47,7 +48,7 @@ class UnavailableSharedData(Exception):


class ImmutableKeyError(TypeError):
"""Accessed key is immutable so does not allow changes or removements."""
"""Accessed key is immutable so does not allow changes or removals."""

def __init__(self, key, msg=None):
self.immutable_key = key
Expand Down Expand Up @@ -1433,7 +1434,7 @@ def __init__(
self.convertors_plugins = {}
self.convertor_items_by_id = {}

self.publish_discover_result = None
self.publish_discover_result: Optional[DiscoverResult] = None
self.publish_plugins_mismatch_targets = []
self.publish_plugins = []
self.plugins_with_defs = []
Expand Down Expand Up @@ -2604,7 +2605,7 @@ def _get_publish_plugins_with_attr_for_context(self):
def collection_shared_data(self):
"""Access to shared data that can be used during creator's collection.
Retruns:
Returns:
Dict[str, Any]: Shared data.
Raises:
Expand Down
65 changes: 35 additions & 30 deletions client/ayon_core/pipeline/create/creator_plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import copy
import collections
from typing import TYPE_CHECKING, Optional

from abc import ABCMeta, abstractmethod

Expand All @@ -21,6 +22,11 @@
from .utils import get_next_versions_for_instances
from .legacy_create import LegacyCreator

if TYPE_CHECKING:
from ayon_core.lib import AbstractAttrDef
# Avoid cyclic imports
from .context import CreateContext, CreatedInstance, UpdateData # noqa: F401


class CreatorError(Exception):
"""Should be raised when creator failed because of known issue.
Expand All @@ -36,15 +42,15 @@ def __init__(self, message):
class ProductConvertorPlugin(object):
"""Helper for conversion of instances created using legacy creators.
Conversion from legacy creators would mean to loose legacy instances,
Conversion from legacy creators would mean to lose legacy instances,
convert them automatically or write a script which must user run. All of
these solutions are workign but will happen without asking or user must
these solutions are working but will happen without asking or user must
know about them. This plugin can be used to show legacy instances in
Publisher and give user ability to run conversion script.
Convertor logic should be very simple. Method 'find_instances' is to
look for legacy instances in scene a possibly call
pre-implemented 'add_convertor_item'.
look for legacy instances in scene and possibly call pre-implemented
'add_convertor_item'.
User will have ability to trigger conversion which is executed by calling
'convert' which should call 'remove_convertor_item' when is done.
Expand All @@ -57,7 +63,7 @@ class ProductConvertorPlugin(object):
can store any information to it's object for conversion purposes.
Args:
create_context
create_context (CreateContext): Context which initialized the plugin.
"""

_log = None
Expand Down Expand Up @@ -122,8 +128,8 @@ def create_context(self):
def collection_shared_data(self):
"""Access to shared data that can be used during 'find_instances'.
Retruns:
Dict[str, Any]: Shared data.
Returns:
dict[str, Any]: Shared data.
Raises:
UnavailableSharedData: When called out of collection phase.
Expand All @@ -150,15 +156,15 @@ def remove_convertor_item(self):
class BaseCreator:
"""Plugin that create and modify instance data before publishing process.
We should maybe find better name as creation is only one part of it's logic
We should maybe find better name as creation is only one part of its logic
and to avoid expectations that it is the same as `avalon.api.Creator`.
Single object should be used for multiple instances instead of single
instance per one creator object. Do not store temp data or mid-process data
to `self` if it's not Plugin specific.
Args:
project_settings (Dict[str, Any]): Project settings.
project_settings (dict[str, Any]): Project settings.
create_context (CreateContext): Context which initialized creator.
headless (bool): Running in headless mode.
"""
Expand All @@ -185,20 +191,20 @@ class BaseCreator:

# Instance attribute definitions that can be changed per instance
# - returns list of attribute definitions from
# `ayon_core.pipeline.attribute_definitions`
instance_attr_defs = []
# `ayon_core.lib.attribute_definitions`
instance_attr_defs: "list[AbstractAttrDef]" = []

# Filtering by host name - can be used to be filtered by host name
# - used on all hosts when set to 'None' for Backwards compatibility
# - was added afterwards
# QUESTION make this required?
host_name = None
host_name: Optional[str] = None

# Settings auto-apply helpers
# Root key in project settings (mandatory for auto-apply to work)
settings_category = None
settings_category: Optional[str] = None
# Name of plugin in create settings > class name is used if not set
settings_name = None
settings_name: Optional[str] = None

def __init__(
self, project_settings, create_context, headless=False
Expand All @@ -207,7 +213,7 @@ def __init__(
self.create_context = create_context
self.project_settings = project_settings

# Creator is running in headless mode (without UI elemets)
# Creator is running in headless mode (without UI elements)
# - we may use UI inside processing this attribute should be checked
self.headless = headless

Expand All @@ -223,7 +229,7 @@ def _get_settings_values(project_settings, category_name, plugin_name):
plugin_name (str): Name of settings.
Returns:
Union[dict[str, Any], None]: Settings values or None.
Optional[dict[str, Any]]: Settings values or None.
"""

settings = project_settings.get(category_name)
Expand Down Expand Up @@ -388,7 +394,7 @@ def _remove_instance_from_context(self, instance):
"""Helper method to remove instance from create context.
Instances must be removed from DCC workfile metadat aand from create
context in which plugin is existing at the moment of removement to
context in which plugin is existing at the moment of removal to
propagate the change without restarting create context.
Args:
Expand Down Expand Up @@ -440,21 +446,21 @@ def update_instances(self, update_list):
"""Store changes of existing instances so they can be recollected.
Args:
update_list(List[UpdateData]): Gets list of tuples. Each item
update_list (list[UpdateData]): Gets list of tuples. Each item
contain changed instance and it's changes.
"""

pass

@abstractmethod
def remove_instances(self, instances):
"""Method called on instance removement.
"""Method called on instance removal.
Can also remove instance metadata from context but should return
'True' if did so.
Args:
instance(List[CreatedInstance]): Instance objects which should be
instances (list[CreatedInstance]): Instance objects which should be
removed.
"""

Expand All @@ -479,8 +485,7 @@ def get_dynamic_data(
):
"""Dynamic data for product name filling.
These may be get dynamically created based on current context of
workfile.
These may be dynamically created based on current context of workfile.
"""

return {}
Expand Down Expand Up @@ -554,7 +559,7 @@ def get_instance_attr_defs(self):
keys/values when plugin attributes change.
Returns:
List[AbstractAttrDef]: Attribute definitions that can be tweaked
list[AbstractAttrDef]: Attribute definitions that can be tweaked
for created instance.
"""

Expand All @@ -564,8 +569,8 @@ def get_instance_attr_defs(self):
def collection_shared_data(self):
"""Access to shared data that can be used during creator's collection.
Retruns:
Dict[str, Any]: Shared data.
Returns:
dict[str, Any]: Shared data.
Raises:
UnavailableSharedData: When called out of collection phase.
Expand Down Expand Up @@ -594,7 +599,7 @@ def get_next_versions_for_instances(self, instances):
versions.
Returns:
Dict[str, int]: Next versions by instance id.
dict[str, int]: Next versions by instance id.
"""

return get_next_versions_for_instances(
Expand Down Expand Up @@ -713,7 +718,7 @@ def get_default_variants(self):
By default, returns `default_variants` value.
Returns:
List[str]: Whisper variants for user input.
list[str]: Whisper variants for user input.
"""

return copy.deepcopy(self.default_variants)
Expand Down Expand Up @@ -786,7 +791,7 @@ def get_pre_create_attr_defs(self):
updating keys/values when plugin attributes change.
Returns:
List[AbstractAttrDef]: Attribute definitions that can be tweaked
list[AbstractAttrDef]: Attribute definitions that can be tweaked
for created instance.
"""
return self.pre_create_attr_defs
Expand All @@ -805,7 +810,7 @@ class AutoCreator(BaseCreator):
"""

def remove_instances(self, instances):
"""Skip removement."""
"""Skip removal."""
pass


Expand Down Expand Up @@ -918,7 +923,7 @@ def cache_and_get_instances(creator, shared_key, list_instances_func):
if data were not yet stored under 'shared_key'.
Returns:
Dict[str, Dict[str, Any]]: Cached instances by creator identifier from
dict[str, dict[str, Any]]: Cached instances by creator identifier from
result of passed function.
"""

Expand Down
7 changes: 7 additions & 0 deletions client/ayon_core/pipeline/create/legacy_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ def get_dynamic_data(
This method can be modified to prefill some values just keep in mind it
is class method.
Args:
project_name (str): Context's project name.
folder_entity (dict[str, Any]): Folder entity.
task_entity (dict[str, Any]): Task entity.
variant (str): What is entered by user in creator tool.
host_name (str): Name of host.
Returns:
dict: Fill data for product name template.
"""
Expand Down
2 changes: 1 addition & 1 deletion client/ayon_core/pipeline/create/product_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def get_product_name_template(
task_name (str): Name of task in which context the product is created.
task_type (str): Type of task in which context the product is created.
default_template (Union[str, None]): Default template which is used if
settings won't find any matching possitibility. Constant
settings won't find any matching possibility. Constant
'DEFAULT_PRODUCT_TEMPLATE' is used if not defined.
project_settings (Union[Dict[str, Any], None]): Prepared settings for
project. Settings are queried if not passed.
Expand Down
2 changes: 1 addition & 1 deletion client/ayon_core/tools/utils/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ def set_orientation(self, orientation):
if self._orientation == orientation:
return

# Reset min/max sizes in opossite direction
# Reset min/max sizes in opposite direction
if self._orientation == QtCore.Qt.Vertical:
self.setMinimumHeight(0)
self.setMaximumHeight(self._maximum_height)
Expand Down

0 comments on commit 6786363

Please sign in to comment.