Re: [Cython] operator() bug in cython

2015-02-13 Thread Stefan Behnel
Ulrich Dobramysl schrieb am 11.02.2015 um 09:56:
> I tried to declare an external c++ class that includes an operator()
> function in a pxd file. When I then call a class instance, cython generates
> faulty c++ code. It includes a call to "operator()()", and not a call to
> the instance object. Here is a minimum working example:
> 
> call_operator.pxd:
> 
> cdef extern from "call_operator.hpp" nogil:
> cdef cppclass OperatorTest:
> int operator()()
> 
> 
> test_call_operator.pyx:
> 
> from call_operator cimport OperatorTest
> def test():
> cdef OperatorTest t
> t()
> 
> 
> Running "cython --cplus test_call_operator.pyx" generates the following
> code for the test() function:
> 
>  (relevant part only)
>   /* "test_call_operator.pyx":4
>  * def test():
>  * cdef OperatorTest t
>  * t() # <<
>  */
>   operator()();
> 
> As you can see, the code that is generated is a call to "operator()()" and
> not "t()" as it should be.

Thanks for the report, I can confirm this.


> From what I've been able to work out, the problem seems to be that the call
> to "t()" is treated as a NameNode in ExprNodes.py and not an AttributeNode.
> However, I don't know enough about Cython's internals to track where
> exactly this decision is made.
> 
> Curiously, this bug isn't always triggered in more complex situations. I
> had a larger pxd file with multiple external declarations where one class
> operator() was treated correctly, while others weren't. I haven't been able
> to find out why this was the case.

It happens only with stack allocated C++ objects, not with heap objects
(i.e. pointers). That can be used as a work-around, I guess.

Stefan

___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] operator() bug in cython

2015-02-13 Thread Ulrich Dobramysl
On Fri Feb 13 2015 at 2:23:45 PM Stefan Behnel  wrote:

> Ulrich Dobramysl schrieb am 11.02.2015 um 09:56:
> > From what I've been able to work out, the problem seems to be that the
> call
> > to "t()" is treated as a NameNode in ExprNodes.py and not an
> AttributeNode.
> > However, I don't know enough about Cython's internals to track where
> > exactly this decision is made.
> >
> > Curiously, this bug isn't always triggered in more complex situations. I
> > had a larger pxd file with multiple external declarations where one class
> > operator() was treated correctly, while others weren't. I haven't been
> able
> > to find out why this was the case.
>
> It happens only with stack allocated C++ objects, not with heap objects
> (i.e. pointers). That can be used as a work-around, I guess.
>
>
Thanks! I haven't figured out how to call heap allocated objects, as the
code
---
cdef OperatorTest *t = new OperatorTest()
t()
---
is not translatable by Cython. Is there a special syntax for calling cython
"function pointers"? The trick dereference(t)() doesn't work either.

However, one thing that works is if the (stack-allocated) called object is
not a local variable (a NameNode), but an attribute of some object (an
AttributeNode). A quick and dirty fix for this would be this patch for
NameNode.calculate_result_code:
---
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index f99ec6e..f894a64 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -1904,6 +1904,8 @@ class NameNode(AtomicExprNode):
 entry = self.entry
 if not entry:
 return "" # There was an error earlier
+if entry.cname=='operator()':
+return self.name
 return entry.cname

 def generate_result_code(self, code):
---
But I have no idea what other side effects that might have.

Ulrich
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] operator() bug in cython

2015-02-13 Thread Greg Ewing

Ulrich Dobramysl wrote:

Thanks! I haven't figured out how to call heap allocated objects, as the 
code

---
cdef OperatorTest *t = new OperatorTest()
t()
---
is not translatable by Cython.


Have you tried:

   t[0]()

?

A quick and dirty fix for this would be this patch 
for NameNode.calculate_result_code:

---
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index f99ec6e..f894a64 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -1904,6 +1904,8 @@ class NameNode(AtomicExprNode):
 entry = self.entry
 if not entry:
 return "" # There was an error earlier
+if entry.cname=='operator()':
+return self.name 
 return entry.cname


I haven't been following the development of Cython's internals,
so I may be speaking naively here, but it looks wrong to me that
the cname of that entry should be 'operator()' rather than the
c-level name of the variable that the NameNode refers to.

--
Greg
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel