Migration Guide🔗
The current development target is v0.12. This guide contains only rewrites, deprecations, and observable changes that existing users need to handle when upgrading. New APIs and capabilities belong in the Changelog and topic guides.
Migrate Legacy Target Values🔗
v0.8 introduced TargetMode so deprecation intent no longer depends on the legacy None, True, and False sentinels. These examples show the current form and the caller behavior to preserve during migration.
target=None → TargetMode.NOTIFY🔗
target=None means "warn, then run the decorated body". It still works, but emits FutureWarning at decoration time. Omit target for the shortest current form; the TargetMode.AUTO default resolves to TargetMode.NOTIFY when no mapping is present. Use target=TargetMode.NOTIFY when being explicit helps the reader.
- # DEPRECATED API — legacy sentinel
- @deprecated(target=None, deprecated_in="1.0", remove_in="2.0")
+ # DEPRECATED API — current warn-only form
+ @deprecated(deprecated_in="1.0", remove_in="2.0")
from deprecate import deprecated
@deprecated(deprecated_in="1.0", remove_in="2.0")
def refresh_cache(cache_key: str) -> str:
"""Refresh one cached value."""
return f"refreshed:{cache_key}"
print(refresh_cache("products"))
The notice respects num_warns (once by default); the function body still executes normally.
target=True → TargetMode.ARGS_REMAP🔗
target=True remaps deprecated keyword names within the same function. Replace it with TargetMode.ARGS_REMAP; existing callers can keep the old keyword during the migration window while new callers use the replacement.
from deprecate import TargetMode, deprecated
@deprecated(
target=TargetMode.ARGS_REMAP,
args_mapping={"ttl": "cache_ttl"},
deprecated_in="1.0",
remove_in="2.0",
)
def configure_cache(cache_ttl: int = 60) -> int:
"""Return the configured cache lifetime."""
return cache_ttl
# DEPRECATED API — old callers are remapped and warned.
print(configure_cache(ttl=30))
# NEW API — callers use the replacement keyword directly.
print(configure_cache(cache_ttl=45))
target=False → TargetMode.NOTIFY or a callable target🔗
target=False was never a valid target. On a callable it now emits UserWarning at decoration time and behaves like warn-only mode. Proxy factories treat it like an omitted target while marking the configuration as misconfigured, so a supplied mapping may still be inferred; do not rely on either compatibility path. Choose the behavior you actually need:
- # DEPRECATED API — invalid legacy sentinel
- @deprecated(target=False, deprecated_in="1.0", remove_in="2.0")
+ # DEPRECATED API — keep running this body after warning
+ @deprecated(target=TargetMode.NOTIFY, deprecated_in="1.0", remove_in="2.0")
from deprecate import TargetMode, deprecated
@deprecated(
target=TargetMode.NOTIFY,
deprecated_in="1.0",
remove_in="2.0",
)
def legacy_checksum(payload: str) -> int:
"""Compute the retained legacy checksum."""
return len(payload)
print(legacy_checksum("abc"))
If the old API should forward to a replacement, pass that callable instead. The deprecated body is then not executed:
from deprecate import deprecated
def checksum_v2(payload: bytes) -> int:
"""Compute the replacement checksum."""
return sum(payload)
@deprecated(
target=checksum_v2,
args_mapping={"text": "payload"},
deprecated_in="1.0",
remove_in="2.0",
)
def checksum(text: bytes) -> int:
"""Retain the deprecated signature during migration."""
...
# DEPRECATED API — forwards to checksum_v2 and warns.
print(checksum(text=b"abc"))
# NEW API — callers move directly to the replacement.
print(checksum_v2(payload=b"abc"))
The same rule applies to deprecated_class() and deprecated_instance(): target=False is not a valid mode.
Misconfigured TargetMode combinations🔗
Contradictory combinations emit UserWarning at decoration time. The warning is a migration task: the ignored configuration is scheduled to become an error in v1.0.
| Combination | Migration |
|---|---|
TargetMode.ARGS_REMAP without args_mapping |
Add a real mapping, or use TargetMode.NOTIFY for warn-only behavior. |
Explicit TargetMode.NOTIFY with args_mapping |
Omit target so AUTO infers ARGS_REMAP, select ARGS_REMAP explicitly, or remove the mapping. |
Explicit TargetMode.NOTIFY with args_extra |
Use a callable target if extra kwargs must reach a replacement, or remove args_extra. |
deprecated_class(target=TargetMode.NOTIFY, attrs_mapping=...) |
Omit target so the proxy infers ATTRS_REMAP, select ATTRS_REMAP explicitly, or remove the mapping. |
deprecated_class(target=TargetMode.ATTRS_REMAP) without a mapping |
Add attrs_mapping={"old": "new"}, or use NOTIFY for class-wide warnings. |
@deprecated(target=TargetMode.ATTRS_REMAP) |
Use deprecated_class(attrs_mapping=...); the common front door does not expose class-only attrs_mapping. |
An explicitly supplied NOTIFY is never rewritten: its mapping stays inert. Inference happens only when target is omitted.
DeprecationWrapperInfo field renames🔗
Two audit fields were renamed in v0.8. The old properties still work but emit DeprecationWarning and will be removed in v1.0:
- # DEPRECATED API — compatibility properties
- info.empty_mapping
- info.identity_mapping
- dataclasses.replace(info, empty_mapping=True)
+ # NEW API — stored field names
+ info.empty_args_mapping
+ info.identity_args_mapping
+ dataclasses.replace(info, empty_args_mapping=True)
The replacement fields are regular dataclass fields, so introspection and dataclasses.replace() use them directly:
from dataclasses import replace
from deprecate.audit import DeprecationWrapperInfo
info = DeprecationWrapperInfo(
empty_args_mapping=True,
identity_args_mapping=["timeout"],
)
updated = replace(info, empty_args_mapping=False)
print(info.empty_args_mapping)
print(info.identity_args_mapping)
print(updated.empty_args_mapping)
Pick Your Upgrade Path🔗
Find the section matching the version you are upgrading from. Each section aggregates every later migration-relevant compatibility change into two tabs:
- Apply every item under Breaking changes.
- Review changed warnings, errors, audit scope, and proxy behavior under Behavior changes.
- Run your suite with
FutureWarningpromoted to an error, then run your pyDeprecate audit/expiry CI checks.
This guide works at minor-line granularity. v0.N.x means the latest available bugfix release in that feature line. The paths assume your dependency constraint allows bugfix updates and that you update within v0.N.x before crossing to the next feature line. Patch and post releases are folded into their minor interval rather than receiving separate sections.
Releases with no migration work are skipped. Where a later release superseded an intermediate behavior, the section describes the final v0.12.x development behavior.
Coming from v0.11.x🔗
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...).- Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default.- Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.10.x🔗
- Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source.- In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.9.x🔗
-
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
- When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.8.x🔗
- Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
- CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.7.x🔗
- Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
- Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.6.x🔗
- Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
- Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.5.x🔗
-
Fix cross-class method forwarding. Passing a class target to a non-
__init__instance method now raisesTypeErrorat decoration time instead of forwarding aselfof the wrong type. -
Replace API names deprecated until v1.0:
Deprecated API Replacement find_deprecated_callablesfind_deprecation_wrappersvalidate_deprecated_callablevalidate_deprecation_wrapperDeprecatedCallableInfoDeprecationWrapperInfono_warning_callassert_no_warnings -
Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
-
Across the v0.6.x line, backward support for
@deprecatedon a class was restored through delegation todeprecated_class(). Existing class decorators need no rewrite for v0.12; delegation remains permanent and only its informational notice is scheduled for removal. -
Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.4.x🔗
-
Fix cross-class method forwarding. Passing a class target to a non-
__init__instance method now raisesTypeErrorat decoration time instead of forwarding aselfof the wrong type. -
Replace API names deprecated until v1.0:
Deprecated API Replacement find_deprecated_callablesfind_deprecation_wrappersvalidate_deprecated_callablevalidate_deprecation_wrapperDeprecatedCallableInfoDeprecationWrapperInfono_warning_callassert_no_warnings -
Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
-
Across the v0.6.x line, backward support for
@deprecatedon a class was restored through delegation todeprecated_class(). Existing class decorators need no rewrite for v0.12; delegation remains permanent and only its informational notice is scheduled for removal. -
Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.3.x🔗
- Update warning filters and assertions from
DeprecationWarningtoFutureWarning. Application users now see the warnings under Python's default filters. - Run on Python 3.9 or newer. Python 3.8 support was removed.
-
Review the license change from MIT to Apache-2.0 if your distribution or compliance process records dependency licenses.
-
Fix cross-class method forwarding. Passing a class target to a non-
__init__instance method now raisesTypeErrorat decoration time instead of forwarding aselfof the wrong type. -
Replace API names deprecated until v1.0:
Deprecated API Replacement find_deprecated_callablesfind_deprecation_wrappersvalidate_deprecated_callablevalidate_deprecation_wrapperDeprecatedCallableInfoDeprecationWrapperInfono_warning_callassert_no_warnings -
Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
-
Mapping errors now include the originating class or function name. Tests that assert complete error strings may need updated expected text.
-
Across the v0.6.x line, backward support for
@deprecatedon a class was restored through delegation todeprecated_class(). Existing class decorators need no rewrite for v0.12; delegation remains permanent and only its informational notice is scheduled for removal. -
Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.2.x🔗
- Update warning filters and assertions from
DeprecationWarningtoFutureWarning. Application users now see the warnings under Python's default filters. - Run on Python 3.9 or newer. Python 3.8 support was removed.
-
Review the license change from MIT to Apache-2.0 if your distribution or compliance process records dependency licenses.
-
Fix cross-class method forwarding. Passing a class target to a non-
__init__instance method now raisesTypeErrorat decoration time instead of forwarding aselfof the wrong type. -
Replace API names deprecated until v1.0:
Deprecated API Replacement find_deprecated_callablesfind_deprecation_wrappersvalidate_deprecated_callablevalidate_deprecation_wrapperDeprecatedCallableInfoDeprecationWrapperInfono_warning_callassert_no_warnings -
Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
-
Mapping errors now include the originating class or function name. Tests that assert complete error strings may need updated expected text.
-
Across the v0.6.x line, backward support for
@deprecatedon a class was restored through delegation todeprecated_class(). Existing class decorators need no rewrite for v0.12; delegation remains permanent and only its informational notice is scheduled for removal. -
Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
Coming from v0.1.x🔗
- Update warning filters and assertions from
DeprecationWarningtoFutureWarning. Application users now see the warnings under Python's default filters. - Run on Python 3.9 or newer. Python 3.8 support was removed.
-
Review the license change from MIT to Apache-2.0 if your distribution or compliance process records dependency licenses.
-
Fix cross-class method forwarding. Passing a class target to a non-
__init__instance method now raisesTypeErrorat decoration time instead of forwarding aselfof the wrong type. -
Replace API names deprecated until v1.0:
Deprecated API Replacement find_deprecated_callablesfind_deprecation_wrappersvalidate_deprecated_callablevalidate_deprecation_wrapperDeprecatedCallableInfoDeprecationWrapperInfono_warning_callassert_no_warnings -
Replace
target=NonewithTargetMode.NOTIFYor omittargetfor a warn-only decorator. - Replace
target=TruewithTargetMode.ARGS_REMAP. - Replace
DeprecationWrapperInfo.empty_mappingwithempty_args_mapping, andidentity_mappingwithidentity_args_mapping. The old properties warn and are removed in v1.0. - If code inspects
wrapper.__deprecated__.target, compare with aTargetMode, callable, orNone.DeprecationConfig.targetstores a normalized value, never legacyTrueorFalse. -
Update external documentation bookmarks from flat paths such as
/pyDeprecate/troubleshooting.htmlto the versioned/pyDeprecate/stable/troubleshooting.htmllayout. -
Rename the CLI flag
--skip_errorsto--exit-zeroin everycheck,expiry,chains, andallcommand. The old flag is rejected.--exit_zeroremains an underscore alias, but the dashed spelling is canonical. -
Fix unsupported stacked decorators. Six shapes, including callable-over-callable, now emit
UserWarningat decoration time and becomeTypeErrorin v1.0. The supported lifecycle stack is outerARGS_REMAPplus innerNOTIFY. -
Outer-order deprecated properties now warn on read, write, and delete. Under
filterwarnings=error::FutureWarning, a setter or deleter that was previously silent now raises. If only reads should warn, keep inner order (@propertyoutside@deprecated) or decorate onlyfget. -
Update proxy detection.
proxy.__class__reports the wrapped object's type forisinstancetransparency. Usetype(proxy)when you need to detect_DeprecatedProxyitself. - Do not use an instance proxy as the second argument to
isinstance()orissubclass(). This misuse now raisesTypeErrorinstead of returningFalse. Class-alias proxies remain valid there. - Review expiry CI scope.
validate_deprecation_expiry()now defaults toinclude_members=True, so expired methods, constructors, descriptors, and properties can newly fail the gate. Passinclude_members=Falseonly when the old narrower scope is intentional. - Fix invalid
remove_inversions. An unparsableremove_innow emitsUserWarningduring batch expiry instead of being skipped silently. - Fix misspelled CLI flags. Unknown flags now fail instead of being silently ignored.
-
Use named
%fields in custom message templates. Bare%sor%dconversions now raiseValueErrorwhen the decorator is applied. -
@deprecated(target=TargetMode.ATTRS_REMAP)now raisesTypeErrorfor a class source. It already raised for functions.ATTRS_REMAPneeds the class-onlyattrs_mappingkeyword, which the common front door does not expose, so a class source previously built a proxy that remapped nothing. Usedeprecated_class(attrs_mapping=...). - Rename
template_mgstomessage_templateondeprecated(),deprecated_callable(),deprecated_class(), anddeprecated_instance(). The typo remains a warning alias until v1.0; supplying both names raisesTypeError.
-
Mapping errors now include the originating class or function name. Tests that assert complete error strings may need updated expected text.
-
Across the v0.6.x line, backward support for
@deprecatedon a class was restored through delegation todeprecated_class(). Existing class decorators need no rewrite for v0.12; delegation remains permanent and only its informational notice is scheduled for removal. -
Omitting
deprecated_inon a function or method emitsUserWarningat decoration time. Add the version as part of every deprecation lifecycle. ARGS_REMAPwithoutargs_mapping,NOTIFYwithargs_mappingorargs_extra, and invalidtarget=Falsenow warn immediately. These are migration failures, not harmless diagnostics; correct them before v1.0.-
Omitting
targetis the canonical warn-only form. Its v0.12 default isTargetMode.AUTO, which resolves toNOTIFYwhen no mapping is present, so the user-visible result is unchanged. -
CLI scans suppress only warnings from
deprecate.*; third-party warnings are now visible. CI that treats all warnings as errors may start failing on dependencies imported during a scan. -
Audit code sees the supported
ARGS_REMAP + NOTIFYchain asChainType.STACKED, notChainType.TARGET. -
When a caller supplies both deprecated and replacement keyword names, the explicit replacement value now wins regardless of call-site order.
-
Circular callable-target chains now raise a named
RuntimeErrorinstead of ending inRecursionError. -
repr(),str(), equality, and hashing on a target-forwarding proxy now reflect the active target rather than the deprecated source. - In-place operators such as
proxy += 1rebind the name to the unwrapped result. Later uses are silent; avoid in-place operators if the proxy must retain its warning budget. args_mapping,args_extra, andattrs_mappingare copied at decoration time. Mutating the original dict later no longer changes forwarding behavior.- Constructing an
attrs_mapping-only class proxy is now silent; only access to a listed deprecated attribute warns. - Concurrent calls now respect exactly the configured
num_warnsbudget. Tests that accidentally relied on one warning per racing thread will see fewer warnings. -
Recursive audits deduplicate re-exports, include deprecated private and dunder members, warn and skip submodules that fail to import, and ignore unrelated foreign objects that raise during metadata probing. Counts and rows can therefore change in both directions.
-
@deprecatednow defaults toTargetMode.AUTO. It resolves at decoration time: a function/class withargs_mappingbecomesARGS_REMAP; a source without a mapping becomes warn-only.AUTOis never stored inDeprecationConfig; do not pass it explicitly because it exists only as the front-door default. - Existing
@deprecateduse on a class remains supported; no code change or decorator rewrite is required. It permanently delegates todeprecated_class()and emits one informationalUserWarningper module-qualified class.stream=Nonesuppresses the notice. Only the notice, not backward support or delegation, is removed in v1.0. message_templateandskip_ifsupplied through@deprecatedon a class now reach the proxy.message_templatewas previously dropped on that path.- Non-callable sources now raise a direct
TypeErrorpointing users todeprecated_instance()instead of failing later on__name__. - Explicit
target=TargetMode.NOTIFYtogether with a mapping still emitsUserWarning, staysNOTIFY, leaves the mapping inert, and is marked misconfigured — unchanged from v0.11.0, and aTypeErrorin v1.0. What changed is that an omittedtargetno longer lands here: it auto-resolves instead. Omittargetto infer remapping, or select the matching remap mode explicitly.
If you hit anything not covered here, open an issue — we are happy to help.