-
Notifications
You must be signed in to change notification settings - Fork 9
Deprecating code
Changing the API in a project that has public users require we don't just change it, but include a notice of the intended change and what the alternate is (if any).
The overview of steps required to deprecate callable code (i.e. a function or a method) include:
- Creating a replacement callable
- Marking the old callable as deprecated
- Replacing internal usage across the codebase
In this how-to guide, we will use an example of deprecating a generic function
old() in place of new().
If there is any ambiguity in what you need to do, please post a question as a comment on the issue.
Begin the deprecation process by adding a new callable that will
replace the old one. Copy the contents of old() into a new function new():
def new():
...
return result
def old():
...
return result... represents the contents of the callable.
In some cases, you many need to add the callable to a new location.
There are a few things required to deprecate the old callable.
from cogent3.util import warning as c3warn
def new():
...
return result
@c3warn.deprecated_callable(version="2024.1", reason="function rename", new="new")
def old(): # pragma: no cover
"""deprecated, use new"""
return new()Decorate old() with c3warn.deprecated_callable(). This will trigger a
warning when the deprecated old() is used.
Refer to the issue post for the decorator arguments required:
-
versionindicates the future release where the callable will be removed. -
reasonindicates the reason for the deprecation. -
newis the name of the new callable.
Modify the deprecated callable old() so that it calls new() when run.
Delete the contents of old() and replace with a comment indicating its
deprecation. This ensures functionality for existing code and users.
Lastly, if the code is to be completely removed, add the markup # pragma: no cover to the definition line. This tells coverage to exclude it from
measurement.
Next, all uses of the deprecated callable old() should be replaced with the
updated one new(). This should be completed for all files under:
src/cogent3/-
tests/, and docs/
We recommend running the test suite and identifying which calls of old()
triggered a deprecation warning. Please see:
You can turn the deprecation warnings into errors, which makes it easier to find the exact file and line:
$ pytest relevant_test_modules/ -W error::DeprecationWarningRun the tests frequently as you amend the code.
TODO
- Refactor the function / method internals to using the new name
- Modify the tests to using the new name
Use the same decorator for deprecating code, setting is_discontinued=True. In the reason, indicate a replacement in another project if possible. Update the docstring to indicate this function will be removed. Add the special comment (# pragma...) on the function definition line.
from cogent3.util import warning as c3warn
@c3warn.deprecated_callable(version="2024.1", reason="use scipy.stats ... instead", is_discontinued=True)
def t_test(): # pragma: no cover
"""being removed"""
return new()Change all cogent3 uses of the code to the replacement. For example, if we are discontinuing a std() function in favour of using numpy.std(), we replace all calls to our std() with calls to numpy.std().
** TODO NEXT: Add docs, tests - here or dev practices?? **
Once you have made all edits, use nox to run the standard test suite:
$ nox -s test-<PYTHON_VERSION>and test the code in the docs:
$ nox -s testdocs-<PYTHON_VERSION>Getting started
- Code of conduct
- How to set up your development environment
- The development workflow
- Development practices for cogent3
Types of issues
Guidelines