| OLD | NEW |
| (Empty) |
| 1 # -*- test-case-name: twisted.python.test.test_deprecate -*- | |
| 2 | |
| 3 # Copyright (c) 2008 Twisted Matrix Laboratories. | |
| 4 # See LICENSE for details. | |
| 5 | |
| 6 | |
| 7 """ | |
| 8 Deprecation framework for Twisted. | |
| 9 | |
| 10 To mark a method or function as being deprecated do this:: | |
| 11 | |
| 12 def badAPI(self, first, second): | |
| 13 ''' | |
| 14 Docstring for badAPI. | |
| 15 ''' | |
| 16 ... | |
| 17 badAPI = deprecate(Version("Twisted", 8, 0, 0))(badAPI) | |
| 18 | |
| 19 The newly-decorated badAPI will issue a warning when called. It will also have | |
| 20 a deprecation notice appended to its docstring. | |
| 21 | |
| 22 See also L{Version}. | |
| 23 """ | |
| 24 | |
| 25 | |
| 26 __all__ = [ | |
| 27 'deprecated', | |
| 28 'getDeprecationWarningString', | |
| 29 'getWarningMethod', | |
| 30 'setWarningMethod', | |
| 31 ] | |
| 32 | |
| 33 | |
| 34 from warnings import warn | |
| 35 | |
| 36 from twisted.python.versions import getVersionString, Version | |
| 37 from twisted.python.reflect import qual | |
| 38 from twisted.python.util import mergeFunctionMetadata | |
| 39 | |
| 40 | |
| 41 def getWarningMethod(): | |
| 42 """ | |
| 43 Return the warning method currently used to record deprecation warnings. | |
| 44 """ | |
| 45 return warn | |
| 46 | |
| 47 | |
| 48 | |
| 49 def setWarningMethod(newMethod): | |
| 50 """ | |
| 51 Set the warning method to use to record deprecation warnings. | |
| 52 | |
| 53 The callable should take message, category and stacklevel. The return | |
| 54 value is ignored. | |
| 55 """ | |
| 56 global warn | |
| 57 warn = newMethod | |
| 58 | |
| 59 | |
| 60 | |
| 61 def _getDeprecationDocstring(version): | |
| 62 return "Deprecated in %s." % getVersionString(version) | |
| 63 | |
| 64 | |
| 65 | |
| 66 def getDeprecationWarningString(callableThing, version): | |
| 67 """ | |
| 68 Return a string indicating that the callable was deprecated in the given | |
| 69 version. | |
| 70 | |
| 71 @param callableThing: A callable to be deprecated. | |
| 72 @param version: The L{twisted.python.versions.Version} that the callable | |
| 73 was deprecated in. | |
| 74 @return: A string describing the deprecation. | |
| 75 """ | |
| 76 return "%s was deprecated in %s" % ( | |
| 77 qual(callableThing), getVersionString(version)) | |
| 78 | |
| 79 | |
| 80 | |
| 81 def deprecated(version): | |
| 82 """ | |
| 83 Return a decorator that marks callables as deprecated. | |
| 84 """ | |
| 85 | |
| 86 def deprecationDecorator(function): | |
| 87 """ | |
| 88 Decorator that marks C{function} as deprecated. | |
| 89 """ | |
| 90 | |
| 91 warningString = getDeprecationWarningString(function, version) | |
| 92 | |
| 93 def deprecatedFunction(*args, **kwargs): | |
| 94 warn( | |
| 95 warningString, | |
| 96 DeprecationWarning, | |
| 97 stacklevel=2) | |
| 98 return function(*args, **kwargs) | |
| 99 | |
| 100 deprecatedFunction = mergeFunctionMetadata( | |
| 101 function, deprecatedFunction) | |
| 102 _appendToDocstring(deprecatedFunction, | |
| 103 _getDeprecationDocstring(version)) | |
| 104 deprecatedFunction.deprecatedVersion = version | |
| 105 return deprecatedFunction | |
| 106 | |
| 107 return deprecationDecorator | |
| 108 | |
| 109 | |
| 110 | |
| 111 def _appendToDocstring(thingWithDoc, textToAppend): | |
| 112 """ | |
| 113 Append the given text to the docstring of C{thingWithDoc}. | |
| 114 | |
| 115 If C{thingWithDoc} has no docstring, then the text just replaces the | |
| 116 docstring. If it has a single-line docstring then it appends a blank line | |
| 117 and the message text. If it has a multi-line docstring, then in appends a | |
| 118 blank line a the message text, and also does the indentation correctly. | |
| 119 """ | |
| 120 if thingWithDoc.__doc__: | |
| 121 docstringLines = thingWithDoc.__doc__.splitlines() | |
| 122 else: | |
| 123 docstringLines = [] | |
| 124 | |
| 125 if len(docstringLines) == 0: | |
| 126 docstringLines.append(textToAppend) | |
| 127 elif len(docstringLines) == 1: | |
| 128 docstringLines.extend(['', textToAppend, '']) | |
| 129 else: | |
| 130 spaces = docstringLines.pop() | |
| 131 docstringLines.extend(['', | |
| 132 spaces + textToAppend, | |
| 133 spaces]) | |
| 134 thingWithDoc.__doc__ = '\n'.join(docstringLines) | |
| OLD | NEW |