Source code for pyworkflow.utils.reflection

# **************************************************************************
# *
# * Authors:     J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
# *
# * Unidad de  Bioinformatica of Centro Nacional de Biotecnologia , CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************
"""
This module contains reflection utilities
(dynamically load classes, inspect object properties and others)
"""

import os
from os.path import exists, join
import sys
from inspect import isclass


[docs]def getModules(path): """ Try to find possible sub-modules under path. A dictionary will be returned with modules names as keys and the modules objects as values. """ sys.path.append(path) folders = os.listdir(path) modules = {} for f in folders: if exists(join(path, f, '__init__.py')): try: m = __import__(f) modules[f] = m checkPlugin(m) except Exception as ex: print(">>> Error loading module: '%s'" % f) print(">>> Exception: ", ex) import traceback traceback.print_exc() return modules
[docs]def getSubclassesFromModules(BaseClass, modules, debug=False): """ Find subclasses of BaseClass from a give dict of modules. """ subclasses = {} for m in modules.values(): if debug: print("loading module: ", m.__name__) subDict = getSubclasses(BaseClass, m.__dict__) for subclass in subDict.values(): # some protocols have pyworkflow.em.packages. in the __module__ and other no moduleName = subclass.__module__.replace('pwem.packages.', '') if moduleName.startswith(m.__name__): subclass._package = m if debug: print(" found: ", subclass.__name__, "module: ", subclass.__module__) subclasses.update(subDict) return subclasses
[docs]def getSubclassesFromPath(BaseClass, path): """ Try to find possible sub-packages under path and find subclasses of BaseClass from them Return a dictionary containing the subclasses. """ modules = getModules(path) return getSubclassesFromModules(BaseClass, modules)
[docs]def getSubclasses(BaseClass, inputDict): """ Iterate over inputDict and find all subclasses of BaseClass, that will be set in outputDict. """ outputDict = {} for k, v in inputDict.items(): # Do not add the base class that is imported in all modules if (not v==BaseClass) and isclass(v) and issubclass(v, BaseClass): outputDict[k] = v return outputDict
[docs]def checkPlugin(module): if not getattr(module, '_plugin', None): print('WARNING: module "%s" using old package structure, ' '_plugin attribute missing' % module.__name__)
[docs]def isSameFunction(function1, function2): """ Check if the content of 2 functions is the same. This could be used to check if a method has been overridden or not From https://stackoverflow.com/questions/13620542/detecting-empty-function-definitions-in-python""" return function1.__code__.co_code == function2.__code__.co_code
[docs]def isModuleAFolder(modulename): """ Returns True if a python module is a folder""" # So far e can test for the filename module = sys.modules[modulename] return module.__file__.endswith("__init__.py")
[docs]def isModuleLoaded(modulename): """ Return True if a python module is loaded, False otherwise """ return modulename in sys.modules