Open empyrical opened 8 years ago
It doesn't seem as if it's just template functions that encounter this - it's also template classes if they're being used outside of a cdef
statement, like:
from libcpp cimport bool
cdef extern from *:
cdef cppclass MyClass[T]:
MyClass()
MyClass(bool someArgument)
@staticmethod
void aMethod()
# Okay
cdef MyClass[int *] myvar
# Not okay
cdef MyClass[int *] myvar = MyClass[int *](True)
# Not okay
MyClass[int *].aMethod()
I've hit this too:
Error compiling Cython file:
------------------------------------------------------------
...
# cython: language_level=2
cdef extern from "golang.h" nogil:
void *makechan[T](unsigned size)
cdef void *a = makechan[int*](10)
^
------------------------------------------------------------
y.pyx:5:28: Expected an identifier or literal
Traceback (most recent call last):
File "/home/kirr/src/wendelin/venv/z-dev/bin/cythonize", line 11, in <module>
load_entry_point('Cython', 'console_scripts', 'cythonize')()
File "/home/kirr/src/tools/py/cython/Cython/Build/Cythonize.py", line 223, in main
cython_compile(path, options)
File "/home/kirr/src/tools/py/cython/Cython/Build/Cythonize.py", line 106, in cython_compile
**options.options)
File "/home/kirr/src/tools/py/cython/Cython/Build/Dependencies.py", line 1096, in cythonize
cythonize_one(*args)
File "/home/kirr/src/tools/py/cython/Cython/Build/Dependencies.py", line 1219, in cythonize_one
raise CompileError(None, pyx_file)
Fails with both 0.29.x and current master (0.29.12-519-gba6d2c5e6)
With just makechan[int](10)
(no star after int) it works.
Yet another case
cdef extern from "../../cpp/complex_object/complex_object.h":
ctypedef struct ComplexReturnType:
cpp_map[string, vector[int]*]* index
^
------------------------------------------------------------
cython/complex_object/complex_object.pxd:9:36: Expected an identifier or literal
Generally if we know that we're parsing a type, there is special code to resolve the "dangling" star as part of the (possibly empty) declarator, but in cases where we expect an expression it is first parsed as a valid Python expression in which case the *
is interpreted as multiplication. This is tricky to resolve; until then using a typedef is the best solution.
It's quite surprising that templating with pointer types requires an extra ctypedef
, which kinda defeats the purpose of templating in the first place. If I have to add ctypedef
s to all of the supported types, a simple template instantiation requires a lot of boilerplate code... 😢
Instantiating a template class like so works fine in Cython:
However, this gives a syntax error:
A small workaround I've been using is making a
ctypedef
like so: