Saya ingin membuat paket Python yang berisi beberapa kode Cython . Saya mendapatkan kode Cython yang berfungsi dengan baik. Namun, sekarang saya ingin tahu cara terbaik untuk mengemasnya.
Bagi kebanyakan orang yang hanya ingin menginstal paket, saya ingin menyertakan .c
file yang dibuat Cython, dan mengaturnya untuk setup.py
mengkompilasinya untuk menghasilkan modul. Maka pengguna tidak perlu menginstal Cython untuk menginstal paket.
Tetapi bagi orang-orang yang mungkin ingin mengubah paket, saya juga ingin menyediakan .pyx
file Cython , dan entah bagaimana juga mengizinkan untuk setup.py
membangunnya menggunakan Cython (sehingga pengguna tersebut perlu menginstal Cython).
Bagaimana saya harus menyusun file dalam paket untuk memenuhi kedua skenario ini?
The dokumentasi Cython memberikan sedikit pengarahan . Tapi itu tidak mengatakan bagaimana membuat single setup.py
yang menangani kasus dengan / tanpa Cython.
Jawaban:
Saya telah melakukan ini sendiri sekarang, dalam paket Python
simplerandom
( BitBucket repo - EDIT: now github ) (Saya tidak berharap ini menjadi paket yang populer, tetapi ini adalah kesempatan bagus untuk mempelajari Cython).Metode ini bergantung pada fakta bahwa membangun
.pyx
file denganCython.Distutils.build_ext
(setidaknya dengan versi Cython 0.14) sepertinya selalu membuat.c
file di direktori yang sama dengan.pyx
file sumber .Berikut adalah versi cut-down
setup.py
yang saya harap menunjukkan hal-hal penting:Saya juga mengedit
MANIFEST.in
untuk memastikan itumycythonmodule.c
termasuk dalam distribusi sumber (distribusi sumber yang dibuat denganpython setup.py sdist
):Saya tidak berkomitmen
mycythonmodule.c
untuk kontrol versi 'trunk' (atau 'default' untuk Mercurial). Ketika saya membuat rilis, saya harus ingat untuk melakukan yangpython setup.py build_ext
pertama, untuk memastikan bahwamycythonmodule.c
ada dan terbaru untuk distribusi kode sumber. Saya juga membuat cabang rilis, dan memasukkan file C ke dalam cabang. Dengan cara itu saya memiliki catatan sejarah dari file C yang didistribusikan dengan rilis tersebut.sumber
Menambahkan jawaban Craig McQueen: lihat di bawah untuk cara menimpa
sdist
perintah agar Cython secara otomatis mengkompilasi file sumber Anda sebelum membuat distribusi sumber.Dengan cara itu, Anda tidak berisiko menyebarkan
C
sumber-sumber yang sudah usang secara tidak sengaja . Ini juga membantu dalam kasus di mana Anda memiliki kendali terbatas atas proses distribusi misalnya ketika secara otomatis membuat distribusi dari integrasi berkelanjutan dll.sumber
http://docs.cython.org/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules
sumber
Yang termudah adalah memasukkan keduanya tetapi cukup gunakan file-c? Menyertakan file .pyx memang bagus, tetapi tidak diperlukan setelah Anda memiliki file .c. Orang yang ingin mengkompilasi ulang .pyx dapat menginstal Pyrex dan melakukannya secara manual.
Jika tidak, Anda perlu memiliki perintah build_ext kustom untuk distutils yang membuat file C terlebih dahulu. Cython sudah termasuk satu. http://docs.cython.org/src/userguide/source_files_and_compilation.html
Apa yang dokumentasi tidak lakukan adalah mengatakan bagaimana membuat ini bersyarat, tapi
Harus menanganinya.
sumber
setup.py
dapat membangun langsung dari.pyx
file ketika Cython diinstal. Jawaban saya telah menerapkannya juga.Menyertakan file .c yang dihasilkan (Cython) cukup aneh. Terutama jika kita memasukkannya ke dalam git. Saya lebih suka menggunakan setuptools_cython . Ketika Cython tidak tersedia, itu akan membuat telur yang memiliki lingkungan Cython built-in, dan kemudian membangun kode Anda menggunakan telur.
Contoh yang memungkinkan: https://github.com/douban/greenify/blob/master/setup.py
Perbarui (2017-01-05):
Karena
setuptools 18.0
, tidak perlu menggunakansetuptools_cython
. Berikut adalah contoh untuk membangun proyek Cython dari awal tanpasetuptools_cython
.sumber
'setuptools>=18.0'
setup_requires daripada membuat metodeis_installed
?setuptools>=18.0
telah terpasang, maka Anda hanya perlu menempatkan'Cython >= 0.18'
disetup_requires
, dan Cython akan dipasang selama instalasi berlangsung. Tetapi jika Anda menggunakan setuptools <18.0, meskipun Anda menggunakan cython tertentu di setup_requires, itu tidak akan diinstal, dalam hal ini, Anda harus mempertimbangkan untuk menggunakannyasetuptools_cython
.pip install wheel
. Maka itu pasti alasan 1. Silakan pasang roda terlebih dahulu dan coba lagi.Ini adalah skrip pengaturan yang saya tulis yang membuatnya lebih mudah untuk menyertakan direktori bersarang di dalam build. Seseorang perlu menjalankannya dari folder dalam sebuah paket.
Struktur Givig seperti ini:
setup.py
Selamat menyusun;)
sumber
Peretasan sederhana yang saya buat:
Instal saja Cython jika tidak bisa diimpor. Seseorang mungkin tidak boleh membagikan kode ini, tetapi untuk dependensi saya sendiri itu cukup baik.
sumber
Semua jawaban lain bergantung pada
Cython.Build
, yang menciptakan masalah ayam-dan-telur antara membutuhkan cython melaluisetup_requires
dan mengimpornya.Solusi modern adalah dengan menggunakan setuptools, lihat jawaban ini (penanganan otomatis ekstensi Cython memerlukan setuptools 18.0, yaitu sudah tersedia selama bertahun-tahun). Standar modern
setup.py
dengan penanganan persyaratan, titik masuk, dan modul cython bisa terlihat seperti ini:sumber
Cython.Build
pada waktu penyiapan menyebabkan ImportError bagi saya. Memiliki setuptools untuk mengkompilasi pyx adalah cara terbaik untuk melakukannya.Cara termudah yang saya temukan dengan hanya menggunakan setuptools daripada fitur distutils terbatas adalah
sumber
Cython.Build
, lihat jawaban saya.Saya rasa saya menemukan cara yang cukup bagus untuk melakukan ini dengan memberikan
build_ext
perintah khusus . Idenya adalah sebagai berikut:Saya menambahkan header numpy dengan menimpa
finalize_options()
dan melakukanimport numpy
di badan fungsi, yang dengan baik menghindari masalah numpy tidak tersedia sebelumsetup()
menginstalnya.Jika cython tersedia di sistem, itu akan menghubungkan ke metode perintah
check_extensions_list()
dan dengan melakukan cython semua modul cython yang sudah kadaluwarsa, menggantinya dengan ekstensi C yang nantinya dapat ditangani olehbuild_extension()
metode. Kami hanya menyediakan bagian terakhir dari fungsionalitas dalam modul kami juga: ini berarti bahwa jika cython tidak tersedia tetapi kami memiliki ekstensi C, ini masih berfungsi, yang memungkinkan Anda untuk melakukan distribusi sumber.Berikut kodenya:
Ini memungkinkan seseorang untuk hanya menulis
setup()
argumen tanpa khawatir tentang impor dan apakah ada cython yang tersedia:sumber