debtcollector(1)

DEBTCOLLECTOR(1) debtcollector DEBTCOLLECTOR(1)

NAME

debtcollector - debtcollector 3.0.0

A collection of Python deprecation patterns and strategies that help you collect your technical debt in a non-destructive manner.

NOTE:

It should be noted that even though it is designed with OpenStack integration in mind, and that is where most of its current integration is it aims to be generally usable and useful in any project.


INSTALLATION

At the command line:

$ pip install debtcollector


Or, if you have virtualenvwrapper installed:

$ mkvirtualenv debtcollector
$ pip install debtcollector


USING DEBTCOLLECTOR

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 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):

>>> from debtcollector import removals
>>> import warnings
>>> warnings.simplefilter('always')
>>> class Car(object):
...   @removals.remove
...   def start(self):
...     pass
...
>>> c = Car()
>>> c.start()


Expected output:

__main__:1: DeprecationWarning: Using function/method 'Car.start()' is deprecated


A basic example to do just this (on a class):

>>> from debtcollector import removals
>>> import warnings
>>> warnings.simplefilter('always')
>>> @removals.removed_class("Pinto")
... class Pinto(object):
...   pass
...
>>> p = Pinto()


Expected output:

__main__:1: DeprecationWarning: Using class 'Pinto' (either directly or via inheritance) is deprecated


A basic example to do just this (on a classmethod):

>>> 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:

__main__:1: DeprecationWarning: Using function/method 'OldAndBusted.fix_things()' is deprecated


Removing a instance property

Use the removed_property() decorator to signal that an attribute of a class is deprecated.

A basic example to do just this:

>>> 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


__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):

>>> 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'


__main__:1: DeprecationWarning: Using the 'resp' argument is deprecated: Please use 'response' instead


A basic example to do just this (on a __init__ method):

>>> 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)


__main__:1: DeprecationWarning: Using the 'bleep' argument is deprecated


Changing the default value of a keyword argument

A basic example to do just this:

>>> 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'


__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


>>> 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'


__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 moved_function() function:

>>> 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:

__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 moved_method() function/decorator can be used to achieve this in a non-destructive manner.

A basic example to do just this:

>>> 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:

__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 moved_property() function/decorator can be used to achieve this in a non-destructive manner.

A basic example to do just this:

>>> 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:

__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 moved_class() type generator function can be used to achieve this in a non-destructive manner.

A basic example to do just this:

>>> 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:

__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 renamed_kwarg() function/decorator can be used to achieve this in a non-destructive manner.

A basic example to do just this:

>>> 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:

__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:

>>> 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:

__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:

>>> 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:

__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:

>>> 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:

__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 deprecate() function to make your own messages (using the message building logic that debtcollector uses itself).

A basic example to do just this:

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


__main__:1: DeprecationWarning: This is no longer supported in version '1.0'


CHANGES

3.0.0

  • Bump hacking
  • Update python classifier in setup.cfg
  • Remove unused babel.cfg
  • coveragerc: Remove non-existent path
  • requirements: Remove unnecessary dependency
  • Revert "Moves supported python runtimes from version 3.8 to 3.10"
  • Moves supported python runtimes from version 3.8 to 3.10
  • Drop python3.6/3.7 support in testing runtime
  • Add Python 3.8 and 3.9 to supported runtimes
  • Update CI to use unversioned jobs template

2.5.0

  • Remove references to Python 2 objects
  • requirements: Remove pbr

2.4.0

  • Remove unnecessary 'coding' lines
  • Remove six
  • Restore reproducibility in docs

2.3.0

  • Replace deprecated inspect.getargspec
  • remove unicode from code
  • setup.cfg: Replace dashes with underscores
  • Remove runtime dependency on pbr
  • Move flake8 as a pre-commit local target
  • Remove lower-constraints remnants
  • Dropping lower constraints testing
  • Use TOX_CONSTRAINTS_FILE
  • Use py3 as the default runtime for tox
  • ignore reno generated artifacts
  • Adding pre-commit
  • Add Python3 wallaby unit tests
  • Update master for stable/victoria

2.2.0

Update lower-constraints versions

2.1.0

  • Stop to use the __future__ module
  • Switch to newer openstackdocstheme and reno versions
  • Switch to Victoria tests
  • Update master for stable/ussuri

2.0.1

  • Update hacking for Python3
  • Update the minversion parameter
  • Move docs linting to pep8

2.0.0

  • [ussuri][goal] Drop python 2.7 support and testing
  • Update master for stable/train

1.22.0

  • Add Python 3 Train unit tests
  • Replace git.openstack.org URLs with opendev.org URLs
  • Update Sphinx requirement
  • OpenDev Migration Patch
  • Dropping the py35 testing
  • Update master for stable/stein
  • add python 3.7 unit test job

1.21.0

  • Use template for lower-constraints
  • Change openstack-dev to openstack-discuss
  • Don't quote {posargs} in tox.ini
  • add lib-forward-testing-python3 test job
  • add python 3.6 unit test job
  • Remove PyPI downloads
  • import zuul job settings from project-config
  • Update reno for stable/rocky

1.20.0

  • Switch to stestr
  • Add release note link in README
  • fix tox python3 overrides
  • Trivial: Update pypi url to new url
  • remove obsolete tox environments
  • set default python to python3
  • add lower-constraints job
  • pypy is not checked at gate
  • Updated from global requirements
  • Updated from global requirements
  • Update links in README
  • Update reno for stable/queens
  • Updated from global requirements
  • Updated from global requirements

1.19.0

  • Avoid tox_install.sh for constraints support
  • Remove setting of version/release from releasenotes
  • Updated from global requirements

1.18.0

  • Updated from global requirements
  • Updated from global requirements
  • Update reno for stable/pike
  • Updated from global requirements

1.17.0

Update URLs in documents according to document migration

1.16.0

  • rearrange existing documentation to fit the new standard layout
  • switch from oslosphinx to openstackdocstheme
  • Updated from global requirements

1.15.0

  • Remove pbr warnerrors in favor of sphinx check
  • Updated from global requirements

1.14.0

  • Do not require oslotest for testing
  • Updated from global requirements
  • Updated from global requirements

1.13.0

  • Remove testscenarios from test-requirements.txt
  • Python 3.4 support has been removed

1.12.0

  • Updated from global requirements
  • Updated from global requirements
  • Update reno for stable/ocata

1.11.0

  • Add Constraints support
  • Show team and repo badges on README

1.10.0

  • Updated from global requirements
  • Typo fix for module debtcollector
  • Updated from global requirements
  • Add reno for release notes management
  • Trivial: Remove 'MANIFEST.in'
  • Updated from global requirements

1.9.0

  • Updated from global requirements
  • Update homepage with developer documentation page
  • Fix a typo in comment

1.8.0

Drop *openstack/common* in flake8 exclude list

1.7.0

  • Remove discover from test-requirements
  • Add Python 3.5 classifier and venv

1.6.0

Updated from global requirements

1.5.0

Updated from global requirements

1.4.0

  • Drop babel as requirement since its not used
  • Fix renamed_kwarg to preserve argspec
  • Add tests for decorated argspec preservation
  • Updated from global requirements
  • Updated from global requirements

1.3.0

  • Updated from global requirements
  • Add debug testenv in tox

1.2.0

  • Add updated_kwarg_default_value decorator
  • Allow replacing a keyword argument
  • Add 'removed_class' class decorator
  • py26/py33 are no longer supported by Infra's CI

1.1.0

Add removals.remove note about metaclasses

1.0.0

  • Updated from global requirements
  • Update get_class_name from olso.utils
  • Remove Python 2.6 classifier
  • Remove python 2.6 and cleanup tox.ini
  • Add 'moved_read_only_property' descriptor

0.10.0

Add ability to disable warnings being emitted

0.9.0

  • Add a 'removed_property' descriptor class
  • No need for Oslo Incubator Sync
  • docs - Set pbr 'warnerrors' option for doc build
  • Include changelog/history in docs
  • tweak language in readme
  • Enhance the README
  • Change ignore-errors to ignore_errors
  • Updated from global requirements
  • Activate pep8 check that _ is imported
  • Add a moved function helper

0.8.0

  • Updated from global requirements
  • Updated from global requirements
  • Updated from global requirements

0.7.0

  • Updated from global requirements
  • Expose a top level 'deprecate' function
  • Add @removals.removed_kwarg on an __init__ method
  • Improve + test keyword argument @classmethod removal
  • Add example for removing a @classmethod

0.6.0

  • Ensure doctesting and doc8 testing done in py27 env
  • Updated from global requirements
  • Fix quoting of examples
  • Updated from global requirements
  • Switch badges from 'pypip.in' to 'shields.io'

0.5.0

  • Remove oslo.utils dependency
  • Updated from global requirements
  • Ensure that the incoming 'new_class' is actually a class
  • Allow providing the deprecation category

0.4.0

  • Uncap library requirements for liberty
  • No longer need to workaround six issue/bug
  • Add pypi download + version badges
  • Updated from global requirements

0.3.0

  • Add a removed module deprecation helper
  • Updated from global requirements
  • Move to hacking 0.10
  • Add a 'removed_kwarg' function/method decorator
  • Match the updated openstack-manuals description
  • Format the method/class removals messages like the others
  • Add examples of using the new removals decorator

0.2.0

  • Add a removal decorator
  • Add doctested examples into the documentation
  • Add universal wheel tag to setup.cfg

0.1.0

  • Upper case python
  • Fix up the docs into reasonable shape
  • Add a moved *instance* method deprecation pattern
  • Initial import of renames/moves + tests
  • Add a .gitreview file with correct values
  • Adjust summary of project
  • Initial commit

API REFERENCE

The currently documented publicly exposed API's for usage in your project are defined below.

WARNING:

External usage of internal utility functions and modules should be kept to a minimum as they may be altered, refactored or moved to other locations without notice (and without the typical deprecation cycle).


Helpers

Moves

Renames

Removals

Fixtures

CONTRIBUTING

If you would like to contribute to the development of OpenStack, you must follow the steps in this page: https://docs.openstack.org/infra/manual/developers.html

Once those steps have been completed, changes to OpenStack should be submitted for review via the Gerrit tool, following the workflow documented at: https://docs.openstack.org/infra/manual/developers.html#development-workflow

Pull requests submitted through GitHub will be ignored.

Bugs should be filed on Launchpad, not GitHub: https://bugs.launchpad.net/debtcollector

Indices and tables

  • Index
  • Module Index
  • Search Page

AUTHOR

Author name not set

COPYRIGHT

OpenStack Foundation

May 29, 2024 3.0.0