summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJose <pepone@users.noreply.github.com>2019-07-16 12:50:50 +0200
committerGitHub <noreply@github.com>2019-07-16 12:50:50 +0200
commit470cf99349045183508050f1f49d4abe9e07f457 (patch)
treeca416155f464725f45cffacad5aae1ed63309309 /python
parentCreate install dir with MKDIR (diff)
downloadice-470cf99349045183508050f1f49d4abe9e07f457.tar.bz2
ice-470cf99349045183508050f1f49d4abe9e07f457.tar.xz
ice-470cf99349045183508050f1f49d4abe9e07f457.zip
Fixes for python custom sequence mapping (#444)
* Fixes for python mappings * Additional fixes for Python custom sequence mapping. * Fix CHANGELOG TOC
Diffstat (limited to 'python')
-rw-r--r--python/modules/IcePy/Types.cpp104
-rw-r--r--python/modules/IcePy/Types.h2
-rw-r--r--python/test/Ice/custom/AllTests.py207
-rwxr-xr-xpython/test/Ice/custom/Server.py6
-rw-r--r--python/test/Ice/custom/Test.ice14
-rw-r--r--python/test/Ice/custom/TestNumPy.ice13
6 files changed, 290 insertions, 56 deletions
diff --git a/python/modules/IcePy/Types.cpp b/python/modules/IcePy/Types.cpp
index 00b821099b6..21a9cd897db 100644
--- a/python/modules/IcePy/Types.cpp
+++ b/python/modules/IcePy/Types.cpp
@@ -42,6 +42,8 @@ static ExceptionInfoMap _exceptionInfoMap;
namespace
{
+const char* emptySeq = "";
+
//
// This exception is raised if the factory specified in a sequence metadata
// cannot be load or is not valid
@@ -281,9 +283,12 @@ bufferGetBuffer(BufferObject* self, Py_buffer* view, int flags)
PyErr_SetString(PyExc_BufferError, "fill buffer info failed");
return -1;
}
-
view->obj = reinterpret_cast<PyObject*>(self);
- Py_INCREF(view->obj);
+ //
+ // Don't nee to increase the view->obj ref count here
+ // PyBuffer_FillInfo already increases it.
+ //
+ //Py_INCREF(view->obj);
return 0;
}
@@ -2276,10 +2281,10 @@ IcePy::SequenceInfo::createSequenceFromMemory(const SequenceMappingPtr& sm,
const char* buffer,
Py_ssize_t size,
BuiltinType type,
- bool copy)
+ bool adopt)
{
PyObjectHandle memoryview;
- if(copy)
+ if(adopt && size > 0)
{
PyObjectHandle bufferObject = createBuffer(new Buffer(buffer, size, type));
if(!bufferObject.get())
@@ -2288,15 +2293,15 @@ IcePy::SequenceInfo::createSequenceFromMemory(const SequenceMappingPtr& sm,
throw AbortMarshaling();
}
memoryview = PyMemoryView_FromObject(bufferObject.get());
- Py_XDECREF(bufferObject.get());
}
else
{
+ char* buf = const_cast<char*>(size == 0 ? emptySeq : buffer);
#if PY_VERSION_HEX >= 0x03030000
- memoryview = PyMemoryView_FromMemory(const_cast<char*>(buffer), size, PyBUF_READ);
+ memoryview = PyMemoryView_FromMemory(buf, size, PyBUF_READ);
#else
Py_buffer pybuffer;
- if(PyBuffer_FillInfo(&pybuffer, 0, const_cast<char*>(buffer), size, 1, PyBUF_SIMPLE) != 0)
+ if(PyBuffer_FillInfo(&pybuffer, 0, buf, size, 1, PyBUF_SIMPLE) != 0)
{
assert(PyErr_Occurred());
throw AbortMarshaling();
@@ -2325,11 +2330,11 @@ IcePy::SequenceInfo::createSequenceFromMemory(const SequenceMappingPtr& sm,
PyTuple_SET_ITEM(args.get(), 0, incRef(memoryview.get()));
PyTuple_SET_ITEM(args.get(), 1, incRef(builtinType.get()));
//
- // If we copy the data to a Buffer object we set the copy factory argument to false
+ // If the Buffer object adopts the data we set the copy factory argument to false
// to avoid a second copy in the factory.
//
- PyTuple_SET_ITEM(args.get(), 2, copy ? incFalse() : incTrue());
- PyObjectHandle result = PyObject_Call(sm->factory.get(), args.get(), 0);
+ PyTuple_SET_ITEM(args.get(), 2, adopt ? incFalse() : incTrue());
+ PyObjectHandle result = PyObject_Call(sm->factory, args.get(), 0);
if(!result.get())
{
@@ -2359,13 +2364,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<bool> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz,
- BuiltinTypeBool,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz, BuiltinTypeBool, adopt);
}
else
{
@@ -2388,7 +2391,7 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
pair<const Ice::Byte*, const Ice::Byte*> p;
is->read(p);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
result = createSequenceFromMemory(sm, reinterpret_cast<const char*>(p.first), sz, BuiltinTypeByte, false);
}
@@ -2433,13 +2436,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<Ice::Short> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz * 2,
- BuiltinTypeShort,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz * 2, BuiltinTypeShort, adopt);
}
else
{
@@ -2469,13 +2470,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<Ice::Int> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz * 4,
- BuiltinTypeInt,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeInt, adopt);
}
else
{
@@ -2504,13 +2503,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<Ice::Long> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz * 8,
- BuiltinTypeLong,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeLong, adopt);
}
else
{
@@ -2540,13 +2537,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<Ice::Float> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz * 4,
- BuiltinTypeFloat,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz * 4, BuiltinTypeFloat, adopt);
}
else
{
@@ -2576,13 +2571,11 @@ IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, Ice:
IceUtil::ScopedArray<Ice::Double> arr;
is->read(p, arr);
int sz = static_cast<int>(p.second - p.first);
- if(sm->factory.get())
+ if(sm->factory)
{
- result = createSequenceFromMemory(sm,
- reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first),
- sz * 8,
- BuiltinTypeDouble,
- arr.get() != 0);
+ bool adopt = arr.get() != 0;
+ const char* data = reinterpret_cast<const char*>(arr.get() != 0 ? arr.release() : p.first);
+ result = createSequenceFromMemory(sm, data, sz * 8, BuiltinTypeDouble, adopt);
}
else
{
@@ -2678,11 +2671,13 @@ IcePy::SequenceInfo::SequenceMapping::getType(const Ice::StringSeq& metaData, Ty
}
IcePy::SequenceInfo::SequenceMapping::SequenceMapping(Type t) :
- type(t)
+ type(t),
+ factory(0)
{
}
-IcePy::SequenceInfo::SequenceMapping::SequenceMapping(const Ice::StringSeq& meta)
+IcePy::SequenceInfo::SequenceMapping::SequenceMapping(const Ice::StringSeq& meta) :
+ factory(0)
{
if(!getType(meta, type))
{
@@ -2696,7 +2691,7 @@ IcePy::SequenceInfo::SequenceMapping::init(const Ice::StringSeq& meta)
if(type == SEQ_ARRAY)
{
factory = lookupType("Ice.createArray");
- if(!factory.get())
+ if(!factory)
{
PyErr_Format(PyExc_ImportError, STRCAST("factory type not found `Ice.createArray'"));
throw InvalidSequenceFactoryException();
@@ -2705,7 +2700,7 @@ IcePy::SequenceInfo::SequenceMapping::init(const Ice::StringSeq& meta)
else if(type == SEQ_NUMPYARRAY)
{
factory = lookupType("Ice.createNumPyArray");
- if(!factory.get())
+ if(!factory)
{
PyErr_Format(PyExc_ImportError, STRCAST("factory type not found `Ice.createNumPyArray'"));
throw InvalidSequenceFactoryException();
@@ -2720,12 +2715,12 @@ IcePy::SequenceInfo::SequenceMapping::init(const Ice::StringSeq& meta)
{
const string typestr = i->substr(prefix.size());
factory = lookupType(typestr);
- if(!factory.get())
+ if(!factory)
{
PyErr_Format(PyExc_ImportError, STRCAST("factory type not found `%s'"), typestr.c_str());
throw InvalidSequenceFactoryException();
}
- if(!PyCallable_Check(factory.get()))
+ if(!PyCallable_Check(factory))
{
PyErr_Format(PyExc_RuntimeError, STRCAST("factory type `%s' is not callable"), typestr.c_str());
throw InvalidSequenceFactoryException();
@@ -2734,7 +2729,6 @@ IcePy::SequenceInfo::SequenceMapping::init(const Ice::StringSeq& meta)
}
}
}
- Py_XINCREF(factory.get());
}
void
@@ -2769,7 +2763,7 @@ IcePy::SequenceInfo::SequenceMapping::createContainer(int sz) const
{
//
// Must never be called for SEQ_MEMORYVIEW, as the container
- // is created by the use factory function.
+ // is created by the user factory function.
//
assert(false);
return 0;
diff --git a/python/modules/IcePy/Types.h b/python/modules/IcePy/Types.h
index fe82c9f4842..06d774eb615 100644
--- a/python/modules/IcePy/Types.h
+++ b/python/modules/IcePy/Types.h
@@ -359,7 +359,7 @@ private:
void setItem(PyObject*, int, PyObject*) const;
Type type;
- PyObjectHandle factory;
+ PyObject* factory;
};
typedef IceUtil::Handle<SequenceMapping> SequenceMappingPtr;
diff --git a/python/test/Ice/custom/AllTests.py b/python/test/Ice/custom/AllTests.py
index d0d7c73d220..7b0a634176c 100644
--- a/python/test/Ice/custom/AllTests.py
+++ b/python/test/Ice/custom/AllTests.py
@@ -125,6 +125,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opBoolSeq(array.array("b", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 127]
v1, v2 = custom.opByteSeq(array.array("b", v))
test(isinstance(v1, array.array))
@@ -135,6 +142,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opByteSeq(array.array("b", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 128, 256]
v1, v2 = custom.opShortSeq(array.array("h", v))
test(isinstance(v1, array.array))
@@ -145,6 +159,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opShortSeq(array.array("h", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 128, 256]
v1, v2 = custom.opIntSeq(array.array("i", v))
test(isinstance(v1, array.array))
@@ -155,6 +176,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opIntSeq(array.array("i", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
#
# The array "q" type specifier is new in Python 3.3
#
@@ -169,6 +197,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opLongSeq(array.array("q", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256]
v1, v2 = custom.opFloatSeq(array.array("f", v))
test(isinstance(v1, array.array))
@@ -179,6 +214,13 @@ def allTests(helper, communicator):
test(round(v1[i], 1) == round(v[i], 1))
test(round(v2[i], 1) == round(v[i], 1))
+ v = []
+ v1, v2 = custom.opFloatSeq(array.array("f", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256]
v1, v2 = custom.opDoubleSeq(array.array("d", v))
test(isinstance(v1, array.array))
@@ -189,6 +231,69 @@ def allTests(helper, communicator):
test(round(v1[i], 1) == round(v[i], 1))
test(round(v2[i], 1) == round(v[i], 1))
+ v = []
+ v1, v2 = custom.opDoubleSeq(array.array("d", v))
+ test(isinstance(v1, array.array))
+ test(isinstance(v2, array.array))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
+
+ d = Test.D()
+ d.boolSeq = array.array("b", [True, False, True, False, True])
+ d.byteSeq = array.array("b", [0, 2, 4, 8, 16, 32, 64, 127])
+ d.shortSeq = array.array("h", [0, 2, 4, 8, 16, 32, 64, 128, 256])
+ d.intSeq = array.array("i", [0, 2, 4, 8, 16, 32, 64, 128, 256])
+ #
+ # The array "q" type specifier is new in Python 3.3
+ #
+ if sys.version_info[:2] >= (3, 3):
+ d.longSeq = array.array("q", [0, 2, 4, 8, 16, 32, 64, 128, 256])
+ d.floatSeq = array.array("f", [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256])
+ d.doubleSeq = array.array("d", [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256])
+
+ d1 = custom.opD(d)
+ test(isinstance(d1.boolSeq, array.array))
+ test(len(d1.boolSeq) == len(d.boolSeq))
+ for i in range(len(d.boolSeq)):
+ test(d.boolSeq[i] == d1.boolSeq[i])
+
+ test(isinstance(d1.byteSeq, array.array))
+ test(len(d1.byteSeq) == len(d.byteSeq))
+ for i in range(len(d.byteSeq)):
+ test(d.byteSeq[i] == d1.byteSeq[i])
+
+ test(isinstance(d1.intSeq, array.array))
+ test(len(d1.intSeq) == len(d.intSeq))
+ for i in range(len(d.intSeq)):
+ test(d.intSeq[i] == d1.intSeq[i])
+
+ #
+ # The array "q" type specifier is new in Python 3.3
+ #
+ if sys.version_info[:2] >= (3, 3):
+ test(isinstance(d1.longSeq, array.array))
+ test(len(d1.longSeq) == len(d.longSeq))
+ for i in range(len(d.longSeq)):
+ test(d.longSeq[i] == d1.longSeq[i])
+
+ test(isinstance(d1.floatSeq, array.array))
+ test(len(d1.floatSeq) == len(d.floatSeq))
+ for i in range(len(d.floatSeq)):
+ test(round(d.floatSeq[i], 1) == round(d1.floatSeq[i], 1))
+
+ test(isinstance(d1.doubleSeq, array.array))
+ test(len(d1.doubleSeq) == len(d.doubleSeq))
+ for i in range(len(d.doubleSeq)):
+ test(round(d.doubleSeq[i], 1) == round(d1.doubleSeq[i], 1))
+
+ d1 = custom.opD(Test.D())
+ test(d1.boolSeq == Ice.Unset)
+ test(d1.byteSeq == Ice.Unset)
+ test(d1.intSeq == Ice.Unset)
+ test(d1.longSeq == Ice.Unset)
+ test(d1.floatSeq == Ice.Unset)
+ test(d1.doubleSeq == Ice.Unset)
#
# With python 3.3 we use the new buffer interface for marshaling
# sequences of types that implement the buffer protocol and this
@@ -290,6 +395,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opBoolSeq(numpy.array(v, numpy.bool_))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 127]
v1, v2 = custom.opByteSeq(numpy.array(v, numpy.int8))
test(isinstance(v1, numpy.ndarray))
@@ -300,6 +412,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opByteSeq(numpy.array(v, numpy.int8))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 128, 256]
v1, v2 = custom.opShortSeq(numpy.array(v, numpy.int16))
test(isinstance(v1, numpy.ndarray))
@@ -310,6 +429,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opShortSeq(numpy.array(v, numpy.int16))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 128, 256]
v1, v2 = custom.opIntSeq(numpy.array(v, numpy.int32))
test(isinstance(v1, numpy.ndarray))
@@ -320,6 +446,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opIntSeq(numpy.array(v, numpy.int32))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0, 2, 4, 8, 16, 32, 64, 128, 256]
v1, v2 = custom.opLongSeq(numpy.array(v, numpy.int64))
test(isinstance(v1, numpy.ndarray))
@@ -330,6 +463,13 @@ def allTests(helper, communicator):
test(v1[i] == v[i])
test(v2[i] == v[i])
+ v = []
+ v1, v2 = custom.opLongSeq(numpy.array(v, numpy.int64))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256]
v1, v2 = custom.opFloatSeq(numpy.array(v, numpy.float32))
test(isinstance(v1, numpy.ndarray))
@@ -340,6 +480,13 @@ def allTests(helper, communicator):
test(round(float(v1[i]), 1) == round(v[i], 1))
test(round(float(v2[i]), 1) == round(v[i], 1))
+ v = []
+ v1, v2 = custom.opFloatSeq(numpy.array(v, numpy.float32))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
v = [0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256]
v1, v2 = custom.opDoubleSeq(numpy.array(v, numpy.float64))
test(isinstance(v1, numpy.ndarray))
@@ -350,6 +497,61 @@ def allTests(helper, communicator):
test(round(float(v1[i]), 1) == round(v[i], 1))
test(round(float(v2[i]), 1) == round(v[i], 1))
+ v = []
+ v1, v2 = custom.opDoubleSeq(numpy.array(v, numpy.float64))
+ test(isinstance(v1, numpy.ndarray))
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == 0)
+ test(len(v2) == 0)
+
+ d = Test.NumPy.D()
+ d.boolSeq = numpy.array([True, False, True, False, True], numpy.bool_)
+ d.byteSeq = numpy.array([0, 2, 4, 8, 16, 32, 64, 127], numpy.int8)
+ d.shortSeq = numpy.array([0, 2, 4, 8, 16, 32, 64, 128, 256], numpy.int16)
+ d.intSeq = numpy.array([0, 2, 4, 8, 16, 32, 64, 128, 256], numpy.int32)
+ d.longSeq = numpy.array([0, 2, 4, 8, 16, 32, 64, 128, 256], numpy.int64)
+ d.floatSeq = numpy.array([0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256], numpy.float32)
+ d.doubleSeq = numpy.array([0.1, 0.2, 0.4, 0.8, 0.16, 0.32, 0.64, 0.128, 0.256], numpy.float64)
+
+ d1 = custom.opD(d)
+ test(isinstance(d1.boolSeq, numpy.ndarray))
+ test(len(d1.boolSeq) == len(d.boolSeq))
+ for i in range(len(d.boolSeq)):
+ test(d.boolSeq[i] == d1.boolSeq[i])
+
+ test(isinstance(d1.byteSeq, numpy.ndarray))
+ test(len(d1.byteSeq) == len(d.byteSeq))
+ for i in range(len(d.byteSeq)):
+ test(d.byteSeq[i] == d1.byteSeq[i])
+
+ test(isinstance(d1.intSeq, numpy.ndarray))
+ test(len(d1.intSeq) == len(d.intSeq))
+ for i in range(len(d.intSeq)):
+ test(d.intSeq[i] == d1.intSeq[i])
+
+ test(isinstance(d1.longSeq, numpy.ndarray))
+ test(len(d1.longSeq) == len(d.longSeq))
+ for i in range(len(d.longSeq)):
+ test(d.longSeq[i] == d1.longSeq[i])
+
+ test(isinstance(d1.floatSeq, numpy.ndarray))
+ test(len(d1.floatSeq) == len(d.floatSeq))
+ for i in range(len(d.floatSeq)):
+ test(round(d.floatSeq[i], 1) == round(d1.floatSeq[i], 1))
+
+ test(isinstance(d1.doubleSeq, numpy.ndarray))
+ test(len(d1.doubleSeq) == len(d.doubleSeq))
+ for i in range(len(d.doubleSeq)):
+ test(round(d.doubleSeq[i], 1) == round(d1.doubleSeq[i], 1))
+
+ d1 = custom.opD(Test.NumPy.D())
+ test(d1.boolSeq == Ice.Unset)
+ test(d1.byteSeq == Ice.Unset)
+ test(d1.intSeq == Ice.Unset)
+ test(d1.longSeq == Ice.Unset)
+ test(d1.floatSeq == Ice.Unset)
+ test(d1.doubleSeq == Ice.Unset)
+
v1 = numpy.array([numpy.complex128(1 + 1j),
numpy.complex128(2 + 2j),
numpy.complex128(3 + 3j),
@@ -360,6 +562,11 @@ def allTests(helper, communicator):
for i in range(len(v1)):
test(v1[i] == v2[i])
+ v1 = numpy.array([], numpy.complex128)
+ v2 = custom.opComplex128Seq(v1)
+ test(isinstance(v2, numpy.ndarray))
+ test(len(v1) == len(v2))
+
v1 = custom.opBoolMatrix()
test(numpy.array_equal(v1, numpy.array([[True, False, True],
[True, False, True],
diff --git a/python/test/Ice/custom/Server.py b/python/test/Ice/custom/Server.py
index f035cfc3144..85b3ba6d02a 100755
--- a/python/test/Ice/custom/Server.py
+++ b/python/test/Ice/custom/Server.py
@@ -146,6 +146,9 @@ class CustomI(Test.Custom):
def opBogusArrayNoCallableFactory(self, current):
return [True, False, True, False]
+ def opD(self, d, current):
+ return d
+
def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
@@ -223,6 +226,9 @@ if hasNumPy:
def opBogusNumpyArrayType(self, current):
return [True, False, True, False]
+ def opD(self, d, current):
+ return d
+
def shutdown(self, current=None):
current.adapter.getCommunicator().shutdown()
diff --git a/python/test/Ice/custom/Test.ice b/python/test/Ice/custom/Test.ice
index db804daa591..bbc5ccae520 100644
--- a/python/test/Ice/custom/Test.ice
+++ b/python/test/Ice/custom/Test.ice
@@ -57,6 +57,17 @@ module Test
["python:seq:default"] StringTuple s4;
}
+ class D
+ {
+ optional(1) BoolSeq1 boolSeq;
+ optional(2) ByteSeq1 byteSeq;
+ optional(3) ShortSeq1 shortSeq;
+ optional(4) IntSeq1 intSeq;
+ optional(5) LongSeq1 longSeq;
+ optional(6) FloatSeq1 floatSeq;
+ optional(7) DoubleSeq1 doubleSeq;
+ }
+
interface Custom
{
ByteString opByteString1(ByteString b1, out ByteString b2);
@@ -93,6 +104,9 @@ module Test
["python:memoryview:Custom.myBogusArraySignatureFactory"]BoolSeq1 opBogusArraySignatureFactory();
["python:memoryview:Custom.myNoCallableFactory"]BoolSeq1 opBogusArrayNoCallableFactory();
+
+ D opD(D d);
+
void shutdown();
}
}
diff --git a/python/test/Ice/custom/TestNumPy.ice b/python/test/Ice/custom/TestNumPy.ice
index aea2256fd85..128f5c1d07d 100644
--- a/python/test/Ice/custom/TestNumPy.ice
+++ b/python/test/Ice/custom/TestNumPy.ice
@@ -31,6 +31,17 @@ module Test
["python:memoryview:Custom.myNumPyComplex128Seq"] sequence<byte> Complex128Seq;
+ class D
+ {
+ optional(1) BoolSeq1 boolSeq;
+ optional(2) ByteSeq1 byteSeq;
+ optional(3) ShortSeq1 shortSeq;
+ optional(4) IntSeq1 intSeq;
+ optional(5) LongSeq1 longSeq;
+ optional(6) FloatSeq1 floatSeq;
+ optional(7) DoubleSeq1 doubleSeq;
+ }
+
interface Custom
{
BoolSeq1 opBoolSeq(BoolSeq1 v1, out BoolSeq2 v2);
@@ -52,6 +63,8 @@ module Test
["python:memoryview:Custom.myBogusNumpyArrayType"]BoolSeq1 opBogusNumpyArrayType();
+ D opD(D d);
+
void shutdown();
}
}