Deprecation and Removal of Functionality
During the course of development, there may be cases where it becomes necessary to deprecate or remove functionality from the standard Pyomo offering.
Deprecation
We offer a set of tools to help with deprecation in
pyomo.common.deprecation
.
By policy, when deprecating or moving an existing capability, one of the
following utilities should be leveraged. Each has a required
version
argument that should be set to current development version (e.g.,
"6.6.2.dev0"
). This version will be updated to the next actual
release as part of the Pyomo release process. The current development version
can be found by running pyomo --version
on your local fork/branch.
|
Decorator to indicate that a function, method, or class is deprecated. |
|
Standardized formatter for deprecation warnings |
|
Provide a deprecation path for moved / renamed modules |
|
Provide a deprecation path for moved / renamed module attributes |
|
Metaclass to provide a deprecation path for renamed classes |
- @pyomo.common.deprecation.deprecated(msg=None, logger=None, version=None, remove_in=None)[source]
Decorator to indicate that a function, method, or class is deprecated.
This decorator will cause a warning to be logged when the wrapped function or method is called, or when the deprecated class is constructed. This decorator also updates the target object’s docstring to indicate that it is deprecated.
- Parameters:
msg (str) – a custom deprecation message (default: “This {function|class} has been deprecated and may be removed in a future release.”)
logger (str) – the logger to use for emitting the warning (default: the calling pyomo package, or “pyomo”)
version (str) – [required] the version in which the decorated object was deprecated. General practice is to set version to the current development version (from pyomo –version) during development and update it to the actual release as part of the release process.
remove_in (str) – the version in which the decorated object will be removed from the code.
Example
>>> from pyomo.common.deprecation import deprecated >>> @deprecated(version='1.2.3') ... def sample_function(x): ... return 2*x >>> sample_function(5) WARNING: DEPRECATED: This function (sample_function) has been deprecated and may be removed in a future release. (deprecated in 1.2.3) ... 10
- pyomo.common.deprecation.deprecation_warning(msg, logger=None, version=None, remove_in=None, calling_frame=None)[source]
Standardized formatter for deprecation warnings
This is a standardized routine for formatting deprecation warnings so that things look consistent and “nice”.
- Parameters:
msg (str) – the deprecation message to format
logger (str) – the logger to use for emitting the warning (default: the calling pyomo package, or “pyomo”)
version (str) – [required] the version in which the decorated object was deprecated. General practice is to set version to the current development version (from pyomo –version) during development and update it to the actual release as part of the release process.
remove_in (str) – the version in which the decorated object will be removed from the code.
calling_frame (frame) – the original frame context that triggered the deprecation warning.
Example
>>> from pyomo.common.deprecation import deprecation_warning >>> deprecation_warning('This functionality is deprecated.', version='1.2.3') WARNING: DEPRECATED: This functionality is deprecated. (deprecated in 1.2.3) ...
- pyomo.common.deprecation.relocated_module(new_name, msg=None, logger=None, version=None, remove_in=None)[source]
Provide a deprecation path for moved / renamed modules
Upon import, the old module (that called relocated_module()) will be replaced in sys.modules by an alias that points directly to the new module. As a result, the old module should have only two lines of executable Python code (the import of relocated_module and the call to it).
- Parameters:
new_name (str) – The new (fully-qualified) module name
msg (str) – A custom deprecation message.
logger (str) – The logger to use for emitting the warning (default: the calling pyomo package, or “pyomo”)
version (str [required]) – The version in which the module was renamed or moved. General practice is to set version to the current development version (from pyomo –version) during development and update it to the actual release as part of the release process.
remove_in (str) – The version in which the module will be removed from the code.
Example
>>> from pyomo.common.deprecation import relocated_module >>> relocated_module('pyomo.common.deprecation', version='1.2.3') WARNING: DEPRECATED: The '...' module has been moved to 'pyomo.common.deprecation'. Please update your import. (deprecated in 1.2.3) ...
- pyomo.common.deprecation.relocated_module_attribute(local, target, version, remove_in=None, msg=None, f_globals=None)[source]
Provide a deprecation path for moved / renamed module attributes
This function declares that a local module attribute has been moved to another location. For Python 3.7+, it leverages a module.__getattr__ method to manage the deferred import of the object from the new location (on request), as well as emitting the deprecation warning.
- Parameters:
local (str) – The original (local) name of the relocated attribute
target (str) – The new absolute import name of the relocated attribute
version (str) – The Pyomo version when this move was released (passed to deprecation_warning)
remove_in (str) – The Pyomo version when this deprecation path will be removed (passed to deprecation_warning)
msg (str) – If not None, then this specifies a custom deprecation message to be emitted when the attribute is accessed from its original location.
- class pyomo.common.deprecation.RenamedClass(name, bases, classdict, *args, **kwargs)[source]
Metaclass to provide a deprecation path for renamed classes
This metaclass provides a mechanism for renaming old classes while still preserving isinstance / issubclass relationships.
Examples
>>> from pyomo.common.deprecation import RenamedClass >>> class NewClass(object): ... pass >>> class OldClass(metaclass=RenamedClass): ... __renamed__new_class__ = NewClass ... __renamed__version__ = '6.0'
Deriving from the old class generates a warning:
>>> class DerivedOldClass(OldClass): ... pass WARNING: DEPRECATED: Declaring class 'DerivedOldClass' derived from 'OldClass'. The class 'OldClass' has been renamed to 'NewClass'. (deprecated in 6.0) ...
As does instantiating the old class:
>>> old = OldClass() WARNING: DEPRECATED: Instantiating class 'OldClass'. The class 'OldClass' has been renamed to 'NewClass'. (deprecated in 6.0) ...
Finally, isinstance and issubclass still work, for example:
>>> isinstance(old, NewClass) True >>> class NewSubclass(NewClass): ... pass >>> new = NewSubclass() >>> isinstance(new, OldClass) WARNING: DEPRECATED: Checking type relative to 'OldClass'. The class 'OldClass' has been renamed to 'NewClass'. (deprecated in 6.0) ... True
Removal
By policy, functionality should be deprecated with reasonable warning, pending extenuating circumstances. The functionality should be deprecated, following the information above.
If the functionality is documented in the most recent edition of [Pyomo - Optimization Modeling in Python], it may not be removed until the next major version release.
For other functionality, it is preferred that ample time is given before removing the functionality. At minimum, significant functionality removal will result in a minor version bump.