Skip to main content

wppm — Manage your Python packages

wppm is a complement to pip, for any Python environment (it was born in WinPython, the portable Windows distribution, but does not require it). Keep using pip to install and remove things — use wppm to see what is actually there.

pip install wppm

Global navigation commands

What packages are there? package version and summary

$ wppm -ls
Package            Version        Summary
__________________ ______________ ______________________________________________________________________
build              1.5.0          A simple, correct Python build frontend
certifi            2026.6.17      Python package for providing Mozilla's CA Bundle.
charset-normalizer 3.4.9          The Real First Universal Charset Detector. Open, modern and actively m
...

What did I actually ask for? Nothing in an environment records which packages you chose and which merely came along. -tl keeps only the entries nothing else pulls in:

$ wppm -tl
build
duckdb
flake8
flit
pandas
pillow
pipdeptree
pytest
PyYAML
wppm
# 32 entries -> 10 kept, 22 already pulled in

What are the dependencies?

$ wppm -tl -p
build==1.5.0 ,
    colorama==0.4.6 ;os_name==nt
    packaging==26.2 >=24.0
    pyproject-hooks==1.2.0
duckdb==1.5.4
flake8==7.1.1 ,
    mccabe==0.7.0 (<0.8.0,>=0.7.0)
...

Navigation per package(s)

What does a package need? -p walks downwards, -l says how many levels:

$ wppm -p pandas -l2
pandas==3.0.3 ,
    numpy==2.4.6 >=2.3.3;python_version>=3.14
    python-dateutil==2.9.0.post0 >=2.8.2,
        six==1.17.0 >=1.5
    tzdata==2025.3 ;sys_platform==win32

What packages are upgrade constrained? -r walks upwards, and ! keeps only the packages that pin or cap the one you name, . means to look for every package:

$ wppm -r  ".!"
charset-normalizer==3.4.9 ,
    requests==2.34.2 [requires: charset-normalizer<4,>=2]
idna==3.18 ,
    requests==2.34.2 [requires: idna<4,>=2.5]
...

Quoting: ! and [ are shell metacharacters in POSIX shells, so quote any argument containing them (wppm -r "pluggy!"). In cmd.exe the quotes are optional.

Package [Extras] analysis

use brackets to specify extra(s) [extra], [.] means every extra, and ! narrows the answer to what is missing==? marks a requirement that is not installed:

What am I missing, per flit extra?

$ wppm -p "flit![.]"
flit[doc]==3.12.0 ,
    pygments-github-lexers==? ;extra==doc
    sphinx==? ;extra==doc
    sphinxcontrib-github-alt==? ;extra==doc
flit[test]==3.12.0 ,
    pytest-cov==? ;extra==test
    responses==? ;extra==test
    testpath==? ;extra==test
    tomli==? ;extra==test

Which package[extra] may want numpy?

$ wppm -r "numpy[.]"
numpy==2.4.6 ,
    pandas==3.0.3 [requires: numpy>=2.3.3;python_version>=3.14]
numpy[all]==2.4.6 ,
    duckdb[all]==1.5.4 [requires: numpy;extra==all]

Pruning a requirements file

Given a file, -tl answers for that file's entries. Plainly, it prints the pruned list and nothing else — so the output is a reduced requirement file, -v will include the reason for each pruned package:

$ wppm requirements.txt -tl > requirements_new.txt
# 160 entries -> 112 kept, 48 already pulled in
# 8 repeated, collapsed: brotli, openai, pympler, pytest, python-barcode, ...
$ wppm requirements.txt -tl -v
# requirements.txt, sorted, 2026-08-13 19:22:43
# 160 entries -> 112 kept, 48 already pulled in
...
#numpy  # <- baresql, clarabel, cvxpy, dask[array,dataframe,diagnostics], datashader, ...
#scikit-learn  # <- imbalanced-learn, mlxtend, prince, skrub, umap-learn
#whatthepatch  # <- spyder

Answers a script can read

-p, -r, -tl, -ls and -md all accept -j / --json, so the same answers can gate a CI job or be diffed between two environments:

$ wppm -p myapp -j | python -c "import sys,json; s=json.load(sys.stdin); [s.extend(n['depends']) for n in s]; sys.exit(1 if any(not n['installed'] for n in s) else 0)"

Better still, skip the terminal: the tree engine is a plain importable module — no subprocess, no parsing of terminal output.

>>> from wppm import piptree
>>> pip = piptree.PipData()             # or PipData(target=r"D:\WPy64\python")
>>> print(pip.down("pandas", "mysql"))
pandas[mysql]==3.0.3 ,
    numpy==2.4.6 >=2.3.3;python_version>=3.14
    pymysql==? >=1.1.1;extra==mysql
    python-dateutil==2.9.0.post0 >=2.8.2,
        six==1.17.0 >=1.5
    sqlalchemy==? >=2.0.36;extra==mysql
    tzdata==2025.3 ;sys_platform==win32
>>> pip.summary("pandas")
'Powerful data structures for data analysis, time series, and statistics'

down() and up() return indented text by default, or a JSON string with format="json"; both take top_level=True to start from the top-level entries. top_level() itself returns plain data — kept, and dropped mapping each dropped entry to whatever pulls it in:

>>> pip.top_level()["kept"]
['build', 'duckdb', 'flake8', 'flit', 'pandas', 'pillow', 'pipdeptree', 'pytest', 'PyYAML', 'wppm']
>>> pip.top_level(["pandas", "numpy", "requests[socks]", "pytest"])["dropped"]
{'numpy': ['pandas']}

Environments you have not installed anything into

-t points wppm at another Python distribution, and -ws at a plain directory of wheels — so you can inspect a portable distribution, or an offline bundle, without installing it first:

$ wppm -p "pandas[.]" -t D:\WPy64\python
$ wppm -ls -ws .\wheelhouse\included.wheels --json

With -ws the facts come from the wheelhouse rather than an installation, so a requirements list can be pruned before anything is built; where several versions of a package are present, the newest one answers.

Beyond inspection, wppm installs from a wheelhouse or a pylock.toml (-i, -ws, -wd), emits a one-document environment manifest — distribution, tools, packages, wheelhouse — as Markdown or JSON (-md, a lightweight SBOM), and does portability housekeeping: on any Windows Python, --movable / --fix rewrite the Scripts\ launchers and shebangs between relative and absolute paths, so a directory can be moved (or pinned back down) without breaking its entry points.

--register / --unregister associate file extensions, icons, context menu and start menu entries with the target Python. Each distribution gets its own start menu folder, so registering one never disturbs another — but note that the target is declared under the WinPython PEP-514 vendor key.

wppm -h lists every option.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wppm-17.12.20260816-py3-none-any.whl (41.3 kB view details)

Uploaded Python 3

File details

Details for the file wppm-17.12.20260816-py3-none-any.whl.

File metadata

  • Download URL: wppm-17.12.20260816-py3-none-any.whl
  • Upload date:
  • Size: 41.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wppm-17.12.20260816-py3-none-any.whl
Algorithm Hash digest
SHA256 c41a205f17dbef6b752d89ce3497a99253f1c3b927d8bc3674c04a36dcd741b0
MD5 bb8bef6dbe38d354aa6c25e539e987f4
BLAKE2b-256 7ab982f5e3fc98810e8349fb26b89cb36619f3f8f09f46796516b2c19cd62bf5

See more details on using hashes here.

Provenance

The following attestation bundles were made for wppm-17.12.20260816-py3-none-any.whl:

Publisher: build_wppm_prod_publish.yml on winpython/winpython

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page