-
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:
-
version
indicates the future release where the callable will be removed. -
reason
indicates the reason for the deprecation. -
new
is 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::DeprecationWarning
Run 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