Introducing dissolve: Declarative Deprecations for Python APIs
I’ve published a new tool called dissolve. It’s aimed at simplifying how library maintainers communicate API changes — and how users of those libraries can automate code migrations.
What is it?
dissolve allows library maintainers to annotate deprecated functions using a decorator, and lets library users rewrite old calls in their own codebases using a command-line tool.
Example (library maintainer)
Mark a function as deprecated:
from dissolve import replace_me def increment(x): """Use this instead.""" return x + 1 @replace_me(since="0.1.0") def inc(x): return increment(x)
When used, this function emits a deprecation warning like:
DeprecationWarning: <function inc> has been deprecated since 0.1.0; use 'increment(3)' instead
Example (library user)
If your codebase uses deprecated APIs marked with @replace_me, you can rewrite those calls automatically:
dissolve migrate path/to/your/code
Options:
- --check: report but don’t modify
- --write: apply changes in-place
Removing old markers
Once users have migrated, maintainers can clean up deprecated decorators:
dissolve remove --all mylib/
Or only those deprecated before a specific version:
dissolve remove --before 2.0.0 mylib/
No hard dependency required
Libraries do not need to make dissolve a hard dependency. They can optionally ship a fallback @replace_me decorator that just emits a plain DeprecationWarning:
try: from dissolve import replace_me except ImportError: import warnings def replace_me(msg, since=None): def decorator(func): def wrapper(*args, **kwargs): warnings.warn( f"{func.__name__} is deprecated; use {msg} instead", DeprecationWarning, stacklevel=2 ) return func(*args, **kwargs) return wrapper return decorator
This ensures that users still receive deprecation warnings, even if they don’t have dissolve installed.
Install
For users:
pip install dissolve
Source
Questions, suggestions, and patches welcome.