Changelog🔗
[0.10.1] — 2026-07-03 — Cycle detection, strict property, & inner-order audit flag🔗
Added🔗
DeprecationWrapperInfo.inner_order_propertyflag.find_deprecation_wrappers()now setsinner_order_property=Truewhen a plainproperty(not_DeprecatedProperty) has a@deprecated-wrappedfget— the inner-order@property @deprecatedshape where only the getter warns; setters and deleters added via@value.setter/@value.deleterremain silently unprotected. CI pipelines can filter on this field to reject the pattern. (#201)- Opt-in strict
propertyreplacement.from deprecate import propertynow exports_StrictProperty, apropertysubclass that raisesTypeErrorat class-definition time when handed an already-@deprecatedgetter (inner-order detection). Import it in modules that want compile-time enforcement; star imports (from deprecate import *) are unaffected. (#201)
Fixed🔗
- Circular deprecation chains now raise
RuntimeErrorat call time. Callabletargetchains that form a cycle (A → B → A) previously caused unbounded recursion and aRecursionError. The decorator now detects the cycle via aContextVarre-entrancy guard and raises a clearRuntimeErrornaming the circular path. Async deprecation cycle detection was also improved to avoid false positives from concurrent tasks sharing a threading-local guard. (#200) _StrictPropertyTypeErrormessage now references the correct module path. The error previously pointed todeprecate._StrictProperty; corrected todeprecate.deprecation._StrictProperty, which is the actual import path. (#201)
[0.10.0] — 2026-06-21 — Property accessors, class attribute mapping & descriptor targets🔗
Added🔗
deprecated_class(attrs_mapping={...})for selective attribute deprecation. Deprecated attribute names emitFutureWarningon read, write, and delete with per-attribute warning budgets.Noneas the redirect value means warn-only (no rename).TargetMode.ATTRS_REMAPis the corresponding mode — can be combined with a callabletargetto redirect attribute access across class boundaries. Multi-hop chains and fan-in renames allowed; cycles raiseValueErrorat decoration time. (#191)target=now accepts rawstaticmethod/classmethoddescriptors directly. Inside a class body the new method is still a raw descriptor (not yet bound); passing it astarget=new_methodno longer requires the explicit.__func__suffix._normalize_targetunwraps the descriptor automatically. Forclassmethoddescriptors the symmetric same-class pattern is supported (both deprecated and replacement are classmethods); asymmetric usage raisesTypeErrorat decoration time. (#192)deprecated_classstacking is now supported. Two@deprecated_classdecorators applied to the same class (each with its ownattrs_mappingand version pair) now work correctly:isinstance()resolves through the proxy chain, instantiation emits at most one warning instead of two, and the type annotation accepts_DeprecatedProxywithout acast. Stacking ATTRS_REMAP outer + ARGS_REMAP inner is also supported: the inner proxy no longer emits a spurious global warning on attribute access —TargetMode.ARGS_REMAPnow correctly restricts its warnings to call-time argument remapping only. No-target two-layer stacking (both layers deprecating the class in-place without forwarding to a different type) is also supported: the outerATTRS_REMAPproxy delegates__call__to the innerARGS_REMAPproxy without firing a second global warning. (#193)- Dataclass
attrs_mappingauto-expand. When the wrapped class is a@dataclass, a singledeprecated_class(attrs_mapping={"old_field": "new_field"})call automatically generates the correspondingargs_mappingentry so both attribute access (obj.old_field) and constructor kwargs (DC(old_field=5)) emitFutureWarningfrom one decorator. Explicitly-providedargs_mappingkeys always win over auto-expanded entries. For non-dataclass targets,attrs_mappingcovers attribute access only. (#193) validate_mapping_compatibility()audit function. Returnslist[DeprecationWrapperInfo]for alldeprecated_classproxies whoseargs_mappingremaps deprecated names toPOSITIONAL_ONLYconstructor parameters — those proxies fall back tosetattrat call time instead of forwarding via kwargs. Use in CI to detect configurations that silently degrade to attribute assignment. (#193)@deprecated @propertynow wrapsfsetandfdelwithFutureWarning. Applying@deprecatedon the outside of@property(outer order, or explicitdeprecated(...)(property(fget, fset, fdel))) now wraps all three accessors. Previously, onlyfgetemitted a warning;fsetandfdelwere silently passed through. Consumers runningfilterwarnings=error::FutureWarningthat wrote to or deleted a deprecated property will now seeFutureWarningerrors — use inner-order (@property @deprecated) or decorate onlyfgetdirectly if you want a silent setter/deleter. Chain-style rebinding via@value.setter/@value.deleteris fully supported through the new_DeprecatedPropertysubclass. (#190)
Fixed🔗
@deprecatednow correctly forwards calls to targets with POSITIONAL_ONLY parameters. When a callabletargetdeclares any parameter as positional-only (def new_fn(x, /): ...), the decorator previously raisedTypeErrorat call time because all arguments were forwarded as kwargs. The decorator now detects POSITIONAL_ONLY params at decoration time, emits aUserWarningnaming the affected parameters, and splits the call-time dispatch so those values are forwarded positionally.args_mappingremaps applied before the split — remapped names that land on a POSITIONAL_ONLY target param are handled correctly. The thin-adapter pattern (def new_fn_compat(x): return new_fn(x)astarget) remains valid and suppresses theUserWarning. (#194)args_mappingprecedence: explicit new-name always wins when both old and new kwargs passed. When a caller passed both the deprecated old argument name and the new name simultaneously (e.g.fn(val=5, new_val=6)), the remapped old-name value previously overwrote the explicit new-name value due to dict-comprehension last-write-wins ordering. The explicit new-name value now always wins, regardless of argument order at the call site. Affects@deprecatedwithtarget=TargetMode.ARGS_REMAPor a callable target, anddeprecated_class()withargs_mapping. (#198)
[0.9.0] — 2026-06-05 — Generators, async, & markdown audit tables🔗
Added🔗
- Generator function support for
@deprecated. Decorating a generator function now emits the deprecation warning eagerly at call time — before the firstnext()— consistent with regular function behavior. The generator body executes lazily as normal when iterated. All threeTargetModevariants (NOTIFY,ARGS_REMAP, callable target) work transparently; noisgeneratorfunctioncheck is required. (#176) async defcoroutine wrapper support for@deprecated. Decorating anasync deffunction now produces anasync defwrapper —inspect.iscoroutinefunction(wrapper)returnsTrue. All threeTargetModevariants (NOTIFY,ARGS_REMAP, callable target) work with async sources and async targets. The deprecation warning fires when the coroutine is awaited, not when the wrapper is called.pytest-asynciois required in the test suite to run the async integration tests. (#180)- Async generator function support for
@deprecated. Decorating anasync def+yieldfunction no longer emits aUserWarningat decoration time. The wrapper is a sync callable that fires the deprecation warning eagerly at call time and returns the async generator object; callers iterate withasync for. All threeTargetModevariants work. Because the wrapper is sync,inspect.isasyncgenfunction(wrapper)returnsFalse— frameworks that branch on that flag may need a thin async generator passthrough. (#181) - Order-agnostic
@classmethod/@staticmethod. Both@classmethod @deprecatedand@deprecated @classmethod(and the equivalent for@staticmethod) now produceclassmethod(deprecated_wrapper)— the descriptor is unwrapped at decoration time, the inner function is deprecated, and the result is re-wrapped.FutureWarningfires at call time in either order; noUserWarningis emitted. (#178) - Stacked
@deprecated—ARGS_REMAP + NOTIFYcombination. Lifecycle pattern: rename arguments first, deprecate the whole function later. The outerARGS_REMAPremaps kwargs, then the innerNOTIFYwarns and runs the source body. Six other stacking shapes (e.g. callable-over-callable, callable-over-ARGS_REMAP) now emitUserWarningat decoration time naming the specific shape and will becomeTypeErrorin v1.0. (#172) - Markdown deprecation tables —
generate_deprecation_table()+pydeprecate statusCLI subcommand. Renders compact or matrix-style Markdown reports grouped by module and API-type (function, method, classmethod, staticmethod, property, class, instance). Two new public enums:DeprecationStatus(lifecycle classification — active, expired, plus dev/alpha/beta/rc removal windows) andTableStyle(compact/matrix). New--styleand--outputCLI flags. Integrated intopydeprecate all. Auto-detects package version frompyproject.tomlor installed metadata. (#133) ChainTypeenum now exported as public API. Previously documented and returned byvalidate_deprecation_chains(); now listed indeprecate.__all__.- Audit discovery extended to class descriptors.
find_deprecation_wrappers()now inspectsclassmethodandstaticmethoddescriptors on class members so@deprecated-wrapped descriptors are found during scans. (#178)
Changed🔗
- CLI: renamed
--skip_errorsto--exit-zeroacross all four subcommands (check,expiry,chains,all). (#187) Breaking change for existing scripts —--skip_errorsno longer accepted; update calls to--exit-zero. The new name matches the established linter convention (ruff, pylint, shellcheck) and accurately describes the behaviour: exit-code override only, no exception suppression. The canonical spelling is--exit-zero(dash); the CLI framework also accepts--exit_zero(underscore) as an alias. - Misconfigured stacking combinations warn at decoration time. Six previously-undefined
@deprecatedstacking shapes (e.g. callable-over-callable, callable-over-ARGS_REMAP) now emitUserWarningat decoration time naming the specific shape. Scheduled to becomeTypeErrorin v1.0. The new module-level_V1_BREAK_VERSION = "v1.0"constant centralises the "Will be TypeError in v1.0" wording across these warnings. (#172) - Audit chain classification —
ARGS_REMAP + NOTIFYis now classified asSTACKEDrather thanTARGET. Fixes audit reports for the supported new stacking shape. (#172) - CLI warning suppression narrowed to
deprecate.*warnings only. Third-party warnings emitted during a scan are no longer silenced. (#133) generate_deprecation_table()gainsinclude_membersparameter for scanning descriptor members;validate_deprecation_expiry()default unchanged atinclude_members=Falseto preserve existing scan scope. (#133)
Fixed🔗
stacklevelattribution on Python 3.12+.inspect.signature(warnings.warn)raisesValueErroron Python 3.12+ because the C builtin lacks an introspectable signature. This caused every@deprecatedwarning to point todeprecation.pyinstead of the caller's file. Fixed by replacing theinspect.signatureprobe with a try/except at call site:stream(msg, stacklevel=N)is tried first; ifTypeErroris raised (stream does not acceptstacklevel), retried asstream(msg). (#176)find_deprecation_wrappers()no longer aborts on PEP 702typing_extensions.deprecatedobjects. The scanner previously checkedcallable(obj) and hasattr(obj, "__deprecated__"), which matched PEP 702 wrappers (whose__deprecated__is a string), causingvalidate_deprecation_wrapperto raiseValueErrorand abort the scan. Replaced with_has_deprecation_meta(obj), which checksisinstance(..., DeprecationConfig). (#178)- Short-circuit forwarding for
*argssources now preserves extra positional arguments. Previously, when forwarding from a*argssource, extra positional arguments past the named parameters were silently dropped. (#180)
[0.8.0] — 2026-05-21 — Default TargetMode enum & CLI audit tools🔗
Added🔗
TargetModeenum exported fromdeprecate.TargetMode.NOTIFYreplacestarget=NoneandTargetMode.ARGS_REMAPreplacestarget=True. Both are public API. (#150)args_extraparameter fordeprecated_class()anddeprecated_instance(). Injects fixed keyword arguments into forwarded calls afterargs_mappinghas been applied, matching the same semantics as@deprecated(args_extra=...). Ignored (with a construction-timeUserWarning) whentargetisTargetMode.NOTIFY. (#150)template_mgsparameter fordeprecated_class()anddeprecated_instance(). Overrides the built-in warning message template with a%-style format string, matching the same semantics as@deprecated(template_mgs=...). Available placeholders:%(source_name)s,%(deprecated_in)s,%(remove_in)s,%(target_name)s(callable target only),%(target_path)s(callable target only),%(argument_map)s(args_mappingwarnings only). (#150)DeprecationConfig.misconfiguredfield. Boolean field on the shared metadata dataclass;Truewhen an invalid raw target sentinel (False) was passed at decoration time. Audit tools surface this viaDeprecationWrapperInfo.misconfigured_target. (#150)- Multi-page topic documentation site. Replaced the monolithic README-copy home page with a curated 7-page MkDocs Material site: Home, Getting Started, User Guide (Use Cases / void() Helper / Audit Tools), Troubleshooting, and demo links. Switched theme to Material, added Open Graph tags, JSON-LD structured data (SoftwareApplication / FAQPage / TechArticle per page), spec-compliant
llms.txt, andgit-revision-date-localizedplugin. README is unchanged (still the PyPI cover page). (#146) pydeprecateCLI command. Runpydeprecate <subcommand> path/to/your/packageto scan any package or module for misconfigured@deprecatedwrappers — reports invalid argument mappings, identity mappings, and no-effect wrappers with rich-formatted output whenrichis available. Also available aspython -m deprecate. (#76)- Four CLI subcommands:
check,expiry,chains,all.checkvalidates wrapper configuration;expiryreports wrappers past theirremove_indeadline (requirespip install 'pyDeprecate[audit]');chainsdetects deprecated-to-deprecated forwarding chains;allruns all three in a single scan pass. Flags:--norecursive,--skip_errors. (#149) - New
DeprecationWrapperInfo.empty_deprecated_infield.Truewhendeprecated_inis absent on a wrapper; intended for CI pipeline introspection.dataclasses.asdict()output andrepr()now include this field. (#166) template_mgsvalidated at decoration time. Malformed%-style format strings now raiseValueErrorimmediately at decoration time — not silently at call time. Applies to@deprecatedand thedeprecated_class()/deprecated_instance()proxy factories. (#169)- Stacked-callable-target guard. Applying
@deprecated(target=fn_a)on a callable whose target is itself a callable-target@deprecatedwrapper now emitsUserWarningat decoration time instead of crashing withTypeErrorat call time. (#169)
Deprecated🔗
target=Nonesentinel — useTargetMode.NOTIFY. Passingtarget=Nonenow emits aFutureWarningat decoration time. The sentinel remains accepted but will be removed in v1.0. Migrate totarget=TargetMode.NOTIFY. (#150)target=Truesentinel — useTargetMode.ARGS_REMAP. Passingtarget=Truenow emits aFutureWarningat decoration time. The sentinel remains accepted but will be removed in v1.0. Migrate totarget=TargetMode.ARGS_REMAP. (#150)DeprecationWrapperInfoattributesempty_mapping→empty_args_mappingandidentity_mapping→identity_args_mapping. Old names are kept as deprecated@propertyaliases that emitDeprecationWarningon access and will be removed in v1.0. (#166)
Changed🔗
- Misconfigured
TargetModecombinations now warn at construction time.TargetMode.ARGS_REMAPwithoutargs_mapping,TargetMode.NOTIFYwithargs_mapping, andTargetMode.NOTIFYwithargs_extraall surface aUserWarningimmediately. (#150) DeprecationConfig.targetalways stores a normalisedTargetModeor callable. Legacy boolean sentinels (True/False) are now normalised at decoration time and are never stored verbatim inDeprecationConfig.target. Code that inspects__deprecated__.targetmust compare againstTargetMode.NOTIFY,TargetMode.ARGS_REMAP, a callable, orNone— never againstTrueorFalse. (#150)deprecated_class()withtarget=TargetMode.NOTIFYnow emitsUserWarningat decoration time whenargs_mappingorargs_extrais supplied. These parameters are ignored inNOTIFYmode; passing them has always been a misconfiguration. The warning will becomeTypeErrorin v1.0. (#150)- Docs site URL layout is now versioned. Content is published under
https://borda.github.io/pyDeprecate/stable/(for the stable alias) andhttps://borda.github.io/pyDeprecate/<tag>/(for release tags). The root URL (https://borda.github.io/pyDeprecate/) redirects tostable/. External bookmarks to flat paths like.../pyDeprecate/troubleshooting.htmlwill break on first deploy — update them to.../pyDeprecate/stable/troubleshooting.html. (#148) targetparameter of@deprecatednow defaults toTargetMode.NOTIFY. Callers can omittargetentirely for warn-only deprecation:@deprecated(deprecated_in="1.0", remove_in="2.0")is now the canonical form. Passingtarget=TargetMode.NOTIFYexplicitly remains valid. This default is permanent and will not change in future releases. (#162)- Decoration-time
UserWarningwhen@deprecatedomitsdeprecated_in. Whendeprecated_inis absent aUserWarningis emitted immediately at decoration time (not at call time) regardless oftargetshape (TargetMode.NOTIFY, callable, orARGS_REMAP), even ifremove_inis set. Applies to functions and methods (not classes). Suppressed whenstream=Noneor when a customtemplate_mgsis provided. (#162) - CLI chains reporting split.
checksubcommand reports deprecated-to-deprecated chains as warnings (exit 0);chainsandallsubcommands report chains as errors (exit 1). (#149)
Fixed🔗
- PEP 702 compatibility crash fixed. When
@deprecatedwas stacked under a PEP 702@typing.deprecateddecorator,wrapped_fnattempted to look up__deprecated__on the outer wrapper and raisedAttributeError. Fixed by capturingdep_metaas a closure variable at decoration time instead of re-reading it from the wrapper. (#169) - Double
FutureWarningemission ondeprecated_class()in NOTIFY mode fixed. Usingdeprecated_class()withtarget=TargetMode.NOTIFYtriggered twoFutureWarningemissions per construction call. (#162) - Cross-class guard false positives resolved;
TypeErrorsemantics preserved. Two previously documented "irresolvable" false-positive scenarios are now handled: (1) targets with metaclass/dynamic-class qualnames (e.g.type("Name", bases, ns)or manualfn.__qualname__ = "FakeOwner.method") — guard now skips silently when the named class is absent from the target's module globals; (2) pre-applied decorators that rewrite the source's__qualname__— guard reads the true enclosing class from the Python class-body frame, which cannot be mutated by user decorators. The guard continues to raiseTypeErrorat decoration time for genuine cross-class forwarding. (#169) args_mappingrename no longer clobbers source default when both old and new parameter names are present. Previously, calling a deprecated wrapper with the old argument name while the source also accepted the new name could silently overwrite the new-name value. The remapping now correctly renamesold=Xtonew=Xwithout discarding a separately suppliednewvalue. (#150)target=Falsesentinel now emitsUserWarningat decoration time.target=Falsewas never a valid configuration; previously the behavior was undefined. The sentinel now surfaces aUserWarningimmediately and will raiseTypeErrorin v1.0. (#150)
[0.7.0] — 2026-03-31 — Docstring Tooling🔗
Added🔗
- MkDocs admonition output.
@deprecatednow acceptsdocstring_style="mkdocs"(alias:"markdown"). Whenupdate_docstring=True, the deprecation notice is injected as a!!! warning "Deprecated in X"admonition instead of a Sphinx.. deprecated::directive. Usedocstring_style="auto"to detect style automatically from existing docstring content. (#134) - Google / NumPy section-aware docstring injection.
update_docstring=Truenow inserts the deprecation notice before the first section (Args:,Returns:,Parameters, …) rather than appending it at the end. (#134) - Inline arg deprecation in docstrings. When
args_mappingis set andupdate_docstring=True, each renamed or removed argument is annotated directly in theArgs:/:paramsection of the docstring. (#136) - Griffe extension for mkdocstrings (
deprecate.docstring.griffe_ext, beta) and Sphinx autodoc extension for deprecated classes (deprecate.docstring.sphinx_ext, beta). (#134) - Live demo documentation published to GitHub Pages — MkDocs demo, Sphinx demo, and portal landing page. (#134, #137)
Fixed🔗
- Fixed
getattr/setattrstring-literal calls (B009/B010) replaced with direct attribute access. (#139) - Fixed proxy swap skipped correctly when
super().import_object()returnsFalsein the Griffe extension; empty_proxy_docnow delegates tosuper().get_doc()in the Sphinx extension. (#139)
[0.6.0.post0] — 2026-03-14 — Deprecation Proxy for class/instances🔗
Changed🔗
- Softer class-deprecation fallback.
@deprecatedapplied directly to a class (Enum, dataclass, or plain class) now emits aUserWarningat decoration time and delegates todeprecated_class()internally, instead of raisingTypeError. Code using the old pattern continues to work; the warning points to the recommended API. (#132)
[0.6.0] — 2026-03-13🔗
Added🔗
deprecated_class()anddeprecated_instance()— full proxy support. Enum, dataclass, and built-in types can now be wrapped in a transparent proxy. Attribute access, item access, method calls, and class behaviour all forward to the underlying type with aFutureWarningemitted on first access. (#114)- Correct
isinstance()/issubclass()semantics on proxy classes.isinstance(x, proxy)andissubclass(Sub, proxy)now work as expected — previously raisedTypeError. Type checks do not consume the warning budget. (#126)
Changed🔗
@deprecatedon a class raisesTypeError. Applying@deprecateddirectly to a class now raisesTypeErrorat decoration time instead of silently misbehaving. Superseded inv0.6.0.post0by aUserWarning+ delegation todeprecated_class(). Use@deprecated_class()for class-level deprecation. (#120)
Deprecated🔗
- Audit API renamed for consistency. Old names remain as
@deprecatedshims until v1.0. (#125)
| Old name | New name |
|---|---|
find_deprecated_callables |
find_deprecation_wrappers |
validate_deprecated_callable |
validate_deprecation_wrapper |
DeprecatedCallableInfo |
DeprecationWrapperInfo |
no_warning_callrenamed toassert_no_warnings. The new name mirrorsassertWarns/assertRaisesfrom the standard library, making test intent immediately obvious. Old name kept as a deprecated alias until v1.0. (#131)
Fixed🔗
- Cross-class method forwarding now fails at decoration time. Passing a class as
targeton a non-__init__method previously silently forwardedselfof the wrong type — always a runtime bug, never a valid pattern. The guard now raisesTypeErrorat decoration time so the misconfiguration is caught immediately. (#121) find_deprecation_wrappers()no longer reports falseinvalid_argsfor proxy objects. The proxy__call__catch-all signature previously caused allargs_mappingkeys to be flagged as invalid; signature validation is now skipped for proxy objects. (#124)
[0.5.0] — 2026-02-23 — Deprecation Lifecycle Management🔗
Added🔗
deprecate.auditmodule — deprecation lifecycle management. A dedicated module grouping all inspection and enforcement utilities, designed to be called from pytest or CI scripts. Requires the optional[audit]extra:pip install pyDeprecate[audit]. (#111)find_deprecated_callables()/validate_deprecated_callable()— zero-impact wrapper detection. Scans a module or package for@deprecatedwrappers that have no real effect: invalidargs_mappingkeys, identity mappings, self-referencing targets, or missing version fields. ReturnsDeprecatedCallableInfodataclasses. (#72)validate_deprecation_expiry()— enforce removal deadlines in CI. Scans a module or package and returns all wrappers whoseremove_inversion has been reached or passed. Auto-detects the installed package version. Integrate as a pytest fixture or CI step to prevent zombie code from shipping past its scheduled removal. (#89)validate_deprecation_chains()— detect deprecated-to-deprecated forwarding. Identifies wrappers whosetargetis itself a deprecated callable, forming chains that users traverse unnecessarily. Reports two chain kinds via theChainTypeenum:TARGET(forwarding chain) andSTACKED(composed argument mappings). (#90)
Fixed🔗
@deprecatedwrappers now correctly handle var-positional Enum signatures. A subtle edge case where callables with var-positional parameters in their Enum signature caused incorrect argument forwarding is now resolved. (#104)
[0.4.0] — 2025-12-03 — Enhanced Documentation & Modernization🔗
Added🔗
update_docstringparameter — automatic Sphinx deprecation notices. Setupdate_docstring=Trueon@deprecatedto automatically append a.. deprecated::reStructuredText block to the function's docstring. IDE tooltips and Sphinx-generated API docs show the notice without any manual edits. (#31)
Changed🔗
- Deprecation warnings now use
FutureWarninginstead ofDeprecationWarning.DeprecationWarningis silenced by Python's default warning filters outside of test contexts, making it invisible to most end-users.FutureWarningis shown by default, ensuring callers actually see the migration message. (#16) - Minimum Python version raised to 3.9. Python 3.8 reached end-of-life in October 2024. (#73)
- License changed from MIT to Apache-2.0.
- Error messages now include the originating class or function name for easier debugging when a mapping fails. (#11)
[0.3.2] — 2021-06-11 — Support containing kwargs in target function🔗
Added🔗
targetfunctions using**kwargsare now supported. Previously, forwarding to a target that accepted**kwargsand accessed them viakwargs.get(...)raisedTypeErrorfor unrecognised argument names. Extra arguments from the deprecated call are now forwarded correctly. (#6)
[0.3.1] — 2021-05-31 — Fixed void typing🔗
Fixed🔗
void()type annotation corrected to satisfy mypy. The return type ofvoid()is now properly annotated — IDE and type checker warnings about unused parameters in deprecated function bodies are suppressed correctly.
[0.3.0] — 2021-04-21 — Conditional skip🔗
Added🔗
skip_ifparameter — conditional deprecation. Pass aboolor a zero-argument callable returningboolto skip the warning and forwarding when a runtime condition is true. Useful for gating deprecation behaviour on package version checks or feature flags. (#4)
[0.2.0] — 2021-03-29 — Improved self arg deprecations🔗
Added🔗
target=True— self-deprecation mode. Deprecate and remap arguments within the same function without forwarding to a separate callable. Use withargs_mappingto rename a parameter while keeping the function body intact. (#3)void()helper. Accepts any arguments and returnsNone. Silences IDE "unused parameter" warnings in deprecated function bodies where the body is never reached.no_warning_call()context manager. Assert that a block of code raises no deprecation warning — useful for verifying that new API paths are clean in tests. Renamed toassert_no_warnings()in v0.6.0. (#2)- Stacked
@deprecateddecorators. Multiple@deprecated(True, ...)decorators can be stacked on the same function for multi-hop argument migrations across versions, each with independent warning counts and version metadata.
[0.1.1] — 2021-03-21 — Allow infinite warning🔗
Added🔗
num_warns=-1— always-on warnings. Settingnum_warnsto-1causes the deprecation warning to fire on every call rather than stopping after N times.target=None— warn-only mode. The original function body still executes;@deprecatedadds only a warning with no call forwarding. Useful when you want to signal deprecation without changing any call behaviour.
[0.1.0] — 2021-03-20 — Initial release🔗
Added🔗
@deprecated(target=callable)decorator. Marks a function as deprecated and automatically forwards all calls — including argument mapping — to a replacement function. The deprecated function body is never executed whentargetis a callable.- Automatic argument mapping. Positional arguments are resolved to keyword arguments and forwarded to the target's signature.
args_mappingrenames ({"old": "new"}) or drops ({"old": None}) individual arguments during forwarding. args_extra— inject additional kwargs into the target call. Pass adictof extra keyword arguments to merge into every forwarded call. Useful for providing default values or adapter arguments that the deprecated API never accepted.- Configurable warning count (
num_warns). Warnings fire once per function by default; set to any positive integer to limit the total count per function lifetime. - Custom warning message template (
template_mgs). Format string with%(source_name)s,%(target_path)s,%(deprecated_in)s,%(remove_in)s, and%(argument_map)splaceholders. - Custom warning stream (
stream). Route warnings tologging.warning,warnings.warn, or any callable.