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 four 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
  • imports of private top-level symbols such as pkg.service._Helper from another production module
  • 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 private symbol imports from production modules:

  src/example/api.py:4: imports private symbol `example.worker.runtime._Helper`

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 private top-level symbols are imported from another production module.
  • 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

test_privata-0.1.2.tar.gz (81.7 kB view details)

Uploaded Source

Built Distribution

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

test_privata-0.1.2-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file test_privata-0.1.2.tar.gz.

File metadata

  • Download URL: test_privata-0.1.2.tar.gz
  • Upload date:
  • Size: 81.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for test_privata-0.1.2.tar.gz
Algorithm Hash digest
SHA256 07c10090e7d1a8d83eeefddec28b3f753197f3061f5ef0887cc66a71d405210d
MD5 f6a7d5825a96cda5af53a75f4ae35bdc
BLAKE2b-256 a6cb317f905e0b807b4076e8d7c9cb91ec66fb11f4f249f467930e31497e48b6

See more details on using hashes here.

File details

Details for the file test_privata-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: test_privata-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for test_privata-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0aa906f6cea19693d4275230b81b4620e1e38f813d6418fb97935a4c7644f2aa
MD5 190bd6f222f7e6c8f6aafab12027dfca
BLAKE2b-256 e7c2b2187eace71637d72b302dcfe6f2b9645eddb8c1f991ff8f99a6fddaf719

See more details on using hashes here.

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