Could not invoke static methods from Python

Static method were handled incorrectly when
called from Python because of incorrect
method receiver.

Change-Id: Id7ef2bc0c74154bd3ac6ef7dcf8fa807a4be757b
Closes-Bug: #1596613
This commit is contained in:
Stan Lagun 2016-06-27 09:46:10 -07:00
parent 0aed285de1
commit 75bded129e
5 changed files with 37 additions and 13 deletions

View File

@ -91,7 +91,9 @@ class MuranoDslExecutor(object):
'Method {0} cannot be called on receiver {1}'.format(
method, this))
return stub(yaql_engine, method_context, this.real_this)(
real_this = this.real_this if isinstance(
this, dsl_types.MuranoObject) else this.get_reference()
return stub(yaql_engine, method_context, real_this)(
*args, **kwargs)
if context[constants.CTX_ACTIONS_ONLY] and not method.is_action:

View File

@ -20,6 +20,7 @@ import six
from murano.dsl import context_manager
from murano.dsl import dsl
from murano.dsl import dsl_exception
from murano.dsl import dsl_types
from murano.dsl import executor
from murano.dsl import helpers
from murano.dsl import murano_object
@ -49,22 +50,27 @@ class Runner(object):
class DslObjectWrapper(object):
def __init__(self, obj, runner):
self._runner = runner
if isinstance(obj, six.string_types):
self._object_id = obj
if isinstance(obj, six.string_types + (dsl_types.MuranoType,)):
pass
elif isinstance(obj, (object_model.Object, object_model.Ref)):
self._object_id = obj.id
obj = obj.id
elif isinstance(obj, murano_object.MuranoObject):
self._object_id = obj.object_id
obj = obj.object_id
else:
raise ValueError(
'obj must be object ID string, MuranoObject or one of '
'object_model helper classes (Object, Ref)')
'obj must be object ID string, MuranoObject, MuranoType '
'or one of object_model helper classes (Object, Ref)')
if isinstance(obj, six.string_types):
self._receiver = runner.executor.object_store.get(obj)
else:
self._receiver = obj
self._preserve_exception = False
def __getattr__(self, item):
def call(*args, **kwargs):
return self._runner._execute(
item, self._object_id, *args, **kwargs)
item, self._receiver, *args, **kwargs)
if item.startswith('test'):
return call
@ -80,8 +86,7 @@ class Runner(object):
execution_session.ExecutionSession())
self._root = self.executor.load(model).object
def _execute(self, name, object_id, *args, **kwargs):
obj = self.executor.object_store.get(object_id)
def _execute(self, name, obj, *args, **kwargs):
try:
final_args = []
final_kwargs = {}
@ -93,9 +98,10 @@ class Runner(object):
if isinstance(arg, object_model.Object):
arg = object_model.build_model(arg)
final_kwargs[name] = arg
runtime_version = obj.type.package.runtime_version
cls = obj if isinstance(obj, dsl_types.MuranoType) else obj.type
runtime_version = cls.package.runtime_version
yaql_engine = yaql_integration.choose_yaql_engine(runtime_version)
return dsl.to_mutable(obj.type.invoke(
return dsl.to_mutable(cls.invoke(
name, self.executor, obj, tuple(final_args), final_kwargs),
yaql_engine)
except dsl_exception.MuranoPlException as e:
@ -118,6 +124,12 @@ class Runner(object):
def on(self, obj):
return Runner.DslObjectWrapper(obj, self)
def on_class(self, class_name):
cls = self.executor.package_loader.load_class_package(
class_name, helpers.parse_version_spec(None)).find_class(
class_name, False)
return Runner.DslObjectWrapper(cls, self)
@property
def root(self):
return self._root

View File

@ -100,7 +100,7 @@ class TestPackageLoader(package_loader.MuranoPackageLoader):
for name, method in six.iteritems(data.get('Methods') or data.get(
'Workflow') or {}):
if name.startswith('test'):
method['Usage'] = 'Action'
method['Scope'] = 'Public'
ns = namespace_resolver.NamespaceResolver(last_ns)
class_name = ns.resolve_name(data['Name'])

View File

@ -235,3 +235,8 @@ Methods:
- :TestStatics.classmethodPythonMethod('!')
- ns:TestStatics.classmethodPythonMethod('!')
- type('test.TestStatics').classmethodPythonMethod('!')
testStaticAction:
Usage: Static
Body:
Return: 'It works!'

View File

@ -143,3 +143,8 @@ class TestStatics(test_case.DslTestCase):
self.assertRaises(
yaql_exceptions.NoMatchingMethodException,
self._runner.testCallStaticMethodOnInvalidClass)
def test_static_method_callable_from_python(self):
self.assertEqual(
'It works!',
self._runner.on_class('test.TestStatics').testStaticAction())