Skip to main content

Export, __all__, and lazy import management for Python projects.

Project description

exportify

exportify is a CLI tool and library for managing Python package exports: generating __init__.py files with lazy imports (using lateimport), managing __all__ declarations, and validating import consistency.

Exportify was previously developed as an internal dev tool to assist with our CodeWeaver project; it slowly grew in function until it didn't make sense to keep it as part of that project. Here it is for anyone to use.

What it Does

Exportify solves the problem of managing consistency and updates in export patterns across a codebase. It ensures module and package-level __all__ exports are consistent, accurate, and complete. It can also validate

Exportify offers a simple rule-based system for enforcing __all__ and __init__ patterns across a codebase with optional per-file overrides. Comes with sane defaults.

Features

  • Lazy __init__.py generation — generates __init__.py files using a lazy __getattr__ pattern powered by lateimport, keeping package imports fast and circular-import-free
  • YAML-driven rule engine — declarative rules control which symbols are exported, with priority ordering and pattern matching
  • Export propagation — symbols exported from submodules automatically propagate up the package hierarchy
  • Code preservation — manually written code above the # === MANAGED EXPORTS === sentinel is preserved across regeneration
  • Validation — checks that lazy import calls are well-formed and that __all__ declarations are consistent
  • Cache — SHA-256-based analysis cache for fast incremental updates

Installation

Easiest to install with uv:

uv tool install exportify

or pipx:

pipx install exportify

Python 3.12+ required.

Quick Start

# Create a default config file (.exportify/config.yaml)
exportify init

# Check current state — runs all checks by default
exportify check

# Bootstrap __init__.py files for packages that don't have one
exportify generate

# Preview what fix would change without writing anything
exportify fix --dry-run

# Sync exports and __all__ to match rules
exportify fix

# Show overall export/import health
exportify status

Documentation

For new users

Document Description
Getting Started Step-by-step tutorial for new projects

Reference

Document Description
CLI Reference Complete command reference with all flags
Rule Engine Rule syntax, priorities, match criteria, provenance
Configuration Initializing and configuring exportify

Guides

Document Description
Troubleshooting & FAQ Common issues and answers
Contributing Development setup and how to contribute

Internals (for contributors)

Document Description
Caching Cache implementation and API
Overload Handling @overload decorator support
Provenance Support Symbol provenance in rules
Schema Versioning Config schema version management

Configuration

Rules live in .exportify/config.yaml (created by exportify init or written manually). Exportify searches for the config file in this order:

  1. EXPORTIFY_CONFIG environment variable (any path)
  2. .exportify/config.yaml
  3. .exportify/config.yml
  4. .exportify.yaml in the current working directory
  5. .exportify.yml
  6. exportify.yaml
  7. exportify.yml
schema_version: "1.0"

rules:
  - name: "exclude-private"
    priority: 1000
    match:
      name_pattern: "^_"
    action: exclude

  - name: "include-public-classes"
    priority: 700
    match:
      name_pattern: "^[A-Z]"
      member_types: [class]
    action: include
    propagate: root

  - name: "include-public-functions"
    priority: 700
    match:
      name_pattern: "^[a-z]"
      member_types: [function]
    action: include
    propagate: parent

Rule Priority Bands

Priority Purpose
1000 Absolute exclusions (private, dunders)
900–800 Infrastructure/framework exclusions
700 Primary export rules (classes, functions)
600–500 Import handling
300–400 Special cases
0–200 Defaults/fallbacks

See the Rule Engine docs for the full rule syntax including logical combinations, match criteria, and advanced propagation options.

Propagation Levels

  • none — export only in the defining module
  • parent — export in the defining module and its direct parent
  • root — export all the way to the package root
  • custom — specify explicit target module

Generated Output

Exportify generates __init__.py files using the lazy __getattr__ pattern from lateimport:

# SPDX-FileCopyrightText: 2026 Your Name
#
# SPDX-License-Identifier: MIT

# === MANAGED EXPORTS ===
# This section is automatically generated. Manual edits below this line will be overwritten.

from __future__ import annotations

from typing import TYPE_CHECKING
from types import MappingProxyType

from lateimport import create_late_getattr

if TYPE_CHECKING:
    from mypackage.core import MyClass
    from mypackage.utils import helper_function

_dynamic_imports: MappingProxyType[str, tuple[str, str]] = MappingProxyType({
    "MyClass": (__spec__.parent, "core"),
    "helper_function": (__spec__.parent, "utils"),
})

__getattr__ = create_late_getattr(_dynamic_imports, globals(), __name__)

__all__ = ("MyClass", "helper_function")

def __dir__() -> list[str]:
    """List available attributes for the package."""
    return list(__all__)

[!IMPORTANT] To use exportify for lazy __init__ management, you must add lateimport as a runtime dependency.

Code Preservation

Add a # === MANAGED EXPORTS === sentinel to an existing __init__.py to protect manually written code above it:

"""My package."""

from .compat import legacy_function  # kept across regeneration

# === MANAGED EXPORTS ===
# ... generated section below (managed by exportify)

Everything above the sentinel is left untouched on every fix or generate run.

CLI Reference

Command Description
exportify check Check exports and __all__ declarations for consistency
exportify fix Sync exports and __all__ to match rules
exportify generate Bootstrap new __init__.py files for packages missing one
exportify status Show current export/import health status
exportify doctor Run health checks and provide actionable advice
exportify init Initialize exportify with a default config file
exportify clear-cache Clear the analysis cache

See the full CLI reference for all flags and options.

Requirements

  • Python 3.12+
  • lateimport (installed automatically)

License

Dual-licensed under MIT and Apache 2.0. See LICENSE-MIT and LICENSE-Apache-2.0.

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

exportify-0.1.6.tar.gz (93.9 kB view details)

Uploaded Source

Built Distribution

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

exportify-0.1.6-py3-none-any.whl (126.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for exportify-0.1.6.tar.gz
Algorithm Hash digest
SHA256 020d46b30bf460d6182446bc7f1411cb27530340bd7a833ec8b65f7aa9de0ea3
MD5 8283d21e348e8336274fec1f3eb5e403
BLAKE2b-256 305b63f00dca242ac88bdbbe9cef9cd444b73074f1d55b4e4c99086a77392bad

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on knitli/exportify

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

File details

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

File metadata

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

File hashes

Hashes for exportify-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 cbdde6d83b2f8cb7e2b182811b1552dbaaea977964256e1f1d426e6d81ee5f71
MD5 b775d3ddd0a759bb51ef5f1af09bfaff
BLAKE2b-256 d599ea2634c5c0c5ae86af1c285057cef1ed783b0b53b3d06a2966632e3a0368

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on knitli/exportify

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