mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
added to lib python functions for work with python modules and classes
This commit is contained in:
parent
b29362411e
commit
2164dbe6c1
2 changed files with 111 additions and 0 deletions
|
|
@ -11,6 +11,12 @@ from .env_tools import (
|
|||
get_paths_from_environ
|
||||
)
|
||||
|
||||
from .python_module_tools import (
|
||||
modules_from_path,
|
||||
recursive_bases_from_class,
|
||||
classes_from_module
|
||||
)
|
||||
|
||||
from .avalon_context import (
|
||||
is_latest,
|
||||
any_outdated,
|
||||
|
|
@ -53,6 +59,10 @@ __all__ = [
|
|||
"env_value_to_bool",
|
||||
"get_paths_from_environ",
|
||||
|
||||
"modules_from_path",
|
||||
"recursive_bases_from_class",
|
||||
"classes_from_module",
|
||||
|
||||
"is_latest",
|
||||
"any_outdated",
|
||||
"get_asset",
|
||||
|
|
|
|||
101
pype/lib/python_module_tools.py
Normal file
101
pype/lib/python_module_tools.py
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import os
|
||||
import types
|
||||
import inspect
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def modules_from_path(folder_path):
|
||||
"""Get python scripts as modules from a path.
|
||||
|
||||
Arguments:
|
||||
path (str): Path to folder containing python scripts.
|
||||
|
||||
Returns:
|
||||
List of modules.
|
||||
"""
|
||||
|
||||
folder_path = os.path.normpath(folder_path)
|
||||
|
||||
modules = []
|
||||
if not os.path.isdir(folder_path):
|
||||
log.warning("Not a directory path: {}".format(folder_path))
|
||||
return modules
|
||||
|
||||
for filename in os.listdir(folder_path):
|
||||
# Ignore files which start with underscore
|
||||
if filename.startswith("_"):
|
||||
continue
|
||||
|
||||
mod_name, mod_ext = os.path.splitext(filename)
|
||||
if not mod_ext == ".py":
|
||||
continue
|
||||
|
||||
full_path = os.path.join(folder_path, filename)
|
||||
if not os.path.isfile(full_path):
|
||||
continue
|
||||
|
||||
try:
|
||||
# Prepare module object where content of file will be parsed
|
||||
module = types.ModuleType(mod_name)
|
||||
module.__file__ = full_path
|
||||
|
||||
with open(full_path) as _stream:
|
||||
# Execute content and store it to module object
|
||||
exec(_stream.read(), module.__dict__)
|
||||
|
||||
modules.append(module)
|
||||
|
||||
except Exception:
|
||||
log.warning(
|
||||
"Failed to load path: \"{0}\"".format(full_path),
|
||||
exc_info=True
|
||||
)
|
||||
continue
|
||||
|
||||
return modules
|
||||
|
||||
|
||||
def recursive_bases_from_class(klass):
|
||||
"""Extract all bases from entered class."""
|
||||
result = []
|
||||
bases = klass.__bases__
|
||||
result.extend(bases)
|
||||
for base in bases:
|
||||
result.extend(recursive_bases_from_class(base))
|
||||
return result
|
||||
|
||||
|
||||
def classes_from_module(superclass, module):
|
||||
"""Return plug-ins from module
|
||||
|
||||
Arguments:
|
||||
superclass (superclass): Superclass of subclasses to look for
|
||||
module (types.ModuleType): Imported module from which to
|
||||
parse valid Avalon plug-ins.
|
||||
|
||||
Returns:
|
||||
List of plug-ins, or empty list if none is found.
|
||||
|
||||
"""
|
||||
|
||||
classes = list()
|
||||
for name in dir(module):
|
||||
# It could be anything at this point
|
||||
obj = getattr(module, name)
|
||||
if not inspect.isclass(obj):
|
||||
continue
|
||||
|
||||
# These are subclassed from nothing, not even `object`
|
||||
if not len(obj.__bases__) > 0:
|
||||
continue
|
||||
|
||||
# Use string comparison rather than `issubclass`
|
||||
# in order to support reloading of this module.
|
||||
bases = recursive_bases_from_class(obj)
|
||||
if not any(base.__name__ == superclass.__name__ for base in bases):
|
||||
continue
|
||||
|
||||
classes.append(obj)
|
||||
return classes
|
||||
Loading…
Add table
Add a link
Reference in a new issue