uv-packsize
report size of python package with its deps using uv
Installation
Run it once with uv—no separate installation needed:
uvx uv-packsize requests
To keep it installed for repeated use:
uv tool install uv-packsize
pip install uv-packsize works too. See the user documentation
for quick starts, locked-project analysis, baselines, and CI budget examples.
Usage
For help, run:
uv-packsize --help
Usage: uv-packsize [OPTIONS] [PACKAGE_NAMES]...
Report the size of a Python package and its dependencies using uv.
Options:
--version Show the version and exit.
--prefix PATH Analyze an existing prefix without running or
changing it.
--project PATH Analyze one explicit pyproject.toml with an
explicit uv.lock.
--lockfile PATH Explicit uv.lock used with --project.
--workspace-member TEXT Select the explicit workspace member by
normalized package name.
--group TEXT Include one explicit dependency group
(repeatable).
--all-groups Include all validated dependency groups.
--extra TEXT Include one explicit extra (repeatable).
--baseline PATH Read a baseline JSON file and report its diff
from a fresh or project analysis.
--write-baseline PATH Atomically write the fresh or project analysis
JSON to PATH.
--overwrite-baseline Replace an existing --write-baseline target
explicitly.
--site-packages REL Relative site-packages directory inside
--prefix (repeatable).
--case-rule [sensitive|insensitive]
Target filesystem case rule required with
--prefix.
--bin Text output only: display RECORD-owned scripts
separately without changing the total.
--allow-build Allow source builds during installation;
disabled by default.
--prerelease [disallow|allow|if-necessary|explicit|if-necessary-or-explicit]
Pre-release resolution policy for package
requests. The default allows pre-releases only
when necessary. [default: (if-necessary)]
--json Write the versioned analysis result as JSON to
stdout.
--comparison-json Write the versioned baseline comparison result
as JSON to stdout.
--report [standard|rich] Text report layout. Rich shows a redacted
primary top-five summary; ignored with --json
or --comparison-json. [default: rich]
--quiet Suppress progress messages without changing
final output or errors.
--color [auto|always|never] Color human-readable final reports; JSON and
diagnostics remain plain. [default: auto]
--budget-config PATH Read budget policy from [tool.uv-
packsize.budget] in PATH.
--max-total BYTES Maximum canonical global logical size in
bytes. [0<=x<=9223372036854775807]
--max-increase BYTES Maximum canonical global logical-size increase
in bytes. [0<=x<=9223372036854775807]
--incomplete-policy [fail|allow-partial]
Budget handling for incomplete measurements.
--explain Text output only: show installed-metadata
dependency paths and attribution. Unavailable
with --prefix or --project.
--breakdown Text output only: show global file-category
and dependency-role sizes. Unavailable with
--prefix or --project.
--contributions Text output only: show non-split requested-
root byte contributions. Unavailable with
--prefix or --project.
-p, --python TEXT Specify the Python version for the virtual
environment.
--help Show this message and exit.
You can also use:
python -m uv_packsize --help
Report layouts
The default --report rich layout is a compact, redacted summary. To retain
the pre-0.2.0 full plain-text table exactly, select both legacy presentation
options explicitly:
uvx uv-packsize requests --report standard --color never
The rich primary summary shows the input kind, build policy, completeness,
warning count, canonical global size, distribution-owned aggregate, and the
five largest distributions by owned logical bytes. That primary summary does
not show raw requirements, installed paths, resolved versions, context
fingerprints, or lock identities. If more than five distributions were
measured, its Largest Distributions heading states Showing 5 of N. Rows
remain ordered by owned size descending, then normalized name; no numeric rank
column is added.
With a baseline, rich mode shows the corresponding redacted comparison summary
and the five largest non-zero distribution changes. --bin, --explain,
--breakdown, --contributions, budgets, and baseline writing retain their
existing behavior around the rich primary report. These appended sections are
not covered by the primary-summary redaction: --bin can show script paths,
and --explain can show installed metadata including resolved versions and
dependency information. --json and --comparison-json ignore --report so
their versioned output remains byte compatible.
Quiet progress
Add --quiet to suppress only transient progress and completion messages:
uvx uv-packsize requests --quiet
uvx uv-packsize requests --json --quiet > analysis.json
This applies consistently to fresh installs, project/lock analysis, and
existing-prefix analysis, with either text report layout and during baseline
comparison or writing. Final text reports, JSON documents, graph explanation
sections, budget results, sanitized operational errors, and Click usage errors
are not suppressed. In JSON modes, --quiet changes only stderr progress;
successful stdout bytes are identical to the corresponding command without
--quiet. The option is useful for scripts that want diagnostics on failure
without routine status messages.
Terminal color
Color defaults to --color auto. Automatic detection keeps redirected and
other non-TTY output plain; force or disable ANSI explicitly when needed:
uvx uv-packsize requests --report rich --color always
uvx uv-packsize requests --report standard --color never
auto decorates a human-readable final stdout report only when stdout is a
TTY, TERM is not dumb, and NO_COLOR is not present in the environment.
always ignores all three conditions, including NO_COLOR, which is useful
when the receiving program explicitly supports ANSI. never disables ANSI;
combined with --report standard, it is the exact pre-0.2.0 full-text escape.
Color changes presentation only: removing ANSI sequences yields the same
standard or rich report text. Primary reports, appended graph and binary
sections, comparisons, and text budget sections share this rule. Progress,
completion messages, sanitized errors, Click usage, and JSON-mode budget
failure diagnostics remain plain. --json and --comparison-json accept and
completely ignore every --color value, preserving their stdout bytes and
channels.
This is a 0.2.0 human-text migration: the defaults changed from standard/never to rich/auto. Scripts should pin the legacy escape above or, preferably, consume versioned JSON.
Locked project analysis
Use --project and --lockfile together to measure the dependencies selected
by one explicit pyproject.toml and uv.lock pair. This mode runs a private,
locked uv sync; it neither discovers a project from the current directory nor
changes either input file.
uv-packsize --project pyproject.toml --lockfile uv.lock --json > analysis.json
uv-packsize --project pyproject.toml --lockfile uv.lock --report rich
These commands must be run against a project/lock pair in the supported subset;
they are not examples for analyzing this uv-packsize repository itself. To
include optional selections, replace the names below with groups and extras
declared by both of your input files:
uv-packsize --project pyproject.toml --lockfile uv.lock --group YOUR_GROUP
uv-packsize --project pyproject.toml --lockfile uv.lock --all-groups --extra YOUR_EXTRA
The default selects no dependency groups. Add a repeatable --group NAME, or
use --all-groups (they are mutually exclusive); add a repeatable --extra NAME for extras. Group and extra names are normalized package names and must
be declared consistently in both explicit inputs. --workspace-member NAME
selects the named root member in the currently supported single-root subset.
Positional package requirements, --prefix, and the prefix-layout options
cannot be combined with project/lock mode.
--explain, --breakdown, and --contributions are also unavailable because
this mode does not yet model a project-root dependency graph. Progress and
diagnostics go to stderr, so stdout contains only a successful report or JSON
document.
The tool reads each input once after rejecting symlinks and unstable files,
validates its supported lock subset, then stages those same bytes under the
standard filenames in a unique temporary directory. It invokes uv sync with
--locked, --no-install-project, and --no-default-groups, plus only the
validated selection flags. It does not use --frozen, --lockfile, workspace
metadata, ambient project discovery, active virtual environments, or ambient
UV_* configuration. The staged directory and temporary environment are
removed after success or failure.
The local root project is deliberately not installed or measured. Its source tree and build configuration cannot be reproduced safely from lock bytes, and measuring it could execute local build code. This initial mode therefore reports the selected locked dependencies only. Local-path, VCS, and workspace dependency sources outside the supported subset are rejected rather than silently approximated.
Project/lock output uses analysis result schema v3.
Its context records the normalized root/member, effective group and extra
selection, measurement conditions, build policy, and an opaque lock_identity
fingerprint. That fingerprint permits correlation of identical lock contents;
it does not expose the lock, paths, sources, URLs, credentials, or opaque uv
identifiers. Treat it as correlation metadata when sharing an analysis.
Existing prefix analysis
Use --prefix to inspect an already-installed environment without running or
changing it. Specify every site-packages directory relative to that prefix and
declare its filesystem case rule explicitly:
uv-packsize --prefix .venv \
--site-packages YOUR_RELATIVE_SITE_PACKAGES \
--case-rule sensitive --json > prefix-analysis.json
Replace YOUR_RELATIVE_SITE_PACKAGES with the environment's actual path
relative to .venv, for example lib/python3.12/site-packages on a typical
POSIX Python 3.12 virtual environment. Choose the case rule that matches the
filesystem being scanned.
--site-packages is repeatable. Its value must be a non-empty, canonical
relative path in the native path form of the host running the command; absolute
paths, ./.., and symlink components are rejected. A relative --prefix is
resolved from the current working directory and fixed to its canonical physical
directory before scanning. This mode only supports the host's native path
flavor. --case-rule sensitive or --case-rule insensitive is a trusted
caller declaration, not a filesystem probe, so it must match the target
filesystem's semantics.
The prefix is never used to create an environment, install or uninstall a
package, run Python, invoke uv, or write metadata. Directory validation and
the subsequent inventory scan are necessarily best-effort: a concurrent change
to the prefix can still race them (TOCTOU), so scan an otherwise stable prefix.
Fresh package requests produce JSON schema v1. Existing-prefix scans produce
schema v2, whose context deliberately leaves unknown resolution fields as
null or empty values and never contains the raw prefix or site-packages
paths. Inspect schema_version before comparing results from the two input
modes. In prefix text output, --bin uses the heading Binaries in prefix;
generated script sizes can differ from a fresh temporary installation because
POSIX script shebangs can contain the installation path.
--explain, --breakdown, and --contributions are unavailable with prefix text output because
the original requested roots and resolver conditions are not known. With
--json, those presentation flags (and --bin) are accepted but ignored, so
all such option combinations produce the same schema v2 bytes.
If virtual environment creation or package installation fails, the command exits
with status 1 and shows a concise failure summary with the uv exit code,
without a Python traceback or raw uv diagnostic output. A wheel-only install
failure explains that a compatible wheel may be unavailable and directs you to
--allow-build only when you trust the package source and its build backend.
Example
uvx uv-packsize requests==2.32.5
Package requests use --prerelease if-necessary by default. This keeps stable
releases preferred while permitting a pre-release dependency when no stable
solution exists. The policy is passed explicitly to uv, so a surrounding
project's [tool.uv].prerelease setting does not silently change the result.
Choose another policy when you need stricter or broader resolution:
uvx uv-packsize apache-airflow==3.0.0 --prerelease if-necessary
uvx uv-packsize requests --prerelease disallow
The selected policy is recorded in JSON as part of
context.resolution_strategy. --prerelease applies only to package requests;
locked-project analysis uses the policy already captured by the explicit lock.
It is independent from --allow-build: prerelease selection controls dependency
resolution, while build permission controls whether source distributions may run
a build backend.
Multiple Packages
You can also specify multiple packages to calculate the total size of all of them combined.
uv-packsize 'iniconfig==2.0.0' six --report standard --color never
Calculating size for 2 requested packages...
Creating virtual environment...
Installing 2 requested packages and their dependencies...
Analyzing sizes...
--- Package Sizes ---
Package Size
------------------- --------
six 37.25 KiB
iniconfig 12.88 KiB
------------------- --------
Total Package Size 50.13 KiB
Total size: 50.13 KiB
Calculation complete.
JSON output
Use --json to write the complete, versioned analysis result to standard
output. It is intended for recording, comparison, and further processing:
uv-packsize requests==2.32.5 --json > analysis.json
Fresh package-request JSON conforms to the committed
analysis result schema v1. Its
top-level fields describe the schema version, measurement definition,
resolution context, resolved distributions and their file inventories,
warnings/completeness, duplicate ownership, and global/distribution totals.
Schema version 1 is a compatibility boundary; consumers should check
schema_version before interpreting a result.
The JSON representation is deliberately safe to share as a measurement record: requirements are non-reversible summaries rather than their raw text, and it does not contain requirement URLs, credentials, digests, raw local paths, or raw symlink targets. File paths in the measured temporary environment remain part of the inventory because they are needed to explain the measurement.
With --json, standard output contains exactly one JSON document and no
progress messages, text table, or completion message. Progress and sanitized
operational errors are written to standard error instead. A successful analysis
exits with status 0; an operational failure exits with status 1 and leaves
standard output empty; invalid command-line usage uses Click's status 2.
Add --quiet to omit only those stderr progress messages. It does not change
the JSON bytes, exit status, sanitized errors, budget diagnostics, or usage
errors.
--bin is a text-presentation option and has no effect on JSON bytes, so
--json --bin is accepted but produces the same JSON as --json.
--explain is also text-only: --json --explain is accepted and produces
byte-identical output (including progress and errors) to --json, preserving
the schema v1 compatibility boundary.
--breakdown and --contributions follow the same rule, including when
combined with other text-only options:
all --json combinations preserve the same schema v1 bytes as --json alone.
Project/lock JSON is instead schema v3; existing-prefix JSON is schema v2.
These schemas are distinct input families, so consumers must check
schema_version and context.input_kind before interpreting or comparing a
record.
Baseline comparison
Record a schema v1 fresh-install measurement with --json, then compare a new
fresh measurement to that read-only file:
uv-packsize requests==2.32.5 --json > baseline.json
uv-packsize requests==2.32.5 --baseline baseline.json
uv-packsize requests==2.32.5 --baseline baseline.json --comparison-json
The default comparison writes only the text diff report to standard output.
For fresh package requests, --comparison-json writes the closed
comparison result schema v1,
including its final newline. Project/lock baselines instead use the closed
comparison result schema v2.
Both comparison documents are separate from analysis JSON: they report the
baseline and current global/distribution aggregates, every distribution change,
nonreconciliation, and completeness rather than a file inventory.
Comparison JSON exposes an opaque context fingerprint for correlation, not raw
requirements, paths, resolver observations, or the individual context
fingerprints. Project/lock comparison v2 never publishes either lock identity;
it exposes only lock_changed to state whether the two lock fingerprints
differ. The two measurements must use the same measurement definition
and resolution context (including requirements, Python/platform fingerprints,
build policy, and resolver conditions). Baselines can be compared only within
their input family: fresh-install v1 with v1, or project-lock v3 with v3.
Existing-prefix schema v2 baselines are deliberately not comparable yet. The
baseline file is read once and never modified.
The report shows both the deduplicated global logical-size change and the distribution-owned aggregate change. They can differ when multiple distributions own the same installed file: global totals count each canonical file once, while distribution totals retain ownership. Incomplete but comparable inputs still exit successfully and label their deltas as partial.
--comparison-json requires --baseline and is mutually exclusive with
--json; the existing --baseline exclusions for --prefix, --bin,
--explain, --breakdown, and --contributions also apply. Progress and
sanitized errors go to standard error. Both comparison forms exit 0 on a
completed comparison, including an incomplete comparison whose JSON
completeness and warning summaries describe the partial result. Regular
install or analysis failures exit 1; invalid usage exits 2; baseline load or
validation failures exit 3; and incompatible baselines exit 4. Every failure
leaves standard output empty, so comparison JSON can be consumed safely only
on success.
Writing a baseline
For a fresh-install or project/lock measurement, --write-baseline PATH writes
the same readable JSON document that --json emits (schema v1 or v3,
respectively). It is useful when the measurement is both a CI artifact and the
next comparison input:
uv-packsize requests==2.32.5 --json --write-baseline next-baseline.json
uv-packsize requests==2.32.5 --baseline next-baseline.json
On success, --json --write-baseline writes byte-identical JSON to stdout and
to the file (including its final newline). Text presentation options such as
--bin, --explain, --breakdown, and --contributions only affect the
report; they never change the saved baseline bytes. The baseline is rendered,
validated, and published before either report or JSON is written to stdout.
Publication is no-clobber by default: an existing target causes a sanitized exit 3 error and is left untouched. Replace a known baseline only with the explicit opt-in:
uv-packsize requests==2.32.5 --json \
--write-baseline next-baseline.json --overwrite-baseline
--overwrite-baseline requires --write-baseline. Writing is unavailable with
--prefix and cannot be combined with --baseline (and consequently not with
--comparison-json). In write mode all progress and Calculation complete.
go to stderr; stdout is only the successful final report or JSON. Render and
write failures also use exit 3, contain only a fixed code and field, and
leave stdout empty.
The atomic writer currently supports POSIX platforms only. It creates a 0600 temporary file in an existing trusted parent directory and atomically publishes it without following symlinks or replacing a target unless overwrite was requested. The parent-directory policy rejects symlinked, unsafe writable, or otherwise untrusted traversal components; choose a normal directory you own. Directory-entry durability after a successful publish is filesystem/platform dependent even when directory fsync is available. On Windows and other unsupported platforms, keep using the portable existing path:
uv-packsize requests==2.32.5 --json > portable-baseline.json
Size budgets
Apply an explicit size policy to a fresh-install or project/lock analysis with
a project file, individual command-line limits, or both. There is no automatic
pyproject.toml discovery: --budget-config reads exactly the path supplied
and uses only its [tool.uv-packsize.budget] table.
[tool.uv-packsize.budget]
max_total_logical_bytes = 52428800
max_increase_logical_bytes = 1048576
incomplete_policy = "fail"
uv-packsize requests==2.32.5 --budget-config pyproject.toml
uv-packsize requests==2.32.5 --baseline baseline.json \
--budget-config pyproject.toml --max-increase 524288
--max-total and --max-increase accept non-negative decimal bytes and apply
to canonical global logical bytes, never distribution-owned aggregates. A
policy file supplies the base policy; each explicitly supplied CLI field
overrides only its corresponding field, while unspecified fields remain from
the file. An absent budget table supplies no policy, while an explicit empty
table or --incomplete-policy alone is a valid no-op policy.
An increase limit requires --baseline; the comparison must pass its matching
fresh-install-v1 or project-lock-v3 compatibility checks before the delta can
be evaluated. Total-only
policies do not use baseline size, completeness, or nonreconciliation as a
budget input. By default, a policy with a limit fails incomplete measurements;
--incomplete-policy allow-partial suppresses only that incomplete-result
violation and still evaluates observed total and increase limits.
Text output appends a Size Budget report to the regular analysis or comparison
report. A budget violation exits with status 5 after that completed text
report. With --json or --comparison-json, successful policy runs retain
the exact pre-existing JSON bytes, while a violation writes no standard output
and instead emits the safe budget report and summary on standard error before
exiting 5. A --write-baseline target is rendered and published only after the
policy passes, so a violation never creates or replaces it.
Budget policy inputs are unavailable with --prefix; existing-prefix JSON v2
is not retroactively budgeted. Invalid explicit policy sources and policy
fields use status 3 without echoing local paths or TOML values. Existing status
codes remain unchanged: operational failures use 1, usage errors 2, baseline
and policy-source failures 3, and incompatible baselines 4.
For CI, commit the policy in the project file and make the baseline an explicit artifact or tracked file:
uv-packsize -p 3.12 --budget-config pyproject.toml \
--baseline .ci/uv-packsize-baseline.json 'your-package==1.2.3'
GitHub Actions: locked project comparison
For a locked project, commit a reviewed baseline (for example,
.ci/uv-packsize-baseline.json) and the optional budget table in
pyproject.toml. Copy this workflow to your repository as
.github/workflows/dependency-footprint.yml:
name: Dependency footprint
on:
pull_request:
push:
permissions:
contents: read
jobs:
dependency-footprint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up uv
uses: astral-sh/setup-uv@v7
with:
version: "0.11.3"
- name: Compare locked dependency footprint
shell: bash
run: |
temporary_directory="$(mktemp -d)"
trap 'rm -rf "$temporary_directory"' EXIT
comparison_json="$temporary_directory/comparison.json"
uvx uv-packsize --project pyproject.toml --lockfile uv.lock --baseline .ci/uv-packsize-baseline.json --budget-config pyproject.toml --comparison-json > "$comparison_json"
python - "$comparison_json" >> "$GITHUB_STEP_SUMMARY" <<'PY'
import json
import sys
with open(sys.argv[1], encoding="utf-8") as comparison_file:
comparison = json.load(comparison_file)
baseline_total = comparison["baseline"]["totals"]["global_logical_bytes"]
current_total = comparison["current"]["totals"]["global_logical_bytes"]
global_delta = comparison["changes"]["totals"]["global_logical_bytes_delta"]
print("## Dependency footprint")
print()
print(f"- Input kind: `{comparison['context']['input_kind']}`")
print(f"- Lock changed: `{comparison['context']['lock_changed']}`")
print(f"- Baseline total: {baseline_total} bytes")
print(f"- Current total: {current_total} bytes")
print(f"- Change: {global_delta:+d} bytes")
PY
This is deliberately a read-only check: it uses least-privilege
contents: read, analyzes only the explicit project and lock file, and never
creates or updates a baseline. The comparison JSON is kept in a private
temporary directory and deleted at job exit. The job summary emits only fixed
schema fields (input kind, whether the lock changed, and global byte totals);
it does not publish the JSON, local paths, requirements, or lock contents.
The workflow is safe to run for ordinary push and fork pull-request events because it needs no secrets, write permissions, PR-comment integration, or automatic baseline update. Keep the baseline reviewable in the repository (or otherwise supply it explicitly) and make any baseline refresh a separate, reviewed change.
Dependency explanations
Pass --explain with text output to append requested-root status, dependency
attribution, and shortest installed dependency paths. The explanation is built
from the installed distributions' Core Metadata after the size measurement; it
is not a claim about resolver provenance. If installed metadata is missing,
invalid, or otherwise incomplete, the command still reports the size and adds
a sanitized graph-warning summary with warning-code counts.
Dependency paths explain which roots reach an installed distribution. Use
--contributions for the corresponding non-split byte view.
Requested-root contributions
Pass --contributions with text output to append requested-root exclusive,
shared, and closure bytes; exact shared root-set buckets; and a reconciliation
to the global total. Reachability is derived from installed distributions'
Core Metadata, not resolver provenance. A closure includes every observed byte
reachable from that root, so closures for different roots must not be summed.
An exact shared root-set bucket is counted once globally, never once per root.
exclusive contains bytes reachable from exactly one recognized root;
shared contains bytes in observed root sets containing that root and at least
one other recognized root; and closure = exclusive + shared. This describes
the fixed, observed installed graph only. It is not a resolver counterfactual
about what would be installed if a root were removed.
Duplicate requested root inputs do not create bytes or root sets: they retain
their distinct 1-based input indices in the root row. If Core Metadata cannot
form a complete graph, contribution numbers and root-set details are marked
unavailable; the measured global footprint and its inventory completeness are
still reported. As with --explain and --breakdown, this text-only option
does not change JSON schema v1.
Global footprint breakdown
Pass --breakdown with text output to append two global, deduplicated views of
the measured inventory. File Category Breakdown always shows all six stable
categories (python, native, data, metadata, script, and other),
including zero-sized rows. Dependency Size Attribution classifies the same
global bytes as self, direct, transitive, unattributed, or
mixed-ownership; a file claimed by more than one distribution is still
counted once globally.
The role breakdown is derived from the same installed Core Metadata graph used
by --explain, not from resolver provenance. If that graph is incomplete, the
category breakdown remains available while dependency-role sizes are marked
unavailable and a sanitized warning-code summary is shown. --explain --breakdown prints the normal report once, then dependency explanations and
the footprint sections; any graph warning is shown once. JSON schema v1 is not
extended by these opt-in text outputs. --contributions follows them, with the
normal report rendered once and its contribution sections last.
Measurement
For package requests, uv-packsize creates a temporary virtual environment,
installs all requested packages and their resolved dependencies with uv pip install, and then scans the installed distributions. Project/lock mode instead
uses the isolated locked sync described above. The temporary environment is
removed after the command finishes.
For each distribution, its .dist-info/RECORD file is the source of file
ownership. The measurement scope is the temporary environment prefix, not just
site-packages: RECORD-owned scripts, data files, and headers are included
when they resolve inside that prefix. Generated .pyc files matching recorded
Python source files are also included when present.
This is installed logical size: it is neither the compressed wheel or sdist size nor the number of filesystem blocks allocated on disk. It sums the filesystem-reported size of each included path and does not account for physical storage savings from hardlinks, clones, or similar sharing.
The final Total size is derived from the included file inventory. If two
distributions claim the same installed file, that file is counted once in the
global total; --breakdown uses that same canonical global inventory rather
than adding distribution rows together. Missing RECORD files, missing installed
files, malformed metadata, and similar conditions produce an incomplete-analysis
warning rather than being silently treated as a complete result.
The total does not include:
- the Python interpreter or the virtual environment's base files;
- the
uvcache; - files not owned by an installed distribution's RECORD or conservative metadata fallback.
--bin is a presentation option. It moves RECORD-owned script files from the
package table into a separate Binaries in .venv/bin table; it never changes
the final global total or scans unowned virtual-environment boilerplate. For an
existing-prefix scan, the equivalent heading is Binaries in prefix.
Sizes use binary units: KiB, MiB, and GiB are powers of 1024.
Current limitations
- Results depend on the selected Python version and platform, and on extras and dependency resolution. Compare results only when those conditions match.
- Multiple requested packages are installed into one environment. The current
resolver normally installs a shared dependency once.
--explainidentifies direct, transitive, and shared installed dependencies and their paths;--breakdowndescribes global category and role totals; and--contributionsprovides a non-split, observed root-set byte view. - Text output is intended for interactive use. For a versioned record with the
measurement context needed for comparison, use
--json.
Installation safety
The default installer is wheel-only: it passes --no-build to uv pip install
or the private uv sync, and does not permit source builds. If no compatible
wheel is available, the command fails without running that distribution's build
backend. It may reuse a compatible wheel that was already built in the uv
cache; the guarantee is that this invocation does not build an sdist.
Use --allow-build only as an explicit permission to let uv build from
source when needed. A temporary virtual environment isolates the install
destination; it is not a security sandbox. When builds are allowed, third-party
build code runs with the current user's permissions and may access the
filesystem or network outside that environment. Use it only for packages and
package indexes you trust.
The JSON context.build_policy records the permission selected for the run
(wheel-only or allow-build). It does not claim which distributions actually
built; the tool does not infer that from uv diagnostics or cache contents.
Packages are installed into the command's temporary virtual environment, not directly into an existing user or system Python environment.
Development
To contribute to this tool, first checkout the code. Then create a new virtual environment using uv:
make sync
To run the tests:
make test
To run all formatting and linting, type check:
make check
this also runs cog on README.md and updates the help message inside it.
Metadata
Release files for uv-packsize 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| uv_packsize-0.2.0.tar.gz | 247.4 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| uv_packsize-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 382.5 kB
Release files / uv_packsize-0.2.0.tar.gz
| Download URL | uv_packsize-0.2.0.tar.gz |
|---|---|
| Size | 247.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
87e5c77495e03bc10426eaf60a7720cdf7fb928463fac59f9bb9a536a90f3090
|
|
BLAKE2b-256 checksum How to use checksums |
d880b5aee0006a3bc46dfef07bae7363fc9176503597855e0dd412f0a2912e58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logRelease files / uv_packsize-0.2.0-py3-none-any.whl
| Download URL | uv_packsize-0.2.0-py3-none-any.whl |
|---|---|
| Size | 135.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6048d0fae94ba0e6c1df5887d9feaa9abb697f5724dbd628dc6ab965e45f3122
|
|
BLAKE2b-256 checksum How to use checksums |
24491cb27c5b87aaf68ef6b169fc8db41b4a88f4f23da11486e55db8242fa49a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logSecurity for uv-packsize 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for uv_packsize-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.