Coverage for python/lsst/utils/deprecated.py: 45%
18 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-02 14:10 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-02 14:10 +0000
1# This file is part of utils.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# Use of this source code is governed by a 3-clause BSD-style
10# license that can be found in the LICENSE file.
12__all__ = ["deprecate_pybind11", "suppress_deprecations"]
14import functools
15import unittest.mock
16import warnings
17from contextlib import contextmanager
18from typing import Any, Iterator, Type
20import deprecated.sphinx
23def deprecate_pybind11(obj: Any, reason: str, version: str, category: Type[Warning] = FutureWarning) -> Any:
24 """Deprecate a pybind11-wrapped C++ interface function, method or class.
26 This needs to use a pass-through Python wrapper so that
27 `~deprecated.sphinx.deprecated` can update its docstring; pybind11
28 docstrings are native and cannot be modified.
30 Note that this is not a decorator; its output must be assigned to
31 replace the method being deprecated.
33 Parameters
34 ----------
35 obj : function, method, or class
36 The function, method, or class to deprecate.
37 reason : `str`
38 Reason for deprecation, passed to `~deprecated.sphinx.deprecated`
39 version : 'str'
40 Next major version in which the interface will be deprecated,
41 passed to `~deprecated.sphinx.deprecated`
42 category : `Warning`
43 Warning category, passed to `~deprecated.sphinx.deprecated`
45 Returns
46 -------
47 obj : function, method, or class
48 Wrapped function, method, or class
50 Examples
51 --------
52 .. code-block:: python
54 ExposureF.getCalib = deprecate_pybind11(ExposureF.getCalib,
55 reason="Replaced by getPhotoCalib. (Will be removed in 18.0)",
56 version="17.0", category=FutureWarning))
57 """
59 @functools.wraps(obj)
60 def internal(*args: Any, **kwargs: Any) -> Any:
61 return obj(*args, **kwargs)
63 # Typeshed seems to have an incorrect definition for the deprecated
64 # function and believes the category should be
65 # Optional[Type[DeprecationWarning]] but this is wrong on two counts:
66 # 1. None is not actually allowed.
67 # 2. FutureWarning is explicitly allowed but that is not a subclass
68 # of DeprecationWarning.
69 # This has been fixed upstream at
70 # https://github.com/python/typeshed/pull/593
71 # and will pass once that is released.
72 return deprecated.sphinx.deprecated(reason=reason, version=version, category=category)(internal)
75@contextmanager
76def suppress_deprecations(category: Type[Warning] = FutureWarning) -> Iterator[None]:
77 """Suppress warnings generated by `deprecated.sphinx.deprecated`.
79 Naively, one might attempt to suppress these warnings by using
80 `~warnings.catch_warnings`. However, `~deprecated.sphinx.deprecated`
81 attempts to install its own filter, overriding that. This convenience
82 method works around this and properly suppresses the warnings by providing
83 a mock `~warnings.simplefilter` for `~deprecated.sphinx.deprecated` to
84 call.
86 Parameters
87 ----------
88 category : `Warning` or subclass
89 The category of warning to suppress.
90 """
91 with warnings.catch_warnings():
92 warnings.simplefilter("ignore", category)
93 with unittest.mock.patch.object(warnings, "simplefilter"):
94 yield