Commit 1db711fe authored by qsr's avatar qsr Committed by Commit bot

mojo: Specialize native type arrays.

R=sdefresne@chromium.org,cmasone@chromium.org

Review URL: https://codereview.chromium.org/548343005

Cr-Commit-Position: refs/heads/master@{#294354}
parent 28281325
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
The descriptors used to define generated elements of the mojo python bindings. The descriptors used to define generated elements of the mojo python bindings.
""" """
import array
# pylint: disable=F0401 # pylint: disable=F0401
from mojo.system import Handle from mojo.system import Handle
...@@ -59,12 +61,12 @@ class IntegerType(NumericType): ...@@ -59,12 +61,12 @@ class IntegerType(NumericType):
def Convert(self, value): def Convert(self, value):
if value is None: if value is None:
raise ValueError('None is not an integer.') raise TypeError('None is not an integer.')
if not isinstance(value, (int, long)): if not isinstance(value, (int, long)):
raise ValueError('%r is not an integer type' % value) raise TypeError('%r is not an integer type' % value)
if value < self._min_value or value > self._max_value: if value < self._min_value or value > self._max_value:
raise ValueError('%r is not in the range [%d, %d]' % raise OverflowError('%r is not in the range [%d, %d]' %
(value, self._min_value, self._max_value)) (value, self._min_value, self._max_value))
return value return value
...@@ -77,9 +79,9 @@ class FloatType(NumericType): ...@@ -77,9 +79,9 @@ class FloatType(NumericType):
def Convert(self, value): def Convert(self, value):
if value is None: if value is None:
raise ValueError('None is not an floating point number.') raise TypeError('None is not an floating point number.')
if not isinstance(value, (int, long, float)): if not isinstance(value, (int, long, float)):
raise ValueError('%r is not a numeric type' % value) raise TypeError('%r is not a numeric type' % value)
return float(value) return float(value)
...@@ -100,7 +102,7 @@ class StringType(Type): ...@@ -100,7 +102,7 @@ class StringType(Type):
return value return value
if isinstance(value, str): if isinstance(value, str):
return unicode(value) return unicode(value)
raise ValueError('%r is not a string' % value) raise TypeError('%r is not a string' % value)
class HandleType(Type): class HandleType(Type):
...@@ -114,25 +116,47 @@ class HandleType(Type): ...@@ -114,25 +116,47 @@ class HandleType(Type):
if value is None: if value is None:
return Handle() return Handle()
if not isinstance(value, Handle): if not isinstance(value, Handle):
raise ValueError('%r is not a handle' % value) raise TypeError('%r is not a handle' % value)
return value return value
class ArrayType(Type): class GenericArrayType(Type):
"""Type object for arrays.""" """Abstract Type object for arrays."""
def __init__(self, sub_type, nullable=False, length=0): def __init__(self, nullable=False, length=0):
Type.__init__(self) Type.__init__(self)
self.sub_type = sub_type
self.nullable = nullable self.nullable = nullable
self.length = length self.length = length
class PointerArrayType(GenericArrayType):
"""Type object for arrays of pointers."""
def __init__(self, sub_type, nullable=False, length=0):
GenericArrayType.__init__(self, nullable, length)
self.sub_type = sub_type
def Convert(self, value): def Convert(self, value):
if value is None: if value is None:
return value return value
return [self.sub_type.Convert(x) for x in value] return [self.sub_type.Convert(x) for x in value]
class NativeArrayType(GenericArrayType):
"""Type object for arrays of native types."""
def __init__(self, typecode, nullable=False, length=0):
GenericArrayType.__init__(self, nullable, length)
self.typecode = typecode
def Convert(self, value):
if value is None:
return value
if isinstance(value, array.array) and value.typecode == self.typecode:
return value
return array.array(self.typecode, value)
class StructType(Type): class StructType(Type):
"""Type object for structs.""" """Type object for structs."""
...@@ -144,7 +168,7 @@ class StructType(Type): ...@@ -144,7 +168,7 @@ class StructType(Type):
def Convert(self, value): def Convert(self, value):
if value is None or isinstance(value, self.struct_type): if value is None or isinstance(value, self.struct_type):
return value return value
raise ValueError('%r is not an instance of %r' % (value, self.struct_type)) raise TypeError('%r is not an instance of %r' % (value, self.struct_type))
def GetDefaultValue(self, value): def GetDefaultValue(self, value):
if value: if value:
......
...@@ -37,6 +37,20 @@ _kind_to_type = { ...@@ -37,6 +37,20 @@ _kind_to_type = {
mojom.NULLABLE_SHAREDBUFFER: "_descriptor.TYPE_NULLABLE_HANDLE", mojom.NULLABLE_SHAREDBUFFER: "_descriptor.TYPE_NULLABLE_HANDLE",
} }
# int64 integers are not handled by array.array. int64/uint64 array are
# supported but storage is not optimized (ie. they are plain python list, not
# array.array)
_kind_to_typecode = {
mojom.INT8: "'b'",
mojom.UINT8: "'B'",
mojom.INT16: "'h'",
mojom.UINT16: "'H'",
mojom.INT32: "'i'",
mojom.UINT32: "'I'",
mojom.FLOAT: "'f'",
mojom.DOUBLE: "'d'",
}
def NameToComponent(name): def NameToComponent(name):
# insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar ->
...@@ -99,12 +113,18 @@ def GetStructClass(kind): ...@@ -99,12 +113,18 @@ def GetStructClass(kind):
def GetFieldType(kind, field=None): def GetFieldType(kind, field=None):
if mojom.IsAnyArrayKind(kind): if mojom.IsAnyArrayKind(kind):
arguments = [ GetFieldType(kind.kind) ] if kind.kind in _kind_to_typecode:
arguments = [ _kind_to_typecode[kind.kind] ]
else:
arguments = [ GetFieldType(kind.kind) ]
if mojom.IsNullableKind(kind): if mojom.IsNullableKind(kind):
arguments.append("nullable=True") arguments.append("nullable=True")
if mojom.IsFixedArrayKind(kind): if mojom.IsFixedArrayKind(kind):
arguments.append("length=%d" % kind.length) arguments.append("length=%d" % kind.length)
return "_descriptor.ArrayType(%s)" % ", ".join(arguments) if kind.kind in _kind_to_typecode:
return "_descriptor.NativeArrayType(%s)" % ", ".join(arguments)
else:
return "_descriptor.PointerArrayType(%s)" % ", ".join(arguments)
if mojom.IsStructKind(kind): if mojom.IsStructKind(kind):
arguments = [ GetStructClass(kind) ] arguments = [ GetStructClass(kind) ]
......
...@@ -84,13 +84,13 @@ class StructBindingsTest(unittest.TestCase): ...@@ -84,13 +84,13 @@ class StructBindingsTest(unittest.TestCase):
max_value = (1 << bits) - 1 max_value = (1 << bits) - 1
entity.__setattr__(field_name, min_value) entity.__setattr__(field_name, min_value)
entity.__setattr__(field_name, max_value) entity.__setattr__(field_name, max_value)
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
entity.__setattr__(field_name, None) entity.__setattr__(field_name, None)
with self.assertRaises(ValueError): with self.assertRaises(OverflowError):
entity.__setattr__(field_name, min_value - 1) entity.__setattr__(field_name, min_value - 1)
with self.assertRaises(ValueError): with self.assertRaises(OverflowError):
entity.__setattr__(field_name, max_value + 1) entity.__setattr__(field_name, max_value + 1)
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
entity.__setattr__(field_name, 'hello world') entity.__setattr__(field_name, 'hello world')
def testTypes(self): def testTypes(self):
...@@ -120,9 +120,9 @@ class StructBindingsTest(unittest.TestCase): ...@@ -120,9 +120,9 @@ class StructBindingsTest(unittest.TestCase):
self.assertEquals(defaults_test.a12, True) self.assertEquals(defaults_test.a12, True)
# Floating point types # Floating point types
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a13 = 'hello' defaults_test.a13 = 'hello'
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a14 = 'hello' defaults_test.a14 = 'hello'
# Array type # Array type
...@@ -131,39 +131,39 @@ class StructBindingsTest(unittest.TestCase): ...@@ -131,39 +131,39 @@ class StructBindingsTest(unittest.TestCase):
defaults_test.a18 = [ 0 ] defaults_test.a18 = [ 0 ]
defaults_test.a18 = [ 255 ] defaults_test.a18 = [ 255 ]
defaults_test.a18 = [ 0, 255 ] defaults_test.a18 = [ 0, 255 ]
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a18 = [[]] defaults_test.a18 = [[]]
with self.assertRaises(ValueError): with self.assertRaises(OverflowError):
defaults_test.a18 = [ -1 ] defaults_test.a18 = [ -1 ]
with self.assertRaises(ValueError): with self.assertRaises(OverflowError):
defaults_test.a18 = [ 256 ] defaults_test.a18 = [ 256 ]
# String type # String type
defaults_test.a19 = None defaults_test.a19 = None
defaults_test.a19 = '' defaults_test.a19 = ''
defaults_test.a19 = 'hello world' defaults_test.a19 = 'hello world'
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a19 = [[]] defaults_test.a19 = [[]]
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a19 = [ -1 ] defaults_test.a19 = [ -1 ]
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a19 = [ 256 ] defaults_test.a19 = [ 256 ]
# Structs # Structs
defaults_test.a21 = None defaults_test.a21 = None
defaults_test.a21 = sample_import_mojom.Point() defaults_test.a21 = sample_import_mojom.Point()
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a21 = 1 defaults_test.a21 = 1
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
defaults_test.a21 = sample_import2_mojom.Thing() defaults_test.a21 = sample_import2_mojom.Thing()
# Handles # Handles
foo_instance = sample_service_mojom.Foo() foo_instance = sample_service_mojom.Foo()
foo_instance.source = None foo_instance.source = None
foo_instance.source = mojo.system.Handle() foo_instance.source = mojo.system.Handle()
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
foo_instance.source = 1 foo_instance.source = 1
with self.assertRaises(ValueError): with self.assertRaises(TypeError):
foo_instance.source = object() foo_instance.source = object()
def testConstructor(self): def testConstructor(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment