1. ホーム
  2. python

[解決済み] Cythonのコードを含むPythonパッケージはどのように構成すればよいのでしょうか?

2022-07-15 13:35:23

質問

Pythonのパッケージを作りたいのですが、いくつかの Cython のコードを含む Python パッケージを作りたいと思います。Cythonのコードはうまく動作しています。しかし、今私はそれをパッケージ化する最良の方法を知りたいのです。

パッケージをインストールしたいだけの人のために、私は .c ファイルを作成し、Cython が作成する setup.py がそれをコンパイルしてモジュールを生成するように手配します。そうすれば、ユーザーはパッケージをインストールするために Cython をインストールする必要はありません。

しかし、パッケージを変更したい人のために、Cython の .pyx ファイルを提供し、さらにどうにかして setup.py を Cython を使ってビルドできるようにしました (そのため、これらのユーザは は Cython をインストールする必要があります)。

これらのシナリオに対応するために、パッケージ内のファイルをどのように構成したらよいでしょうか。

このような場合 Cythonのドキュメントに少し指針があります . しかし、それは単一の setup.py を作る方法は書かれていません。

どのように解決するのですか?

私自身は、Pythonのパッケージの中で simplerandom ( ビットバケツレポ - 編集:現在 ギズブ になりました)(これが人気のあるパッケージになるとは思っていませんが、Cythonを学ぶ良い機会でした)。

このメソッドは .pyx ファイルを Cython.Distutils.build_ext (は、(少なくともCythonバージョン0.14では)常に .c ファイルを作成します。 .pyx ファイルを作成します。

以下は、切り出した setup.py を切り出したもので、要点を示していると思います。

from distutils.core import setup
from distutils.extension import Extension

try:
    from Cython.Distutils import build_ext
except ImportError:
    use_cython = False
else:
    use_cython = True

cmdclass = {}
ext_modules = []

if use_cython:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.pyx"]),
    ]
    cmdclass.update({'build_ext': build_ext})
else:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.c"]),
    ]

setup(
    name='mypackage',
    ...
    cmdclass=cmdclass,
    ext_modules=ext_modules,
    ...
)

また MANIFEST.in を確実にするために mycythonmodule.c が含まれていることを確認します (ソースディストリビューションは python setup.py sdist ):

...
recursive-include cython *
...

コミットしない mycythonmodule.c をバージョンコントロールの 'trunk' (Mercurial では 'default') にコミットしていません。リリースを作成するときは、忘れずに python setup.py build_ext を行う必要があります。 mycythonmodule.c が存在し、ソースコード配布のために最新であることを確認します。また、リリース用のブランチを作成し、そのブランチにCファイルをコミットします。そうすることで、そのリリースで配布された C ファイルの歴史的な記録を得ることができます。