Skip to content

Commit

Permalink
Merge pull request #13824 from eerovaher/deprecated-attr-alternative
Browse files Browse the repository at this point in the history
Allow a deprecated attribute to access its replacement
  • Loading branch information
pllim committed Oct 13, 2022
2 parents 37f9cea + b523532 commit 06e66c3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
14 changes: 11 additions & 3 deletions astropy/utils/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def deprecated_attribute(name, since, message=None, alternative=None,
property that will warn when the given attribute name is accessed.
To prevent the warning (i.e. for internal code), use the private
name for the attribute by prepending an underscore
(i.e. ``self._name``).
(i.e. ``self._name``), or set an alternative explicitly.
Parameters
----------
Expand Down Expand Up @@ -248,12 +248,20 @@ def deprecated_attribute(name, since, message=None, alternative=None,
class MyClass:
# Mark the old_name as deprecated
old_name = misc.deprecated_attribute('old_name', '0.1')
old_name = deprecated_attribute("old_name", "0.1")
def method(self):
self._old_name = 42
class MyClass2:
old_name = deprecated_attribute(
"old_name", "1.2", alternative="new_name"
)
def method(self):
self.new_name = 24
"""
private_name = '_' + name
private_name = alternative or "_" + name

specific_deprecated = deprecated(since, name=name, obj_type='attribute',
message=message, alternative=alternative,
Expand Down
67 changes: 41 additions & 26 deletions astropy/utils/tests/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,12 @@ class NewDeprecationWarning(AstropyDeprecationWarning):
def test_deprecated_attribute():
class DummyClass:
def __init__(self):
self.other = [42]
self._foo = 42
self._bar = 4242
self._message = '42'
self._alternative = [42]
self._pending = {42}

def set_private(self):
self._foo = 100
self._bar = 1000
self._message = '100'
self._alternative = [100]
self._pending = {100}

foo = deprecated_attribute('foo', '0.2')

bar = deprecated_attribute('bar', '0.2',
Expand All @@ -50,26 +43,48 @@ def set_private(self):

dummy = DummyClass()

with pytest.warns(AstropyDeprecationWarning, match="The foo attribute is "
"deprecated and may be removed in a future version.") as w:
dummy.foo
assert len(w) == 1
default_msg = (
r"^The {} attribute is deprecated and may be removed in a future version\.$"
)

with pytest.warns(NewDeprecationWarning, match="The bar attribute is "
"deprecated and may be removed in a future version.") as w:
dummy.bar
# Test getters and setters.
msg = default_msg.format("foo")
with pytest.warns(AstropyDeprecationWarning, match=msg) as w:
assert dummy.foo == 42
assert len(w) == 1

with pytest.warns(AstropyDeprecationWarning, match="MSG"):
dummy.message

with pytest.warns(AstropyDeprecationWarning, match=r"Use other instead\."):
dummy.alternative

with pytest.warns(AstropyPendingDeprecationWarning):
dummy.pending

dummy.set_private()
with pytest.warns(AstropyDeprecationWarning, match=msg):
dummy.foo = 24
# Handling ``_foo`` should not cause deprecation warnings.
assert dummy._foo == 24
dummy._foo = 13
assert dummy._foo == 13

msg = default_msg.format("bar")
with pytest.warns(NewDeprecationWarning, match=msg) as w:
assert dummy.bar == 4242
assert len(w) == 1
with pytest.warns(NewDeprecationWarning, match=msg):
dummy.bar = 2424

with pytest.warns(AstropyDeprecationWarning, match="^MSG$"):
assert dummy.message == "42"
with pytest.warns(AstropyDeprecationWarning, match="^MSG$"):
dummy.message = "24"

msg = default_msg.format("alternative")[:-1] + r"\n Use other instead\.$"
with pytest.warns(AstropyDeprecationWarning, match=msg):
assert dummy.alternative == [42]
with pytest.warns(AstropyDeprecationWarning, match=msg):
dummy.alternative = [24]
# ``other`` is not deprecated.
assert dummy.other == [24]
dummy.other = [31]

msg = r"^The pending attribute will be deprecated in a future version\.$"
with pytest.warns(AstropyPendingDeprecationWarning, match=msg):
assert dummy.pending == {42}
with pytest.warns(AstropyPendingDeprecationWarning, match=msg):
dummy.pending = {24}


# This needs to be defined outside of the test function, because we
Expand Down
3 changes: 3 additions & 0 deletions docs/changes/utils/13824.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
If an attribute is created using ``deprecated_attribute()`` with the
``alternative`` argument then getting or setting the value of the deprecated
attribute now accesses its replacement.

0 comments on commit 06e66c3

Please sign in to comment.