[Cython] cython --cplus --embed generates invalid code

2014-11-30 Thread Michael Enßlin
Hi,

on my system, --embed does not work with --cplus.

How to reproduce: Any valid pyx file works:

$ rm -f test.pyx; touch test.pyx
$ cython --embed --cplus test.pyx
$ g++ -c test.cpp -I/usr/include/python3.4m
test.cpp: In function ‘wchar_t* __Pyx_char2wchar(char*)’:
test.cpp:945:41: error: invalid conversion from ‘void*’ to ‘wchar_t*’
[-fpermissive]
 res = malloc(argsize*sizeof(wchar_t));
$ clang++ -c test.cpp -I/usr/include/python3.4m
test.cpp:945:9: error: assigning to 'wchar_t *' from incompatible type
'void *'
res = malloc(argsize*sizeof(wchar_t));


The issue can easily be fixed by manually casting the malloc result to
(wchar_t *).
In C it is not recommended to cast the malloc result, while in C++ it is
required (and malloc is discouraged).

System info:

$ cython --version
Cython version 0.21.1
$ g++ --version
g++ (Debian 4.9.2-2) 4.9.2
$ python3 --version
Python 3.4.2
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:Debian GNU/Linux unstable (sid)
Release:unstable
Codename:   sid

~ Michael



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Cython produces invalid C code

2015-04-22 Thread Michael Enßlin
Hi everybody,

Cython 0.21.1, from Debian Sid, and Cython 0.22, from Gentoo, produce
invalid C Code for the following .pyx file:



$ cat test.pyx
cimport cpython

cdef extern from "test.h":
cdef void foo(int i = 0)

def bar(self):
foo(0)



$ cat test.h
void foo(int i);



$ cython test.pyx



$ gcc -c test.c -I/usr/include/python3.4m
test.c: In function ‘__pyx_pf_4test_bar’:
test.c:659:35: error: storage size of ‘__pyx_t_1’ isn’t known
   struct __pyx_opt_args_4test_foo __pyx_t_1;



$ clang test.c -I/usr/include/python3.4m
test.c:659:35: error: variable has incomplete type 'struct
__pyx_opt_args_4test_foo'
  struct __pyx_opt_args_4test_foo __pyx_t_1;
test.c:659:10: note: forward declaration of 'struct
__pyx_opt_args_4test_foo'
  struct __pyx_opt_args_4test_foo __pyx_t_1;



Note that this is a minimal example; removing anything from test.pyx
fixes the issue (the 'cimport' statement, the default value for int i,
and the call to foo). The issue also occurs with --cplus.


Happy debugging,
mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Cython produces invalid C code

2015-04-22 Thread Michael Enßlin
Hi,

On 23/04/15 06:25, Robert Bradshaw wrote:
> I've made this an explicit error.

thanks; I hope this will save future users some WTFs.

~mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Misleading error message when assigning function pointers with differing except* declarations

2015-05-07 Thread Michael Enßlin
Hi,

consider the following example:

$ cat demo.pyx
cdef void (*foo)()

cdef void bar() except*:
pass

foo = bar



$ cython demo.pyx

Error compiling Cython file:

...
cdef void (*foo)()

cdef void bar() except*:
pass

foo = bar
^


demo.pyx:6:9: Cannot assign type 'void (void)' to 'void (*)(void)'



this is all expected behavior, but the error message is entirely
misleading; it should be something like


demo.pyx:6:9: Function pointers have incompatible 'except *' declarations.


Note that the same error message also occurs when the pointer is
declared except*, and the function isn't.

~ mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Cython generates invalid C code for some generator expressions in cdef functions

2015-05-08 Thread Michael Enßlin
Take the following example:


$ cat t2.pyx
cdef void read_callback():
foo = b"asdf"
bar = (c for c in foo)



$ cython t2.pyx



$ gcc -I/usr/include/python3.4m t2.c
t2.c: In function ‘__pyx_f_2t2_read_callback’:
t2.c:778:12: error: ‘None’ undeclared (first use in this function)
 return None;
^
t2.c:778:12: note: each undeclared identifier is reported only once for
each function it appears in
t2.c:778:5: warning: ‘return’ with a value, in function returning void
 return None;
 ^


Note that the error does not occur for

bar = (c for c in b"asdf")

or

bar = [c for c in b"asdf"]


 ~ mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Feature request: Expose methods to fake stack traces

2015-06-08 Thread Michael Enßlin
Hi everybody,

my C++ exceptions contain some stack trace information (starting with
__FILE__ and __LINE__), and I'd like to preserve that information in my
custom 'except+' translator.

Cython seems to have some internal methods to fake Python stack trace
objects, but research (and an unanswered question on the Users list
[https://groups.google.com/forum/#!topic/cython-users/9coFCVwigpE])
seems to imply that this functionality is not currently exposed.

I'd like to see that internal functionality exposed for usage from .pyx
files.

 ~ mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Cython produces invalid code for operator()

2015-06-11 Thread Michael Enßlin
Hi guys,

have a look at this:

$ cat bar.pyx
cdef extern from "foo.h":
cdef cppclass Foo:
int operator() (int arg)
int do_call (int arg)


cdef int bar(int arg):
cdef Foo foo
foo.do_call(arg)
return foo(arg)

$ cython3 --cplus bar.pyx
$ cat bar.cpp

(...)

static int __pyx_f_3bar_bar(int __pyx_v_arg) {
  Foo __pyx_v_foo;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("bar", 0);

  /* "bar.pyx":9
 * cdef int bar(int arg):
 * cdef Foo foo
 * foo.do_call(arg) # <<
 * return foo(arg)
 */
  __pyx_v_foo.do_call(__pyx_v_arg);

  /* "bar.pyx":10
 * cdef Foo foo
 * foo.do_call(arg)
 * return foo(arg) # <<
 */
  __pyx_r = operator()(__pyx_v_arg);
  goto __pyx_L0;

  /* "bar.pyx":7
 *
 *
 * cdef int bar(int arg): # <<
 * cdef Foo foo
 * foo.do_call(arg)
 */

  /* function exit code */
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

(...)



Note how the function invocation for "do_call" is generated correctly,
but the invocation of operator() is nonsensical.

The correct line would be this:

  __pyx_r = __pyx_v_foo(__pyx_v_arg);

Happy debugging :D

~ mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Compiler crash in AnalyseExpressionsTransform

2015-06-12 Thread Michael Enßlin
Hi,

another bug report:


mic@mic /tmp $ cat t11.pyx
cdef cppclass foo:
pass

def test():
foo()



mic@mic /tmp $ cython --cplus t11.pyx

Error compiling Cython file:

...
cdef cppclass foo:
pass

def test():
foo()
  ^


t11.pyx:5:7: Compiler crash in AnalyseExpressionsTransform

ModuleNode.body = StatListNode(t11.pyx:1:0)
StatListNode.stats[1] = DefNode(t11.pyx:4:0,
modifiers = [...]/0,
name = u'test',
py_wrapper_required = True,
reqd_kw_flags_cname = '0',
used = True)
File 'Nodes.py', line 421, in analyse_expressions: StatListNode(t11.pyx:5:7)
File 'Nodes.py', line 4652, in analyse_expressions:
ExprStatNode(t11.pyx:5:7)
File 'ExprNodes.py', line 434, in analyse_expressions:
SimpleCallNode(t11.pyx:5:7,
use_managed_ref = True)
File 'ExprNodes.py', line 4495, in analyse_types:
SimpleCallNode(t11.pyx:5:7,
use_managed_ref = True)
File 'ExprNodes.py', line 4429, in analyse_as_type_constructor:
SimpleCallNode(t11.pyx:5:7,
use_managed_ref = True)

Compiler crash traceback from this point on:
  File "/usr/lib/python2.7/dist-packages/Cython/Compiler/ExprNodes.py",
line 4429, in analyse_as_type_constructor
self.function = RawCNameExprNode(self.function.pos, constructor.type)
AttributeError: 'NoneType' object has no attribute 'type'



The code  is obviously nonsensical, but Cython should produce a proper
error message instead of crashing.



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Can't call functions with multi-token template arguments such as 'char *'

2015-06-12 Thread Michael Enßlin
Hi,

it seems to be impossible to use anything but a single word as a
template type for functions.

Classes don't suffer from this issue, as seen below.

As a workaround, complex types can be ctypedef-d to a single word (also
seen below).

$ cat t10.pyx

cdef extern from "nope.h":
cdef cppclass bar[T]:
void func(T arg)

void foo[T](T arg)


ctypedef char * charptr


def test():
# works
cdef bar[char *] barobj
barobj.func(NULL)

# works
foo[int](5)

# works
foo[charptr](NULL)

# fails
foo[char *](NULL)



$ cython --cplus t10.pyx

Error compiling Cython file:

...

# works
foo[charptr](NULL)

# fails
foo[char *](NULL)
 ^


t10.pyx:27:14: Expected an identifier or literal



Happy debugging,
~ mic_e



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


[Cython] Feature request: Flag to enable warnings when 'extern' functions are not declared 'except +'

2015-06-12 Thread Michael Enßlin
Hi everybody,

as you surely have guessed from the amount of Bug reports I have
recently submitted to this mailing list, I'm currently working on a
rather large Cython project.
More precisely: I'm using Cython as the glue layer between the Python
and C++ components of openage; an overview and source code may be found
here:
https://github.com/mic-e/openage/blob/pyinterface/doc/implementation/pyinterface.md
https://github.com/mic-e/openage/tree/pyinterface/cpp/pyinterface
https://github.com/mic-e/openage/tree/pyinterface/openage/cppinterface


In openage, almost all C++ functions that are exposed to Cython SHOULD
be declared as 'except +'.
Forgetting to do so can cause hard-to-debug issues, including useless
Exception messages, corruption of CPython and right-out program
termination, if those methods should throw a C++ exception.


As a solution, I'd like to see Cython warnings if an extern cimport has
no 'except' declaration.

To intentionally omit the "except +", I suggest a new except
declaration, "except -", or, even better, the C++11 keyword "noexcept"
(since precisely those methods that are declared 'noexcept' should be
cimported without 'except+').

Of course, those warnings (or errors?) should be disabled by default,
and enabled by a special command-line flag.

Any thoughts on this?

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


[Cython] Feature Request: Variadic Templates

2015-06-21 Thread Michael Enßlin
Hi,

I'd like to see support for variadic template arguments, such as this:




test.h:

template
RetT foo(VARARGS ...);



test.pyx:

cdef extern from "test.h":
cdef RetT foo[RetT, ... VARARGS](... VARARGS)


def test():
cdef int i = foo[int, float, int](1, 2.5, 3)





This would allow Cython's libcpp to easily support many of C++11's new
types, including std::tuple and std::function.

Support for the latter in particular would prove quite useful in passing
around function pointers between Cython and C++.




I have tried to implement this feature myself, but I'm entirely
unfamiliar with Cython's codebase, and all my attempts ended in
unsatisfactorily hacky, unstable code.
I believe that any experienced Cython developer on this list would be
able to properly implement this in a matter of a few hours, as it seems
like a rather minor feature.




The current workaround for the non-existance of this feature involves
typedefs for every possible number of arguments, like this:


template
struct S {};

using S0 = S<>;

template
using S1 = S;

template
using S2 = S;

template
using S3 = S;


then exporting all of S0, S1, ... individually in the .pxd file.

This is inconvenient, but acceptable.



Now assume that S has a member function f,

template
void f(Ts..., Us ...);

due to the nature of C++, the same trick as above does not work, and the
user will be forced to clutter the C++ code with a function body for
every possible len(Us). Even worse, the .pxd file will now contain a
quadratic number of wrappers (one for every possible combination of
len(Ts), len(Us)), all of them extremely prone to mistakes.

Thanks for reading,

  ~ Michael



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


Re: [Cython] Multidimensional indexing of C++ objects

2015-07-04 Thread Michael Enßlin
Drawback 1) could be solved by declaring the operator as

cdef inline operator []()

instead of

cdef inline __getitem__()



signature.asc
Description: OpenPGP digital signature
___
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel