def translate(): """ Loop through the algorithms and register a function call for each of them @returns a list of new function calls """ from api import AlgorithmFactory, AlgorithmManager new_functions = [] algs = AlgorithmFactory.getRegisteredAlgorithms(True) algorithm_mgr = AlgorithmManager for name, versions in algs.iteritems(): if specialization_exists(name): continue try: # Create the algorithm object _algm_object = algorithm_mgr.createUnmanaged(name, max(versions)) _algm_object.initialize() except Exception: continue create_algorithm(name, max(versions), _algm_object) create_algorithm_dialog(name, max(versions), _algm_object) new_functions.append(name) return new_functions
def _mockup(plugins): """ Creates fake, error-raising functions for all loaded algorithms plus any plugins given. The function name for the Python algorithms are taken from the filename so this mechanism requires the algorithm name to match the filename. This mechanism solves the "chicken-and-egg" problem with Python algorithms trying to use other Python algorithms through the simple API functions. The issue occurs when a python algorithm tries to import the simple API function of another Python algorithm that has not been loaded yet, usually when it is further along in the alphabet. The first algorithm stops with an import error as that function is not yet known. By having a pre-loading step all of the necessary functions on this module can be created and after the plugins are loaded the correct function definitions can overwrite the "fake" ones. :param plugins: A list of modules that have been loaded """ #-------------------------------------------------------------------------------------------------------- def create_fake_function(name): """Create fake functions for the given name """ #------------------------------------------------------------------------------------------------ def fake_function(*args, **kwargs): raise RuntimeError("Mantid import error. The mock simple API functions have not been replaced!" + " This is an error in the core setup logic of the mantid module, please contact the development team.") #------------------------------------------------------------------------------------------------ if "." in name: name = name.rstrip('.py') if specialization_exists(name): return fake_function.__name__ = name f = fake_function.func_code c = f.__new__(f.__class__, f.co_argcount, f.co_nlocals, f.co_stacksize, f.co_flags, f.co_code, f.co_consts, f.co_names,\ ("", ""), f.co_filename, f.co_name, f.co_firstlineno, f.co_lnotab, f.co_freevars) # Replace the code object of the wrapper function fake_function.func_code = c globals()[name] = fake_function #-------------------------------------------------------- def create_fake_functions(alg_names): """Create fake functions for all of the listed names """ for alg_name in alg_names: create_fake_function(alg_name) #------------------------------------- # Start with the loaded C++ algorithms from api import AlgorithmFactory import os cppalgs = AlgorithmFactory.getRegisteredAlgorithms(True) create_fake_functions(cppalgs.keys()) # Now the plugins for plugin in plugins: name = os.path.basename(plugin) name = os.path.splitext(name)[0] create_fake_function(name)
def _translate(): """ Loop through the algorithms and register a function call for each of them :returns: a list of new function calls """ from api import AlgorithmFactory, AlgorithmManager new_functions = [] # Names of new functions added to the global namespace new_methods = {} # Method names mapped to their algorithm names. Used to detect multiple copies of same method name # on different algorithms, which is an error algs = AlgorithmFactory.getRegisteredAlgorithms(True) algorithm_mgr = AlgorithmManager for name, versions in algs.iteritems(): if specialization_exists(name): continue try: # Create the algorithm object algm_object = algorithm_mgr.createUnmanaged(name, max(versions)) algm_object.initialize() except Exception: continue algorithm_wrapper = _create_algorithm_function(name, max(versions), algm_object) method_name = algm_object.workspaceMethodName() if len(method_name) > 0: if method_name in new_methods: other_alg = new_methods[method_name] raise RuntimeError("simpleapi: Trying to attach '%s' as method to point to '%s' algorithm but " "it has already been attached to point to the '%s' algorithm.\n" "Does one inherit from the other? " "Please check and update one of the algorithms accordingly." % (method_name,algm_object.name(),other_alg)) _attach_algorithm_func_as_method(method_name, algorithm_wrapper, algm_object) new_methods[method_name] = algm_object.name() # Dialog variant _create_algorithm_dialog(name, max(versions), algm_object) new_functions.append(name) return new_functions