Namespace resolution error was fixed

For method invocation context of a sender object was used.
Then the current type was taken from it and class names were
resolved using namespaces of that class. However in situations
when contracted method was located in parent class that had
different namespace declarations it lead to a wrong namespaces
being used.

This commit adds information on which class has the contract
so that the sender could be upcasted to it first.

Change-Id: Ieb4fca4ea7f2c64c7a731b81fee2ccaff1b1a531
Closes-Bug: #1489524
This commit is contained in:
Stan Lagun 2015-08-27 18:58:34 +03:00
parent 14bc93d1f9
commit 864aa3da57
5 changed files with 14 additions and 9 deletions

View File

@ -71,7 +71,7 @@ class MuranoClassLoader(object):
properties = data.get('Properties') or {}
for property_name, property_spec in properties.iteritems():
spec = typespec.PropertySpec(property_spec)
spec = typespec.PropertySpec(property_spec, type_obj)
type_obj.add_property(property_name, spec)
methods = data.get('Methods') or data.get('Workflow') or {}

View File

@ -68,7 +68,7 @@ class MuranoMethod(dsl_types.MuranoMethod):
raise ValueError()
name = record.keys()[0]
self._arguments_scheme[name] = typespec.ArgumentSpec(
record[name])
record[name], self.murano_class)
self._yaql_function_definition = \
yaql_integration.build_wrapper_function_definition(self)

View File

@ -26,7 +26,7 @@ class MuranoObject(dsl_types.MuranoObject):
name=None, known_classes=None, defaults=None, this=None):
if known_classes is None:
known_classes = {}
self.__owner = owner
self.__owner = owner.real_this if owner else None
self.__object_id = object_id or helpers.generate_id()
self.__type = murano_class
self.__properties = {}
@ -222,7 +222,7 @@ class MuranoObject(dsl_types.MuranoObject):
obj = self.cast(mc)
values_to_assign.append((obj, spec.validate(
value, context or self.context, self.real_this,
value, self.real_this,
self.real_this, default=default)))
for obj, value in values_to_assign:
obj.__properties[name] = value
@ -240,7 +240,7 @@ class MuranoObject(dsl_types.MuranoObject):
return parent.cast(type)
except TypeError:
continue
raise TypeError('Cannot cast')
raise TypeError('Cannot cast {0} to {1}'.format(self, type))
def __repr__(self):
return '<{0} {1} ({2})>'.format(

View File

@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import weakref
from murano.dsl import exceptions
from murano.dsl import type_scheme
@ -28,7 +30,8 @@ class PropertyUsages(object):
class Spec(object):
def __init__(self, declaration):
def __init__(self, declaration, container_class):
self._container_class = weakref.ref(container_class)
self._contract = type_scheme.TypeScheme(declaration['Contract'])
self._usage = declaration.get('Usage') or 'In'
self._default = declaration.get('Default')
@ -38,10 +41,12 @@ class Spec(object):
'Unknown type {0}. Must be one of ({1})'.format(
self._usage, ', '.join(PropertyUsages.All)))
def validate(self, value, context, this, owner, default=None):
def validate(self, value, this, owner, default=None):
if default is None:
default = self.default
return self._contract(value, context, this, owner, default)
return self._contract(
value, this.cast(self._container_class()).context,
this, owner, default)
@property
def default(self):

View File

@ -61,7 +61,7 @@ class ContractedValue(yaqltypes.GenericType):
True, None,
lambda value, sender, context, *args, **kwargs:
self._value_spec.validate(
value, sender.context, helpers.get_this(context),
value, sender.real_this,
context[constants.CTX_ARGUMENT_OWNER]))
def convert(self, value, *args, **kwargs):