Skip to main content

uv-packsize

PyPI Changelog Tests License Docs

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 uv cache;
  • 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. --explain identifies direct, transitive, and shared installed dependencies and their paths; --breakdown describes global category and role totals; and --contributions provides 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)

Source distribution for uv-packsize 0.2.0
File Size Uploaded Provenance
uv_packsize-0.2.0.tar.gz 247.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for uv-packsize 0.2.0
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page