Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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. 

11 

12__all__ = ['deprecate_pybind11', 'suppress_deprecations'] 

13 

14import deprecated.sphinx 

15import functools 

16import unittest.mock 

17import warnings 

18 

19from contextlib import contextmanager 

20 

21from typing import ( 

22 Any, 

23 Iterator, 

24 Type, 

25) 

26 

27 

28def deprecate_pybind11(obj: Any, reason: str, version: str, category: Type[Warning] = FutureWarning) -> Any: 

29 """Deprecate a pybind11-wrapped C++ interface function, method or class. 

30 

31 This needs to use a pass-through Python wrapper so that 

32 `~deprecated.sphinx.deprecated` can update its docstring; pybind11 

33 docstrings are native and cannot be modified. 

34 

35 Note that this is not a decorator; its output must be assigned to 

36 replace the method being deprecated. 

37 

38 Parameters 

39 ---------- 

40 obj : function, method, or class 

41 The function, method, or class to deprecate. 

42 reason : `str` 

43 Reason for deprecation, passed to `~deprecated.sphinx.deprecated` 

44 version : 'str' 

45 Next major version in which the interface will be deprecated, 

46 passed to `~deprecated.sphinx.deprecated` 

47 category : `Warning` 

48 Warning category, passed to `~deprecated.sphinx.deprecated` 

49 

50 Returns 

51 ------- 

52 obj : function, method, or class 

53 Wrapped function, method, or class 

54 

55 Examples 

56 -------- 

57 .. code-block:: python 

58 

59 ExposureF.getCalib = deprecate_pybind11(ExposureF.getCalib, 

60 reason="Replaced by getPhotoCalib. (Will be removed in 18.0)", 

61 version="17.0", category=FutureWarning)) 

62 """ 

63 

64 @functools.wraps(obj) 

65 def internal(*args: Any, **kwargs: Any) -> Any: 

66 return obj(*args, **kwargs) 

67 

68 # Typeshed seems to have an incorrect definition for the deprecated 

69 # function and believes the category should be 

70 # Optional[Type[DeprecationWarning]] but this is wrong on two counts: 

71 # 1. None is not actually allowed. 

72 # 2. FutureWarning is explicitly allowed but that is not a subclass 

73 # of DeprecationWarning. 

74 # This has been fixed upstream at 

75 # https://github.com/python/typeshed/pull/593 

76 # and will pass once that is released. 

77 return deprecated.sphinx.deprecated( 

78 reason=reason, 

79 version=version, 

80 category=category)(internal) 

81 

82 

83@contextmanager 

84def suppress_deprecations(category: Type[Warning] = FutureWarning) -> Iterator[None]: 

85 """Suppress warnings generated by `deprecated.sphinx.deprecated`. 

86 

87 Naively, one might attempt to suppress these warnings by using 

88 `~warnings.catch_warnings`. However, `~deprecated.sphinx.deprecated` 

89 attempts to install its own filter, overriding that. This convenience 

90 method works around this and properly suppresses the warnings by providing 

91 a mock `~warnings.simplefilter` for `~deprecated.sphinx.deprecated` to 

92 call. 

93 

94 Parameters 

95 ---------- 

96 category : `Warning` or subclass 

97 The category of warning to suppress. 

98 """ 

99 with warnings.catch_warnings(): 

100 warnings.simplefilter("ignore", category) 

101 with unittest.mock.patch.object(warnings, "simplefilter"): 

102 yield