Type inference and C++
Here is part of original testcase: from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator. Then I tried to comment out for loop and compile it with upstream/master, same error here: note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator' Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------ cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator' Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------ cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item. -- vitja.
2012/7/23 Vitja Makarov <vitja.makarov@gmail.com>:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
It seems that dereference is the only way we can get iterator's value, but UnopNode doesn't respect overloaded operator*() -- vitja.
On 23 July 2012 20:28, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2012/7/23 Vitja Makarov <vitja.makarov@gmail.com>:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
It seems that dereference is the only way we can get iterator's value, but UnopNode doesn't respect overloaded operator*()
I thought unary * was only used for argument unpacking and consuming left-over items when unpacking an iterable.
-- vitja. _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel
2012/7/24 mark florisson <markflorisson88@gmail.com>:
On 23 July 2012 20:28, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2012/7/23 Vitja Makarov <vitja.makarov@gmail.com>:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
It seems that dereference is the only way we can get iterator's value, but UnopNode doesn't respect overloaded operator*()
I thought unary * was only used for argument unpacking and consuming left-over items when unpacking an iterable.
Yes, in Python here it means C/C++ * unary operator that is called with cython.operator.dereference() -- vitja.
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type(). Stefan
Stefan Behnel, 24.07.2012 12:43:
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type().
... and not only DereferenceNode. Pretty much all C++ operators do not properly implement type inference. I'll take a look. Stefan
2012/7/24 Stefan Behnel <stefan_ml@behnel.de>:
Stefan Behnel, 24.07.2012 12:43:
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
It doesn't work with local type inference enabled since `a` in for-loop is infered as pyobject and in while loop it's inferred as reverse_iterator.
Then I tried to comment out for loop and compile it with upstream/master, same error here:
note: cpp_stl_vector.pyx:8:6: inferred 'v' to be of type 'vector[int] *' note: cpp_stl_vector.pyx:11:7: inferred 'it' to be of type 'reverse_iterator' note: cpp_stl_vector.pyx:13:10: inferred 'a' to be of type 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... v = new vector[int]() #for a in L: # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:13:13: Cannot assign type 'int &' to 'reverse_iterator'
Error compiling Cython file: ------------------------------------------------------------ ... # v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a) ^ ------------------------------------------------------------
cpp_stl_vector.pyx:15:15: Cannot convert 'reverse_iterator' to Python object
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type().
... and not only DereferenceNode. Pretty much all C++ operators do not properly implement type inference. I'll take a look.
Ok, thanks! -- vitja.
Vitja Makarov, 24.07.2012 14:48:
2012/7/24 Stefan Behnel:
Stefan Behnel, 24.07.2012 12:43:
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type().
... and not only DereferenceNode. Pretty much all C++ operators do not properly implement type inference. I'll take a look.
Ok, thanks!
Here's my fix. https://github.com/cython/cython/commit/43f3d87d9760d3c7e7fa6a127d0bdaf54988... It became a bit more involved than I had anticipated, including some cleanups and fixes for a couple of quirks that I ran into. It's really too bad that the Sage build is currently broken. The C++ code in there would be a good exercise for this change (even if it won't benefit from the type inference). At least, so far, it doesn't seem like it has broken more than what was broken before. Stefan
2012/7/24 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 24.07.2012 14:48:
2012/7/24 Stefan Behnel:
Stefan Behnel, 24.07.2012 12:43:
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type().
... and not only DereferenceNode. Pretty much all C++ operators do not properly implement type inference. I'll take a look.
Ok, thanks!
Here's my fix.
https://github.com/cython/cython/commit/43f3d87d9760d3c7e7fa6a127d0bdaf54988...
It became a bit more involved than I had anticipated, including some cleanups and fixes for a couple of quirks that I ran into.
It's really too bad that the Sage build is currently broken. The C++ code in there would be a good exercise for this change (even if it won't benefit from the type inference). At least, so far, it doesn't seem like it has broken more than what was broken before.
And sorry for stupid question: do we support multiple overloaded operators of the same kind? -- vitja.
Vitja Makarov, 24.07.2012 18:42:
2012/7/24 Stefan Behnel:
Vitja Makarov, 24.07.2012 14:48:
2012/7/24 Stefan Behnel:
Stefan Behnel, 24.07.2012 12:43:
Vitja Makarov, 23.07.2012 07:13:
Here is part of original testcase:
from cython.operator cimport dereference as d from cython.operator cimport preincrement as incr from libcpp.vector cimport vector
def reverse_iteration_test(L): v = new vector[int]() for a in L: v.push_back(a) it = v.rbegin() while it != v.rend(): a = d(it) incr(it) print(a)
I think it's not correct to infer `a` as reverse_iterator because it's not an iterator it's vector's item.
Right. DereferenceNode should implement infer_type().
... and not only DereferenceNode. Pretty much all C++ operators do not properly implement type inference. I'll take a look.
Ok, thanks!
Here's my fix.
https://github.com/cython/cython/commit/43f3d87d9760d3c7e7fa6a127d0bdaf54988...
It became a bit more involved than I had anticipated, including some cleanups and fixes for a couple of quirks that I ran into.
It's really too bad that the Sage build is currently broken. The C++ code in there would be a good exercise for this change (even if it won't benefit from the type inference). At least, so far, it doesn't seem like it has broken more than what was broken before.
And sorry for stupid question: do we support multiple overloaded operators of the same kind?
I'm sure we're lacking a test for that. At least in the change above, I'm using "lookup_operator_for_types()", which should do the right thing. Stefan
participants (3)
-
mark florisson -
Stefan Behnel -
Vitja Makarov