Python Modern Practices
stuartellis.name
stuartellis.name
I have seen occasional hiccups, so we don't use it in prod just yet. But I use it in local all the time.
They've been responsive to issues, so give it a shot.
[0] pipenv.pypa.io
Isn't this obsoleted by the previous section on using pyproject.toml?
Also kinda weird he says to not use pip, but requirements.txt are pip commands... And should be running with pip... Hmm I don't know about this article anymore.
I did come across a weird dependency confusion issue recently when I tried using it on a server setup with piku though, but haven't gotten around to find what exactly is happening.
Also don't think I'll ever give up on YAML for it's easy read+write, and I love the simplicity of fire for CLI things. And pathlib.Path().glob() for directory listing.
For my use the key is how easily you can add simple conversion of values to attrs. IIRC this was intentionally omitted from dataclasses. For a 1-off using a factory with a dataclass is easy but repeated uses send me back to attrs
Most people don't need, say, a[-3] as an alias for a.field_name.
Otherwise, for those who want the standard library, use a dataclass with frozen=True for immutability.
If you want easier than recarray and almost as fast I think you're in pandas-ville
What? This is the first I've heard of this.
As far as I can tell the issue is still open and has been for awhile.
But that's not what soured me on Poetry. What soured me was recently I needed to create a release of one of their libraries with a Git commit in the local version identifier and... Poetry doesn't do that. There's an issue that was open on GitHub for years before they finally agreed to implement it, and since February the change is now merged to master, but despite several point releases since then, that change has not landed in any of them. When will we be able to get a local version part? Who knows!
This experience has really made me skeptical of Poetry being the One True Packaging Tool that fixes everything. As usual, it just fixes the things the devs want fixed and everything else is still janky or half implemented. From my perspective, if you're gonna deal with jank anyway, might as well just deal with the standard jank that comes as part of Python itself.
It manages both python versions (which it downloads instead of compiling) and package versions. It's written in rust so it's faster and can replace pipx as well for installing global tools. (Some people will recommend uv which rye is slowly merging with buy uv is still missing some rye features, probably some time in the future you might want to switch).
No complaints, and has shoot-in-the-foot safety features
what's wrong with pip freeze? why are there so many competing tools?
it's very anti-python IMO.
I prefer my requirements.txt to include only the packages I install with pip myself (and not their dependencies).
Aside from all the obvious issues of having no distinction between transitive and direct dependencies, it completely breaks cross-platform support if any of your dependencies have platform-specific sub-dependencies (which is not uncommon in python).
fair point, so when this packaging mess happens, can one not strike a balance, and define the dependencies that you need, then, and let the resolver handle the rest?
A final few, even with the explanation given, feels like preference, such as the Poetry opinion. I suppose if I wrote a similar article, it would end up with a similar mix of obvious defaults and a few of my preferences.
It could also be because of different use cases? For example, writing a library for packaging, vs a deployed application, vs a personal projects' workbench. Or perhaps if you are collaborating with people who use Windows without WSL. I have heard tell that Poetry can sometimes trip over its own shoelaces on Windows. I have never experienced it myself, and don't personally care to support any projects involving Windows, but if I did I might have different preferences.
The power of Pydantic models comes with benefits in terms of what they're able to do out of the box. But this comes at a significant cost of speed, which does matter for some applications. There are plenty of applications where it simply doesn't make sense to validate types every time you stand up a class.
Sure you can turn some of that off with Pydantic, etc, etc, but the fact that dataclasses don't require a third party install and are efficient and easy out of the box makes them useful and non-duplicative.