Bug 2299712 - Review Request: uv - An extremely fast Python package installer and resolver, written in Rust
Summary: Review Request: uv - An extremely fast Python package installer and resolver,...
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: Package Review
Version: rawhide
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Miro Hrončok
QA Contact: Fedora Extras Quality Assurance
URL: https://github.com/astral-sh/uv
Whiteboard:
Depends On:
Blocks: 2278565 2299646
TreeView+ depends on / blocked
 
Reported: 2024-07-24 16:36 UTC by Ben Beasley
Modified: 2024-08-13 01:34 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2024-08-01 04:24:22 UTC
Type: ---
Embargoed:
mhroncok: fedora-review+


Attachments (Terms of Use)

Description Ben Beasley 2024-07-24 16:36:28 UTC
Spec URL: https://music.fedorapeople.org/uv.spec
SRPM URL: https://music.fedorapeople.org/uv-0.2.28-1.fc40.src.rpm

Description:

An extremely fast Python package installer and resolver, written in Rust.
Designed as a drop-in replacement for common pip and pip-tools workflows.

Highlights:

  • ⚖️  Drop-in replacement for common pip, pip-tools, and virtualenv commands.
  • ⚡️ 10-100x faster than pip and pip-tools (pip-compile and pip-sync).
  • 💾 Disk-space efficient, with a global cache for dependency deduplication.
  • 🐍 Installable via curl, pip, pipx, etc. uv is a static binary that can be
    installed without Rust or Python.
  • 🧪 Tested at-scale against the top 10,000 PyPI packages.
  • 🖥️i Support for macOS, Linux, and Windows.
  • 🧰 Advanced features such as dependency version overrides and alternative
    resolution strategies.
  • ⁉️  Best-in-class error messages with a conflict-tracking resolver.
  • 🤝 Support for a wide range of advanced pip features, including editable
    installs, Git dependencies, direct URL dependencies, local dependencies,
    constraints, source distributions, HTML and JSON indexes, and more.

Fedora Account System Username: music

This package built in koji:

https://koji.fedoraproject.org/koji/taskinfo?taskID=120971201

Since upstream development is very rapid, with usually more than one release per week, it is likely that this submission will be slightly out of date by the time the review is completed. I plan to update this regularly after import to avoid falling behind on dealing with new and updated Rust crate dependencies.

Comment 1 Miro Hrončok 2024-07-24 17:38:14 UTC
Spec sanity:

----------

This is not a Rust crate, so the name of the component is OK.

----------

The Licenses in the comment and in the License tag seem to be represented differently. See e.g. "Zlib OR Apache-2.0 OR MIT" vs "Apache-2.0 OR MIT OR Zlib" -- this is confusing and hard to verify.

----------

Suggestion: Number patches after sources, i.e. rename Patch100 to Patch201 and Patch101 to Patch301 -- that way it is more obvious which potch goes where (and possibly also %autopatch could be used, with ranges, but I have not tried that from subdirectories).

----------

> # Downstream-only: do not override the default allocator

It is not obvious why this is needed. The comment rather says we might want to drop it. I assume this is to avoid an unpackaged dependency... ?

----------

>  • ⚖️  Drop-in replacement for common pip, pip-tools, and virtualenv commands.
>  • ⁉️  Best-in-class error messages with a conflict-tracking resolver.

Those two bullet points have double spaces after the emoji.

----------

> %package -n python3-uv
> Summary:        %{summary}

This subpackage should have a different summary.

----------

> %if 0%{?__isa_bits} == 32

Have you considered excluding i686 from the start? This should be a leaf package except for hatch which is noarch.

https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval

----------

The %prep section is a monstrosity, but it was surprisingly easy to follow. The comments are very helpful, thanks.

----------

> export RUSTFLAGS='%{build_rustflags}'

This should be part of %set_build_flags, is it actually needed?

----------

> # -p uv-auth --lib:

I got a bit confused by this comment in %check. What does it relate to?

Comment 2 Ben Beasley 2024-07-24 18:24:44 UTC
(In reply to Miro Hrončok from comment #1)
> The Licenses in the comment and in the License tag seem to be represented
> differently. See e.g. "Zlib OR Apache-2.0 OR MIT" vs "Apache-2.0 OR MIT OR
> Zlib" -- this is confusing and hard to verify.

I ordered the components of disjunctive license expressions alphabetically because in very many cases, there are differently-ordered equivalent versions among the statically linked crate dependencies. For example, the raw %{cargo_license_summary} output contains all of the following:

# MIT OR Apache-2.0 OR Zlib
# MIT OR Zlib OR Apache-2.0
# Zlib OR Apache-2.0 OR MIT

It’s hard to deduplicate these, or quickly check if a combination of licenses already exits in the License expression, without applying some sort of consistent normalization. It’s also kind of aesthetically displeasing to have to choose one form over the other two with no particular rationale.

I’m open to other approaches, but I’m also also mindful of the need to cross-check and update the License expression when updating the package, without having to go through every part of it from scratch. How would you prefer to write the License expression?

> Suggestion: Number patches after sources, i.e. rename Patch100 to Patch201
> and Patch101 to Patch301 -- that way it is more obvious which potch goes
> where (and possibly also %autopatch could be used, with ranges, but I have
> not tried that from subdirectories).

This is a good suggestion. I’ll try it.

> > # Downstream-only: do not override the default allocator
> 
> It is not obvious why this is needed. The comment rather says we might want
> to drop it. I assume this is to avoid an unpackaged dependency... ?

Yes, I can add some detail to that comment. Packaging tikv-jemallocator would
involve packaging a cluster of its dependencies and overcoming some fussy
packaging issues. Since using it is “just” a performance optimization, and a
relatively moderate one, this can be optional follow-up work rather than a
blocker for packaging uv.

> >  • ⚖️  Drop-in replacement for common pip, pip-tools, and virtualenv commands.
> >  • ⁉️  Best-in-class error messages with a conflict-tracking resolver.
> 
> Those two bullet points have double spaces after the emoji.

Good catch! It looks like I introduced those spaces downstream. I’ll fix them.

> > %package -n python3-uv
> > Summary:        %{summary}
> 
> This subpackage should have a different summary.

How about this?

  Summary:        Importable Python module for uv

> Have you considered excluding i686 from the start? This should be a leaf
> package except for hatch which is noarch.

Sure, that’s a good idea now that noarch packages no longer build on i686.

> > export RUSTFLAGS='%{build_rustflags}'
> 
> This should be part of %set_build_flags, is it actually needed?

Hmm, it doesn’t look like it. Perhaps I copied that thoughtlessly from something else, or perhaps I did it in anticipation of possibly backporting to EPEL9 where %set_build_flags is not automatic – but I can cross that bridge when and if I get there.

> > # -p uv-auth --lib:
> 
> I got a bit confused by this comment in %check. What does it relate to?

It corresponds to the "cargo test" options that would run the group of tests in which the failure occurred:

  Package Selection:
    -p, --package [<SPEC>]  Package to run tests for
  Target Selection:
        --lib               Test only this package's library

So these tests are in the library (vs. binary, example, test, or bench) tests of the uv-auth workspace crate.

  test result: FAILED. 15 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s
  
  error: test failed, to rerun pass `-p uv-auth --lib`

Additionally, these flags are the "target" for which cargo test reports failure when summarizing all test results:

  error: 1 target failed:
      `-p uv-auth --lib`

Comment 3 Yaakov Selkowitz 2024-07-24 19:03:43 UTC
Are emoji in the spec file even acceptable (iow might they break something)?

Comment 4 Fabio Valentini 2024-07-24 20:04:20 UTC
> > > export RUSTFLAGS='%{build_rustflags}'
> > 
> > This should be part of %set_build_flags, is it actually needed?

> Hmm, it doesn’t look like it. Perhaps I copied that thoughtlessly from something else, or perhaps I did it in anticipation of possibly backporting to EPEL9 where %set_build_flags is not automatic – but I can cross that bridge when and if I get there.

RUSTFLAGS are only part of %set_build_flags on newer Fedora branches. I don't quite remember if it's F40+ or F39+ ... so it's necessary for older branches (and just redundant on newer branches).

Comment 5 Fabio Valentini 2024-07-24 20:09:46 UTC
Side note:

Maybe just drop ", written in Rust" from the Summary. That's arguably an implementation detail and not really useful in the Summary

Comment 6 Miro Hrončok 2024-07-24 22:45:11 UTC
(In reply to Ben Beasley from comment #2)
> (In reply to Miro Hrončok from comment #1)
> > The Licenses in the comment and in the License tag seem to be represented
> > differently. See e.g. "Zlib OR Apache-2.0 OR MIT" vs "Apache-2.0 OR MIT OR
> > Zlib" -- this is confusing and hard to verify.
> 
> I ordered the components of disjunctive license expressions alphabetically
> because in very many cases, there are differently-ordered equivalent
> versions among the statically linked crate dependencies. For example, the
> raw %{cargo_license_summary} output contains all of the following:
> 
> # MIT OR Apache-2.0 OR Zlib
> # MIT OR Zlib OR Apache-2.0
> # Zlib OR Apache-2.0 OR MIT
> 
> It’s hard to deduplicate these, or quickly check if a combination of
> licenses already exits in the License expression, without applying some sort
> of consistent normalization. It’s also kind of aesthetically displeasing to
> have to choose one form over the other two with no particular rationale.
> 
> I’m open to other approaches, but I’m also also mindful of the need to
> cross-check and update the License expression when updating the package,
> without having to go through every part of it from scratch. How would you
> prefer to write the License expression?

I'll think about it.


> > > %package -n python3-uv
> > > Summary:        %{summary}
> > 
> > This subpackage should have a different summary.
> 
> How about this?
> 
>   Summary:        Importable Python module for uv

+1

(In reply to Fabio Valentini from comment #4)
> > > > export RUSTFLAGS='%{build_rustflags}'
> > > 
> > > This should be part of %set_build_flags, is it actually needed?
> 
> > Hmm, it doesn’t look like it. Perhaps I copied that thoughtlessly from something else, or perhaps I did it in anticipation of possibly backporting to EPEL9 where %set_build_flags is not automatic – but I can cross that bridge when and if I get there.
> 
> RUSTFLAGS are only part of %set_build_flags on newer Fedora branches. I
> don't quite remember if it's F40+ or F39+ ... so it's necessary for older
> branches (and just redundant on newer branches).

F39+ but it is necessary on EPEL9 (which does not have automatic %set_build_flags and dos not seem to have RUSATFLAGS in %set_build_flags).



(In reply to Yaakov Selkowitz from comment #3)
> Are emoji in the spec file even acceptable (iow might they break something)?

As with any Unicode symbols, they are acceptable. A bit unorthodox, but definitively acceptable.


(In reply to Fabio Valentini from comment #5)
> Side note:
> 
> Maybe just drop ", written in Rust" from the Summary. That's arguably an
> implementation detail and not really useful in the Summary

That's how upstream presents itself. I'd keep it. (It's probably not allowed to write a tool in Rust without saying "written in Rust" in the description :D)

Comment 7 Fedora Review Service 2024-07-25 07:23:13 UTC
Copr build:
https://copr.fedorainfracloud.org/coprs/build/7784059
(succeeded)

Review template:
https://download.copr.fedorainfracloud.org/results/@fedora-review/fedora-review-2299712-uv/fedora-rawhide-x86_64/07784059-uv/fedora-review/review.txt

Found issues:

- No gcc, gcc-c++ or clang found in BuildRequires
  Read more: https://docs.fedoraproject.org/en-US/packaging-guidelines/C_and_C++/

Please know that there can be false-positives.

---
This comment was created by the fedora-review-service
https://github.com/FrostyX/fedora-review-service

If you want to trigger a new Copr build, add a comment containing new
Spec and SRPM URLs or [fedora-review-service-build] string.

Comment 8 Miro Hrončok 2024-07-25 08:16:09 UTC
$ rpmlint uv-0.2.28-1.fc41.src.rpm python3-uv-0.2.28-1.fc41.noarch.rpm uv-0.2.28-1.fc41.src.rpm ../srpm/uv.spec 
============================ rpmlint session starts ============================
rpmlint: 2.5.0
configuration:
    /usr/lib/python3.12/site-packages/rpmlint/configdefaults.toml
    /etc/xdg/rpmlint/fedora-legacy-licenses.toml
    /etc/xdg/rpmlint/fedora-spdx-licenses.toml
    /etc/xdg/rpmlint/fedora.toml
    /etc/xdg/rpmlint/scoring.toml
    /etc/xdg/rpmlint/users-groups.toml
    /etc/xdg/rpmlint/warn-on-functions.toml
checks: 32, packages: 3

python3-uv.noarch: E: spelling-error ('deduplication', '%description -l en_US deduplication -> reduplication, duplication, quadruplication')
python3-uv.noarch: E: spelling-error ('pipx', '%description -l en_US pipx -> pip, pix, pipe')
python3-uv.noarch: E: spelling-error ('macOS', '%description -l en_US macOS -> ma Cos, mac OS, mac-OS')
uv.src: E: spelling-error ('deduplication', '%description -l en_US deduplication -> reduplication, duplication, quadruplication')
uv.src: E: spelling-error ('pipx', '%description -l en_US pipx -> pip, pix, pipe')
uv.src: E: spelling-error ('macOS', '%description -l en_US macOS -> ma Cos, mac OS, mac-OS')
python3-uv.noarch: W: no-documentation
 2 packages and 1 specfiles checked; 6 errors, 1 warnings, 9 filtered, 6 badness; has taken 0.7 s 


<mock-chroot> sh-5.2# rpmlint --installed uv python3-uv
============================ rpmlint session starts ============================
rpmlint: 2.5.0
configuration:
    /usr/lib/python3.13/site-packages/rpmlint/configdefaults.toml
    /etc/xdg/rpmlint/fedora-legacy-licenses.toml
    /etc/xdg/rpmlint/fedora-spdx-licenses.toml
    /etc/xdg/rpmlint/fedora.toml
    /etc/xdg/rpmlint/scoring.toml
    /etc/xdg/rpmlint/users-groups.toml
    /etc/xdg/rpmlint/warn-on-functions.toml
checks: 32, packages: 2

uv.x86_64: E: spelling-error ('virtualenv', '%description -l en_US virtualenv -> virtual')
uv.x86_64: E: spelling-error ('deduplication', '%description -l en_US deduplication -> reduplication, duplication, quadruplication')
uv.x86_64: E: spelling-error ('pipx', '%description -l en_US pipx -> pip, pix, pipe')
uv.x86_64: E: spelling-error ('macOS', '%description -l en_US macOS -> ma Cos, mac OS, mac-OS')
python3-uv.noarch: E: spelling-error ('virtualenv', '%description -l en_US virtualenv -> virtual')
python3-uv.noarch: E: spelling-error ('deduplication', '%description -l en_US deduplication -> reduplication, duplication, quadruplication')
python3-uv.noarch: E: spelling-error ('pipx', '%description -l en_US pipx -> pip, pix, pipe')
python3-uv.noarch: E: spelling-error ('macOS', '%description -l en_US macOS -> ma Cos, mac OS, mac-OS')
uv.x86_64: W: no-manual-page-for-binary uv
uv.x86_64: W: no-manual-page-for-binary uvx
python3-uv.noarch: W: no-documentation
 2 packages and 0 specfiles checked; 8 errors, 3 warnings, 7 filtered, 8 badness; has taken 0.3 s 



The spelling-errors are OK, possibly to be excluded in rpmlint.toml.
The no-manual-page-for-binary is addressed in a comment in the specfile.

Comment 9 Miro Hrončok 2024-07-25 08:17:27 UTC
The license comment in the specfile matches the output of %{cargo_license_summary} during the build.

Comment 10 Miro Hrončok 2024-07-25 08:34:00 UTC
There are bundled things in the sources:


uv-0.2.28/crates/uv-python/python/packaging is python3dist(packaging) = 24.1~~dev0; BSD-2-Clause OR Apache-2.0

This is not present in the uv package as Python files but it seems compiled into the uv executable:

  $ grep -E '__title__ = "packaging"' bin/uv
  grep: bin/uv: binary file matches
  $ grep -E '__author__ = "Donald Stufft and individual contributors"' bin/uv
  grep: bin/uv: binary file matches


uv-0.2.28/crates/uv-extract/src/vendor/cloneable_seekable_reader.rs
// Copyright 2022 Google LLC

// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.


uv-0.2.28/crates/uv-client/src/remote_metadata.rs
/// This method is derived from `prefix-dev/rip`, which is available under the following BSD-3
/// Clause license:
///
/// ```text
/// BSD 3-Clause License
///
/// Copyright (c) 2023, prefix.dev GmbH
///
/// ...
/// ```
///
/// Additional work and modifications to the originating source are available under the
/// Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
/// or MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>), as per the
/// rest of the crate.



uv-0.2.28/crates/pep440-rs
uv-0.2.28/crates/pep508-rs

Both are Apache-2.0 OR BSD-2-Clause, both re 0.6.0 seem to be from crates.io

There are other crates in uv-0.2.28/crates/ that seem suspicious.




Files in uv-0.2.28/crates/uv-virtualenv/src/activator/ seem bundled from virtualenv

# Copyright (c) 2020-202x The virtualenv developers ... MIT

Comment 11 Miro Hrončok 2024-07-25 08:40:26 UTC
Package Review
==============

Legend:
[x] = Pass, [!] = Fail, [-] = Not applicable, [?] = Not evaluated


Issues:
=======
The list of bundles things is not complete. License might be complete, as the rust dependencies licenses are quite exhausting, so the bundled stuff is likely already covered by chance.



===== MUST items =====

C/C++ (it is not, but I kept the checks):
[x]: Package does not contain kernel modules.
[x]: Header files in -devel subpackage, if present.
[x]: Package does not contain any libtool archives (.la)
[x]: Package contains no static executables.
[x]: Rpath absent or only used for internal libs.

Generic:
[x]: Package is licensed with an open-source compatible license and meets
     other legal requirements as defined in the legal section of Packaging
     Guidelines.
[ ]: License field in the package spec file matches the actual license.
     Note: Checking patched sources after %prep for licenses. Licenses
     found: "Unknown or generated", "MIT License", "*No copyright* Apache
     License 2.0", "*No copyright* Apache License and/or MIT License", "BSD
     2-Clause License", "Apache License 2.0 and/or BSD 3-Clause License",
     "Apache License (v2.0) or MIT license", "*No copyright* BSD 2-Clause
     License". 778 files have unknown license. Detailed output of
     licensecheck in
     /home/churchyard/rpmbuild/FedoraReview/2299712-uv/licensecheck.txt
[x]: License file installed when any subpackage combination is installed.
[x]: If the package is under multiple licenses, the licensing breakdown
     must be documented in the spec.
[x]: Package requires other packages for directories it uses.
[x]: Package must own all directories that it creates.
[x]: %build honors applicable compiler flags or justifies otherwise.
[-]: Package contains no bundled libraries or specifies bundled libraries
     with Provides: bundled(<libname>) if unbundling is not possible.
[x]: Changelog in prescribed format.
[x]: Sources contain only permissible code or content.
[-]: Package contains desktop file if it is a GUI application.
[-]: Development files must be in a -devel package
[x]: Package uses nothing in %doc for runtime.
[x]: Package consistently uses macros (instead of hard-coded directory
     names).
[x]: Package is named according to the Package Naming Guidelines.
[x]: Package does not generate any conflict.
[x]: Package obeys FHS, except libexecdir and /usr/target.
[-]: If the package is a rename of another package, proper Obsoletes and
     Provides are present.
[x]: Requires correct, justified where necessary.
[x]: Spec file is legible and written in American English.
[-]: Package contains systemd file(s) if in need.
[x]: Useful -debuginfo package or justification otherwise.
[-]: Package is not known to require an ExcludeArch tag.
[-]: Large documentation must go in a -doc subpackage. Large could be size
     (~1MB) or number of files.
     Note: Documentation size is 177526 bytes in 4 files.
[x]: Package complies to the Packaging Guidelines
[x]: Package successfully compiles and builds into binary rpms on at least
     one supported primary architecture.
[x]: Package installs properly.
[x]: Rpmlint is run on all rpms the build produces.
     Note: There are rpmlint messages (see attachment).
[x]: If (and only if) the source package includes the text of the
     license(s) in its own file, then that file, containing the text of the
     license(s) for the package is included in %license.
[x]: The License field must be a valid SPDX expression.
[x]: Package does not own files or directories owned by other packages.
[x]: Package uses either %{buildroot} or $RPM_BUILD_ROOT
[x]: Package does not run rm -rf %{buildroot} (or $RPM_BUILD_ROOT) at the
     beginning of %install.
[x]: Macros in Summary, %description expandable at SRPM build time.
[x]: Dist tag is present.
[x]: Package does not contain duplicates in %files.
[x]: Permissions on files are set properly.
[x]: Package must not depend on deprecated() packages.
[x]: Package use %makeinstall only when make install DESTDIR=... doesn't
     work.
[x]: Package is named using only allowed ASCII characters.
[x]: Package does not use a name that already exists.
[x]: Package is not relocatable.
[x]: Sources used to build the package match the upstream source, as
     provided in the spec URL.
[x]: Spec file name must match the spec package %{name}, in the format
     %{name}.spec.
[x]: File names are valid UTF-8.
[x]: Packages must not store files under /srv, /opt or /usr/local

Python:
[x]: Python eggs must not download any dependencies during the build
     process.
[x]: A package which is used by another package via an egg interface should
     provide egg info.
[x]: Package meets the Packaging Guidelines::Python
[x]: Package contains BR: python2-devel or python3-devel
[x]: Packages MUST NOT have dependencies (either build-time or runtime) on
     packages named with the unversioned python- prefix unless no properly
     versioned package exists. Dependencies on Python packages instead MUST
     use names beginning with python2- or python3- as appropriate.
[x]: Python packages must not contain %{pythonX_site(lib|arch)}/* in %files
[x]: Binary eggs must be removed in %prep

===== SHOULD items =====

Generic:
[-]: If the source package does not include license text(s) as a separate
     file from upstream, the packager SHOULD query upstream to include it.
[x]: Final provides and requires are sane (see attachments).
[x]: Fully versioned dependency in subpackages if applicable.
[?]: Package functions as described.
[?]: Latest version is packaged.
[x]: Package does not include license text files separate from upstream.
[x]: Patches link to upstream bugs/comments/lists or are otherwise
     justified.
[-]: Sources are verified with gpgverify first in %prep if upstream
     publishes signatures.
     Note: gpgverify is not used.
[x]: Package should compile and build into binary rpms on all supported
     architectures.
[x]: %check is present and all tests pass.
[?]: Packages should try to preserve timestamps of original installed
     files.
[x]: Reviewer should test that the package builds in mock.
[x]: Buildroot is not present
[x]: Package has no %clean section with rm -rf %{buildroot} (or
     $RPM_BUILD_ROOT)
[x]: No file requires outside of /etc, /bin, /sbin, /usr/bin, /usr/sbin.
[x]: Packager, Vendor, PreReq, Copyright tags should not be in spec file
[x]: Sources can be downloaded from URI in Source: tag
[x]: SourceX is a working URL.
[x]: Spec use %global instead of %define unless justified.

===== EXTRA items =====

Generic:
[x]: Rpmlint is run on debuginfo package(s).
[x]: Rpmlint is run on all installed packages.
[-]: Large data in /usr/share should live in a noarch subpackage if package
     is arched.
[x]: Spec file according to URL is the same as in SRPM.


Source checksums
----------------
https://github.com/astral-sh/reqwest-middleware/archive/21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe/reqwest-middleware-21ceec9a5fd2e8d6f71c3ea2999078fecbd13cbe.tar.gz :
  CHECKSUM(SHA256) this package     : 12bfb6a377ad687fd91b732b0559ddbdd0813f5f7a57abcac066dcbf9db438a0
  CHECKSUM(SHA256) upstream package : 12bfb6a377ad687fd91b732b0559ddbdd0813f5f7a57abcac066dcbf9db438a0
https://github.com/astral-sh/pubgrub/archive/3f0ba760951ab0deeac874b98bb18fc90103fcf7/pubgrub-3f0ba760951ab0deeac874b98bb18fc90103fcf7.tar.gz :
  CHECKSUM(SHA256) this package     : 23c23e71f648d9585e298f14d4ca1bdc748b1d4448d8d136f6ffd24a1e7a2aee
  CHECKSUM(SHA256) upstream package : 23c23e71f648d9585e298f14d4ca1bdc748b1d4448d8d136f6ffd24a1e7a2aee
https://github.com/charliermarsh/rs-async-zip/archive/1dcb40cfe1bf5325a6fd4bfcf9894db40241f585/rs-async-zip-1dcb40cfe1bf5325a6fd4bfcf9894db40241f585.tar.gz :
  CHECKSUM(SHA256) this package     : b7012ce0becccf5829b0e22514ac038eba5835d8468ed0e41a024377cb3ce38d
  CHECKSUM(SHA256) upstream package : b7012ce0becccf5829b0e22514ac038eba5835d8468ed0e41a024377cb3ce38d
https://github.com/astral-sh/uv/archive/0.2.28/uv-0.2.28.tar.gz :
  CHECKSUM(SHA256) this package     : 3a99515b8031c7622baa3c677a19b53a2459b0c5a32b5752751a7296b2e99f20
  CHECKSUM(SHA256) upstream package : 3a99515b8031c7622baa3c677a19b53a2459b0c5a32b5752751a7296b2e99f20



$ rpm -qRp uv-0.2.28-1.fc41.src.rpm 
(crate(anstream/default) >= 0.6.13 with crate(anstream/default) < 0.7.0~)
(crate(anyhow/default) >= 1.0.0 with crate(anyhow/default) < 2.0.0~)
(crate(anyhow/default) >= 1.0.80 with crate(anyhow/default) < 2.0.0~)
(crate(assert_cmd/default) >= 2.0.14 with crate(assert_cmd/default) < 3.0.0~)
(crate(assert_fs/default) >= 1.1.0 with crate(assert_fs/default) < 2.0.0~)
(crate(assert_fs/default) >= 1.1.1 with crate(assert_fs/default) < 2.0.0~)
(crate(async-channel/default) >= 2.2.0 with crate(async-channel/default) < 3.0.0~)
(crate(async-compression) >= 0.4.2 with crate(async-compression) < 0.5.0~)
(crate(async-compression/bzip2) >= 0.4.2 with crate(async-compression/bzip2) < 0.5.0~)
(crate(async-compression/bzip2) >= 0.4.6 with crate(async-compression/bzip2) < 0.5.0~)
(crate(async-compression/default) >= 0.4.6 with crate(async-compression/default) < 0.5.0~)
(crate(async-compression/deflate) >= 0.4.2 with crate(async-compression/deflate) < 0.5.0~)
(crate(async-compression/deflate64) >= 0.4.2 with crate(async-compression/deflate64) < 0.5.0~)
(crate(async-compression/futures-io) >= 0.4.2 with crate(async-compression/futures-io) < 0.5.0~)
(crate(async-compression/gzip) >= 0.4.6 with crate(async-compression/gzip) < 0.5.0~)
(crate(async-compression/lzma) >= 0.4.2 with crate(async-compression/lzma) < 0.5.0~)
(crate(async-compression/xz) >= 0.4.2 with crate(async-compression/xz) < 0.5.0~)
(crate(async-compression/zstd) >= 0.4.2 with crate(async-compression/zstd) < 0.5.0~)
(crate(async-compression/zstd) >= 0.4.6 with crate(async-compression/zstd) < 0.5.0~)
(crate(async-trait/default) >= 0.1.51 with crate(async-trait/default) < 0.2.0~)
(crate(async-trait/default) >= 0.1.78 with crate(async-trait/default) < 0.2.0~)
(crate(async_http_range_reader/default) >= 0.8.0 with crate(async_http_range_reader/default) < 0.9.0~)
(crate(backoff/default) >= 0.4.0 with crate(backoff/default) < 0.5.0~)
(crate(backoff/tokio) >= 0.4.0 with crate(backoff/tokio) < 0.5.0~)
(crate(base64/default) >= 0.22.0 with crate(base64/default) < 0.23.0~)
(crate(byteorder/default) >= 1.5.0 with crate(byteorder/default) < 2.0.0~)
(crate(cachedir/default) >= 0.3.1 with crate(cachedir/default) < 0.4.0~)
(crate(cargo-util/default) >= 0.2.8 with crate(cargo-util/default) < 0.3.0~)
(crate(chrono) >= 0.4.0 with crate(chrono) < 0.5.0~)
(crate(chrono) >= 0.4.19 with crate(chrono) < 0.5.0~)
(crate(chrono/clock) >= 0.4.0 with crate(chrono/clock) < 0.5.0~)
(crate(chrono/clock) >= 0.4.19 with crate(chrono/clock) < 0.5.0~)
(crate(chrono/default) >= 0.4.31 with crate(chrono/default) < 0.5.0~)
(crate(chrono/serde) >= 0.4.31 with crate(chrono/serde) < 0.5.0~)
(crate(clap/default) >= 4.5.9 with crate(clap/default) < 5.0.0~)
(crate(clap/derive) >= 4.5.9 with crate(clap/derive) < 5.0.0~)
(crate(clap/env) >= 4.5.9 with crate(clap/env) < 5.0.0~)
(crate(clap/string) >= 4.5.9 with crate(clap/string) < 5.0.0~)
(crate(clap/wrap_help) >= 4.5.9 with crate(clap/wrap_help) < 5.0.0~)
(crate(clap_complete_command/default) >= 0.6.0 with crate(clap_complete_command/default) < 0.7.0~)
(crate(configparser/default) >= 3.0.4 with crate(configparser/default) < 4.0.0~)
(crate(console) >= 0.15.8 with crate(console) < 0.16.0~)
(crate(crc32fast/default) >= 1.0.0 with crate(crc32fast/default) < 2.0.0~)
(crate(csv/default) >= 1.3.0 with crate(csv/default) < 2.0.0~)
(crate(ctrlc/default) >= 3.4.4 with crate(ctrlc/default) < 4.0.0~)
(crate(dashmap/default) >= 6.0.0 with crate(dashmap/default) < 7.0.0~)
(crate(data-encoding/default) >= 2.5.0 with crate(data-encoding/default) < 3.0.0~)
(crate(derivative/default) >= 2.2.0 with crate(derivative/default) < 3.0.0~)
(crate(directories/default) >= 5.0.1 with crate(directories/default) < 6.0.0~)
(crate(dirs-sys/default) >= 0.4.1 with crate(dirs-sys/default) < 0.5.0~)
(crate(dunce/default) >= 1.0.4 with crate(dunce/default) < 2.0.0~)
(crate(either/default) >= 1.12.0 with crate(either/default) < 2.0.0~)
(crate(encoding_rs_io/default) >= 0.1.7 with crate(encoding_rs_io/default) < 0.2.0~)
(crate(env_logger/default) >= 0.11.2 with crate(env_logger/default) < 0.12.0~)
(crate(env_logger/default) >= 0.11.3 with crate(env_logger/default) < 0.12.0~)
(crate(filetime/default) >= 0.2.23 with crate(filetime/default) < 0.3.0~)
(crate(flate2) >= 1.0.28 with crate(flate2) < 2.0.0~)
(crate(flate2/zlib-ng) >= 1.0.28 with crate(flate2/zlib-ng) < 2.0.0~)
(crate(fs-err/default) >= 2.11.0 with crate(fs-err/default) < 3.0.0~)
(crate(fs-err/tokio) >= 2.11.0 with crate(fs-err/tokio) < 3.0.0~)
(crate(fs2/default) >= 0.4.3 with crate(fs2/default) < 0.5.0~)
(crate(futures-lite) >= 2.1.0 with crate(futures-lite) < 3.0.0~)
(crate(futures-lite/std) >= 2.1.0 with crate(futures-lite/std) < 3.0.0~)
(crate(futures/default) >= 0.3.0 with crate(futures/default) < 0.4.0~)
(crate(futures/default) >= 0.3.30 with crate(futures/default) < 0.4.0~)
(crate(glob/default) >= 0.3.1 with crate(glob/default) < 0.4.0~)
(crate(hex/default) >= 0.4.3 with crate(hex/default) < 0.5.0~)
(crate(home/default) >= 0.5.9 with crate(home/default) < 0.6.0~)
(crate(html-escape/default) >= 0.2.13 with crate(html-escape/default) < 0.3.0~)
(crate(http-body-util/default) >= 0.1.0 with crate(http-body-util/default) < 0.2.0~)
(crate(http/default) >= 1.0.0 with crate(http/default) < 2.0.0~)
(crate(http/default) >= 1.1.0 with crate(http/default) < 2.0.0~)
(crate(hyper-util/default) >= 0.1.3 with crate(hyper-util/default) < 0.2.0~)
(crate(hyper-util/tokio) >= 0.1.3 with crate(hyper-util/tokio) < 0.2.0~)
(crate(hyper/default) >= 1.0.0 with crate(hyper/default) < 2.0.0~)
(crate(hyper/default) >= 1.2.0 with crate(hyper/default) < 2.0.0~)
(crate(hyper/http1) >= 1.2.0 with crate(hyper/http1) < 2.0.0~)
(crate(hyper/server) >= 1.2.0 with crate(hyper/server) < 2.0.0~)
(crate(ignore/default) >= 0.4.22 with crate(ignore/default) < 0.5.0~)
(crate(indexmap/default) >= 2.2.5 with crate(indexmap/default) < 3.0.0~)
(crate(indexmap/default) >= 2.2.6 with crate(indexmap/default) < 3.0.0~)
(crate(indexmap/serde) >= 2.2.5 with crate(indexmap/serde) < 3.0.0~)
(crate(indicatif/default) >= 0.17.7 with crate(indicatif/default) < 0.18.0~)
(crate(indoc/default) >= 2.0.4 with crate(indoc/default) < 3.0.0~)
(crate(indoc/default) >= 2.0.5 with crate(indoc/default) < 3.0.0~)
(crate(insta/default) >= 1.36.1 with crate(insta/default) < 2.0.0~)
(crate(insta/default) >= 1.39.0 with crate(insta/default) < 2.0.0~)
(crate(insta/filters) >= 1.36.1 with crate(insta/filters) < 2.0.0~)
(crate(insta/filters) >= 1.39.0 with crate(insta/filters) < 2.0.0~)
(crate(insta/json) >= 1.36.1 with crate(insta/json) < 2.0.0~)
(crate(insta/json) >= 1.39.0 with crate(insta/json) < 2.0.0~)
(crate(insta/redactions) >= 1.36.1 with crate(insta/redactions) < 2.0.0~)
(crate(insta/redactions) >= 1.39.0 with crate(insta/redactions) < 2.0.0~)
(crate(itertools/default) >= 0.13.0 with crate(itertools/default) < 0.14.0~)
(crate(log/default) >= 0.4.14 with crate(log/default) < 0.5.0~)
(crate(log/default) >= 0.4.21 with crate(log/default) < 0.5.0~)
(crate(mailparse/default) >= 0.14.0 with crate(mailparse/default) < 0.16.0~)
(crate(md-5/default) >= 0.10.6 with crate(md-5/default) < 0.11.0~)
(crate(memchr/default) >= 2.7.4 with crate(memchr/default) < 3.0.0~)
(crate(miette/default) >= 7.2.0 with crate(miette/default) < 8.0.0~)
(crate(miette/fancy) >= 7.2.0 with crate(miette/fancy) < 8.0.0~)
(crate(nanoid/default) >= 0.4.0 with crate(nanoid/default) < 0.5.0~)
(crate(once_cell/default) >= 1.19.0 with crate(once_cell/default) < 2.0.0~)
(crate(owo-colors/default) >= 4.0.0 with crate(owo-colors/default) < 5.0.0~)
(crate(paste/default) >= 1.0.0 with crate(paste/default) < 2.0.0~)
(crate(path-absolutize/default) >= 3.1.1 with crate(path-absolutize/default) < 4.0.0~)
(crate(path-slash/default) >= 0.2.1 with crate(path-slash/default) < 0.3.0~)
(crate(pathdiff/default) >= 0.2.1 with crate(pathdiff/default) < 0.3.0~)
(crate(petgraph/default) >= 0.6.4 with crate(petgraph/default) < 0.7.0~)
(crate(pin-project/default) >= 1.0.0 with crate(pin-project/default) < 2.0.0~)
(crate(platform-info/default) >= 2.0.2 with crate(platform-info/default) < 3.0.0~)
(crate(predicates/default) >= 3.0.4 with crate(predicates/default) < 4.0.0~)
(crate(priority-queue/default) >= 2.0.3 with crate(priority-queue/default) < 3.0.0~)
(crate(proc-macro2/default) >= 1.0.86 with crate(proc-macro2/default) < 2.0.0~)
(crate(proptest/default) >= 1.4.0 with crate(proptest/default) < 2.0.0~)
(crate(pyo3-log/default) >= 0.10.0 with crate(pyo3-log/default) < 0.11.0~)
(crate(pyo3/abi3) >= 0.21.0 with crate(pyo3/abi3) < 0.22.0~)
(crate(pyo3/abi3-py37) >= 0.21.0 with crate(pyo3/abi3-py37) < 0.22.0~)
(crate(pyo3/default) >= 0.21.0 with crate(pyo3/default) < 0.22.0~)
(crate(pyo3/extension-module) >= 0.21.0 with crate(pyo3/extension-module) < 0.22.0~)
(crate(quote/default) >= 1.0.36 with crate(quote/default) < 2.0.0~)
(crate(rayon/default) >= 1.8.0 with crate(rayon/default) < 2.0.0~)
(crate(reflink-copy/default) >= 0.1.15 with crate(reflink-copy/default) < 0.2.0~)
(crate(regex/default) >= 1.10.2 with crate(regex/default) < 2.0.0~)
(crate(regex/default) >= 1.10.3 with crate(regex/default) < 2.0.0~)
(crate(reqwest) >= 0.12.0 with crate(reqwest) < 0.13.0~)
(crate(reqwest) >= 0.12.3 with crate(reqwest) < 0.13.0~)
(crate(reqwest/blocking) >= 0.12.3 with crate(reqwest/blocking) < 0.13.0~)
(crate(reqwest/charset) >= 0.12.0 with crate(reqwest/charset) < 0.13.0~)
(crate(reqwest/gzip) >= 0.12.3 with crate(reqwest/gzip) < 0.13.0~)
(crate(reqwest/http2) >= 0.12.0 with crate(reqwest/http2) < 0.13.0~)
(crate(reqwest/json) >= 0.12.0 with crate(reqwest/json) < 0.13.0~)
(crate(reqwest/json) >= 0.12.3 with crate(reqwest/json) < 0.13.0~)
(crate(reqwest/multipart) >= 0.12.0 with crate(reqwest/multipart) < 0.13.0~)
(crate(reqwest/rustls-tls) >= 0.12.0 with crate(reqwest/rustls-tls) < 0.13.0~)
(crate(reqwest/rustls-tls) >= 0.12.3 with crate(reqwest/rustls-tls) < 0.13.0~)
(crate(reqwest/rustls-tls-native-roots) >= 0.12.3 with crate(reqwest/rustls-tls-native-roots) < 0.13.0~)
(crate(reqwest/stream) >= 0.12.3 with crate(reqwest/stream) < 0.13.0~)
(crate(retry-policies/default) >= 0.4.0 with crate(retry-policies/default) < 0.5.0~)
(crate(rkyv/default) >= 0.7.43 with crate(rkyv/default) < 0.8.0~)
(crate(rkyv/strict) >= 0.7.43 with crate(rkyv/strict) < 0.8.0~)
(crate(rkyv/validation) >= 0.7.43 with crate(rkyv/validation) < 0.8.0~)
(crate(rmp-serde/default) >= 1.1.2 with crate(rmp-serde/default) < 2.0.0~)
(crate(ron/default) >= 0.8.1 with crate(ron/default) < 0.9.0~)
(crate(rust-netrc/default) >= 0.1.1 with crate(rust-netrc/default) < 0.2.0~)
(crate(rustc-hash/default) >= 1.1.0 with crate(rustc-hash/default) < 2.0.0~)
(crate(rustc-hash/default) >= 2.0.0 with crate(rustc-hash/default) < 3.0.0~)
(crate(rustix) >= 0.38.34 with crate(rustix) < 0.39.0~)
(crate(rustix/fs) >= 0.38.34 with crate(rustix/fs) < 0.39.0~)
(crate(rustix/std) >= 0.38.34 with crate(rustix/std) < 0.39.0~)
(crate(same-file/default) >= 1.0.6 with crate(same-file/default) < 2.0.0~)
(crate(sanitize-filename/default) >= 0.5.0 with crate(sanitize-filename/default) < 0.6.0~)
(crate(schemars/default) >= 0.8.16 with crate(schemars/default) < 0.9.0~)
(crate(schemars/url) >= 0.8.16 with crate(schemars/url) < 0.9.0~)
(crate(seahash/default) >= 4.1.0 with crate(seahash/default) < 5.0.0~)
(crate(serde/default) >= 1.0.0 with crate(serde/default) < 2.0.0~)
(crate(serde/default) >= 1.0.106 with crate(serde/default) < 2.0.0~)
(crate(serde/default) >= 1.0.197 with crate(serde/default) < 2.0.0~)
(crate(serde/derive) >= 1.0.0 with crate(serde/derive) < 2.0.0~)
(crate(serde/derive) >= 1.0.197 with crate(serde/derive) < 2.0.0~)
(crate(serde/rc) >= 1.0.197 with crate(serde/rc) < 2.0.0~)
(crate(serde_json/default) >= 1.0.114 with crate(serde_json/default) < 2.0.0~)
(crate(sha2/default) >= 0.10.8 with crate(sha2/default) < 0.11.0~)
(crate(syn/default) >= 2.0.66 with crate(syn/default) < 3.0.0~)
(crate(sys-info/default) >= 0.9.1 with crate(sys-info/default) < 0.10.0~)
(crate(target-lexicon/default) >= 0.12.14 with crate(target-lexicon/default) < 0.13.0~)
(crate(temp-env/default) >= 0.3.6 with crate(temp-env/default) < 0.4.0~)
(crate(tempfile/default) >= 3.9.0 with crate(tempfile/default) < 4.0.0~)
(crate(test-case/default) >= 3.3.1 with crate(test-case/default) < 4.0.0~)
(crate(test-log) >= 0.2.15 with crate(test-log) < 0.3.0~)
(crate(test-log/trace) >= 0.2.15 with crate(test-log/trace) < 0.3.0~)
(crate(testing_logger/default) >= 0.1.1 with crate(testing_logger/default) < 0.2.0~)
(crate(textwrap/default) >= 0.16.1 with crate(textwrap/default) < 0.17.0~)
(crate(thiserror/default) >= 1.0.0 with crate(thiserror/default) < 2.0.0~)
(crate(thiserror/default) >= 1.0.21 with crate(thiserror/default) < 2.0.0~)
(crate(thiserror/default) >= 1.0.56 with crate(thiserror/default) < 2.0.0~)
(crate(thiserror/default) >= 1.0.61 with crate(thiserror/default) < 2.0.0~)
(crate(tl/default) >= 0.7.7 with crate(tl/default) < 0.8.0~)
(crate(tokio-stream/default) >= 0.1.14 with crate(tokio-stream/default) < 0.2.0~)
(crate(tokio-tar/default) >= 0.3.1 with crate(tokio-tar/default) < 0.4.0~)
(crate(tokio-util/compat) >= 0.7.0 with crate(tokio-util/compat) < 0.8.0~)
(crate(tokio-util/compat) >= 0.7.10 with crate(tokio-util/compat) < 0.8.0~)
(crate(tokio-util/default) >= 0.7.0 with crate(tokio-util/default) < 0.8.0~)
(crate(tokio-util/default) >= 0.7.10 with crate(tokio-util/default) < 0.8.0~)
(crate(tokio/default) >= 1.0.0 with crate(tokio/default) < 2.0.0~)
(crate(tokio/default) >= 1.35.1 with crate(tokio/default) < 2.0.0~)
(crate(tokio/default) >= 1.6.0 with crate(tokio/default) < 2.0.0~)
(crate(tokio/fs) >= 1.0.0 with crate(tokio/fs) < 2.0.0~)
(crate(tokio/fs) >= 1.35.1 with crate(tokio/fs) < 2.0.0~)
(crate(tokio/full) >= 1.0.0 with crate(tokio/full) < 2.0.0~)
(crate(tokio/full) >= 1.6.0 with crate(tokio/full) < 2.0.0~)
(crate(tokio/io-util) >= 1.0.0 with crate(tokio/io-util) < 2.0.0~)
(crate(tokio/io-util) >= 1.35.1 with crate(tokio/io-util) < 2.0.0~)
(crate(tokio/macros) >= 1.0.0 with crate(tokio/macros) < 2.0.0~)
(crate(tokio/macros) >= 1.35.1 with crate(tokio/macros) < 2.0.0~)
(crate(tokio/process) >= 1.35.1 with crate(tokio/process) < 2.0.0~)
(crate(tokio/rt-multi-thread) >= 1.0.0 with crate(tokio/rt-multi-thread) < 2.0.0~)
(crate(tokio/sync) >= 1.35.1 with crate(tokio/sync) < 2.0.0~)
(crate(tokio/time) >= 1.0.0 with crate(tokio/time) < 2.0.0~)
(crate(tokio/time) >= 1.6.0 with crate(tokio/time) < 2.0.0~)
(crate(toml/default) >= 0.8.12 with crate(toml/default) < 0.9.0~)
(crate(toml_edit/default) >= 0.22.13 with crate(toml_edit/default) < 0.23.0~)
(crate(tower-service/default) >= 0.3.0 with crate(tower-service/default) < 0.4.0~)
(crate(tracing-subscriber/default) >= 0.3.18 with crate(tracing-subscriber/default) < 0.4.0~)
(crate(tracing-subscriber/env-filter) >= 0.3.18 with crate(tracing-subscriber/env-filter) < 0.4.0~)
(crate(tracing-subscriber/json) >= 0.3.18 with crate(tracing-subscriber/json) < 0.4.0~)
(crate(tracing-subscriber/registry) >= 0.3.18 with crate(tracing-subscriber/registry) < 0.4.0~)
(crate(tracing-tree/default) >= 0.3.1 with crate(tracing-tree/default) < 0.5.0~)
(crate(tracing/default) >= 0.1.26 with crate(tracing/default) < 0.2.0~)
(crate(tracing/default) >= 0.1.40 with crate(tracing/default) < 0.2.0~)
(crate(tracing/log) >= 0.1.40 with crate(tracing/log) < 0.2.0~)
(crate(unicode-width/default) >= 0.1.11 with crate(unicode-width/default) < 0.2.0~)
(crate(unscanny/default) >= 0.1.0 with crate(unscanny/default) < 0.2.0~)
(crate(url/default) >= 2.5.0 with crate(url/default) < 3.0.0~)
(crate(url/serde) >= 2.5.0 with crate(url/serde) < 3.0.0~)
(crate(urlencoding/default) >= 2.1.3 with crate(urlencoding/default) < 3.0.0~)
(crate(walkdir/default) >= 2.5.0 with crate(walkdir/default) < 3.0.0~)
(crate(which/default) >= 6.0.0 with crate(which/default) < 7.0.0~)
(crate(which/regex) >= 6.0.0 with crate(which/regex) < 7.0.0~)
(crate(zip) >= 0.6.6 with crate(zip) < 0.7.0~)
(crate(zip/default) >= 0.6.3 with crate(zip/default) < 0.7.0~)
(crate(zip/deflate) >= 0.6.6 with crate(zip/deflate) < 0.7.0~)
(python3dist(maturin) < 2~~ with python3dist(maturin) >= 1)
(python3dist(tomli) if python3-devel < 3.11)
cargo-rpm-macros >= 24
pyproject-rpm-macros
python3-devel
python3dist(packaging)
python3dist(pip) >= 19
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(DynamicBuildRequires) <= 4.15.0-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(RichDependencies) <= 4.12.0-1
rpmlib(TildeInVersions) <= 4.10.0-1
rust >= 1.77
rust2rpm-helper
tomcli


$ rpm -qRp uv-0.2.28-1.fc41.x86_64.rpm 
ld-linux-x86-64.so.2()(64bit)
ld-linux-x86-64.so.2(GLIBC_2.3)(64bit)
libbz2.so.1()(64bit)
libc.so.6()(64bit)
libc.so.6(GLIBC_2.14)(64bit)
libc.so.6(GLIBC_2.15)(64bit)
libc.so.6(GLIBC_2.16)(64bit)
libc.so.6(GLIBC_2.17)(64bit)
libc.so.6(GLIBC_2.18)(64bit)
libc.so.6(GLIBC_2.2.5)(64bit)
libc.so.6(GLIBC_2.25)(64bit)
libc.so.6(GLIBC_2.27)(64bit)
libc.so.6(GLIBC_2.28)(64bit)
libc.so.6(GLIBC_2.29)(64bit)
libc.so.6(GLIBC_2.3)(64bit)
libc.so.6(GLIBC_2.3.2)(64bit)
libc.so.6(GLIBC_2.3.4)(64bit)
libc.so.6(GLIBC_2.32)(64bit)
libc.so.6(GLIBC_2.33)(64bit)
libc.so.6(GLIBC_2.34)(64bit)
libc.so.6(GLIBC_2.4)(64bit)
libc.so.6(GLIBC_2.6)(64bit)
libc.so.6(GLIBC_2.7)(64bit)
libc.so.6(GLIBC_2.9)(64bit)
libgcc_s.so.1()(64bit)
libgcc_s.so.1(GCC_3.0)(64bit)
libgcc_s.so.1(GCC_3.3)(64bit)
libgcc_s.so.1(GCC_4.2.0)(64bit)
libm.so.6()(64bit)
libm.so.6(GLIBC_2.2.5)(64bit)
libm.so.6(GLIBC_2.27)(64bit)
libm.so.6(GLIBC_2.29)(64bit)
libm.so.6(GLIBC_2.38)(64bit)
libz-ng.so.2()(64bit)
libz-ng.so.2(ZLIB_NG_2.0.0)(64bit)
libz-ng.so.2(ZLIB_NG_2.1.0)(64bit)
libzstd.so.1()(64bit)
rpmlib(CaretInVersions) <= 4.15.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsZstd) <= 5.4.18-1
rtld(GNU_HASH)


$ rpm -qRp python3-uv-0.2.28-1.fc41.noarch.rpm 
python(abi) = 3.13
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PartialHardlinkSets) <= 4.0.4-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsZstd) <= 5.4.18-1
uv = 0.2.28-1.fc41


$ rpm -qPp uv-0.2.28-1.fc41.x86_64.rpm 
bundled(crate(async_zip)) = 0.0.17^20240403git1dcb40c
bundled(crate(pubgrub)) = 0.2.1^20240715git3f0ba76
bundled(crate(reqwest-middleware)) = 0.3.2^20240701git21ceec9
bundled(crate(reqwest-retry)) = 0.7.0^20240701git21ceec9
uv = 0.2.28-1.fc41
uv(x86-64) = 0.2.28-1.fc41


$ rpm -qPp python3-uv-0.2.28-1.fc41.noarch.rpm 
python-uv = 0.2.28-1.fc41
python3-uv = 0.2.28-1.fc41
python3.13-uv = 0.2.28-1.fc41
python3.13dist(uv) = 0.2.28
python3dist(uv) = 0.2.28




Generated by fedora-review 0.7.0 (fed5495) last change: 2019-03-17
Command line :try-fedora-review -b 2299712 -m fedora-rawhide-x86_64 -o=--enablerepo=local
Buildroot used: fedora-rawhide-x86_64
Active plugins: Shell-api, Generic, C/C++, Python
Disabled plugins: Java, R, Ruby, PHP, Haskell, SugarActivity, Ocaml, Perl, fonts
Disabled flags: EXARCH, EPEL6, EPEL7, DISTTAG, BATCH

Comment 12 Ben Beasley 2024-07-25 14:36:23 UTC
Adjusted so that Patch100-Patch199 are automatically applied for Source1, Patch200-299 for Source2, and so on.

----------

Expanded and clarified the justification for 0001-Downstream-only-do-not-override-the-default-allocato.patch.

----------

Fixed extra spaces after two emojis in the description. I blame working via SSH from a MacOS terminal, which doesn’t give those two emojis enough width.

(I am not especially attached to the emojis, but I default to keeping the description very close to the upstream one, and upstream really likes their emojis!)

----------

Added

# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
ExcludeArch:    %{ix86}

and therefore removed

%if 0%{?__isa_bits} == 32
# These tests check zip64 support with files >4GiB, which doesn’t work on
# 32-bit platforms because the file size doesn’t fit in a usize.
mv crates/async_zip/src/tests/write/zip64/mod.rs{,.disabled}
sed -r -i 's@^mod zip64;@// &@' crates/async_zip/src/tests/write/mod.rs
%endif

----------

Removed

export RUSTFLAGS='%{build_rustflags}'

with the understanding that I will need to add

%set_build_flags
export RUSTFLAGS='%{build_rustflags}'

if I do backport this to EPEL9.

I’m happy to let a hypothetical epel9 branch diverge from Fedora and follow a cherry-picking workflow, but we can cross that bridge if/when we get there.

----------

Adjusted the Summary for python3-uv to "Importable Python module for uv".

----------

Adjusted

# -p uv-auth --lib:

to

# cargo test -p uv-auth --lib:

in the hopes that the meaning will be a little more clear without making the comment too verbose.

----------

I did NOT:

- drop ", written in Rust" from the main summary: I see and somewhat agree with both arguments, and for now I’ve chosen to stay closer to upstream
- drop the emojis from the descriptions: as noted, I am not too attached to them, but everything in Fedora should be fully Unicode-safe, and they are part of upstream’s communication style
- adjust the style of the License expression: I am still prepared to consider suggestions for improving this

----------

I do plan to add a uv.rpmlintrc file on import.

----------

I will take some time to audit the bundling pointed out in https://bugzilla.redhat.com/show_bug.cgi?id=2299712#c10 before uploading a new submission. I had a feeling I had forgotten to do something, and now I know what it was.

Comment 13 Miro Hrončok 2024-07-25 14:53:58 UTC
I've used https://pypi.org/project/license-expression/ to validate that:

expressions = [l.removeprefix('# ') for l in comment.splitlines()]
combined = ' AND '.join([f'({l})' for l in expressions])
from_comment = licensing.parse(combined)

from_license = licensing.parse(license_tag)

licensing.is_equivalent(from_license, from_comment)

---

I believe I can turn this into something to use in %check, but that is beyond the scope of this package review.

Comment 14 Ben Beasley 2024-07-25 15:23:53 UTC
There is a problem with https://github.com/charliermarsh/rs-async-zip/blob/main/SPECIFICATION.md:

## 1.4 Permitted Use 

   ### 1.4.1
   This document, "APPNOTE.TXT -  .ZIP File Format Specification" is the
   exclusive property of PKWARE.  Use of the information contained in this 
   document is permitted solely for the purpose of creating products, 
   programs and processes that read and write files in the ZIP format
   subject to the terms and conditions herein.

   ### 1.4.2
   Use of the content of this document within other publications is 
   permitted only through reference to this document.  Any reproduction
   or distribution of this document in whole or in part without prior
   written permission from PKWARE is strictly prohibited.

   ### 1.4.3
   Certain technological components provided in this document are the 
   patented proprietary technology of PKWARE and as such require a 
   separate, executed license agreement from PKWARE.  Applicable 
   components are marked with the following, or similar, statement: 
   'Refer to the section in this document entitled  "Incorporating 
   PKWARE Proprietary Technology into Your Product" for more information'.

This is clearly a proprietary license, and we need to avoid including this file in our source RPMs.

This affects https://src.fedoraproject.org/rpms/rust-async_zip too, since the file is present in the published crate.

I’ll start by trying to get the main upstream https://github.com/Majored/rs-async-zip and the fork https://github.com/charliermarsh/rs-async-zip to remove this file, ideally from the git repository, but at least from the published crates. However, it looks like it will be necessary to use a "filtered" source archive both here and in rust-async_zip as an interim measure.

Comment 15 Ben Beasley 2024-07-25 16:59:39 UTC
I filed https://github.com/Majored/rs-async-zip/issues/146, and async_zip upstream removed the problematic document in https://github.com/Majored/rs-async-zip/commit/2d841d600c6d509cb4ecc611001ec339876ca6c9. I’m working on a solution for rust-async_zip. For the fork https://github.com/charliermarsh/rs-async-zip, I’m going to have to resort to email or something, since the fork has no issue tracker and pull requests are limited to collaborators.

Comment 16 Ben Beasley 2024-07-29 12:52:02 UTC
(In reply to Ben Beasley from comment #15)
> I filed https://github.com/Majored/rs-async-zip/issues/146, and async_zip
> upstream removed the problematic document in
> https://github.com/Majored/rs-async-zip/commit/
> 2d841d600c6d509cb4ecc611001ec339876ca6c9. I’m working on a solution for
> rust-async_zip. For the fork https://github.com/charliermarsh/rs-async-zip,
> I’m going to have to resort to email or something, since the fork has no
> issue tracker and pull requests are limited to collaborators.

I have added a script to filter the snapshot bundled in uv to avoid uploading the problematic SPECIFICATION.md to the lookaside cache or including it in source RPMs. Since I filed https://github.com/astral-sh/uv/issues/5556 upstream asking uv to update their async_zip fork, and upstream tends to be very responsive, I expect this will not be necessary for long and we will be able to go back to just using a snapshot archive directly in a near-future release. In fact, I wouldn’t be surprised if this is handled upstream before I finish preparing a new submission for review.

I am fixing the rust-async_zip package via https://src.fedoraproject.org/rpms/rust-async_zip/pull-request/1, and I will backport the same fix to the compat package https://src.fedoraproject.org/rpms/rust-async_zip0.0.15 . These are not used for uv, but the fix is still important.

-----

I reviewed the archives for the bundled pubsub and reqwest-retry/reqwest-middleware crates and didn’t find anything new, problematic, or notable. I think %{cargo_license_summary} should already be handling their licenses, but I added explicit spec-file comments documenting them anyway.

-----

I am currently tracking upstream release 0.2.30, with no significant packaging or dependency changes from the original submission.

-----

I still need to audit and document possibly-bundled sources in the main uv archive before uploading a new submission.

Comment 17 Ben Beasley 2024-07-31 21:19:22 UTC
Updated to 0.2.32, and I think I’ve done a reasonable job of digging through bundled sources. The spec file is now, inevitably, quite a bit longer.

The following were filed, merged, and released upstream in the process:

https://github.com/astral-sh/uv/pull/5585
https://github.com/astral-sh/uv/pull/5587

Spec URL: https://music.fedorapeople.org/20240731/uv.spec
SRPM URL: https://music.fedorapeople.org/20240731/uv-0.2.32-1.fc40.src.rpm

Comment 18 Miro Hrončok 2024-07-31 22:43:00 UTC
Thank you. I think this is as good as it gets. If we find issues later, we can always fix them later.

Comment 19 Ben Beasley 2024-08-01 01:24:27 UTC
Thank you for the review!

Further suggestions in bugzillas or PR’s are appreciated. I will add python-packagers-sig and rust-sig as group maintainers, and Miro as an individual maintainer. Other co-maintainers are welcome.

I plan to build this for all Fedora releases. I’m not sure if EPEL9 will happen. Upstream just started requiring Rust 1.80, so I could probably package a very recent version, the last one that built on Rust 1.79 (after getting a number of dependencies branched), but I wouldn’t be able to update it.

https://release-monitoring.org/project/372636/

Comment 20 Fedora Admin user for bugzilla script actions 2024-08-01 01:25:13 UTC
The Pagure repository was created at https://src.fedoraproject.org/rpms/uv

Comment 21 Ben Beasley 2024-08-01 03:42:51 UTC
Building for Rawhide and F40 now, F39 after https://bodhi.fedoraproject.org/updates/FEDORA-2024-f6fe6bda1e reaches stable.

Comment 22 Fedora Update System 2024-08-01 04:19:13 UTC
FEDORA-2024-1a28cfbe36 (uv-0.2.32-1.fc41) has been submitted as an update to Fedora 41.
https://bodhi.fedoraproject.org/updates/FEDORA-2024-1a28cfbe36

Comment 23 Fedora Update System 2024-08-01 04:24:22 UTC
FEDORA-2024-1a28cfbe36 (uv-0.2.32-1.fc41) has been pushed to the Fedora 41 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 24 Fedora Update System 2024-08-01 04:53:21 UTC
FEDORA-2024-7b54874ee4 (uv-0.2.32-1.fc40) has been submitted as an update to Fedora 40.
https://bodhi.fedoraproject.org/updates/FEDORA-2024-7b54874ee4

Comment 25 Fedora Update System 2024-08-02 03:39:59 UTC
FEDORA-2024-7b54874ee4 has been pushed to the Fedora 40 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf install --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-7b54874ee4 \*`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2024-7b54874ee4

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 26 Fedora Update System 2024-08-04 23:39:43 UTC
FEDORA-2024-819999a193 (uv-0.2.32-1.fc39) has been submitted as an update to Fedora 39.
https://bodhi.fedoraproject.org/updates/FEDORA-2024-819999a193

Comment 27 Fedora Update System 2024-08-05 02:33:30 UTC
FEDORA-2024-819999a193 has been pushed to the Fedora 39 testing repository.
Soon you'll be able to install the update with the following command:
`sudo dnf install --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-819999a193 \*`
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2024-819999a193

See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information on how to test updates.

Comment 28 Fedora Update System 2024-08-11 04:48:09 UTC
FEDORA-2024-7b54874ee4 (uv-0.2.32-1.fc40) has been pushed to the Fedora 40 stable repository.
If problem still persists, please make note of it in this bug report.

Comment 29 Fedora Update System 2024-08-13 01:34:59 UTC
FEDORA-2024-819999a193 (uv-0.2.32-1.fc39) has been pushed to the Fedora 39 stable repository.
If problem still persists, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.