6ed4cacbe7
Trivial fix Change-Id: I8d0e33710af8de089823eceb8ca5cf2511f15511
448 lines
12 KiB
ReStructuredText
448 lines
12 KiB
ReStructuredText
========
|
|
Examples
|
|
========
|
|
|
|
Removing a class/classmethod/method/function
|
|
--------------------------------------------
|
|
|
|
To signal to a user that a method (staticmethod, classmethod, or regular
|
|
instance method) or a class or function is going to be removed at some point
|
|
in the future the :py:func:`~debtcollector.removals.remove` function/decorator
|
|
can be used to achieve this in a non-destructive manner.
|
|
|
|
A basic example to do just this (on a method/function):
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import removals
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> class Car(object):
|
|
... @removals.remove
|
|
... def start(self):
|
|
... pass
|
|
...
|
|
>>> c = Car()
|
|
>>> c.start()
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using function/method 'Car.start()' is deprecated
|
|
|
|
A basic example to do just this (on a class):
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import removals
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> @removals.removed_class("Pinto")
|
|
... class Pinto(object):
|
|
... pass
|
|
...
|
|
>>> p = Pinto()
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using class 'Pinto' (either directly or via inheritance) is deprecated
|
|
|
|
A basic example to do just this (on a classmethod):
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import removals
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> class OldAndBusted(object):
|
|
... @removals.remove
|
|
... @classmethod
|
|
... def fix_things(cls):
|
|
... pass
|
|
...
|
|
>>> OldAndBusted.fix_things()
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using function/method 'OldAndBusted.fix_things()' is deprecated
|
|
|
|
Removing a instance property
|
|
----------------------------
|
|
|
|
Use the :py:func:`~debtcollector.removals.removed_property` decorator
|
|
to signal that an attribute of a class is deprecated.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> from debtcollector import removals
|
|
>>> class OldAndBusted(object):
|
|
... @removals.removed_property
|
|
... def thing(self):
|
|
... return 'old-and-busted'
|
|
... @thing.setter
|
|
... def thing(self, value):
|
|
... pass
|
|
... @thing.deleter
|
|
... def thing(self):
|
|
... pass
|
|
...
|
|
>>> o = OldAndBusted()
|
|
>>> o.thing
|
|
'old-and-busted'
|
|
>>> o.thing = '2'
|
|
>>> del o.thing
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Reading the 'thing' property is deprecated
|
|
__main__:1: DeprecationWarning: Setting the 'thing' property is deprecated
|
|
__main__:1: DeprecationWarning: Deleting the 'thing' property is deprecated
|
|
|
|
Removing a keyword argument
|
|
---------------------------
|
|
|
|
A basic example to do just this (on a classmethod):
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> from debtcollector import removals
|
|
>>> class OldAndBusted(object):
|
|
... @removals.removed_kwarg('resp', message="Please use 'response' instead")
|
|
... @classmethod
|
|
... def factory(cls, resp=None, response=None):
|
|
... response = resp or response
|
|
... return response
|
|
...
|
|
>>> OldAndBusted.factory(resp='super-duper')
|
|
'super-duper'
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'resp' argument is deprecated: Please use 'response' instead
|
|
|
|
A basic example to do just this (on a ``__init__`` method):
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> from debtcollector import removals
|
|
>>> class OldAndBusted(object):
|
|
... @removals.removed_kwarg('bleep')
|
|
... def __init__(self, bleep=None):
|
|
... self.bloop = bleep
|
|
...
|
|
>>> o = OldAndBusted(bleep=2)
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'bleep' argument is deprecated
|
|
|
|
Changing the default value of a keyword argument
|
|
------------------------------------------------
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> from debtcollector import updating
|
|
>>> class OldAndBusted(object):
|
|
... ip = '127.0.0.1'
|
|
... @updating.updated_kwarg_default_value('type', 'http', 'https')
|
|
... def url(self, type='http'):
|
|
... response = '%s://%s' % (type, self.ip)
|
|
... return response
|
|
...
|
|
>>> OldAndBusted().url()
|
|
'http://127.0.0.1'
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: FutureWarning: The http argument is changing its default value to https, please update the code to explicitly set http as the value
|
|
|
|
|
|
A basic classmethod example.
|
|
|
|
.. note:: the @classmethod decorator is before the debtcollector one
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("once")
|
|
>>> from debtcollector import updating
|
|
>>> class OldAndBusted(object):
|
|
... ip = '127.0.0.1'
|
|
... @classmethod
|
|
... @updating.updated_kwarg_default_value('type', 'http', 'https')
|
|
... def url(cls, type='http'):
|
|
... response = '%s://%s' % (type, cls.ip)
|
|
... return response
|
|
...
|
|
>>> OldAndBusted.url()
|
|
'http://127.0.0.1'
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: FutureWarning: The http argument is changing its default value to https, please update the code to explicitly set http as the value
|
|
|
|
Moving a function
|
|
-----------------
|
|
|
|
To change the name or location of a regular function use the
|
|
:py:func:`~debtcollector.moves.moved_function` function:
|
|
|
|
.. doctest::
|
|
|
|
>>> 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__)
|
|
>>> new_thing()
|
|
'new thing'
|
|
>>> old_thing()
|
|
'new thing'
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Function '__main__.old_thing()' has moved to '__main__.new_thing()'
|
|
|
|
Moving a method
|
|
---------------
|
|
|
|
To move a *instance* method from an existing one to a new one
|
|
the :py:func:`~debtcollector.moves.moved_method` function/decorator can be
|
|
used to achieve this in a non-destructive manner.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import moves
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> class Cat(object):
|
|
... @moves.moved_method('meow')
|
|
... def mewow(self):
|
|
... return self.meow()
|
|
... def meow(self):
|
|
... return 'kitty'
|
|
...
|
|
>>> c = Cat()
|
|
>>> c.mewow()
|
|
'kitty'
|
|
>>> c.meow()
|
|
'kitty'
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Method 'Cat.mewow()' has moved to 'Cat.meow()'
|
|
|
|
Moving a property
|
|
-----------------
|
|
|
|
To move a *instance* property from an existing one to a new one
|
|
the :py:func:`~debtcollector.moves.moved_property` function/decorator can be
|
|
used to achieve this in a non-destructive manner.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import moves
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> class Dog(object):
|
|
... @property
|
|
... @moves.moved_property('bark')
|
|
... def burk(self):
|
|
... return self.bark
|
|
... @property
|
|
... def bark(self):
|
|
... return 'woof'
|
|
...
|
|
>>> d = Dog()
|
|
>>> d.burk
|
|
'woof'
|
|
>>> d.bark
|
|
'woof'
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Property 'Dog.burk' has moved to 'Dog.bark'
|
|
|
|
Moving a class
|
|
--------------
|
|
|
|
To move a *class* from an existing one to a new one
|
|
the :py:func:`~debtcollector.moves.moved_class` type generator function can
|
|
be used to achieve this in a non-destructive manner.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import moves
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> class WizBang(object):
|
|
... pass
|
|
...
|
|
>>> OldWizBang = moves.moved_class(WizBang, 'OldWizBang', __name__)
|
|
>>> a = OldWizBang()
|
|
>>> b = WizBang()
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Class '__main__.OldWizBang' has moved to '__main__.WizBang'
|
|
|
|
Renaming a keyword argument
|
|
---------------------------
|
|
|
|
To notify the user when a keyword argument has been replaced with a new and
|
|
improved keyword argument and the user is still using the old keyword argument
|
|
the :py:func:`~debtcollector.renames.renamed_kwarg` function/decorator
|
|
can be used to achieve this in a non-destructive manner.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import renames
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> @renames.renamed_kwarg('snizzle', 'nizzle')
|
|
... def do_the_deed(snizzle=True, nizzle=True):
|
|
... return (snizzle, nizzle)
|
|
...
|
|
>>> do_the_deed()
|
|
(True, True)
|
|
>>> do_the_deed(snizzle=False)
|
|
(False, True)
|
|
>>> do_the_deed(nizzle=False)
|
|
(True, False)
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'snizzle' argument is deprecated, please use the 'nizzle' argument instead
|
|
|
|
Further customizing the emitted messages
|
|
----------------------------------------
|
|
|
|
It is typically useful to tell the user when a deprecation has started and
|
|
when the deprecated item will be officially removed (deleted or other). To
|
|
enable this all the currently provided functions this library provides
|
|
take a ``message``, ``version`` and ``removal_version`` keyword arguments.
|
|
These are used in forming the message that is shown to the user when they
|
|
trigger the deprecated activity.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import renames
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> @renames.renamed_kwarg('snizzle', 'nizzle', version="0.5", removal_version="0.7")
|
|
... def do_the_deed(snizzle=True, nizzle=True):
|
|
... pass
|
|
...
|
|
>>> do_the_deed(snizzle=False)
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'snizzle' argument is deprecated in version '0.5' and will be removed in version '0.7', please use the 'nizzle' argument instead
|
|
|
|
If the ``removal_version`` is unknown the special character ``?`` can be used
|
|
instead (to denote that the deprecated activity will be removed sometime in
|
|
the future).
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import renames
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> @renames.renamed_kwarg('snizzle', 'nizzle', version="0.5", removal_version="?")
|
|
... def do_the_deed(snizzle=True, nizzle=True):
|
|
... pass
|
|
...
|
|
>>> do_the_deed(snizzle=False)
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'snizzle' argument is deprecated in version '0.5' and will be removed in a future version, please use the 'nizzle' argument instead
|
|
|
|
To further customize the message (with a special postfix) the ``message``
|
|
keyword argument can be provided.
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> from debtcollector import renames
|
|
>>> import warnings
|
|
>>> warnings.simplefilter('always')
|
|
>>> @renames.renamed_kwarg('snizzle', 'nizzle', message="Pretty please stop using it")
|
|
... def do_the_deed(snizzle=True, nizzle=True):
|
|
... pass
|
|
...
|
|
>>> do_the_deed(snizzle=False)
|
|
|
|
**Expected output:**
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: Using the 'snizzle' argument is deprecated, please use the 'nizzle' argument instead: Pretty please stop using it
|
|
|
|
Deprecating anything else
|
|
-------------------------
|
|
|
|
For use-cases which do not fit the above decorators, properties other
|
|
provided functionality the final option is to use debtcollectors
|
|
the :py:func:`~debtcollector.deprecate` function to make your own
|
|
messages (using the message building logic that debtcollector uses itself).
|
|
|
|
A basic example to do just this:
|
|
|
|
.. doctest::
|
|
|
|
>>> import warnings
|
|
>>> warnings.simplefilter("always")
|
|
>>> import debtcollector
|
|
>>> debtcollector.deprecate("This is no longer supported", version="1.0")
|
|
|
|
.. testoutput::
|
|
|
|
__main__:1: DeprecationWarning: This is no longer supported in version '1.0'
|