提交 574d0203 authored 作者: notoraptor's avatar notoraptor

Address @nouiz 's comments.

上级 3654195c
......@@ -238,7 +238,7 @@ class ParamsType(Type):
self.length = len(kwargs)
self.fields = tuple(sorted(kwargs.keys()))
self.types = tuple(kwargs[field] for field in self.fields)
self.name = self.__generate_struct_name()
self.name = self.generate_struct_name()
self.__const_to_enum = {}
self.__alias_to_enum = {}
......@@ -246,10 +246,15 @@ class ParamsType(Type):
if enum_types:
# We don't want same enum names in different enum types.
if sum(len(t) for t in enum_types) != len(set(k for t in enum_types for k in t)):
raise AttributeError('ParamsType: found different enum types with common constant names.')
raise AttributeError('ParamsType: found different enum types with common constants names.')
# We don't want same aliases in different enum types.
if sum(len(t.aliases) for t in enum_types) != len(set(alias for t in enum_types for alias in t.aliases)):
raise AttributeError('ParamsType: found different enum types with common constant aliases.')
raise AttributeError('ParamsType: found different enum types with common constants aliases.')
# We don't want aliases that have same names as some constants.
all_enums = {e for t in enum_types for e in t}
all_aliases = {a for t in enum_types for a in t.aliases}
if [a for a in all_aliases if a in all_enums]:
raise AttributeError('ParamsType: found aliases that have same names as constants.')
# We map each enum name to the enum type in which it is defined.
# We will then use this dict to find enum value when looking for enum name in Wrapper object directly.
self.__const_to_enum = {enum_name: enum_type for enum_type in enum_types for enum_name in enum_type}
......@@ -270,7 +275,7 @@ class ParamsType(Type):
def __hash__(self):
return hash((type(self),) + self.fields + self.types)
def __generate_struct_name(self):
def generate_struct_name(self):
# This method tries to generate an unique name for the current instance.
# This name is intended to be used as struct name in C code and as constant
# definition to check if a similar ParamsType has already been created
......@@ -396,7 +401,7 @@ class ParamsType(Type):
value_for_c = False
# Value for c can't be retrieved from o, so we add a value for that field in kwargs.
params1 = params_type.get_params(o, c=value_for_c)
params = params_type.get_params(o, c=value_for_c)
# params.a contains 10
# params.b contains [[1, 2, 3], [4, 5, 6]]
# params.c contains value_for_c
......@@ -519,7 +524,6 @@ class ParamsType(Type):
struct_name = self.name
struct_name_defined = struct_name.upper()
c_support_code_set = set()
c_support_code_list = []
c_declare_list = []
c_init_list = []
c_cleanup_list = []
......@@ -527,10 +531,7 @@ class ParamsType(Type):
for attribute_name, type_instance in zip(self.fields, self.types):
try:
c_support_code_current = type_instance.c_support_code()
if c_support_code_current not in c_support_code_set:
c_support_code_list.append(c_support_code_current)
c_support_code_set.add(c_support_code_current)
c_support_code_set.add(type_instance.c_support_code())
except MethodNotDefined:
pass
......@@ -549,7 +550,7 @@ class ParamsType(Type):
'extract_code': type_instance.c_extract(attribute_name, sub)
})
support_code = '\n'.join(c_support_code_list)
support_code = '\n'.join(sorted(list(c_support_code_set)))
struct_declare = '\n'.join(c_declare_list)
struct_init = '\n'.join(c_init_list)
struct_cleanup = '\n'.join(c_cleanup_list)
......
......@@ -214,14 +214,22 @@ class TestParamsType(TestCase):
assert w.values_eq_approx(o1, o3)
def test_params_type_with_enums(self):
# Test that we fail if we create a wrapper with common enum names inside different enum types.
# Test that we fail if we create a params type with common enum names inside different enum types.
try:
w = ParamsType(enum1=EnumList('A', 'B', 'C'), enum2=EnumList('A', 'B', 'F'))
ParamsType(enum1=EnumList('A', 'B', 'C'), enum2=EnumList('A', 'B', 'F'))
except AttributeError:
pass
else:
raise Exception('ParamsType should fail with common enum names inside different enum types.')
# Test that we fail if we create a params type with common names in both aliases and constants.
try:
ParamsType(enum1=EnumList(('A', 'a'), ('B', 'b')), enum2=EnumList(('ONE', 'a'), ('TWO', 'two')))
except AttributeError:
ParamsType(enum1=EnumList(('A', 'a'), ('B', 'b')), enum2=EnumList(('ONE', 'one'), ('TWO', 'two')))
else:
raise Exception('ParamsType should fail when there are aliases with same names as some constants.')
# Test that we can access enum values through wrapper directly.
w = ParamsType(enum1=EnumList('A', ('B', 'beta'), 'C'), enum2=EnumList(('D', 'delta'), 'E', 'F'))
assert w.A == 0 and w.B == 1 and w.C == 2
......
......@@ -228,6 +228,14 @@ class TestEnumTypes(TestCase):
assert e1.filter('beta') == e1.fromalias('beta') == e1.B == 1
assert e1.filter('C') == e1.fromalias('C') == e1.C == 2
# Check that invalid alias (same as a constant) raises exception.
try:
EnumList(('A', 'a'), ('B', 'B'))
except TypeError:
EnumList(('A', 'a'), ('B', 'b'))
else:
raise Exception('Enum with an alias name equal to a constant name should fail.')
def test_op_with_enumlist(self):
a = scalar.int32()
b = scalar.int32()
......
......@@ -925,6 +925,9 @@ class EnumType(Type, dict):
if not isinstance(alias, str):
raise TypeError('%s: constant alias should be a string, got "%s".'
% (type(self).__name__, alias))
if alias == k:
raise TypeError("%s: it's useless to create an alias "
"with the same name as its associated constant." % type(self).__name__)
if alias in self.aliases:
raise TypeError('%s: consant alias "%s" already used.' % (type(self).__name__, alias))
self.aliases[alias] = k
......@@ -934,6 +937,8 @@ class EnumType(Type, dict):
elif not isinstance(kwargs[k], (int, float)):
raise TypeError('%s: constant "%s": expected integer or floating value, got "%s".'
% (type(self).__name__, k, type(kwargs[k]).__name__))
if [a for a in self.aliases if a in self]:
raise TypeError("%s: some aliases have same names as constants." % type(self).__name__)
super(EnumType, self).__init__(**kwargs)
def fromalias(self, alias):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论