[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