[Cython] operator() bug in cython

Ian Henriksen insertinterestingnamehere at gmail.com
Tue Jun 23 04:25:22 CEST 2015


On Mon, Jun 22, 2015 at 3:13 PM Ian Henriksen <
insertinterestingnamehere at gmail.com> wrote:

> On Tue, Feb 17, 2015 at 2:51 AM Ulrich Dobramysl <uli-do at gmx.at> wrote:
>
>> On Fri Feb 13 2015 at 11:07:39 PM Greg Ewing <greg.ewing at canterbury.ac.nz>
>> wrote:
>>
>>> 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]()
>>>
>>> ?
>>>
>>
>> Thanks, I didn't think about the t[0] trick!
>>
>>
>>> 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.
>>>
>>>
>> The cname of the entry is correct IMO, because it cannot have any
>> knowledge about the cname of the object it is being called as later. The
>> logic dealing with the special case of an operator() member function of a
>> c++ class in SimpleCallNode.analyse_c_function_call() needs to be changed
>> slightly to not treat operator() as an overloaded entry. Rather, the
>> function type of the SimpleCallNode needs to be set to the type of the
>> looked-up operator() entry. Then, at the code generation stage, the correct
>> cname of the SimpleCallNode entry is used and not the entry of operator().
>> With the patch below my test case compiles and runs without problems:
>> ----
>> diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
>> index f99ec6e..88522c9 100644
>> --- a/Cython/Compiler/ExprNodes.py
>> +++ b/Cython/Compiler/ExprNodes.py
>> @@ -4569,11 +4569,13 @@ class SimpleCallNode(CallNode):
>>              args = self.args
>>
>>          if func_type.is_cpp_class:
>> -            overloaded_entry =
>> self.function.type.scope.lookup("operator()")
>> -            if overloaded_entry is None:
>> +            call_operator = self.function.type.scope.lookup("operator()")
>> +            if call_operator is None:
>>                  self.type = PyrexTypes.error_type
>>                  self.result_code = "<error>"
>>                  return
>> +            self.function.type = call_operator.type
>> +            overloaded_entry = None
>>          elif hasattr(self.function, 'entry'):
>>              overloaded_entry = self.function.entry
>>          elif (isinstance(self.function, IndexNode) and
>> @@ -4603,7 +4605,7 @@ class SimpleCallNode(CallNode):
>>          else:
>>              entry = None
>>              func_type = self.function_type()
>> -            if not func_type.is_cfunction:
>> +            if not (func_type.is_cfunction or func_type.is_cpp_class):
>>                  error(self.pos, "Calling non-function type '%s'" %
>> func_type)
>>                  self.type = PyrexTypes.error_type
>>                  self.result_code = "<error>"
>> ----
>> What do you think? I don't know a lot about cython's internals, so there
>> might be use cases which break this code.
>>
>> Ulrich
>>
>> _______________________________________________
>> cython-devel mailing list
>> cython-devel at python.org
>> https://mail.python.org/mailman/listinfo/cython-devel
>
>
> What is the status on this? The most recent patch appears to work
> if the first two changed lines are ignored. If it would help move this
> along, I can open a PR with the modified patch and a commit that still
> attributes the patch to the original author.
> Thanks!
> -Ian Henriksen
>

Alright, I've put up a pull request at
https://github.com/cython/cython/pull/400.
I hope this makes things a bit easier.
-Ian Henriksen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20150623/06bdd90e/attachment.html>


More information about the cython-devel mailing list