Uh oh!
There was an error while loading. Please reload this page.
Add deprecated_generic(), deprecated_class(), and deprecated_property() - #734
Open
hadley wants to merge 1 commit into
Open
Add deprecated_generic(), deprecated_class(), and deprecated_property()#734hadley wants to merge 1 commit into
hadley wants to merge 1 commit into
Conversation
Provides a standard way to deprecate parts of an S7 API while keeping old code working: * deprecated_generic() wraps a generic: calls warn then delegate, and method registrations are silently redirected to the replacement. * deprecated_class() aliases a class: the constructor warns, and every other context (signatures, parent, property classes, external class references) silently resolves to the replacement. * deprecated_property() warns on read/write, delegating storage to the replacement property. All three require a `when` version, support deprecation without a replacement (via `old` for generics/classes), and signal with a .Deprecated()-style warning by default; method = "lifecycle(warn)" or "lifecycle(stop)" uses the lifecycle package instead. Also relaxes resolve_external_class_req() so new_external_class() references resolve through exported aliases (plain or deprecated), allowing classes to be renamed without breaking downstream packages. Fixes#727. Fixes#730.
hadley
marked this pull request as ready for review
July 28, 2026 21:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#727. Fixes#730.
This PR adds a standard way to deprecate the pieces of an S7 API — generics, classes, and properties — so that old code keeps working but warns users to update.
API
All three helpers require
when(the package version when the deprecation began) and share amethodargument controlling how the deprecation is signalled:"base"(the default, a.Deprecated()-style warning attributed to the user's call),"lifecycle(warn)", or"lifecycle(stop)". The lifecycle options require lifecycle as a dependency of the deprecating package.deprecated_generic()Calling the old name warns then delegates to the target (via call rewriting, so arguments pass through lazily and unmodified).
method<-,method(),method_explain(),S7_methods(), and deferred external-generic registrations all silently unwrap to the target, so downstream packages keep installing and working. This also mitigates #729 for renames: a stale downstream registration finds the deprecated object and resolves through it.deprecated_class()Calling the constructor warns then constructs an instance of
new. In every other context (as_class()is the chokepoint: method signatures,parent, property classes, unions,convert(),S7_inherits(),new_external_class()resolution) the alias is silently treated as the replacement. The no-replacement form mirrors the generic:Cat := deprecated_class(old = Cat, when = "3.0.0").deprecated_property()Generalizes the getter/setter pattern from
vignette("classes-objects")(which now uses it): reading or writing the old name warns and delegates to the replacement, and the generateddefaultmeans the constructor only warns when the deprecated argument is actually supplied. With nonew, the property stores data itself and warns on access (construction can't warn in that case, since S7 can't distinguish a user-supplied value from the default).new_external_class()now resolves aliases (#727)resolve_external_class_req()no longer requires the exported object's@name/@packageto match the reference, so a class renamed with a plain alias (Foo <- Bar) or adeprecated_class()keeps working for downstream packages.