【问题标题】:Cython + Windows 8.1 + VS express 2013Cython + Windows 8.1 + VS Express 2013
【发布时间】:2026-02-15 04:20:03
【问题描述】:

所以,这是另一个 Windows + cython 问题... Cython 确实成功地编译了一些简单的脚本(尽管不是全部),并且 gcc 在大多数情况下都会以错误代码退出。我已将Setup.py 配置为使用来自Setup.cfg 的MingW32 作为编译器。我也安装了 MCVS express,但使用它作为编译器似乎需要我拥有 2008 版本,现在找不到了。我读了很多关于在 Windows 上 cythonize 失败的文章,但我找不到魔术。似乎任何包含cdef 的脚本都将无法编译。有人可以帮忙吗?

配置:

  • Windows 8.1(当然是 x64)
  • Python 2.7.6 32 位
  • 为 32 位窗口预编译的 Cython 0.20.2
  • Microsoft Visual Studio Express 2013

测试项目:

  • test.py
  • setup.py
  • setup.cfg

Setup.cfg:

[build]
compiler = mingw32

Setup.py:

from distutils.core import setup
from Cython.Build import cythonize


setup(
    ext_modules = cythonize("test.py")
)

有效的test.py:

def say_hello_to(name):
    print("Hello %s!" % name)

失败的test2.py(相应地更改Setup.py):

def primes(int kmax):
cdef int n, k, i
cdef int p[1000]
result = []
if kmax > 1000:
    kmax = 1000
k = 0
n = 2
while k < kmax:
    i = 0
    while i < k and n % p[i] != 0:
        i = i + 1
    if i == k:
        p[k] = n
        k = k + 1
        result.append(n)
    n = n + 1
return result

Mingw32 错误输出:

PS C:\Users\Raoul\Desktop\cython_trys> python setup.py build_ext --inplace
Compiling test2.py because it changed.
Cythonizing test2.py

Error compiling Cython file:
------------------------------------------------------------
...
def primes(int kmax):
              ^
------------------------------------------------------------

test2.py:1:15: Expected ')', found 'kmax'
Traceback (most recent call last):
  File "setup.py", line 6, in <module>
    ext_modules = cythonize("test2.py")
  File "C:\Python27\lib\site-packages\Cython\Build\Dependencies.py", line 798, in cythonize
cythonize_one(*args[1:])
  File "C:\Python27\lib\site-packages\Cython\Build\Dependencies.py", line 915, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: test2.py

【问题讨论】:

  • 错误消息是来自文件系统的“权限被拒绝”,与代码无关。任何机会你构建了第一个,imported 到 Python 交互式解释器或脚本中,然后,没有退出,尝试在完全相同的路径中构建第二个,从而试图覆盖仍然打开的现有的,并且锁定?
  • 您将 Cython 文件命名为 .py 而不是 .pyx 是否有原因?此外,如果这真的是您的代码,那么显然有 IndentationError;问题仅仅是 Cython 给你错误的错误信息吗?

标签: python windows cython


【解决方案1】:

新问题只是您将文件命名为test2.py 而不是test2.pyx

如果您手动执行操作,Cython 并不关心您对文件的名称 — 如果您告诉它将某些代码编译为 Cython 代码,它就会编译它。

但是当您使用cythonize 函数创建ext_modules 时,它会根据扩展名猜测文件类型:.py 表示纯 Python 代码,.pyx 表示 Cython 代码。因此,它试图将您的代码编译为纯 Python,当然 int kmax 在 Python 中不是有效参数。 (当然,在其他测试中cdef 出错的原因是相同的。)

【讨论】:

    【解决方案2】:

    我不肯定这是问题所在,但至少有可能:

    错误信息是:

    cannot open output file C:\Users\Raoul\Desktop\cython_trys\test.pyd: Permission denied
    

    这可能不是因为您没有在cython_trys 中创建新文件的权限,而是因为已经有一个名为test.pyd 的文件以独占方式打开并因此被锁定,因此尝试使用新文件(正如gcc 试图做的那样)将失败。

    为什么它会被打开和锁定?

    好吧,如果您在交互式 Python 会话或脚本中执行了 import test 以测试第一个有效的 test.py,并且您让它运行,它仍然有 test.pyd 打开。最简单的解决方法是退出该 Python 会话或脚本。

    或者,您可以创建一个具有不同名称的新文件,而不是重复使用同一个文件。


    Unix 人编写的教程没有提到这一点的原因是,在 Unix 上,文件不会被删除,直到您删除文件系统中指向该文件的最后一个链接关闭最后一个文件在任何过程中处理它。所以,你可以rm 一个文件,或者在它上面写一个新文件,任何打开它的人仍然可以打开它并且可以很好地读写它。但是在 Windows 上,一旦最后一个文件系统链接消失,文件就可以被删除,即使其他人有它的句柄。这显然是灾难性的。所以 Windows 到处都使用独占访问锁来防止你做这样的事情。

    【讨论】:

    • 似乎我的部分问题来自于此(是的,我可能很愚蠢......),但是编译错误仍然存​​在(似乎任何包含cdef 的脚本都会产生该错误),请参阅更新的问题。顺便说一句,问题改变了,所以如果没有人完全解决这个问题,我会接受你的回答。
    • @Raoul:与其将一个问题编辑成一个完全不同的问题,不如只创建一个新问题(如果合适的话,将每个问题的链接放在另一个问题上)。从您的角度来看,您可以通过这种方式获得更多的代表;从网站优势的角度来看,这意味着任何遇到您原始问题的人都可以在搜索中找到它,而不是找到与他搜索的内容无关的完全不同的问题。
    • Oooooooook,所以我想我会躲在角落里,现在...问题是我将输入文件命名为 .py 而不是 .pyx。不管出于什么原因,我认为它与 pyrex 有关......非常感谢您的帮助!
    • @Raoul:它与 Pyrex 有关。 Cython 基本上是 Pyrex 的继承者,它使用相同的扩展的方式大致相同。
    • @Raoul:另外,那些简单的错误正是每个人都需要帮助的那种。你的大脑不会注意到如此琐碎和明显的事情,尤其是在你自己的代码中......