{"id":5018,"library":"pydeprecate","title":"pyDeprecate: Deprecation Tooling","description":"pyDeprecate is a lightweight Python library (version 0.7.0) for managing function and class deprecations with zero dependencies. It provides automatic call forwarding to replacement functions, argument mapping between old and new APIs, and configurable warning controls to prevent log spam. It is actively maintained and designed to help library maintainers evolve APIs while maintaining backward compatibility.","status":"active","version":"0.7.0","language":"en","source_language":"en","source_url":"https://github.com/Borda/pyDeprecate","tags":["deprecation","api management","backward compatibility","warnings","refactoring","code quality"],"install":[{"cmd":"pip install pydeprecate","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"deprecated","correct":"from deprecate import deprecated"},{"symbol":"deprecated_class","correct":"from deprecate import deprecated_class"},{"symbol":"deprecated_instance","correct":"from deprecate import deprecated_instance"},{"note":"Helper function to silence IDE warnings about unused parameters in deprecated functions when a 'target' is specified.","symbol":"void","correct":"from deprecate import void"}],"quickstart":{"code":"import warnings\nfrom deprecate import deprecated, void\n\n# Suppress DeprecationWarning for cleaner output in example, will re-enable later\nwarnings.simplefilter('ignore', DeprecationWarning)\n\n# NEW/FUTURE API — renamed to be more explicit about what it computes\ndef compute_sum(a: int = 0, b: int = 3) -> int:\n    \"\"\"Computes the sum of two numbers.\"\"\"\n    return a + b\n\n# OLD API — 'addition' was the original name before the rename\n@deprecated(target=compute_sum, deprecated_in=\"1.0\", remove_in=\"2.0\", template_mgs=\"{name} is deprecated, use {target_path} instead.\")\ndef addition(a: int, b: int = 5) -> int:\n    \"\"\"Adds two numbers (deprecated).\"\"\"\n    # The body of 'addition' is never executed because 'target' is specified.\n    # The 'void' helper is used here to silence IDE warnings about 'a' and 'b' being unused.\n    return void(a, b)\n\n# Deprecating a function with no direct target (its own body runs)\n@deprecated(target=None, deprecated_in=\"0.5\", remove_in=\"0.8\", template_mgs=\"Method {name} is deprecated and will be removed.\")\ndef old_method(value: str) -> str:\n    \"\"\"An old method that will be removed.\"\"\"\n    return f\"Processing: {value}\"\n\n# Example usage:\nprint(\"--- Using deprecated function with target ---\")\nprint(f\"Result of addition(1, 2): {addition(1, 2)}\")\nprint(f\"Result of addition(10): {addition(10)}\")\n\nprint(\"\\n--- Using deprecated function with no target ---\")\nprint(f\"Result of old_method('test'): {old_method('test')}\")\n\n# To demonstrate the warning, re-enable DeprecationWarnings\nprint(\"\\n--- Enabling warnings to show deprecation output ---\")\nwarnings.simplefilter('default', DeprecationWarning)\nprint(f\"Result of addition(3, 4): {addition(3, 4)}\")\nprint(f\"Result of old_method('another test'): {old_method('another test')}\")","lang":"python","description":"This quickstart demonstrates how to use the `@deprecated` decorator with and without a `target` function. When a `target` is provided, calls are forwarded to the new function, and the `void` helper silences IDE warnings. When `target=None`, the deprecated function's own body is executed after a warning is issued. Warnings are initially suppressed for clean output but re-enabled to show the deprecation messages."},"warnings":[{"fix":"Ensure all necessary logic resides within the `target` function. If the deprecated function's body *must* be executed, set `target=None` to only issue a warning without forwarding.","message":"When using `@deprecated` with a `target` function, the body of the deprecated function is never executed; all calls are automatically forwarded to the target. Do not put critical logic inside a deprecated function if a target is specified.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Understand the behavior difference: `target=Callable` forwards calls and skips the deprecated body; `target=None` runs the deprecated body after warning. Choose based on whether the old implementation should still execute.","message":"Conversely, if `target=None` is explicitly set in `@deprecated`, the deprecated function's own body *will* be executed after the warning is issued. This behavior is distinct from when a callable target is provided.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For primitive constants that need deprecation warnings, either wrap them in a custom object/dictionary or manually update all call sites to use the new API directly.","message":"`deprecated_instance` cannot intercept primitive protocol methods (e.g., numeric arithmetic on `float`, concatenation on `str`). This means direct operations on wrapped primitive constants will not trigger deprecation warnings.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Explicitly set `docstring_style` in the `@deprecated` decorator (e.g., `docstring_style='mkdocs'`) or use `docstring_style='auto'` to let `pydeprecate` attempt to detect the style from existing docstring content.","message":"When using `update_docstring=True` with the `@deprecated` decorator, consider setting the `docstring_style` parameter (e.g., `'sphinx'`, `'mkdocs'`, or `'auto'`) to ensure the deprecation notice is injected and formatted correctly for your specific documentation generator.","severity":"gotcha","affected_versions":"0.7.0 and later"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}