6 ms·
One other key part of this is freezing a timestamp with your dependency list, because Python packages are absolutely terrible at maintaining compatibility a yea
by epistasis 2y ago
One other key part of this is freezing a timestamp with your dependency list, because Python packages are absolutely terrible at maintaining compatibility a year or three or five later as PyPI populates with newer and newer versions. The special toml incantation is [tool.uv] exclude-newer:
# /// script
# dependencies = [
# "requests",
# ]
# [tool.uv]
# exclude-newer = "2023-10-16T00:00:00Z"
# ///
https://docs.astral.sh/uv/guides/scripts/#improving-reproducibility https://docs.astral.sh/uv/guides/scripts/#improving-reproduc...
This has also let me easily reconstruct some older environments in less than a minute, when I've been version hunting for 30-60 minutes in the past. The speed of uv environment building helps a ton too.
- athrun 2y agoGosh, thanks for sharing! This is the remaining piece I felt I was missing.
- epistasis 2y agoFor completeness, there's also a script.py.lock file that can be checked into version controls but then you have twice as many files to maintain, and potentially lose sync as people forget about it or don't know what to do with it.
- sunshowers 2y agoOooh! Do you end up doing a binary search by hand and/or does uv provide tools for that?
- code_biologist 2y agoWhere would binary search come into it? In the example, the version solver just sees the world as though no versions released after `2023-10-16T00:00:00Z` existed.
- sunshowers 2y agoI mean a binary search or a bisect over dates.
- woodruffw 2y agoMaybe I'm missing something, but why wouldn't you just pin to an exact version of `requests` (or whatever) instead? I think that would be equivalent in practice to limiting resolutions by release date, except that it would express your intent directly ("resolve these known working things") rather than indirectly ("resolve things from when I know they worked").
- athrun 2y agoPinning deps is a good thing, but it won't necessarily solve the issue of transitive dependencies (ie: the dependencies of requests itself for example), which will not be pinned themselves, given you don't have a lock file. To be clear, a lock file is strictly the better option—but for single file scripts it's a bit overkill.
- woodruffw 2y agoOh yeah, I completely forgot about transitive dependencies. That makes perfect sense, then! Very thoughtful design/inclusion from `uv`.
- einpoklum 2y agoOne could indicate implicit time-based pinning of transitive dependencies, using the time point at which the dependended-on versions were released. Not a perfect solution, but it's a possible approach.
- froh 2y agoisn't that quite exactly what the above does?
- kokada 2y agoI think OP was saying to look at when the package was build instead of explicitly adding a timestamp. Of course, this would only work if you speficied `requests@1.2.3` instead of just `requests`. This looks like a good strategy, but I wouldn't want it by default since it would be very weird to suddenly having a script pull dependencies from 1999 without explanation why.
- leni536 2y agoThat's fantastic, that's exactly what I need to revive a bit-rotten python project I am working with.
- procaryote 2y agoOh that's neat! I've just gotten into the habit of using only the dependencies I really must, because python culture around compatibility is so awful
- isoprophlex 2y agoWow, this is such an insanely useful tip. Thanks!
- zelphirkalt 2y agoWhy didn't you create a lock file with the versions and of course hashsums in it? No version hunting needed.
- zahlman 2y agoA major part of the point of PEP 723 (and the original competing design in PEP 722) is that the information a) is contained in the same physical file and b) can be produced by less sophisticated users.
- CJefferson 2y agoBecause the aim is to have a single file, fairly short, script. Even if we glued the lock file in somehow, it would be huge! I prefer this myself, as almost all lock files are in practice “the version of packages at this time and date”, so why not be explicit about that?
- CJefferson 2y agoThis is the feature I would most like added to rust, if you don’t save a lock file it is horrible trying to get back to the same versions of packages.
- HumanOstrich 2y agoWhy wouldn't you save the lock file?
- CJefferson 2y agoWell, of course you should, but it’s easy to forget as it’s not required. It also used to be recommended to not save it, so some people put it in their gitignore. For example, here is a post saying it was previously recommended to not save it for libraries: https://blog.rust-lang.org/2023/08/29/committing-lockfiles.html https://blog.rust-lang.org/2023/08/29/committing-lockfiles.h...