[PYTHON] Smartly announce that it is a deprecated implementation --debtcollerctor

There are warnings in python to notify module users of deprecated classes and methods.

When you run the code below

# -*- coding: utf-8 -*-
import warnings


def deprecated_method():
    warn_msg = "`deprecated_method` is deprecated and will be removed in v0.5"
    warnings.warn(warn_msg, UserWarning)
    print "I'm old"


if __name__ == '__main__':
    deprecated_method()

You will see warnings as shown below.

$ python warning_sample.py 
warning_sample.py:7: UserWarning: `deprecated_method` is deprecated and will be removed in v0.5
  warnings.warn(warn_msg, UserWarning)
I'm old

This time, I would like to introduce deptcollector that makes it easier to compose this deprecated message.

How to use debt collector

You can almost always look at Examples, but I'll try it myself. ..

deprecated for class, calssmethod, method, function

If the methods in the class are deprecated, use the @ removeals.remove decorator as shown below.

# -*- coding: utf-8 -*-
from debtcollector import removals
import warnings

warnings.simplefilter('always')


class Car(object):
    @removals.remove
    def start(self):
        pass


if __name__ == '__main__':
    Car().start()

The execution result is as follows.

$ python removals_sample.py 
removals_sample.py:15: DeprecationWarning: Using function/method 'Car.start()' is deprecated
  Car().start()

Why do you need the warnings.simplefilter ('always') in your code?

By default, @ removeals.remove is not displayed because DeprecationWarning is passed to warnings.warn and executed. You can read more about warnings in Warning category.

You can also display the warning on the command line by specifying the -W option instead of writing it in your code. Delete warnings.simplefilter ('always') from the previous source code and execute as follows.

$ python -Wd removals_sample.py

... omitted file, filename, etc = imp.find_module(subname, path) removals_sample.py:15: DeprecationWarning: Using function/method 'Car.start()' is deprecated Car().start()

Other warnings were displayed along with the Car (). start () error. If you make your own library, you may want to try it once.

The warning to the class is written as follows.

@removals.remove
class Pinto(object):
    pass

For class methods, put it above the @classmethod decorator.

 class OldAndBusted(object):
    @removals.remove
    @classmethod
    def fix_things(cls):
        pass

When method, property, class, keyword, etc. are changed to other names

When the function name changes, use moves.moved_function.

# -*- coding: utf-8 -*-
from debtcollector import moves
import warnings
warnings.simplefilter('always')


def new_thing():
    return "new thing"

old_thing = moves.moved_function(new_thing, 'old_thing', __name__)


if __name__ == '__main__':
    print new_thing()
    print old_thing()

When you run it, you can see that the new method is called even if you call old_thing ().

$ python moving_sample.py 
new thing
moving_sample.py:15: DeprecationWarning: Function '__main__.old_thing()' has moved to '__main__.new_thing()'
  print old_thing()
new thing

For method, you can do it with a decorator.

class Cat(object):
    @moves.moved_method('meow')
    def mewow(self):
        return self.meow()
    def meow(self):
        return 'kitty'

For more examples, see the link introduced at the beginning.

Specify a version that will be replaced in the future

To specify the current version and the version to be replaced, specify the version and removal_version keywords as follows:

# -*- coding: utf-8 -*-
from debtcollector import moves
import warnings
warnings.simplefilter('always')


def new_thing():
    return "new thing"

old_thing = moves.moved_function(new_thing, 'old_thing', __name__,
                                 version="0.5", removal_version="0.7")


if __name__ == '__main__':
    print new_thing()
    print old_thing()

The execution result is as follows.

$ python moving_version_sample.py 
new thing
moving_version_sample.py:16: DeprecationWarning: Function '__main__.old_thing()' has moved to '__main__.new_thing()' in version '0.5' and will be removed in version '0.7'
  print old_thing()
new thing

Other methods

You can also issue a message in the method as follows.

import debtcollector
debtcollector.deprecate("This is no longer supported", version="1.0")

Summary

With ** deptcollector **, it seems that you can smartly notify users of deprecated methods just by using a decorator.

Recommended Posts

Smartly announce that it is a deprecated implementation --debtcollerctor
Is it a character string operation?
Is it deprecated to use pip directly?
It seems that unidic-lite is required in mecab-python3
It is said that libmysqlclient.so.18 does not exist
It is a piggybacking story about the service that returns "Nyan" when you ping