Registry Management¶
For Framework Developers
This section is for developers building frameworks or plugin ecosystems.
If you're just adding deprecations to your own package, use for_package() directly—see the Getting Started guide.
When Do You Need a Registry?¶
Most packages don't need a registry. Use for_package() directly:
You need a registry when you're building a framework where:
- Multiple packages contribute to your ecosystem (plugins, extensions)
- You want to track deprecations across all contributing packages together
- You need coordinated deprecation timelines across the ecosystem
API Reference¶
DeprecatorRegistry
¶
collection of deprecators bound to a specific framework
we use deprecator as "framework" for unbound deprecators
Source code in deprecator/_registry.py
for_package
¶
Get or create a deprecator for the given package and version.
:param package_name: Name of the package to create deprecator for :param _version: NOTE: This is private/internal. User code should NOT provide this argument. This is Version of the package. If None, will be looked up automatically. :returns: Deprecator instance for the package
Source code in deprecator/_registry.py
registry_for
¶
return a registry bound to a specific package name
Core Concept¶
Registries solve the problem of tracking deprecations across an ecosystem:
┌─────────────────────────────────────────────────────┐
│ Framework Registry │
│ (e.g., "myframework") │
├─────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ core pkg │ │ plugin A │ │ plugin B │ │
│ │ deprecator │ │ deprecator │ │ deprecator │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────┘
- Framework declares a registry: The main framework creates a registry for its ecosystem
- Contributing packages use the registry: Plugins register their deprecations with the framework's registry
- Centralized tracking: All deprecations can be tracked and managed together
Usage Examples¶
Framework: Declare a Registry¶
# myframework/_deprecations.py - Main framework declares the registry
from deprecator import registry_for
# Create the ecosystem registry
framework_registry = registry_for(framework="myframework")
framework_deprecator = framework_registry.for_package("myframework")
# Framework's own deprecations
OLD_ROUTER = framework_deprecator.define(
"Router.add_route() is deprecated, use Router.route()",
warn_in="2.0.0",
gone_in="3.0.0"
)
Plugin: Join the Ecosystem¶
# myframework_auth/_deprecations.py - Auth plugin uses framework's registry
from deprecator import registry_for
# Join the framework ecosystem
framework_registry = registry_for(framework="myframework")
auth_deprecator = framework_registry.for_package("myframework-auth")
# This deprecation is grouped with the framework's ecosystem
LEGACY_LOGIN = auth_deprecator.define(
"login_user() is deprecated, use authenticate()",
warn_in="0.8.0",
gone_in="1.0.0"
)
Entry Point Integration¶
Frameworks can expose their registry via entry points for automatic discovery:
# Framework's pyproject.toml
[project.entry-points."deprecator.registry"]
myframework = "myframework._deprecations:framework_registry"
# Plugin's pyproject.toml
[project.entry-points."deprecator.deprecator"]
myframework-auth = "myframework_auth._deprecations:auth_deprecator"
This enables:
Benefits¶
- Ecosystem Coordination: All packages coordinate deprecation timelines
- Consistent User Experience: Users see consistent deprecation patterns
- Framework-Wide Planning: Plan major releases considering all ecosystem deprecations
- Centralized CLI: Use
deprecator show-registryto inspect all deprecations
Caching Behavior¶
Registry operations are cached for performance:
# Deprecator instances are cached per registry
dep1 = registry.for_package("mypackage")
dep2 = registry.for_package("mypackage")
assert dep1 is dep2 # Same instance
Registry operations are thread-safe through functools.lru_cache, allowing concurrent access during import.
Best Practices¶
- Only frameworks create registries - Plugins should use their framework's registry
- Use consistent naming - Registry name should match framework's canonical name
- Document for plugin authors - Explain how plugins should use the registry
- Standalone packages don't need registries - Just use
for_package()directly