mrkeyoor.com_
Sun 20 Sept 02:42 UTC
PyPIInfraupdated 18 Sept 2026

distro review

distro turns the host's release files and commands into a small Python API for Linux and BSD identity. It can return a normalized ID such as `ubuntu`, a display name, version parts, codename, and the `ID_LIKE` family list. Version 1.9.0 changed `distro.info()` to return the typed `InfoDict` and stopped treating `/etc/board-release` and `/etc/ec2_version` as distribution release files. Our Python 3.12 install stayed small and imported successfully, which fits its job as an early bootstrap dependency.

Verdict

Install distro when Linux-family and fallback detection affect real setup logic, especially on mixed fleets. Skip it for a Python 3.10+ service that only reads standard `os-release` fields or for any cross-platform hardware inventory tool.

We installed it

Lab card: what happened when we installed distroScreenshot of distro documentation
Install✓ · 0.3s1 package on disk · 1 MB
Importimport distro in 0.18s · pure Python · py.typed · requires Python >=3.6
Known vulns0(pip-audit)

Answers from our run

Does distro install cleanly?

Yes. In a fresh container with an empty cache, pip install distro finished in 0.3s, leaving 1 package and 1 MB on disk. pip-audit reported no known vulnerabilities.

What does distro need to run?

Python >=3.6, and nothing compiled: it is pure Python. In our run import distro succeeded in 0.18s, and the package ships py.typed for type checkers.

distro or psutil: which should you use?

psutil: Choose it when the report needs CPU, memory, disks, network interfaces, and processes in addition to platform identity. Install distro when Linux-family and fallback detection affect real setup logic, especially on mixed fleets.

When should you not use distro?

You only support Python 3.10 or newer and only read /etc/os-release; platform.freedesktop_os_release() already handles that file in the standard library.

API stability5/5The public calls remain narrow and recognizable: `id`, `name`, `version`, `version_parts`, `like`, `codename`, and `info`. Version 1.9.0 refined the return type of `info()` to `InfoDict` without replacing the basic access pattern. The package still documents module-level functions and an instantiable `LinuxDistribution` for callers that need explicit data-source control.
Docs4/5The README explains the source precedence, supported operating systems, standalone CLI, vendoring option, and common calls with real output. Read the API reference for constructor controls and raw attributes. The weak spot is operational guidance: it does not spend much time on containers, missing codenames, stale mounted files, or choosing between normal and `best=True` version results.
Maintenance3/5PyPI still points to 1.9.0, released in January 2024, while the repository was pushed in July 2026 and currently shows 13 issues and pull requests combined. That looks like slow maintenance of a settled interface rather than frequent releases. The current release added modern interpreter test coverage and distribution fixtures, but consumers should not expect quick feature delivery.
Ecosystem5/5The stored registry snapshot records 97,498,424 weekly downloads, and the project README links native packages for Debian, Ubuntu, Fedora, Arch, Gentoo, and others. Its role as the replacement for the removed `platform.linux_distribution()` API gives downstream tooling one familiar vocabulary for otherwise inconsistent release files and commands.

Discussed on

  1. hnTiny Core Linux: a 23 MB Linux distro with graphical desktop527 points
  2. hnSnakeware – Linux distro with Python userspace inspired by Commodore 64436 points
  3. hnJingOS: Linux Distro Inspired by the iPad435 points
  4. hnShow HN: CoreOS, a Linux distro for containers417 points
  5. hnKali Linux 2023.1 introduces 'Purple' distro for defensive security380 points

Use it if

  • Your installer must choose apt, dnf, or another path from a normalized Linux distribution ID.
  • You need `ID_LIKE` family matching so a derivative can follow its Debian, Ubuntu, Fedora, or RHEL parent path.
  • Your support bundle needs a JSON-ready set of distribution name, version, codename, and family fields.
  • You must inspect older or unusual hosts where reading only `/etc/os-release` is insufficient.
Skip it if

Setup reality

We installed distro 1.9.0 in a fresh unprivileged Python 3.12 Bookworm container. Installation succeeded in 0.3 seconds and left one package using 1 MB on disk. It has no direct dependencies, is pure Python, includes py.typed, and requires Python 3.6 or newer. import distro worked in 0.18 seconds. pip-audit found 0 known vulnerabilities.

There are no credentials or config files. The data comes from the host: /etc/os-release, then lsb_release, distribution release files, and uname for BSD. A minimal container may omit lsb_release, while a bind-mounted or custom os-release file can describe the image rather than the physical host. Treat the result as the current runtime environment.

Fields are not equally dependable. id() is the safest branch value, while name(pretty=True), codename(), and version parts may be empty or vary with the available source. version(best=True) deliberately searches for the most detailed version and can differ from the normal precedence result. Module-level calls use a cached LinuxDistribution instance, so tests that replace release files should construct their own instance with explicit paths.

The project also permits copying distro.py into bootstrap code that cannot install dependencies yet. Vendoring transfers update responsibility to you. Version 1.9.0 ignores /etc/board-release and /etc/ec2_version, which avoids false identification on systems where those files describe hardware or an EC2 image rather than the distribution.

Patterns

Read the normalized distribution ID get-distro-id

import distro

os_id = distro.id()
if os_id == "ubuntu":
    configure_ubuntu()

Branch on `id()`, not the display name. Unsupported systems or missing data can produce an empty string.

Match a distribution and its parent families match-distro-family

import distro

family = {distro.id(), *distro.like().split()}
if family & {"debian", "ubuntu"}:
    package_manager = "apt"
elif family & {"fedora", "rhel", "centos"}:
    package_manager = "dnf"

`like()` returns the space-separated `ID_LIKE` value. Keep the distribution's own ID in the set because the field may be empty.

Format a readable name for diagnostics display-distro-name

import distro

label = distro.name(pretty=True) or distro.id() or "unknown"
print(f"Distribution: {label}")

The pretty value may include a version or codename and should not be used as a stable comparison key.

Read version parts without assuming they exist read-version-parts

import distro

major, minor, build = distro.version_parts(best=True)
if distro.id() == "ubuntu" and major.isdigit() and int(major) >= 22:
    enable_new_repository_layout()

Version parts are strings. Rolling releases and sparse release files can return empty strings, so guard numeric conversion.

Attach distribution details to a support report collect-distro-info

import json
import distro

report = {
    "distribution": distro.info(pretty=False, best=True),
}
print(json.dumps(report, indent=2))

In 1.9.0 `info()` returns the typed `InfoDict`; its values are suitable for JSON serialization.

Read an os-release field outside the high-level API read-raw-os-release

import distro

variant = distro.os_release_attr("variant_id")
build = distro.os_release_attr("build_id")

Pass the lowercase form of the os-release key. Missing attributes return an empty string.

Inspect release files under another root use-custom-root

from distro import LinuxDistribution

target = LinuxDistribution(
    root_dir="/mnt/image",
    include_lsb=False,
    include_uname=False,
    include_oslevel=False,
)
print(target.info())

With `root_dir`, command-based sources default off because they would describe the running host rather than the mounted image.

Read distribution data from a shell script use-cli-json

python -m distro --json
python -m distro --json | jq -r '.id'

Use `python -m distro` when the virtual environment's console-script directory may not be on `PATH`.

Use the standard library for os-release only prefer-stdlib

import platform

try:
    release = platform.freedesktop_os_release()
except OSError:
    release = {}

os_id = release.get("ID", "")

This Python 3.10+ API reads freedesktop os-release data but does not add distro's `lsb_release`, release-file, or BSD fallbacks.

Fall back when os-release is unavailable fallback-to-distro

import platform

try:
    os_id = platform.freedesktop_os_release().get("ID", "")
except (AttributeError, OSError):
    import distro
    os_id = distro.id()

Keep the package only if the extra fallbacks or Python versions below 3.10 are part of your support matrix.

Alternatives

PackageRegistryPick it when
psutilPyPIChoose it when the report needs CPU, memory, disks, network interfaces, and processes in addition to platform identity.
distro-infoPyPIChoose it for Debian and Ubuntu release names, support status, and lifecycle data rather than local-host detection.
platformdirsPyPIChoose it when the actual task is finding platform-specific config, cache, log, or data directories.

More infra guides

boto3 · opentelemetry-api · @opentelemetry/api · psutil · @aws-sdk/client-s3 · google-cloud-storage · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.