[Cython] operator() bug in cython

Ian Henriksen insertinterestingnamehere at gmail.com
Mon Jun 22 23:13:19 CEST 2015


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cython-devel/attachments/20150622/7244646b/attachment.html>


More information about the cython-devel mailing list