As I said in the comments, you can do it by using .pxd files in addition to the .py files to specify the types in. I realise this isn't as elegant as putting everything in the .py files, but as far as I know it's the best you can do.
a.py:
class Test: pass
a.pxd:
cdef class Test: pass
b.py:
# here I use Test in all the places I think you could want to use it: # as a function argument # as a variable in a function # in a class import a def f(x): return x def g(): t = a.Test() return t class C: pass
b.pxd:
import cython cimport a cpdef f(a.Test x) @cython.locals(t=a.Test) cpdef g() cdef class C: cdef a.Test t
You can verify that it's using the type information correctly by inspecting the generated b.c file.
For reference, the relevant documentation is http://docs.cython.org/src/tutorial/pure.html#magic-attributes-within-the-pxd
a.pyandb.pyand define the types there. Unfortunately, it involves duplicating information in two places, but it doesn't break the ability to usea.pyand.b.pyfrom plain Python.cimportin a.pyfile to share the definition file