5 ms·
May take on this, as a Python specialist who maintains a C++ library that exposes Python bindings (but not an expert in such), is that the Python packaging ecos
by avidphantasm 4y ago
May take on this, as a Python specialist who maintains a C++ library that exposes Python bindings (but not an expert in such), is that the Python packaging ecosystem (as it has organically grown) is a mess. I would like an authoritative (i.e., in the standard library) way to accomplish the major packaging tasks. I shouldn’t have to track down the current canonical way to do things from two or three sources.
- deleted 4y ago[deleted]
- noisenotsignal 4y agoAgree. I had a build pipeline pulling down an internal package to build into a `.pex` [0] file for running a Python program in a release pipeline that did not have access to the internal package repository. I came up with this solution because the typical virtualenv that you might build locally does not appreciate being copied wholesale to another system (iirc it had some absolute paths). One day the release pipeline broke because a dependency's authors published a new version containing a wheel for a newer ABI, though the older ABI was still supported. My build pipeline pulled the one for the later ABI because it was compatible, but the release pipeline environment, which could not be upgraded, did not have the newer version of gcc required. It was a nasty introduction to the fact that one Python package version can have multiple published wheels targeting different C++ compilers! But the worst part was not that I learned something new! It was that I wrangled with both pex and pip for a few hours trying to figure out how to download a wheel for an older ABI as both tools resolve the latest compatible by default. The options to do so are ostensibly there but the effect was not. I definitely could have made some mistakes but in my mind it shouldn't be _hard_ to get it right. I ended up downloading the wheel for the internal package in the build and copying it directly into the artifact. The release pipeline resolved public dependencies and installed the internal package from the local file. [0] - https://pex.readthedocs.io/en/latest/ https://pex.readthedocs.io/en/latest/
- orf 4y agoThe release pipeline broke because you didn't lock your dependencies.
- noisenotsignal 4y agoNot sure what you mean. pex is the dependency lock, at least from a version perspective. To be clear, it broke after I intentionally upgraded the offending package to the later version. I admit to being unaware of "versions inside versions" where a version may have multiple published ABIs that are not compatible across systems, but a nice packaging system would still make it easy for me to use platform X to build for platform Y.
- orf 4y agoOh, from your "One day the release pipeline broke because a dependency's authors published a new version..." wording it seemed that this breakage occurred without you upgrading anything.
- noisenotsignal 4y agoSorry for the wording, I see how it can be interpreted that way. Seems I skipped a few details on accident.
- bsder 4y ago> It was a nasty introduction to the fact that one Python package version can have multiple published wheels targeting different C++ compilers! Erm, is this not the failure of C++ standards instead of Python? This seems like Python is the failure point being caused by C++ not having a stable ABI. Python is simply trying to paper over the brokenness of the C++ ecosystem. Am I missing something?
- noisenotsignal 4y agoThat’s a good point! However, there’s still things Python could do to help make the experience better. The package I was using had multiple artifacts per version, including the raw zipped source code and wheels for each ABI they built for. It’s certainly convenient that the most applicable one for your current system is pulled automatically by pip. But in this case that’s not the behavior I wanted, and I could not successfully get pex or pip to download a “less optimal” artifact. You can blame C++, but if Python is already papering over deficiencies it’s not unreasonable to expect improvements that aren’t fundamentally impossible. It should definitely be possible for there to be one easily understood argument to specify which artifact pip should download. In my (potentially flawed) experience, figuring out which ABI value to pass was already not straightforward. Even then, the arguments for selecting an ABI or even asking for the raw source instead of a wheel weren’t seeming to have an effect.
- inferiorhuman 4y agoIt always struck me as a bit ironic that such an opinionated language could utterly fail to have "one right way" to package things. As much as Rust's aversion to binaries can be a pain, building and packaging (even cross building) is generally painless.
- 323 4y agoThat's because Rust is tiny and new. Wait until you have Rust packages which include and wrap hundred of thousands of lines of very old C and Fortran code like numpy has.
- inferiorhuman 4y agoNah. It'd probably be surprising how many crates have dependencies here and there on C code – mostly it's seamless even when cross compiling. I've gotten (ages ago) a cross toolchain setup to build binaries for one of those MIPS routers and the biggest pain point was being stuck on an antiquated Debian where cross compiling was painful. There are popularity issues with Rust (e.g. crate namespacing), but non-Rust code hasn't been one of them for me. So far Conda is pretty much the only problem I've had with native code mingling with Python (although pip was able to get numpy installed on my BSD box). Otherwise it's an issue of the tooling just being really archaic. Which is amusing to me given how much hand wringing there is over providing one right, idiomatic way to do things (e.g. ternary operator). For me digging into Stable Diffusion (and related bits and bobs) was a bit of an eye opener with just how much cargo culting is going on. Installation instructions are often copy and pasted from other related projects. Or maybe just check out our repo and follow the instructions from some other project. Honestly, my hope is that some of the effort spent obsessing about language details gets spent on coming up with a better packaging and dependency management story.
- fiedzia 4y ago> That's because Rust is tiny and new. Dozens of other languages that are tiny and new do not have good packaging story. Rust does, because it cares about developer experience. > Wait until you have Rust packages which include and wrap hundred of thousands of lines of very old C and Fortran code like numpy has. I don't know about Fortran, but C is basically legacy at this point, it doesn't change much and even if it does, there is one some-c-lib wrapper package that takes care of all those issues, Rust apps rarely depend on some C dependency directly.
- blooalien 4y agohttps://www.pypa.io/ https://www.pypa.io/ ? "The PyPA publishes the Python Packaging User Guide [1], which is the authoritative resource on how to package, publish, and install Python projects using current tools." [1]: https://packaging.python.org/ https://packaging.python.org/
- avidphantasm 4y agoLast I checked, and I could be missing something, PyPA doesn’t say how to package extensions using the new pyproject.toml style. I happen to be using SWIG (which I inherited), which suggests the use of setup.py alone. I just haven’t had time to figure out the right path.
- blooalien 4y agoI dunno about using it with SWIG but I've had a pretty good experience using Poetry [1] for pure Python stuff myself. That uses pyproject.toml to declare all your project's dependencies, but no idea if it can be used with SWIG or not. I'd have to research it… [1]: https://python-poetry.org/ https://python-poetry.org/ Edit: Some quick cursory research seems to indicate I'd have to do some custom scripting to integrate SWIG into the process.
- filmor 4y agoPoetry is currently not useful for extensions: https://github.com/python-poetry/poetry/issues/2740 https://github.com/python-poetry/poetry/issues/2740
- filmor 4y agoYou can migrate a lot out of your setup.py into the pyproject.toml nowadays (https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html https://setuptools.pypa.io/en/latest/userguide/pyproject_con...).
- xapata 4y agoWouldn't you make a wheel?