Skip to main content

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.

Exception — test helper modules in a test source root: when tach.toml lists a directory such as tests/ under source_roots, non-test files inside that root (e.g. tests/something.py) are scanned as ordinary modules. Imports from co-located test files do count as cross-module usage in this case, because those helper modules exist solely to serve the test suite. A symbol that at least one test file imports is treated as public; a symbol that no test file imports is still flagged as a private candidate.

Development

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

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.3.tar.gz (83.0 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.3-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: test_privata-0.1.3.tar.gz
  • Upload date:
  • Size: 83.0 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.3.tar.gz
Algorithm Hash digest
SHA256 7992f42d13ef25e4731e119487add351fad36a6a481a11f69b78c7d047d95a2f
MD5 d2ad02e32534c6becbfc7338e8eac948
BLAKE2b-256 16cb63c6b1359d0cbaa6c7ba713e98852c46eaaf2161d32ee1e6bd30578905b8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: test_privata-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 17.3 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 8f57c1ee35108e6a1ad46e4a9cb8926b7c118805f4545926419e15c4b292ec80
MD5 f3e2e66108df76202494920dbde47b87
BLAKE2b-256 57463284d16d2b3a64da78582765892532054529088ed98890e1ac47f3ff8365

See more details on using hashes here.

Release history Release notifications | RSS feed

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.2

2 files

0.10.1

2 files

0.10.0

2 files

0.9.0

2 files

0.1.4

2 files

This release

0.1.3 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

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