Debtcollector
Debtcollector is a Python library providing a collection of deprecation patterns and strategies. Its purpose is to help developers manage technical debt in a non-destructive manner by emitting standard `DeprecationWarning` or `PendingDeprecationWarning` messages to users of evolving APIs. It facilitates a smooth transition for consumers of libraries and applications when features are planned for removal or have moved.
Warnings
- gotcha By default, Python's `DeprecationWarning` and `PendingDeprecationWarning` are suppressed and not shown to end-users unless explicitly configured. This can lead to users being unaware of impending API removals until they encounter breaking changes.
- breaking Removing a previously deprecated API without adhering to a clear deprecation policy (e.g., a minimum number of minor releases after deprecation) can lead to unexpected breakage for users who haven't yet migrated, especially if they weren't seeing the warnings.
- gotcha The `new_location` argument for `debtcollector.moved` functions (like `moved_function` or `moved_class`) expects a string representing the *new* fully qualified import path. If the new location is incorrect or not importable, it will lead to import errors or runtime exceptions instead of graceful redirection.
Install
-
pip install debtcollector
Imports
- deprecate
from debtcollector import deprecate
- moved
from debtcollector import moved
- removals
from debtcollector import removals
Quickstart
import warnings
from debtcollector import deprecate, moved
# Ensure DeprecationWarnings are shown for this example
warnings.simplefilter('always', DeprecationWarning)
@deprecate(version='1.0', removal_version='2.0', message='Please use new_add_function instead.')
def old_add_function(a, b):
"""This function adds two numbers (deprecated)."""
print("Using old_add_function")
return a + b
def new_add_function(a, b):
"""This is the new function to add two numbers."""
print("Using new_add_function")
return a + b
print(f"Result from old function: {old_add_function(1, 2)}")
print(f"Result from new function: {new_add_function(1, 2)}")
# Example of marking a function as moved (conceptually)
# In a real scenario, `moved_function` would be used by a proxy module
# to redirect calls from an old path to a new path. For quickstart,
# we'll simulate the definition and a call.
# Imagine this was in `old_module.py`:
# def old_sub_function(a, b): return a - b
# Imagine this is in `new_module.py`:
# def current_sub_function(a, b): return a - b
# To simulate the 'moved' behavior (without actual module creation):
# You would typically define a proxy in the old location.
# For direct demonstration, we show how it would redirect:
class OldClass:
@moved(new_location='new_module.NewClass.new_method')
def old_method(self):
pass
# To see the warning for a moved class/function, one would typically import
# from the old path which `debtcollector.moved` has replaced.
# For a runnable example:
@deprecate(version='1.0', new_location='actual_new_func', message='Function renamed/moved.')
def legacy_func(x):
print(f"Legacy func called with {x}")
return x * 2
def actual_new_func(x):
print(f"Actual new func called with {x}")
return x * 2
print(f"Result from legacy func: {legacy_func(5)}")