cythonize не перезапускает модифицированный файл pyx после второго вызова во время выполнения - PullRequest
1 голос
/ 29 марта 2020

Мне нужно сгенерировать pyx-файл несколько раз, запустить его перекомпиляцию и перезагрузить соответствующее расширение в программу за один раз. Вот упрощенный пример:

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)

Однако при выполнении, несмотря на изменение файла pyx, у меня только одна компиляция. Это вывод в консоли:

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

Есть идеи, как мне это решить?

1 Ответ

0 голосов
/ 29 марта 2020

Я смог решить эту проблему, только когда каждый раз использовал разные имена для файла pyx и для расширения:

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)

Вывод:

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
...