Enable registering of legacy attributes without exact substitutes (#1438)
* Enable registering of legacy attributes without... ... exact substitutes. (See diff for an example.) * Take new callable instead of old name ... ... so we can ensure existence * Require old names to be passed as key words This is a lot simpler, less error prone, and works for all kinds of old names, not only those which are proper camelcase.
This commit is contained in:
parent
4678b12570
commit
54df350cda
@ -44,15 +44,21 @@ class DeprecatedNamesMixin:
|
||||
# attributes on the consuming class
|
||||
|
||||
_deprecated_aliases: dict[str, str] = {}
|
||||
_deprecated_attributes: dict[str, tuple[str, str]] = {}
|
||||
|
||||
@no_type_check
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
remapped = self._deprecated_aliases.get(name) or stringcase.snakecase(name)
|
||||
if remapped == name:
|
||||
raise AttributeError
|
||||
if some_tuple := self._deprecated_attributes.get(name):
|
||||
remapped, replacement = some_tuple
|
||||
else:
|
||||
replacement = remapped = self._deprecated_aliases.get(
|
||||
name
|
||||
) or stringcase.snakecase(name)
|
||||
if remapped == name:
|
||||
raise AttributeError
|
||||
|
||||
out = getattr(self, remapped)
|
||||
_print_warning(f"'{name}'", f"please use '{remapped}'")
|
||||
_print_warning(f"'{name}'", f"please use '{replacement}'")
|
||||
|
||||
return out
|
||||
|
||||
@ -67,6 +73,28 @@ class DeprecatedNamesMixin:
|
||||
"""
|
||||
cls._deprecated_aliases = {k: _target_to_string(v) for k, v in kwargs.items()}
|
||||
|
||||
@no_type_check
|
||||
@classmethod
|
||||
def register_deprecated_attributes(
|
||||
cls,
|
||||
**kwargs: tuple[DeprecatedAliasTarget, DeprecatedAliasTarget],
|
||||
) -> None:
|
||||
"""Manually add deprecated attributes without exact substitutes.
|
||||
|
||||
Pass a tuple of (alias, replacement), where alias is the attribute's new
|
||||
name (by convention: snakecase, prepended with '_legacy_'), and
|
||||
replacement is any callable to be used instead in new code.
|
||||
Also note the docstring of `register_deprecated_aliases`.
|
||||
|
||||
E.g. given `def oldFunc(args): return new_func(additionalLogic(args))`,
|
||||
rename `oldFunc` to `_legacy_old_func` and call
|
||||
`register_deprecated_attributes(oldFunc=(_legacy_old_func, new_func))`.
|
||||
"""
|
||||
cls._deprecated_attributes = {
|
||||
k: (_target_to_string(v[0]), _target_to_string(v[1]))
|
||||
for k, v in kwargs.items()
|
||||
}
|
||||
|
||||
|
||||
def deprecated(replaced_by: Callable | None = None, info: str = "") -> Callable:
|
||||
"""Print a deprecation warning, telling users to use `replaced_by`, or show `doc`."""
|
||||
|
Loading…
Reference in New Issue
Block a user