Skip to main content

A Python module privacy checker for keeping public interfaces intentional.

Project description

Privata

License CI PyPI Python Versions Docs

Privata logo

Find Python code that looks public but is only used privately.

Privata is a static checker for keeping module boundaries intentional. It scans your production Python modules and reports three kinds of interface drift:

  • public top-level functions, classes, variables, and type aliases that are only used inside their own module
  • imports of private modules such as pkg._internal from outside their owning package subtree
  • literal __all__ declarations that are stale, incomplete, or exporting names that do not exist

It is designed for packages and applications where helper() should become _helper() once it is no longer part of the production interface. Test imports do not count, so tests can still reach internals without forcing those internals to stay public.

Example

Given:

# src/example/service.py
def helper() -> int:
    return 1


def run() -> int:
    return helper()

Privata reports:

Found 1 public symbols that could be made private:

  src/example/service.py:1: function `helper`

Install

uv tool install privata

For local development:

uv sync --extra dev --group docs
uv run pre-commit install

Usage

Run Privata from a project root:

privata .

Privata uses tach.toml source_roots when present. Otherwise it prefers src/ when that directory exists, and falls back to scanning the project root while ignoring tests, virtualenvs, build output, docs output, and hidden tooling directories.

Use Privata as a pre-commit hook in another repository:

repos:
  - repo: https://github.com/basnijholt/privata
    rev: v0.1.2
    hooks:
      - id: privata

For a less strict setup that only runs when requested:

repos:
  - repo: https://github.com/basnijholt/privata
    rev: v0.1.2
    hooks:
      - id: privata-manual
pre-commit run --hook-stage manual privata-manual --all-files

Full output can include multiple issue types:

Found 2 public symbols that could be made private:

  src/example/service.py:12: function `helper`
  src/example/service.py:21: class `InternalState`

Found 1 private module imports outside their package subtree:

  src/example/api.py:3: imports private module `example.worker._runtime`

Found 1 __all__ export issues:

  src/example/__init__.py:5: public name `Service` missing from __all__

If the project is clean:

No module privacy issues found.

What Privata Checks

  • Public top-level functions, classes, variables, and type aliases in production source roots.
  • Whether those symbols are imported by another production module under those roots.
  • Whether private modules such as pkg._internal are imported outside their containing package subtree.
  • Whether literal __all__ declarations exactly match public top-level bindings.
  • Console entry points in pyproject.toml.
  • Uvicorn entry points in shell scripts and Dockerfiles.
  • Symbols exported through package __init__.py and __all__.
  • Tach [[interfaces]] entries, when tach.toml is present.

Privata intentionally ignores imports from tests/. If only tests import a symbol, Privata treats that symbol as private.

Development

uv run pytest  # enforces 100% coverage
uv run pre-commit run --all-files
uv build

Project details


Download files

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

Source Distribution

privata-0.1.6.tar.gz (63.2 kB view details)

Uploaded Source

Built Distribution

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

privata-0.1.6-py3-none-any.whl (15.5 kB view details)

Uploaded Python 3

File details

Details for the file privata-0.1.6.tar.gz.

File metadata

  • Download URL: privata-0.1.6.tar.gz
  • Upload date:
  • Size: 63.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for privata-0.1.6.tar.gz
Algorithm Hash digest
SHA256 ff189bcaf1c5b8bc12e54b8756c8456df4daee52916b8191952f1b07338dbd06
MD5 4fb03fdeedae861aed184ea8dad92952
BLAKE2b-256 c8bc5ec06ff2878fb9d744886395c2b5ba89b18fe2030508ea498dd7dbca9b4a

See more details on using hashes here.

Provenance

The following attestation bundles were made for privata-0.1.6.tar.gz:

Publisher: release.yml on basnijholt/privata

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

File details

Details for the file privata-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: privata-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 15.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for privata-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 27b66ad6eaef45703b826209c686c929140d0c29772f58932a12ef8149bce480
MD5 743ec4e72eecb3ada107c19d43c5d2f4
BLAKE2b-256 763d2ba6f47d847ed0f42fd73a74d30336c42a5647322af283f4db2467702448

See more details on using hashes here.

Provenance

The following attestation bundles were made for privata-0.1.6-py3-none-any.whl:

Publisher: release.yml on basnijholt/privata

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 Pingdom Monitoring Sentry Error logging StatusPage Status page