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 functions should be imported. In use,
the version
option should be set to current development
version. This can be found by running pyomo --version
on
your local fork/branch.
-
class
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
-
class
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) ...
-
class
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) ...
-
class
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.
It contains backports of the __getattr__ functionality for earlier versions of Python (although the implementation for 3.5+ is more efficient that the implementation for 2.7+)
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.