{"id":3955,"library":"debtcollector","title":"Debtcollector","description":"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.","status":"active","version":"3.1.0","language":"en","source_language":"en","source_url":"https://opendev.org/openstack/debtcollector","tags":["deprecation","technical debt","api management","warnings","python"],"install":[{"cmd":"pip install debtcollector","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Used for packaging and project metadata.","package":"pbr","optional":false},{"reason":"Provides decorators for function and method wrapping, essential for deprecation functionality.","package":"wrapt","optional":false}],"imports":[{"note":"Main decorator for marking functions, methods, or classes as deprecated.","symbol":"deprecate","correct":"from debtcollector import deprecate"},{"note":"Decorator/function to indicate an object (like a function or class) has moved.","symbol":"moved","correct":"from debtcollector import moved"},{"note":"Utility for managing removal versions and messages.","symbol":"removals","correct":"from debtcollector import removals"}],"quickstart":{"code":"import warnings\nfrom debtcollector import deprecate, moved\n\n# Ensure DeprecationWarnings are shown for this example\nwarnings.simplefilter('always', DeprecationWarning)\n\n@deprecate(version='1.0', removal_version='2.0', message='Please use new_add_function instead.')\ndef old_add_function(a, b):\n    \"\"\"This function adds two numbers (deprecated).\"\"\"\n    print(\"Using old_add_function\")\n    return a + b\n\ndef new_add_function(a, b):\n    \"\"\"This is the new function to add two numbers.\"\"\"\n    print(\"Using new_add_function\")\n    return a + b\n\nprint(f\"Result from old function: {old_add_function(1, 2)}\")\nprint(f\"Result from new function: {new_add_function(1, 2)}\")\n\n# Example of marking a function as moved (conceptually)\n# In a real scenario, `moved_function` would be used by a proxy module\n# to redirect calls from an old path to a new path. For quickstart,\n# we'll simulate the definition and a call.\n\n# Imagine this was in `old_module.py`:\n# def old_sub_function(a, b): return a - b\n\n# Imagine this is in `new_module.py`:\n# def current_sub_function(a, b): return a - b\n\n# To simulate the 'moved' behavior (without actual module creation):\n# You would typically define a proxy in the old location.\n# For direct demonstration, we show how it would redirect:\n\nclass OldClass:\n    @moved(new_location='new_module.NewClass.new_method')\n    def old_method(self):\n        pass\n\n# To see the warning for a moved class/function, one would typically import\n# from the old path which `debtcollector.moved` has replaced.\n# For a runnable example:\n\n@deprecate(version='1.0', new_location='actual_new_func', message='Function renamed/moved.')\ndef legacy_func(x):\n    print(f\"Legacy func called with {x}\")\n    return x * 2\n\ndef actual_new_func(x):\n    print(f\"Actual new func called with {x}\")\n    return x * 2\n\nprint(f\"Result from legacy func: {legacy_func(5)}\")","lang":"python","description":"This quickstart demonstrates the core functionality of `debtcollector` by using the `@deprecate` decorator on a function. It configures Python's warnings to ensure `DeprecationWarning` messages are always visible, as they are often hidden by default. It also provides conceptual context for how the `moved` decorator or function would be applied."},"warnings":[{"fix":"Developers using `debtcollector` in their libraries should advise users to enable deprecation warnings in their testing or development environments (e.g., `python -Wd your_app.py` or `warnings.simplefilter('always', DeprecationWarning)`).","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Establish and communicate a clear deprecation policy (e.g., semantic versioning guidelines). Use `removal_version` in `@deprecate` to explicitly state when an API will be removed, giving users ample time to adapt across major versions.","message":"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.","severity":"breaking","affected_versions":"All versions (if used improperly)"},{"fix":"Always test the `new_location` thoroughly to ensure it correctly points to the new target. Ensure the new target is importable in all relevant environments.","message":"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.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}