Skip to content

Commit

Permalink
Be selective with the algorithms that are loaded by Python. Refs #4399
Browse files Browse the repository at this point in the history
  • Loading branch information
martyngigg committed Apr 17, 2012
1 parent 5846a2a commit 50b88ec
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 7 deletions.
7 changes: 5 additions & 2 deletions Code/Mantid/Framework/PythonAPI/MantidFramework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@ def _process_file(file_path, modname):
os.path.getmtime(compiled) >= os.path.getmtime(original):
return
try:
if self._containsPyAlgorithm(original):
if self._containsOldAPIAlgorithm(original):
# Temporarily insert into path
sys.path.insert(0, file_path)
if modname in sys.modules:
Expand All @@ -1484,7 +1484,7 @@ def _process_file(file_path, modname):

return changes

def _containsPyAlgorithm(self, modfilename):
def _containsOldAPIAlgorithm(self, modfilename):
file = open(modfilename,'r')
line_count = 0
alg_found = False
Expand All @@ -1494,6 +1494,9 @@ def _containsPyAlgorithm(self, modfilename):
if line == '':
alg_found = False
break
if 'mantid' in line and 'mantidsimple' not in line:
alg_found = False
break
if line.rfind('PythonAlgorithm') >= 0:
alg_found = True
break
Expand Down
3 changes: 1 addition & 2 deletions Code/Mantid/Framework/PythonInterface/mantid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def apiVersion():

_simpleapi.mockout_api()
if 'MantidFramework' not in _sys.modules: # Just while the other API is still around
#loaded = _plugins.load(config['pythonalgorithms.directories'])
_plugins.load(config['pythonalgorithms.directories'])
# Now everything is loaded create the proper definitions
_simpleapi.translate()

36 changes: 33 additions & 3 deletions Code/Mantid/Framework/PythonInterface/mantid/kernel/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ def load(path):
loaded = {}
if _os.path.isfile(path) and path.endswith('.py'): # Single file
try:
name, module = load_plugin(path)
loaded[name] = module
if contains_newapi_algorithm(path):
name, module = load_plugin(path)
loaded[name] = module
except Exception, exc:
logger.warning("Failed to load plugin %s. Error: %s" % (path, str(exc)))
elif _os.path.isdir(path): # Directory
Expand Down Expand Up @@ -87,10 +88,39 @@ def load_plugin(plugin_path):
Load a plugin and return the name & module object
@param plugin_path :: A path that must should point
to a .py file that will be loaded. An ValueError is raised if
to a .py file that will be loaded. A ValueError is raised if
path is not a valid plugin path. Any exceptions raised by the
import are passed to the caller
"""
loader = PluginLoader(plugin_path)
module = loader.run()
return module.__name__, module

def contains_newapi_algorithm(filename):
"""
Inspects the given file to check whether
it contains an algorithm written with this API.
The check is simple. If either the import
MantidFramework or mantidsimple are discovered then
it will not be considered a new API algorithm
@param filename :: A full file path pointing to a python file
@returns True if a python algorithm written with the new API
has been found.
"""
maxlines_to_check = 25
file = open(filename,'r')
line_count = 0
alg_found = True
while line_count < maxlines_to_check:
line = file.readline()
# EOF
if line == '':
alg_found = True
break
if 'MantidFramework' in line or 'mantidsimple' in line:
alg_found = False
break
line_count += 1
file.close()
return alg_found
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""A test for the simple API dedicated to Python algorithms. Checks
things like sub-algorithm calls
"""
import unittest
import inspect
import os
import shutil


#import mantid.simpleapi as simpleapi


class PythonAlgorithmSubAlgCallTest(unittest.TestCase):

_testdir = os.path.join(os.getcwd(), 'PythonAlgorithmSimpleAPITest_TmpDir')
_parentalg = None
_childalg = None

def test_subalg_call_of_one_python_call_from_other_suceeds(self):


def setUp(self):
__PARENTALG__ = \
"""from mantid import PythonAlgorithm, registerAlgorithm
class ParentAlgorithm(PythonAlgorithm):
def PyInit(self):
pass
def PyExec(self):
ChildAlgorithm() # If not setup correct this will raise a RuntimeError
registerAlgorithm(ParentAlgorithm)
"""

__CHILDALG__ = \
"""from mantid import PythonAlgorithm, registerAlgorithm
class ChildAlgorithm(PythonAlgorithm):
def PyInit(self):
pass
def PyExec(self):
pass
registerAlgorithm(ChildAlgorithm)
"""
try:
os.mkdir(self._testdir)
except OSError:
pass # Already exists, maybe it was not removed when a test failed?
_parentalg = os.path.join(self._testdir, 'ParentAlgorithm.py')
if not os.path.exists(_parentalg):
plugin = file(_parentalg, 'w')
plugin.write(__PARENTALG__)
plugin.close()
_childalg = os.path.join(self._testdir, 'ChildAlgorithm.py')
if not os.path.exists(_parentalg):
plugin = file(_parentalg, 'w')
plugin.write(__CHILDALG__)
plugin.close()

__import__


def tearDown(self):
try:
shutil.rmtree(self._testdir)
except shutil.Error:
pass

if __name__ == '__main__':
unittest.main()

0 comments on commit 50b88ec

Please sign in to comment.