mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 12:54:40 +01:00
General: Lib code cleanup (#5003)
* implemented 'is_func_signature_supported' function * 'WeakMethod' can be imported from 'python_2_comp' all the time * simplified events logic for callback registration * modified docstrings in publish lib * removed unused imports * fixed 'run_openpype_process' docstring
This commit is contained in:
parent
a03a0cc886
commit
248336bb0d
6 changed files with 129 additions and 88 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# flake8: noqa E402
|
||||
"""Pype module API."""
|
||||
"""OpenPype lib functions."""
|
||||
# add vendor to sys path based on Python version
|
||||
import sys
|
||||
import os
|
||||
|
|
@ -94,7 +94,8 @@ from .python_module_tools import (
|
|||
modules_from_path,
|
||||
recursive_bases_from_class,
|
||||
classes_from_module,
|
||||
import_module_from_dirpath
|
||||
import_module_from_dirpath,
|
||||
is_func_signature_supported,
|
||||
)
|
||||
|
||||
from .profiles_filtering import (
|
||||
|
|
@ -243,6 +244,7 @@ __all__ = [
|
|||
"recursive_bases_from_class",
|
||||
"classes_from_module",
|
||||
"import_module_from_dirpath",
|
||||
"is_func_signature_supported",
|
||||
|
||||
"get_transcode_temp_directory",
|
||||
"should_convert_for_ffmpeg",
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ import inspect
|
|||
import logging
|
||||
import weakref
|
||||
from uuid import uuid4
|
||||
try:
|
||||
from weakref import WeakMethod
|
||||
except Exception:
|
||||
from openpype.lib.python_2_comp import WeakMethod
|
||||
|
||||
from .python_2_comp import WeakMethod
|
||||
from .python_module_tools import is_func_signature_supported
|
||||
|
||||
|
||||
class MissingEventSystem(Exception):
|
||||
|
|
@ -80,40 +79,8 @@ class EventCallback(object):
|
|||
|
||||
# Get expected arguments from function spec
|
||||
# - positional arguments are always preferred
|
||||
expect_args = False
|
||||
expect_kwargs = False
|
||||
fake_event = "fake"
|
||||
if hasattr(inspect, "signature"):
|
||||
# Python 3 using 'Signature' object where we try to bind arg
|
||||
# or kwarg. Using signature is recommended approach based on
|
||||
# documentation.
|
||||
sig = inspect.signature(func)
|
||||
try:
|
||||
sig.bind(fake_event)
|
||||
expect_args = True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
sig.bind(event=fake_event)
|
||||
expect_kwargs = True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
else:
|
||||
# In Python 2 'signature' is not available so 'getcallargs' is used
|
||||
# - 'getcallargs' is marked as deprecated since Python 3.0
|
||||
try:
|
||||
inspect.getcallargs(func, fake_event)
|
||||
expect_args = True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
inspect.getcallargs(func, event=fake_event)
|
||||
expect_kwargs = True
|
||||
except TypeError:
|
||||
pass
|
||||
expect_args = is_func_signature_supported(func, "fake")
|
||||
expect_kwargs = is_func_signature_supported(func, event="fake")
|
||||
|
||||
self._func_ref = func_ref
|
||||
self._func_name = func_name
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ def run_openpype_process(*args, **kwargs):
|
|||
|
||||
Example:
|
||||
```
|
||||
run_openpype_process("run", "<path to .py script>")
|
||||
run_detached_process("run", "<path to .py script>")
|
||||
```
|
||||
|
||||
Args:
|
||||
|
|
|
|||
|
|
@ -1,41 +1,44 @@
|
|||
import weakref
|
||||
|
||||
|
||||
class _weak_callable:
|
||||
def __init__(self, obj, func):
|
||||
self.im_self = obj
|
||||
self.im_func = func
|
||||
WeakMethod = getattr(weakref, "WeakMethod", None)
|
||||
|
||||
def __call__(self, *args, **kws):
|
||||
if self.im_self is None:
|
||||
return self.im_func(*args, **kws)
|
||||
else:
|
||||
return self.im_func(self.im_self, *args, **kws)
|
||||
if WeakMethod is None:
|
||||
class _WeakCallable:
|
||||
def __init__(self, obj, func):
|
||||
self.im_self = obj
|
||||
self.im_func = func
|
||||
|
||||
def __call__(self, *args, **kws):
|
||||
if self.im_self is None:
|
||||
return self.im_func(*args, **kws)
|
||||
else:
|
||||
return self.im_func(self.im_self, *args, **kws)
|
||||
|
||||
|
||||
class WeakMethod:
|
||||
""" Wraps a function or, more importantly, a bound method in
|
||||
a way that allows a bound method's object to be GCed, while
|
||||
providing the same interface as a normal weak reference. """
|
||||
class WeakMethod:
|
||||
""" Wraps a function or, more importantly, a bound method in
|
||||
a way that allows a bound method's object to be GCed, while
|
||||
providing the same interface as a normal weak reference. """
|
||||
|
||||
def __init__(self, fn):
|
||||
try:
|
||||
self._obj = weakref.ref(fn.im_self)
|
||||
self._meth = fn.im_func
|
||||
except AttributeError:
|
||||
# It's not a bound method
|
||||
self._obj = None
|
||||
self._meth = fn
|
||||
def __init__(self, fn):
|
||||
try:
|
||||
self._obj = weakref.ref(fn.im_self)
|
||||
self._meth = fn.im_func
|
||||
except AttributeError:
|
||||
# It's not a bound method
|
||||
self._obj = None
|
||||
self._meth = fn
|
||||
|
||||
def __call__(self):
|
||||
if self._dead():
|
||||
return None
|
||||
return _weak_callable(self._getobj(), self._meth)
|
||||
def __call__(self):
|
||||
if self._dead():
|
||||
return None
|
||||
return _WeakCallable(self._getobj(), self._meth)
|
||||
|
||||
def _dead(self):
|
||||
return self._obj is not None and self._obj() is None
|
||||
def _dead(self):
|
||||
return self._obj is not None and self._obj() is None
|
||||
|
||||
def _getobj(self):
|
||||
if self._obj is None:
|
||||
return None
|
||||
return self._obj()
|
||||
def _getobj(self):
|
||||
if self._obj is None:
|
||||
return None
|
||||
return self._obj()
|
||||
|
|
|
|||
|
|
@ -230,3 +230,70 @@ def import_module_from_dirpath(dirpath, folder_name, dst_module_name=None):
|
|||
dirpath, folder_name, dst_module_name
|
||||
)
|
||||
return module
|
||||
|
||||
|
||||
def is_func_signature_supported(func, *args, **kwargs):
|
||||
"""Check if a function signature supports passed args and kwargs.
|
||||
|
||||
This check does not actually call the function, just look if function can
|
||||
be called with the arguments.
|
||||
|
||||
Notes:
|
||||
This does NOT check if the function would work with passed arguments
|
||||
only if they can be passed in. If function have *args, **kwargs
|
||||
in paramaters, this will always return 'True'.
|
||||
|
||||
Example:
|
||||
>>> def my_function(my_number):
|
||||
... return my_number + 1
|
||||
...
|
||||
>>> is_func_signature_supported(my_function, 1)
|
||||
True
|
||||
>>> is_func_signature_supported(my_function, 1, 2)
|
||||
False
|
||||
>>> is_func_signature_supported(my_function, my_number=1)
|
||||
True
|
||||
>>> is_func_signature_supported(my_function, number=1)
|
||||
False
|
||||
>>> is_func_signature_supported(my_function, "string")
|
||||
True
|
||||
>>> def my_other_function(*args, **kwargs):
|
||||
... my_function(*args, **kwargs)
|
||||
...
|
||||
>>> is_func_signature_supported(
|
||||
... my_other_function,
|
||||
... "string",
|
||||
... 1,
|
||||
... other=None
|
||||
... )
|
||||
True
|
||||
|
||||
Args:
|
||||
func (function): A function where the signature should be tested.
|
||||
*args (tuple[Any]): Positional arguments for function signature.
|
||||
**kwargs (dict[str, Any]): Keyword arguments for function signature.
|
||||
|
||||
Returns:
|
||||
bool: Function can pass in arguments.
|
||||
"""
|
||||
|
||||
if hasattr(inspect, "signature"):
|
||||
# Python 3 using 'Signature' object where we try to bind arg
|
||||
# or kwarg. Using signature is recommended approach based on
|
||||
# documentation.
|
||||
sig = inspect.signature(func)
|
||||
try:
|
||||
sig.bind(*args, **kwargs)
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
else:
|
||||
# In Python 2 'signature' is not available so 'getcallargs' is used
|
||||
# - 'getcallargs' is marked as deprecated since Python 3.0
|
||||
try:
|
||||
inspect.getcallargs(func, *args, **kwargs)
|
||||
return True
|
||||
except TypeError:
|
||||
pass
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import os
|
||||
import sys
|
||||
import types
|
||||
import inspect
|
||||
import copy
|
||||
import tempfile
|
||||
import xml.etree.ElementTree
|
||||
|
||||
import six
|
||||
import pyblish.util
|
||||
import pyblish.plugin
|
||||
import pyblish.api
|
||||
|
|
@ -42,7 +40,9 @@ def get_template_name_profiles(
|
|||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for templates.
|
||||
project_settings(Dic[str, Any]): Prepared project settings.
|
||||
project_settings (Dict[str, Any]): Prepared project settings.
|
||||
logger (Optional[logging.Logger]): Logger object to be used instead
|
||||
of default logger.
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: Publish template profiles.
|
||||
|
|
@ -103,7 +103,9 @@ def get_hero_template_name_profiles(
|
|||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for templates.
|
||||
project_settings(Dic[str, Any]): Prepared project settings.
|
||||
project_settings (Dict[str, Any]): Prepared project settings.
|
||||
logger (Optional[logging.Logger]): Logger object to be used instead
|
||||
of default logger.
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: Publish template profiles.
|
||||
|
|
@ -172,9 +174,10 @@ def get_publish_template_name(
|
|||
project_name (str): Name of project where to look for settings.
|
||||
host_name (str): Name of host integration.
|
||||
family (str): Family for which should be found template.
|
||||
task_name (str): Task name on which is intance working.
|
||||
task_type (str): Task type on which is intance working.
|
||||
project_setting (Dict[str, Any]): Prepared project settings.
|
||||
task_name (str): Task name on which is instance working.
|
||||
task_type (str): Task type on which is instance working.
|
||||
project_settings (Dict[str, Any]): Prepared project settings.
|
||||
hero (bool): Template is for hero version publishing.
|
||||
logger (logging.Logger): Custom logger used for 'filter_profiles'
|
||||
function.
|
||||
|
||||
|
|
@ -264,19 +267,18 @@ def load_help_content_from_plugin(plugin):
|
|||
def publish_plugins_discover(paths=None):
|
||||
"""Find and return available pyblish plug-ins
|
||||
|
||||
Overridden function from `pyblish` module to be able collect crashed files
|
||||
and reason of their crash.
|
||||
Overridden function from `pyblish` module to be able to collect
|
||||
crashed files and reason of their crash.
|
||||
|
||||
Arguments:
|
||||
paths (list, optional): Paths to discover plug-ins from.
|
||||
If no paths are provided, all paths are searched.
|
||||
|
||||
"""
|
||||
|
||||
# The only difference with `pyblish.api.discover`
|
||||
result = DiscoverResult(pyblish.api.Plugin)
|
||||
|
||||
plugins = dict()
|
||||
plugins = {}
|
||||
plugin_names = []
|
||||
|
||||
allow_duplicates = pyblish.plugin.ALLOW_DUPLICATES
|
||||
|
|
@ -302,7 +304,7 @@ def publish_plugins_discover(paths=None):
|
|||
|
||||
mod_name, mod_ext = os.path.splitext(fname)
|
||||
|
||||
if not mod_ext == ".py":
|
||||
if mod_ext != ".py":
|
||||
continue
|
||||
|
||||
try:
|
||||
|
|
@ -533,10 +535,10 @@ def find_close_plugin(close_plugin_name, log):
|
|||
def remote_publish(log, close_plugin_name=None, raise_error=False):
|
||||
"""Loops through all plugins, logs to console. Used for tests.
|
||||
|
||||
Args:
|
||||
log (openpype.lib.Logger)
|
||||
close_plugin_name (str): name of plugin with responsibility to
|
||||
close host app
|
||||
Args:
|
||||
log (Logger)
|
||||
close_plugin_name (str): name of plugin with responsibility to
|
||||
close host app
|
||||
"""
|
||||
# Error exit as soon as any error occurs.
|
||||
error_format = "Failed {plugin.__name__}: {error} -- {error.traceback}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue