Merge branch 'python-stl-overloading'
* python-stl-overloading: Python STL container method overloading fix
This commit is contained in:
commit
5e2b8f3ec9
9 changed files with 200 additions and 24 deletions
|
|
@ -10,6 +10,56 @@ Version 4.0.1 (in progress)
|
|||
2019-08-08: rokups
|
||||
[C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
|
||||
|
||||
2019-08-07: wsfulton
|
||||
[Python] Fix method overloading of methods that take STL containers of different
|
||||
types. The following usage (using std::vector) would fail when using -builtin:
|
||||
|
||||
%include <std_string.i>
|
||||
%include <std_vector.i>
|
||||
|
||||
%inline %{
|
||||
struct X {};
|
||||
%}
|
||||
|
||||
%template(VectorX) std::vector<X>;
|
||||
%template(VectorInt) std::vector<int>;
|
||||
|
||||
%inline %{
|
||||
using namespace std;
|
||||
string VectorOverload(vector<X> v);
|
||||
string VectorOverload(vector<int> v);
|
||||
%}
|
||||
|
||||
The following would incorrectly fail:
|
||||
|
||||
s = VectorOverload([1, 2, 3])
|
||||
|
||||
With:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "runme3.py", line 20, in <module>
|
||||
ret = VectorOverload([1, 2, 3])
|
||||
TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
|
||||
Possible C/C++ prototypes are:
|
||||
VectorOverload(std::vector< Number,std::allocator< Number > >)
|
||||
VectorOverload(std::vector< int,std::allocator< int > >)
|
||||
|
||||
The problem was due to some error handling that was not cleared during typehecking.
|
||||
In this case an error was not cleared when the elements in the list failed the
|
||||
typecheck for converting to X. Only occurs in Python 3+.
|
||||
|
||||
In some combinations of overloaded methods, the following type of error message would
|
||||
occur:
|
||||
|
||||
RuntimeError: in sequence element 0
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "runme3.py", line 23, in <module>
|
||||
check(VectorOverload(v), "vector<X>")
|
||||
SystemError: <built-in function VectorOverload> returned a result with an error set
|
||||
|
||||
2019-08-01: wsfulton
|
||||
#1602 Fix regression in 4.0.0 where a template function containing a parameter
|
||||
with the same name as the function name led to the parameter name used in the
|
||||
|
|
|
|||
|
|
@ -643,6 +643,7 @@ CPP_STD_TEST_CASES += \
|
|||
director_string \
|
||||
ignore_template_constructor \
|
||||
li_std_combinations \
|
||||
li_std_containers_overload \
|
||||
li_std_deque \
|
||||
li_std_except \
|
||||
li_std_except_as_class \
|
||||
|
|
|
|||
33
Examples/test-suite/li_std_containers_overload.i
Normal file
33
Examples/test-suite/li_std_containers_overload.i
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
%module li_std_containers_overload
|
||||
|
||||
// Suppress warning that ought not to appear, but there is no easy fix
|
||||
%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) VectorOverload;
|
||||
|
||||
%include <std_string.i>
|
||||
%include <std_vector.i>
|
||||
|
||||
%inline %{
|
||||
struct X {};
|
||||
struct Y {};
|
||||
%}
|
||||
|
||||
%template(VectorX) std::vector<X>;
|
||||
%template(VectorY) std::vector<Y>;
|
||||
%template(VectorString) std::vector<std::string>;
|
||||
%template(VectorInt) std::vector<int>;
|
||||
|
||||
%inline %{
|
||||
using namespace std;
|
||||
string VectorOverload(vector<X> v) {
|
||||
return "vector<X>";
|
||||
}
|
||||
string VectorOverload(vector<Y> v) {
|
||||
return "vector<Y>";
|
||||
}
|
||||
string VectorOverload(vector<string> v) {
|
||||
return "vector<string>";
|
||||
}
|
||||
string VectorOverload(vector<int> v) {
|
||||
return "vector<int>";
|
||||
}
|
||||
%}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# do not dump Octave core
|
||||
if exist("crash_dumps_octave_core", "builtin")
|
||||
crash_dumps_octave_core(0);
|
||||
endif
|
||||
|
||||
li_std_containers_overload
|
||||
|
||||
function check(got, expected)
|
||||
if (!strcmp(got, expected))
|
||||
error("Failed check. '%s' != '%s'", got, expected)
|
||||
endif
|
||||
end
|
||||
|
||||
v = VectorX();
|
||||
check(VectorOverload(v), "vector<X>");
|
||||
|
||||
v = VectorY();
|
||||
check(VectorOverload(v), "vector<Y>");
|
||||
|
||||
v = VectorInt();
|
||||
check(VectorOverload(v), "vector<int>");
|
||||
|
||||
v = VectorString();
|
||||
check(VectorOverload(v), "vector<string>");
|
||||
|
||||
# TODO: Conversion from an Octave sequence not implemented yet
|
||||
# v = {X()};
|
||||
# check(VectorOverload(v), "vector<X>");
|
||||
|
||||
# v = {Y()};
|
||||
# check(VectorOverload(v), "vector<Y>");
|
||||
|
||||
# v = {1, 2, 3};
|
||||
# check(VectorOverload(v), "vector<int>");
|
||||
|
||||
# v = {"aaa", "bbb", "ccc"};
|
||||
# check(VectorOverload(v), "vector<string>");
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
from li_std_containers_overload import *
|
||||
|
||||
def check(got, expected):
|
||||
if got != expected:
|
||||
raise RuntimeError("Failed check. '{}' != '{}'".format(got, expected))
|
||||
|
||||
v = VectorX()
|
||||
check(VectorOverload(v), "vector<X>")
|
||||
|
||||
v = VectorY()
|
||||
check(VectorOverload(v), "vector<Y>")
|
||||
|
||||
v = VectorInt()
|
||||
check(VectorOverload(v), "vector<int>")
|
||||
|
||||
v = VectorString()
|
||||
check(VectorOverload(v), "vector<string>")
|
||||
|
||||
v = [X()]
|
||||
check(VectorOverload(v), "vector<X>")
|
||||
|
||||
v = [Y()]
|
||||
check(VectorOverload(v), "vector<Y>")
|
||||
|
||||
v = [1, 2, 3]
|
||||
check(VectorOverload(v), "vector<int>")
|
||||
|
||||
v = ["aaa", "bbb", "ccc"]
|
||||
check(VectorOverload(v), "vector<string>")
|
||||
44
Examples/test-suite/ruby/li_std_containers_overload_runme.rb
Normal file
44
Examples/test-suite/ruby/li_std_containers_overload_runme.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# Put description here
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
require 'swig_assert'
|
||||
|
||||
require 'li_std_containers_overload'
|
||||
|
||||
include Li_std_containers_overload
|
||||
|
||||
def check(got, expected)
|
||||
if (got != expected)
|
||||
raise RuntimeError, "Failed check. '#{got}' != '#{expected}'"
|
||||
end
|
||||
end
|
||||
|
||||
v = VectorX.new()
|
||||
check(VectorOverload(v), "vector<X>")
|
||||
|
||||
v = VectorY.new()
|
||||
check(VectorOverload(v), "vector<Y>")
|
||||
|
||||
v = VectorInt.new()
|
||||
check(VectorOverload(v), "vector<int>")
|
||||
|
||||
v = VectorString.new()
|
||||
check(VectorOverload(v), "vector<string>")
|
||||
|
||||
v = [X.new()]
|
||||
check(VectorOverload(v), "vector<X>")
|
||||
|
||||
v = [Y.new()]
|
||||
check(VectorOverload(v), "vector<Y>")
|
||||
|
||||
v = [1, 2, 3]
|
||||
check(VectorOverload(v), "vector<int>")
|
||||
|
||||
v = ["aaa", "bbb", "ccc"]
|
||||
check(VectorOverload(v), "vector<string>")
|
||||
|
|
@ -401,20 +401,14 @@ namespace swig
|
|||
return const_reference(_seq, n);
|
||||
}
|
||||
|
||||
bool check(bool set_err = true) const
|
||||
bool check() const
|
||||
{
|
||||
int s = size();
|
||||
for (int i = 0; i < s; ++i) {
|
||||
// swig::SwigVar_PyObject item = OctSequence_GetItem(_seq, i);
|
||||
octave_value item; // * todo
|
||||
if (!swig::check<value_type>(item)) {
|
||||
if (set_err) {
|
||||
char msg[1024];
|
||||
sprintf(msg, "in sequence element %d", i);
|
||||
SWIG_Error(SWIG_RuntimeError, msg);
|
||||
}
|
||||
if (!swig::check<value_type>(item))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -672,19 +672,13 @@ namespace swig
|
|||
return const_reference(_seq, n);
|
||||
}
|
||||
|
||||
bool check(bool set_err = true) const
|
||||
bool check() const
|
||||
{
|
||||
Py_ssize_t s = size();
|
||||
for (Py_ssize_t i = 0; i < s; ++i) {
|
||||
swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
|
||||
if (!swig::check<value_type>(item)) {
|
||||
if (set_err) {
|
||||
char msg[1024];
|
||||
sprintf(msg, "in sequence element %d", (int)i);
|
||||
SWIG_Error(SWIG_RuntimeError, msg);
|
||||
}
|
||||
if (!swig::check<value_type>(item))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -395,19 +395,13 @@ namespace swig
|
|||
return const_reference(_seq, n);
|
||||
}
|
||||
|
||||
bool check(bool set_err = false) const
|
||||
bool check() const
|
||||
{
|
||||
int s = (int) size();
|
||||
for (int i = 0; i < s; ++i) {
|
||||
VALUE item = rb_ary_entry(_seq, i );
|
||||
if (!swig::check<value_type>(item)) {
|
||||
if (set_err) {
|
||||
char msg[1024];
|
||||
sprintf(msg, "in sequence element %d", i);
|
||||
SWIG_Error(SWIG_RuntimeError, msg);
|
||||
}
|
||||
if (!swig::check<value_type>(item))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue