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 {0} cannot be called on receiver {1}'.format(
method, this)) 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) *args, **kwargs)
if context[constants.CTX_ACTIONS_ONLY] and not method.is_action: 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 context_manager
from murano.dsl import dsl from murano.dsl import dsl
from murano.dsl import dsl_exception from murano.dsl import dsl_exception
from murano.dsl import dsl_types
from murano.dsl import executor from murano.dsl import executor
from murano.dsl import helpers from murano.dsl import helpers
from murano.dsl import murano_object from murano.dsl import murano_object
@ -49,22 +50,27 @@ class Runner(object):
class DslObjectWrapper(object): class DslObjectWrapper(object):
def __init__(self, obj, runner): def __init__(self, obj, runner):
self._runner = runner self._runner = runner
if isinstance(obj, six.string_types): if isinstance(obj, six.string_types + (dsl_types.MuranoType,)):
self._object_id = obj pass
elif isinstance(obj, (object_model.Object, object_model.Ref)): elif isinstance(obj, (object_model.Object, object_model.Ref)):
self._object_id = obj.id obj = obj.id
elif isinstance(obj, murano_object.MuranoObject): elif isinstance(obj, murano_object.MuranoObject):
self._object_id = obj.object_id obj = obj.object_id
else: else:
raise ValueError( raise ValueError(
'obj must be object ID string, MuranoObject or one of ' 'obj must be object ID string, MuranoObject, MuranoType '
'object_model helper classes (Object, Ref)') '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 self._preserve_exception = False
def __getattr__(self, item): def __getattr__(self, item):
def call(*args, **kwargs): def call(*args, **kwargs):
return self._runner._execute( return self._runner._execute(
item, self._object_id, *args, **kwargs) item, self._receiver, *args, **kwargs)
if item.startswith('test'): if item.startswith('test'):
return call return call
@ -80,8 +86,7 @@ class Runner(object):
execution_session.ExecutionSession()) execution_session.ExecutionSession())
self._root = self.executor.load(model).object self._root = self.executor.load(model).object
def _execute(self, name, object_id, *args, **kwargs): def _execute(self, name, obj, *args, **kwargs):
obj = self.executor.object_store.get(object_id)
try: try:
final_args = [] final_args = []
final_kwargs = {} final_kwargs = {}
@ -93,9 +98,10 @@ class Runner(object):
if isinstance(arg, object_model.Object): if isinstance(arg, object_model.Object):
arg = object_model.build_model(arg) arg = object_model.build_model(arg)
final_kwargs[name] = 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) 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), name, self.executor, obj, tuple(final_args), final_kwargs),
yaql_engine) yaql_engine)
except dsl_exception.MuranoPlException as e: except dsl_exception.MuranoPlException as e:
@ -118,6 +124,12 @@ class Runner(object):
def on(self, obj): def on(self, obj):
return Runner.DslObjectWrapper(obj, self) 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 @property
def root(self): def root(self):
return self._root 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( for name, method in six.iteritems(data.get('Methods') or data.get(
'Workflow') or {}): 'Workflow') or {}):
if name.startswith('test'): if name.startswith('test'):
method['Usage'] = 'Action' method['Scope'] = 'Public'
ns = namespace_resolver.NamespaceResolver(last_ns) ns = namespace_resolver.NamespaceResolver(last_ns)
class_name = ns.resolve_name(data['Name']) class_name = ns.resolve_name(data['Name'])

View File

@ -235,3 +235,8 @@ Methods:
- :TestStatics.classmethodPythonMethod('!') - :TestStatics.classmethodPythonMethod('!')
- ns:TestStatics.classmethodPythonMethod('!') - ns:TestStatics.classmethodPythonMethod('!')
- type('test.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( self.assertRaises(
yaql_exceptions.NoMatchingMethodException, yaql_exceptions.NoMatchingMethodException,
self._runner.testCallStaticMethodOnInvalidClass) self._runner.testCallStaticMethodOnInvalidClass)
def test_static_method_callable_from_python(self):
self.assertEqual(
'It works!',
self._runner.on_class('test.TestStatics').testStaticAction())