I need to generate a pyx file several times and run its recompilation and reload corresponding extension into the program in one runtime. Here is a simplified example:
from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
pyxfile = "foo.pyx"
def write_pyx(incval):
with open(pyxfile, 'w') as f:
f.write('cpdef int foo(int x):\n return x+%i' % incval)
def ext_compile():
oldargv = sys.argv
sys.argv = ['thisfile.py', 'build_ext', '--inplace']
setup(
ext_modules=cythonize(
[ Extension("example", [pyxfile]) ],
compiler_directives={'language_level': 2}
)
)
sys.argv = oldargv
write_pyx(1)
ext_compile()
import example
print "foo(1) =", example.foo(1)
write_pyx(10)
ext_compile()
reload(example)
print "foo(1) =", example.foo(1)
However, when executed, despite the changing pyx file, I have only one compilation. This is the output in the console:
Compiling foo.pyx because it changed.
[1/1] Cythonizing foo.pyx
running build_ext
building 'example' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo.c -o build/temp.linux-x86_64-2.7/foo.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo.o -o build/lib.linux-x86_64-2.7/example.so
copying build/lib.linux-x86_64-2.7/example.so ->
foo(1) = 2
running build_ext
copying build/lib.linux-x86_64-2.7/example.so ->
foo(1) = 2
Any idea how can I solve this?
I was able to solve this only when each time I use different names for the pyx file and for the extension:
from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
import importlib
def write_pyx(pyxfile, incval):
with open(pyxfile, 'w') as f:
f.write('cpdef int foo(int x):\n return x+%i' % incval)
def ext_compile(extname, pyxfile):
oldargv = sys.argv
sys.argv = ['thisfile.py', 'build_ext', '--inplace']
setup(
ext_modules=cythonize(
[ Extension(extname, [pyxfile]) ],
compiler_directives={'language_level': 2}
)
)
sys.argv = oldargv
pyxfile = "foo01.pyx"
extname = "example01"
write_pyx(pyxfile, 1)
ext_compile(extname, pyxfile)
example = importlib.import_module(extname)
print "foo(1) =", example.foo(1)
pyxfile = "foo10.pyx"
extname = "example10"
write_pyx(pyxfile, 10)
ext_compile(extname, pyxfile)
example = importlib.import_module(extname)
print "foo(1) =", example.foo(1)
Output is:
Compiling foo01.pyx because it changed.
[1/1] Cythonizing foo01.pyx
running build_ext
building 'example01' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo01.c -o build/temp.linux-x86_64-2.7/foo01.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo01.o -o build/lib.linux-x86_64-2.7/example01.so
copying build/lib.linux-x86_64-2.7/example01.so ->
foo(1) = 2
Compiling foo10.pyx because it changed.
[1/1] Cythonizing foo10.pyx
running build_ext
building 'example10' extension
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/home/artem/.pyenv/versions/2.7.16/include/python2.7 -c foo10.c -o build/temp.linux-x86_64-2.7/foo10.o
gcc -pthread -shared -L/home/artem/.pyenv/versions/2.7.16/lib build/temp.linux-x86_64-2.7/foo10.o -o build/lib.linux-x86_64-2.7/example10.so
copying build/lib.linux-x86_64-2.7/example10.so ->
foo(1) = 11