Ticket #2491: deprecateFunction.patch

File deprecateFunction.patch, 7.3 KB (added by Michael, 6 years ago)
  • twisted/python/test/test_deprecate.py

     
    516516        warnings = self.flushWarnings([self.test_deprecatedModule])
    517517        self.assertEquals(len(warnings), 1)
    518518
     519
     520class TestDeprecateFunction(TestCase):
     521    """
     522    Tests for L{twisted.python.deprecate.deprecateFunction} which
     523    allows the callers of a function to issue a C{DeprecationWarning}.
     524    """
     525    def setUp(self):
     526        """
     527        Create a file that will have known line numbers when emitting warnings.
     528        """
     529        self.package = FilePath(self.mktemp()).child('twisted_private_helper')
     530        self.package.makedirs()
     531        self.package.child('__init__.py').setContent('')
     532        self.package.child('module.py').setContent('''
     533"A module string"
     534
     535from twisted.python import deprecate
     536
     537def testFunction():
     538    "A doc string"
     539    a = 1 + 2
     540    return a
     541
     542def callTestFunction():
     543    b = testFunction()
     544    if b == 3:
     545        deprecate.deprecateFunction(testFunction, "A Warning String")
     546''')
     547        sys.path.insert(0, self.package.parent().path)
     548        self.addCleanup(sys.path.remove, self.package.parent().path)
     549
     550
     551    def test_warning(self):
     552        def aFunc():
     553            pass
     554        deprecate.deprecateFunction(aFunc, 'A Warning Message')
     555        warnings = self.flushWarnings()
     556        filename = __file__
     557        if filename.lower().endswith('.pyc'):
     558            filename = filename[:-1]
     559        self.assertEquals(warnings[0]["filename"], filename)
     560        self.assertEquals(warnings[0]["message"], "A Warning Message")
     561
     562    def test_warning_lineno(self):
     563        """
     564        L{twisted.python.deprecate.deprecateFunction} should emit a
     565        C{DeprecationWarning} with a lineno of 9 rather than a lineno
     566        of 12.
     567        """
     568        from twisted_private_helper import module
     569        module.callTestFunction()
     570        warnings = self.flushWarnings()
     571        self.assertEquals(warnings[0]["filename"], self.package.dirname()+'/twisted_private_helper/module.py')
     572        self.assertEquals(warnings[0]["lineno"], 9)
     573        self.assertEquals(warnings[0]["message"], "A Warning String")
     574        self.assertEquals(len(warnings), 1)
     575
     576
     577    def test_renamedFile(self):
     578        """
     579        L{twisted.python.deprecate.deprecateFunction} should emit a
     580        C{DeprecationWarning} with a lineno of 9 rather than a lineno
     581        of 12.
     582        """
     583        from twisted_private_helper import module
     584        # Clean up the state resulting from that import; we're not going to use
     585        # this module, so it should go away.
     586        del sys.modules['twisted_private_helper']
     587        del sys.modules[module.__name__]
     588
     589        # Rename the source directory
     590        self.package.moveTo(self.package.sibling('twisted_renamed_helper'))
     591
     592        # Import the newly renamed version
     593        from twisted_renamed_helper import module
     594        self.addCleanup(sys.modules.pop, 'twisted_renamed_helper')
     595        self.addCleanup(sys.modules.pop, module.__name__)
     596
     597        module.callTestFunction()
     598        warnings = self.flushWarnings()
     599        self.assertEquals(warnings[0]["filename"], self.package.dirname()+'/twisted_renamed_helper/module.py')
     600        self.assertEquals(warnings[0]["lineno"], 9)
     601        self.assertEquals(warnings[0]["message"], "A Warning String")
     602        self.assertEquals(len(warnings), 1)
     603
  • twisted/python/deprecate.py

     
    5555
    5656
    5757import sys, inspect
    58 from warnings import warn
     58from warnings import warn, warn_explicit
     59from dis import findlinestarts
    5960
    6061from twisted.python.versions import getVersionString
    6162from twisted.python.util import mergeFunctionMetadata
     
    448449        sys.modules[moduleName] = module
    449450
    450451    _deprecateAttribute(module, name, version, message)
     452
     453
     454def deprecateFunction(offender, warningString):
     455    """
     456    Declare a Function Deprecated.
     457
     458    This function is used by the caller of a function to deprecate a
     459    function at runtime depending on the return value. The warning
     460    that is issued refers to the function being deprecated rather than
     461    the function doing the deprecating.
     462
     463    @type function: C{object}
     464    @param function: The callable that is being deprecated.
     465
     466    @type warningString: C{str}
     467    @param warningString: The string that should be emitted by this warning
     468    """
     469    # inspect.getmodule() is attractive, but somewhat
     470    # broken in Python < 2.6.  See Python bug 4845.
     471
     472    offenderModule = sys.modules[offender.__module__]
     473    filename = inspect.getabsfile(offenderModule)
     474    lineStarts = list(findlinestarts(offender.func_code))
     475    lastLineNo = lineStarts[-1][1]
     476
     477    kwargs = dict(category=DeprecationWarning,
     478        filename=filename,
     479        lineno=lastLineNo,
     480        module=offenderModule.__name__,
     481        registry=getattr(offenderModule, "__warningregistry__", {}),
     482        module_globals=offenderModule.__dict__)
     483
     484    if sys.version < (2,5):
     485        kwargs.pop('module_globals')
     486    warn_explicit(warningString, **kwargs)
  • twisted/internet/tcp.py

     
    1313
    1414# System Imports
    1515import os
    16 import inspect
    1716import types
    1817import socket
    1918import sys
     
    462461        rval = self.protocol.dataReceived(data)
    463462        if rval is not None:
    464463            offender = self.protocol.dataReceived
    465             module = inspect.getmodule(offender)
    466464            warningFormat = (
    467                 'Returning a value other than None from dataReceived is '
     465                'Returning a value other than None from %(fqpn)s is '
    468466                'deprecated since %(version)s.')
    469467            warningString = deprecate.getDeprecationWarningString(
    470468                offender, versions.Version('Twisted', 11, 0, 0),
    471469                format=warningFormat)
    472             warnings.warn_explicit(
    473                 warningString, category=DeprecationWarning,
    474                 filename=inspect.getsourcefile(offender),
    475                 lineno=149,
    476                 module=module.__name__,
    477                 registry=getattr(module, "__warningregistry__", {}),
    478                 module_globals=module.__dict__)
    479 
     470            deprecate.deprecateFunction(offender, warningString)
    480471        return rval
    481472
    482473
  • twisted/trial/unittest.py

     
    930930                    # better (or at least agrees with the warning system
    931931                    # more often), and does some normalization for us which
    932932                    # is desirable.  inspect.getmodule() is attractive, but
    933                     # somewhat broken in Python 2.3.  See Python bug 4845.
     933                    # somewhat broken in Python < 2.6.  See Python bug 4845.
    934934                    aModule = sys.modules[aFunction.__module__]
    935935                    filename = inspect.getabsfile(aModule)
    936936