Victor Stinner schrieb am 17.06.20 um 13:25:
Le mer. 17 juin 2020 à 12:38, Petr Viktorin a écrit :
There is an ongoing discussion about always requiring to run Cython when installing a C extension which uses Cython.
Do you have a link to that discussion?
Yeah, I was wondering, too. :)
Hum, I forgot where the discussion happened. Maybe it wasn't a proper "discussion", but just a few tweets: https://twitter.com/tacaswell/status/1266472526806474752
Thomas A Caswell wrote: "also, if you use cython please make it a build-time dependency and please don't put the generated c code in the sdists. cython can only handle the changes in the CPyhon c-api if you let it!"
So much for random opinions on the Internet. ;-)
I still recommend generating the C code on the maintainer side and then shipping it. Both approaches have their pros and cons, but that's definitely what I recommend.
First of all, making Cython a build time dependency and then pinning an exact Cython version with it is entirely useless, because the C code that Cython outputs is deterministic and you can just generate it on your side and ship it. One dependency less, lots of user side complexity avoided. So, the only case we're talking about here is allowing different (usually newer) Cython versions to build your code.
If you ship the C file, then you know what you get and you don't depend on whatever Cython version users have installed on their side. You avoid the maintenance burden of having to respond to bug reports for seemingly unrelated C code lines or bugs in certain Cython versions. The C code that Cython generates is very intentionally adaptive to where you compile it and we work hard to do all environment specific adaptations in the C code and not in the code generator that creates it. It's the holy cow of "generate once, compile everywhere". But obviously, it cannot take as-of-now unknown future environmental changes into account, such as changes to the CPython C-API.
If, instead, you use Cython at package build time, then you risk build failures on user side due to users having a buggy Cython version installed (which may not have existed when you shipped the package, so you couldn't exclude it), or your code failing to compile with the installed Cython due to incompatible language changes. However, if those (somewhat exceptional) cases don't happen, then you may end up with a setting in which your code adapts also to newer environments, by using a recent Cython version automatically. That is definitely an advantage.
Basically, for maintained packages, I consider shipping the generated C code the right way. Less hassle, easier debugging, better user experience. For unmaintained packages, regenerating the C code at build time *can* extend the lifetime of the package to newer environments for as long as it does not run into failures due to Cython compiler changes (so you trade one compatibility level for another one).
The question is whether the point at which a package becomes unmaintained can ever be clear enough to make the switch. Regardless of which way you choose, at some point in the future someone will have to do something, either to your code or to your build setup, in order to prevent fatal bitrot.