Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecated names? #44

Open
AstraLuma opened this issue Mar 27, 2021 · 5 comments
Open

Deprecated names? #44

AstraLuma opened this issue Mar 27, 2021 · 5 comments

Comments

@AstraLuma
Copy link

(Feature request)

I would like to see a way to move a class, function, or method from one name to another, deprecating the old name.

So you could say:

class NewName:
    ...

OldName = deprecated_name(NewName)

I would say that it should raise a warning on direct use (ideally when the code referring to it is compiled, but implementing that would be unacceptably magical).

  • Functions, methods: When called
  • Classes: When subclassed or directly instantiated (maybe when a class-level attribute is accessed as well?)
@tantale
Copy link
Collaborator

tantale commented Mar 28, 2021

Thank you for your question.

Actually, you can already have a old function which is a deprecated version of a new function name, here is how you can do that:

from deprecated import deprecated


def new_function():
    pass


old_function = deprecated(reason=u"Use new_function() instead", version="2.3.0")(new_function)

if __name__ == '__main__':
    old_function()
    new_function()

You'll have a warning message only if you use the old function:

demo.py:12: DeprecationWarning: Call to deprecated function (or staticmethod) new_function. (Use new_function() instead) -- Deprecated since version 2.3.0.
  old_function()

For classes, it's another story because this is the __new__ method which is actually decorated. So, this is not the right way to do that. You may need module-level deprecation, which is a modern feature only available for Python 3.7+ (see: PEP 562 -- Module __getattr__ and __dir__.

I'll try to given you a workaround later.

@tantale tantale self-assigned this Mar 28, 2021
@tantale
Copy link
Collaborator

tantale commented Mar 28, 2021

A workaround for classes could be designed as follow: the "old" class can be redefined and inherit the "new" class. Then you need to implement a __new__ method which will receive the deprecation warning:

from deprecated import deprecated


class NewClass(object):
    pass


@deprecated(reason=u"Use NewClass instead", version="2.3.0")
class OldClass(NewClass):
    @classmethod
    def __new__(cls, *args, **kwargs):
        return super(OldClass, cls).__new__(cls)
        # or, if ``NewClass.__new__`` is defined:
        # return super(OldClass, cls).__new__(cls, *args, **kwargs)


if __name__ == '__main__':
    old_obj = OldClass()
    new_obj = NewClass()

You get:

demo.py:19: DeprecationWarning: Call to deprecated class OldClass. (Use NewClass instead) -- Deprecated since version 2.3.0.
  old_obj = OldClass()

@tantale
Copy link
Collaborator

tantale commented Mar 28, 2021

I will leave this issue opened until I implement module-level deprecation.

@tantale tantale added this to the 2.0 milestone Mar 28, 2021
@tantale
Copy link
Collaborator

tantale commented May 27, 2023

Module-level depreciation is currently being developed. Stay tune.

@benjamin-kirkbride
Copy link

Adding these examples to the docs would be good too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants