mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
Merge pull request #1201 from ynput/bugfix/fix-publish-plugin-loading2
Fix publish plugin discovery
This commit is contained in:
commit
3d9fa01058
2 changed files with 35 additions and 21 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
|
"""Tools for working with python modules and classes."""
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
from typing import Optional
|
||||||
import importlib
|
import importlib
|
||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
@ -8,13 +10,22 @@ import logging
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def import_filepath(filepath, module_name=None):
|
def import_filepath(
|
||||||
|
filepath: str,
|
||||||
|
module_name: Optional[str] = None,
|
||||||
|
sys_module_name: Optional[str] = None) -> types.ModuleType:
|
||||||
"""Import python file as python module.
|
"""Import python file as python module.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filepath (str): Path to python file.
|
filepath (str): Path to python file.
|
||||||
module_name (str): Name of loaded module. Only for Python 3. By default
|
module_name (str): Name of loaded module. Only for Python 3. By default
|
||||||
is filled with filename of filepath.
|
is filled with filename of filepath.
|
||||||
|
sys_module_name (str): Name of module in `sys.modules` where to store
|
||||||
|
loaded module. By default is None so module is not added to
|
||||||
|
`sys.modules`.
|
||||||
|
|
||||||
|
Todo (antirotor): We should add the module to the sys.modules always but
|
||||||
|
we need to be careful about it and test it properly.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if module_name is None:
|
if module_name is None:
|
||||||
|
|
@ -28,6 +39,9 @@ def import_filepath(filepath, module_name=None):
|
||||||
module_loader = importlib.machinery.SourceFileLoader(
|
module_loader = importlib.machinery.SourceFileLoader(
|
||||||
module_name, filepath
|
module_name, filepath
|
||||||
)
|
)
|
||||||
|
# only add to sys.modules if requested
|
||||||
|
if sys_module_name:
|
||||||
|
sys.modules[sys_module_name] = module
|
||||||
module_loader.exec_module(module)
|
module_loader.exec_module(module)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
|
@ -126,7 +140,8 @@ def classes_from_module(superclass, module):
|
||||||
return classes
|
return classes
|
||||||
|
|
||||||
|
|
||||||
def import_module_from_dirpath(dirpath, folder_name, dst_module_name=None):
|
def import_module_from_dirpath(
|
||||||
|
dirpath, folder_name, dst_module_name=None):
|
||||||
"""Import passed directory as a python module.
|
"""Import passed directory as a python module.
|
||||||
|
|
||||||
Imported module can be assigned as a child attribute of already loaded
|
Imported module can be assigned as a child attribute of already loaded
|
||||||
|
|
@ -193,7 +208,7 @@ def is_func_signature_supported(func, *args, **kwargs):
|
||||||
Notes:
|
Notes:
|
||||||
This does NOT check if the function would work with passed arguments
|
This does NOT check if the function would work with passed arguments
|
||||||
only if they can be passed in. If function have *args, **kwargs
|
only if they can be passed in. If function have *args, **kwargs
|
||||||
in paramaters, this will always return 'True'.
|
in parameters, this will always return 'True'.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
>>> def my_function(my_number):
|
>>> def my_function(my_number):
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
"""Library functions for publishing."""
|
||||||
|
from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
|
|
@ -12,8 +14,8 @@ import pyblish.plugin
|
||||||
import pyblish.api
|
import pyblish.api
|
||||||
|
|
||||||
from ayon_core.lib import (
|
from ayon_core.lib import (
|
||||||
Logger,
|
|
||||||
import_filepath,
|
import_filepath,
|
||||||
|
Logger,
|
||||||
filter_profiles,
|
filter_profiles,
|
||||||
)
|
)
|
||||||
from ayon_core.settings import get_project_settings
|
from ayon_core.settings import get_project_settings
|
||||||
|
|
@ -163,7 +165,7 @@ class HelpContent:
|
||||||
|
|
||||||
def load_help_content_from_filepath(filepath):
|
def load_help_content_from_filepath(filepath):
|
||||||
"""Load help content from xml file.
|
"""Load help content from xml file.
|
||||||
Xml file may containt errors and warnings.
|
Xml file may contain errors and warnings.
|
||||||
"""
|
"""
|
||||||
errors = {}
|
errors = {}
|
||||||
warnings = {}
|
warnings = {}
|
||||||
|
|
@ -208,8 +210,9 @@ def load_help_content_from_plugin(plugin):
|
||||||
return load_help_content_from_filepath(filepath)
|
return load_help_content_from_filepath(filepath)
|
||||||
|
|
||||||
|
|
||||||
def publish_plugins_discover(paths=None):
|
def publish_plugins_discover(
|
||||||
"""Find and return available pyblish plug-ins
|
paths: Optional[list[str]] = None) -> DiscoverResult:
|
||||||
|
"""Find and return available pyblish plug-ins.
|
||||||
|
|
||||||
Overridden function from `pyblish` module to be able to collect
|
Overridden function from `pyblish` module to be able to collect
|
||||||
crashed files and reason of their crash.
|
crashed files and reason of their crash.
|
||||||
|
|
@ -252,17 +255,14 @@ def publish_plugins_discover(paths=None):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
module = import_filepath(abspath, mod_name)
|
module = import_filepath(
|
||||||
|
abspath, mod_name, sys_module_name=mod_name)
|
||||||
|
|
||||||
# Store reference to original module, to avoid
|
except Exception as err: # noqa: BLE001
|
||||||
# garbage collection from collecting it's global
|
# we need broad exception to catch all possible errors.
|
||||||
# imports, such as `import os`.
|
|
||||||
sys.modules[abspath] = module
|
|
||||||
|
|
||||||
except Exception as err:
|
|
||||||
result.crashed_file_paths[abspath] = sys.exc_info()
|
result.crashed_file_paths[abspath] = sys.exc_info()
|
||||||
|
|
||||||
log.debug("Skipped: \"%s\" (%s)", mod_name, err)
|
log.debug('Skipped: "%s" (%s)', mod_name, err)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for plugin in pyblish.plugin.plugins_from_module(module):
|
for plugin in pyblish.plugin.plugins_from_module(module):
|
||||||
|
|
@ -280,9 +280,8 @@ def publish_plugins_discover(paths=None):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
plugin_names.append(plugin.__name__)
|
plugin_names.append(plugin.__name__)
|
||||||
|
plugin.__file__ = module.__file__
|
||||||
plugin.__module__ = module.__file__
|
key = f"{module.__file__}.{plugin.__name__}"
|
||||||
key = "{0}.{1}".format(plugin.__module__, plugin.__name__)
|
|
||||||
plugins[key] = plugin
|
plugins[key] = plugin
|
||||||
|
|
||||||
# Include plug-ins from registration.
|
# Include plug-ins from registration.
|
||||||
|
|
@ -361,7 +360,7 @@ def get_plugin_settings(plugin, project_settings, log, category=None):
|
||||||
# Settings category determined from path
|
# Settings category determined from path
|
||||||
# - usually path is './<category>/plugins/publish/<plugin file>'
|
# - usually path is './<category>/plugins/publish/<plugin file>'
|
||||||
# - category can be host name of addon name ('maya', 'deadline', ...)
|
# - category can be host name of addon name ('maya', 'deadline', ...)
|
||||||
filepath = os.path.normpath(inspect.getsourcefile(plugin))
|
filepath = os.path.normpath(inspect.getfile(plugin))
|
||||||
|
|
||||||
split_path = filepath.rsplit(os.path.sep, 5)
|
split_path = filepath.rsplit(os.path.sep, 5)
|
||||||
if len(split_path) < 4:
|
if len(split_path) < 4:
|
||||||
|
|
@ -427,7 +426,7 @@ def filter_pyblish_plugins(plugins):
|
||||||
log = Logger.get_logger("filter_pyblish_plugins")
|
log = Logger.get_logger("filter_pyblish_plugins")
|
||||||
|
|
||||||
# TODO: Don't use host from 'pyblish.api' but from defined host by us.
|
# TODO: Don't use host from 'pyblish.api' but from defined host by us.
|
||||||
# - kept becau on farm is probably used host 'shell' which propably
|
# - kept because on farm is probably used host 'shell' which probably
|
||||||
# affect how settings are applied there
|
# affect how settings are applied there
|
||||||
host_name = pyblish.api.current_host()
|
host_name = pyblish.api.current_host()
|
||||||
project_name = os.environ.get("AYON_PROJECT_NAME")
|
project_name = os.environ.get("AYON_PROJECT_NAME")
|
||||||
|
|
@ -529,7 +528,7 @@ def filter_instances_for_context_plugin(plugin, context):
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
plugin (pyblish.api.Plugin): Plugin with filters.
|
plugin (pyblish.api.Plugin): Plugin with filters.
|
||||||
context (pyblish.api.Context): Pyblish context with insances.
|
context (pyblish.api.Context): Pyblish context with instances.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Iterator[pyblish.lib.Instance]: Iteration of valid instances.
|
Iterator[pyblish.lib.Instance]: Iteration of valid instances.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue