Permalink
Browse files

Merge deprecate-py3-6036-2.

Author: itamar
Review: exarkun
Fixes: #6036

twisted.python.deprecate now runs on Python 3.


git-svn-id: svn://svn.twistedmatrix.com/svn/Twisted/trunk@35927 bbbe8e31-12d6-0310-92fd-ac37d47ddeeb
  • Loading branch information...
1 parent e573dfe commit 907b1650b7125683246690212c4c84d1b14782f3 itamarst committed Oct 3, 2012
View
5 admin/_twistedpython3.py
@@ -40,7 +40,7 @@
"twisted.python.compat",
"twisted.python.components",
"twisted.python.context",
- "twisted.python._deprecatepy3",
+ "twisted.python.deprecate",
"twisted.python.failure",
# filepaths depends on twisted.python.win32 which hasn't yet been ported,
# but works well enough to be imported:
@@ -50,6 +50,7 @@
"twisted.python._reflectpy3",
"twisted.python.runtime",
"twisted.python.test",
+ "twisted.python.test.deprecatedattributes",
"twisted.python.test.modules_helpers",
"twisted.python.threadable",
"twisted.python.threadpool",
@@ -86,7 +87,7 @@
"twisted.internet.test.test_utilspy3",
"twisted.protocols.test.test_basic",
"twisted.python.test.test_components",
- "twisted.python.test.test_deprecatepy3",
+ "twisted.python.test.test_deprecate",
"twisted.python.test.test_reflectpy3",
"twisted.python.test.test_runtime",
"twisted.python.test.test_utilpy3",
View
2 twisted/internet/test/reactormixins.py
@@ -25,7 +25,7 @@
from twisted.trial.util import DEFAULT_TIMEOUT_DURATION, acquireAttribute
from twisted.python.runtime import platform
from twisted.python._reflectpy3 import namedAny
-from twisted.python._deprecatepy3 import _fullyQualifiedName as fullyQualifiedName
+from twisted.python.deprecate import _fullyQualifiedName as fullyQualifiedName
from twisted.python import log
from twisted.python.failure import Failure
View
230 twisted/python/_deprecatepy3.py
@@ -1,230 +0,0 @@
-# -*- test-case-name: twisted.python.test.test_deprecatepy3 -*-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-The parts of L{twisted.python.deprecate} which have been ported to Python 3.
-"""
-
-from __future__ import division, absolute_import
-
-import inspect
-from functools import wraps
-from warnings import warn
-
-from twisted.python.versions import getVersionString
-
-DEPRECATION_WARNING_FORMAT = '%(fqpn)s was deprecated in %(version)s'
-
-# Notionally, part of twisted.python.reflect, but defining it there causes a
-# cyclic dependency between this module and that module. Define it here,
-# instead, and let reflect import it to re-expose to the public.
-def _fullyQualifiedName(obj):
- """
- Return the fully qualified name of a module, class, method or function.
- Classes and functions need to be module level ones to be correctly
- qualified.
-
- @rtype: C{str}.
- """
- try:
- name = obj.__qualname__
- except AttributeError:
- name = obj.__name__
-
- if inspect.isclass(obj) or inspect.isfunction(obj):
- moduleName = obj.__module__
- return "%s.%s" % (moduleName, name)
- elif inspect.ismethod(obj):
- try:
- cls = obj.im_class
- except AttributeError:
- # Python 3 eliminates im_class, substitutes __module__ and
- # __qualname__ to provide similar information.
- return "%s.%s" % (obj.__module__, obj.__qualname__)
- else:
- className = _fullyQualifiedName(cls)
- return "%s.%s" % (className, name)
- return name
-# Try to keep it looking like something in twisted.python.reflect.
-_fullyQualifiedName.__module__ = 'twisted.python.reflect'
-_fullyQualifiedName.__name__ = 'fullyQualifiedName'
-_fullyQualifiedName.__qualname__ = 'fullyQualifiedName'
-
-
-def _getReplacementString(replacement):
- """
- Surround a replacement for a deprecated API with some polite text exhorting
- the user to consider it as an alternative.
-
- @type replacement: C{str} or callable
-
- @return: a string like "please use twisted.python.modules.getModule
- instead".
- """
- if callable(replacement):
- replacement = _fullyQualifiedName(replacement)
- return "please use %s instead" % (replacement,)
-
-
-
-def _getDeprecationDocstring(version, replacement=None):
- """
- Generate an addition to a deprecated object's docstring that explains its
- deprecation.
-
- @param version: the version it was deprecated.
- @type version: L{Version}
-
- @param replacement: The replacement, if specified.
- @type replacement: C{str} or callable
-
- @return: a string like "Deprecated in Twisted 27.2.0; please use
- twisted.timestream.tachyon.flux instead."
- """
- doc = "Deprecated in %s" % (getVersionString(version),)
- if replacement:
- doc = "%s; %s" % (doc, _getReplacementString(replacement))
- return doc + "."
-
-
-
-def _getDeprecationWarningString(fqpn, version, format=None, replacement=None):
- """
- Return a string indicating that the Python name was deprecated in the given
- version.
-
- @param fqpn: Fully qualified Python name of the thing being deprecated
- @type fqpn: C{str}
-
- @param version: Version that C{fqpn} was deprecated in.
- @type version: L{twisted.python.versions.Version}
-
- @param format: A user-provided format to interpolate warning values into, or
- L{DEPRECATION_WARNING_FORMAT
- <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
- given.
- @type format: C{str}
-
- @param replacement: what should be used in place of C{fqpn}. Either pass in
- a string, which will be inserted into the warning message, or a
- callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
-
- @return: A textual description of the deprecation
- @rtype: C{str}
- """
- if format is None:
- format = DEPRECATION_WARNING_FORMAT
- warningString = format % {
- 'fqpn': fqpn,
- 'version': getVersionString(version)}
- if replacement:
- warningString = "%s; %s" % (
- warningString, _getReplacementString(replacement))
- return warningString
-
-
-
-def getDeprecationWarningString(callableThing, version, format=None,
- replacement=None):
- """
- Return a string indicating that the callable was deprecated in the given
- version.
-
- @type callableThing: C{callable}
- @param callableThing: Callable object to be deprecated
-
- @type version: L{twisted.python.versions.Version}
- @param version: Version that C{callableThing} was deprecated in
-
- @type format: C{str}
- @param format: A user-provided format to interpolate warning values into,
- or L{DEPRECATION_WARNING_FORMAT
- <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
- given
-
- @param callableThing: A callable to be deprecated.
-
- @param version: The L{twisted.python.versions.Version} that the callable
- was deprecated in.
-
- @param replacement: what should be used in place of the callable. Either
- pass in a string, which will be inserted into the warning message,
- or a callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
-
- @return: A string describing the deprecation.
- @rtype: C{str}
- """
- return _getDeprecationWarningString(
- _fullyQualifiedName(callableThing), version, format, replacement)
-
-
-
-def _appendToDocstring(thingWithDoc, textToAppend):
- """
- Append the given text to the docstring of C{thingWithDoc}.
-
- If C{thingWithDoc} has no docstring, then the text just replaces the
- docstring. If it has a single-line docstring then it appends a blank line
- and the message text. If it has a multi-line docstring, then in appends a
- blank line a the message text, and also does the indentation correctly.
- """
- if thingWithDoc.__doc__:
- docstringLines = thingWithDoc.__doc__.splitlines()
- else:
- docstringLines = []
-
- if len(docstringLines) == 0:
- docstringLines.append(textToAppend)
- elif len(docstringLines) == 1:
- docstringLines.extend(['', textToAppend, ''])
- else:
- spaces = docstringLines.pop()
- docstringLines.extend(['',
- spaces + textToAppend,
- spaces])
- thingWithDoc.__doc__ = '\n'.join(docstringLines)
-
-
-
-def deprecated(version, replacement=None):
- """
- Return a decorator that marks callables as deprecated.
-
- @type version: L{twisted.python.versions.Version}
- @param version: The version in which the callable will be marked as
- having been deprecated. The decorated function will be annotated
- with this version, having it set as its C{deprecatedVersion}
- attribute.
-
- @param version: the version that the callable was deprecated in.
- @type version: L{twisted.python.versions.Version}
-
- @param replacement: what should be used in place of the callable. Either
- pass in a string, which will be inserted into the warning message,
- or a callable, which will be expanded to its full import path.
- @type replacement: C{str} or callable
- """
- def deprecationDecorator(function):
- """
- Decorator that marks C{function} as deprecated.
- """
- warningString = getDeprecationWarningString(
- function, version, None, replacement)
-
- @wraps(function)
- def deprecatedFunction(*args, **kwargs):
- warn(
- warningString,
- DeprecationWarning,
- stacklevel=2)
- return function(*args, **kwargs)
-
- _appendToDocstring(deprecatedFunction,
- _getDeprecationDocstring(version, replacement))
- deprecatedFunction.deprecatedVersion = version
- return deprecatedFunction
-
- return deprecationDecorator
View
226 twisted/python/deprecate.py
@@ -44,6 +44,7 @@ def badAPI(self, first, second):
to use when one is not provided by the user.
"""
+from __future__ import division, absolute_import
__all__ = [
'deprecated',
@@ -57,10 +58,225 @@ def badAPI(self, first, second):
import sys, inspect
from warnings import warn, warn_explicit
from dis import findlinestarts
+from functools import wraps
+
+from twisted.python.versions import getVersionString
+
+DEPRECATION_WARNING_FORMAT = '%(fqpn)s was deprecated in %(version)s'
+
+# Notionally, part of twisted.python.reflect, but defining it there causes a
+# cyclic dependency between this module and that module. Define it here,
+# instead, and let reflect import it to re-expose to the public.
+def _fullyQualifiedName(obj):
+ """
+ Return the fully qualified name of a module, class, method or function.
+ Classes and functions need to be module level ones to be correctly
+ qualified.
+
+ @rtype: C{str}.
+ """
+ try:
+ name = obj.__qualname__
+ except AttributeError:
+ name = obj.__name__
+
+ if inspect.isclass(obj) or inspect.isfunction(obj):
+ moduleName = obj.__module__
+ return "%s.%s" % (moduleName, name)
+ elif inspect.ismethod(obj):
+ try:
+ cls = obj.im_class
+ except AttributeError:
+ # Python 3 eliminates im_class, substitutes __module__ and
+ # __qualname__ to provide similar information.
+ return "%s.%s" % (obj.__module__, obj.__qualname__)
+ else:
+ className = _fullyQualifiedName(cls)
+ return "%s.%s" % (className, name)
+ return name
+# Try to keep it looking like something in twisted.python.reflect.
+_fullyQualifiedName.__module__ = 'twisted.python.reflect'
+_fullyQualifiedName.__name__ = 'fullyQualifiedName'
+_fullyQualifiedName.__qualname__ = 'fullyQualifiedName'
+
+
+def _getReplacementString(replacement):
+ """
+ Surround a replacement for a deprecated API with some polite text exhorting
+ the user to consider it as an alternative.
+
+ @type replacement: C{str} or callable
+
+ @return: a string like "please use twisted.python.modules.getModule
+ instead".
+ """
+ if callable(replacement):
+ replacement = _fullyQualifiedName(replacement)
+ return "please use %s instead" % (replacement,)
+
+
+
+def _getDeprecationDocstring(version, replacement=None):
+ """
+ Generate an addition to a deprecated object's docstring that explains its
+ deprecation.
+
+ @param version: the version it was deprecated.
+ @type version: L{Version}
+
+ @param replacement: The replacement, if specified.
+ @type replacement: C{str} or callable
+
+ @return: a string like "Deprecated in Twisted 27.2.0; please use
+ twisted.timestream.tachyon.flux instead."
+ """
+ doc = "Deprecated in %s" % (getVersionString(version),)
+ if replacement:
+ doc = "%s; %s" % (doc, _getReplacementString(replacement))
+ return doc + "."
+
+
+
+def _getDeprecationWarningString(fqpn, version, format=None, replacement=None):
+ """
+ Return a string indicating that the Python name was deprecated in the given
+ version.
+
+ @param fqpn: Fully qualified Python name of the thing being deprecated
+ @type fqpn: C{str}
+
+ @param version: Version that C{fqpn} was deprecated in.
+ @type version: L{twisted.python.versions.Version}
+
+ @param format: A user-provided format to interpolate warning values into, or
+ L{DEPRECATION_WARNING_FORMAT
+ <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
+ given.
+ @type format: C{str}
+
+ @param replacement: what should be used in place of C{fqpn}. Either pass in
+ a string, which will be inserted into the warning message, or a
+ callable, which will be expanded to its full import path.
+ @type replacement: C{str} or callable
+
+ @return: A textual description of the deprecation
+ @rtype: C{str}
+ """
+ if format is None:
+ format = DEPRECATION_WARNING_FORMAT
+ warningString = format % {
+ 'fqpn': fqpn,
+ 'version': getVersionString(version)}
+ if replacement:
+ warningString = "%s; %s" % (
+ warningString, _getReplacementString(replacement))
+ return warningString
+
+
+
+def getDeprecationWarningString(callableThing, version, format=None,
+ replacement=None):
+ """
+ Return a string indicating that the callable was deprecated in the given
+ version.
+
+ @type callableThing: C{callable}
+ @param callableThing: Callable object to be deprecated
+
+ @type version: L{twisted.python.versions.Version}
+ @param version: Version that C{callableThing} was deprecated in
+
+ @type format: C{str}
+ @param format: A user-provided format to interpolate warning values into,
+ or L{DEPRECATION_WARNING_FORMAT
+ <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
+ given
+
+ @param callableThing: A callable to be deprecated.
+
+ @param version: The L{twisted.python.versions.Version} that the callable
+ was deprecated in.
+
+ @param replacement: what should be used in place of the callable. Either
+ pass in a string, which will be inserted into the warning message,
+ or a callable, which will be expanded to its full import path.
+ @type replacement: C{str} or callable
+
+ @return: A string describing the deprecation.
+ @rtype: C{str}
+ """
+ return _getDeprecationWarningString(
+ _fullyQualifiedName(callableThing), version, format, replacement)
+
+
+
+def _appendToDocstring(thingWithDoc, textToAppend):
+ """
+ Append the given text to the docstring of C{thingWithDoc}.
+
+ If C{thingWithDoc} has no docstring, then the text just replaces the
+ docstring. If it has a single-line docstring then it appends a blank line
+ and the message text. If it has a multi-line docstring, then in appends a
+ blank line a the message text, and also does the indentation correctly.
+ """
+ if thingWithDoc.__doc__:
+ docstringLines = thingWithDoc.__doc__.splitlines()
+ else:
+ docstringLines = []
+
+ if len(docstringLines) == 0:
+ docstringLines.append(textToAppend)
+ elif len(docstringLines) == 1:
+ docstringLines.extend(['', textToAppend, ''])
+ else:
+ spaces = docstringLines.pop()
+ docstringLines.extend(['',
+ spaces + textToAppend,
+ spaces])
+ thingWithDoc.__doc__ = '\n'.join(docstringLines)
+
+
+
+def deprecated(version, replacement=None):
+ """
+ Return a decorator that marks callables as deprecated.
+
+ @type version: L{twisted.python.versions.Version}
+ @param version: The version in which the callable will be marked as
+ having been deprecated. The decorated function will be annotated
+ with this version, having it set as its C{deprecatedVersion}
+ attribute.
+
+ @param version: the version that the callable was deprecated in.
+ @type version: L{twisted.python.versions.Version}
+
+ @param replacement: what should be used in place of the callable. Either
+ pass in a string, which will be inserted into the warning message,
+ or a callable, which will be expanded to its full import path.
+ @type replacement: C{str} or callable
+ """
+ def deprecationDecorator(function):
+ """
+ Decorator that marks C{function} as deprecated.
+ """
+ warningString = getDeprecationWarningString(
+ function, version, None, replacement)
+
+ @wraps(function)
+ def deprecatedFunction(*args, **kwargs):
+ warn(
+ warningString,
+ DeprecationWarning,
+ stacklevel=2)
+ return function(*args, **kwargs)
+
+ _appendToDocstring(deprecatedFunction,
+ _getDeprecationDocstring(version, replacement))
+ deprecatedFunction.deprecatedVersion = version
+ return deprecatedFunction
+
+ return deprecationDecorator
-from twisted.python._deprecatepy3 import (
- DEPRECATION_WARNING_FORMAT, deprecated, getDeprecationWarningString,
- _getDeprecationWarningString)
def getWarningMethod():
@@ -308,9 +524,9 @@ def warnAboutFunction(offender, warningString):
# broken in Python < 2.6. See Python bug 4845.
offenderModule = sys.modules[offender.__module__]
filename = inspect.getabsfile(offenderModule)
- lineStarts = list(findlinestarts(offender.func_code))
+ lineStarts = list(findlinestarts(offender.__code__))
lastLineNo = lineStarts[-1][1]
- globals = offender.func_globals
+ globals = offender.__globals__
kwargs = dict(
category=DeprecationWarning,
View
3 twisted/python/reflect.py
@@ -10,7 +10,6 @@
import sys
import types
import pickle
-import traceback
import weakref
import re
import warnings
@@ -30,7 +29,7 @@
from twisted.python._utilpy3 import unsignedID
from twisted.python.deprecate import deprecated, deprecatedModuleAttribute
-from twisted.python._deprecatepy3 import _fullyQualifiedName as fullyQualifiedName
+from twisted.python.deprecate import _fullyQualifiedName as fullyQualifiedName
from twisted.python.versions import Version
from twisted.python._reflectpy3 import prefixedMethods, accumulateMethods
View
13 twisted/python/test/deprecatedattributes.py
@@ -1,6 +1,13 @@
-# Import reflect first, so that circular imports (between deprecate and
-# reflect) don't cause headaches.
-import twisted.python.reflect
+# Copyright (c) Twisted Matrix Laboratories.
+# See LICENSE for details.
+
+"""
+A module that is deprecated, used by L{twisted.python.test.test_deprecate} for
+testing purposes.
+"""
+
+from __future__ import division, absolute_import
+
from twisted.python.versions import Version
from twisted.python.deprecate import deprecatedModuleAttribute
View
328 twisted/python/test/test_deprecate.py
@@ -5,19 +5,35 @@
Tests for Twisted's deprecation framework, L{twisted.python.deprecate}.
"""
+from __future__ import division, absolute_import
+
import sys, types, warnings
from os.path import normcase
+from warnings import simplefilter, catch_warnings
+try:
+ from importlib import invalidate_caches
+except ImportError:
+ invalidate_caches = None
from twisted.python import deprecate
from twisted.python.deprecate import _getDeprecationWarningString
from twisted.python.deprecate import DEPRECATION_WARNING_FORMAT
+from twisted.python.deprecate import (
+ getDeprecationWarningString,
+ deprecated, _appendToDocstring, _getDeprecationDocstring,
+ _fullyQualifiedName as fullyQualifiedName)
+
from twisted.python.versions import Version
from twisted.python.filepath import FilePath
from twisted.python.test import deprecatedattributes
from twisted.python.test.modules_helpers import TwistedModulesMixin
-from twisted.trial.unittest import TestCase
+from twisted.trial.unittest import SynchronousTestCase
+
+# Note that various tests in this module require manual encoding of paths to
+# utf-8. This can be fixed once FilePath supports Unicode; see #2366, #4736,
+# #5203.
class _MockDeprecatedAttribute(object):
@@ -38,7 +54,7 @@ def get(self):
-class ModuleProxyTests(TestCase):
+class ModuleProxyTests(SynchronousTestCase):
"""
Tests for L{twisted.python.deprecate._ModuleProxy}, which proxies
access to module-level attributes, intercepting access to deprecated
@@ -53,7 +69,7 @@ def _makeProxy(self, **attrs):
@rtype: L{twistd.python.deprecate._ModuleProxy}
"""
mod = types.ModuleType('foo')
- for key, value in attrs.iteritems():
+ for key, value in attrs.items():
setattr(mod, key, value)
return deprecate._ModuleProxy(mod)
@@ -117,7 +133,7 @@ def test_repr(self):
-class DeprecatedAttributeTests(TestCase):
+class DeprecatedAttributeTests(SynchronousTestCase):
"""
Tests for L{twisted.python.deprecate._DeprecatedAttribute} and
L{twisted.python.deprecate.deprecatedModuleAttribute}, which issue
@@ -226,7 +242,7 @@ def test_wrappedModule(self):
-class ImportedModuleAttributeTests(TwistedModulesMixin, TestCase):
+class ImportedModuleAttributeTests(TwistedModulesMixin, SynchronousTestCase):
"""
Tests for L{deprecatedModuleAttribute} which involve loading a module via
'import'.
@@ -259,7 +275,7 @@ def makeSomeFiles(pathobj, dirdict):
pathdict = {}
for (key, value) in dirdict.items():
child = pathobj.child(key)
- if isinstance(value, str):
+ if isinstance(value, bytes):
pathdict[key] = child
child.setContent(value)
elif isinstance(value, dict):
@@ -268,11 +284,12 @@ def makeSomeFiles(pathobj, dirdict):
else:
raise ValueError("only strings and dicts allowed as values")
return pathdict
- base = FilePath(self.mktemp())
+ base = FilePath(self.mktemp().encode("utf-8"))
base.makedirs()
result = makeSomeFiles(base, tree)
- self.replaceSysPath([base.path] + sys.path)
+ # On Python 3, sys.path cannot include byte paths:
+ self.replaceSysPath([base.path.decode("utf-8")] + sys.path)
self.replaceSysModules(sys.modules.copy())
return result
@@ -283,18 +300,18 @@ def simpleModuleEntry(self):
pointing at the module which will be loadable as C{package.module}.
"""
paths = self.pathEntryTree(
- {"package": {"__init__.py": self._packageInit,
- "module.py": ""}})
- return paths['package']['module.py']
+ {b"package": {b"__init__.py": self._packageInit.encode("utf-8"),
+ b"module.py": b""}})
+ return paths[b'package'][b'module.py']
def checkOneWarning(self, modulePath):
"""
Verification logic for L{test_deprecatedModule}.
"""
- # import package.module
from package import module
- self.assertEqual(module.__file__, modulePath.path)
+ self.assertEqual(FilePath(module.__file__.encode("utf-8")),
+ modulePath)
emitted = self.flushWarnings([self.checkOneWarning])
self.assertEqual(len(emitted), 1)
self.assertEqual(emitted[0]['message'],
@@ -334,7 +351,7 @@ def test_deprecatedModuleMultipleTimes(self):
-class WarnAboutFunctionTests(TestCase):
+class WarnAboutFunctionTests(SynchronousTestCase):
"""
Tests for L{twisted.python.deprecate.warnAboutFunction} which allows the
callers of a function to issue a C{DeprecationWarning} about that function.
@@ -343,10 +360,11 @@ def setUp(self):
"""
Create a file that will have known line numbers when emitting warnings.
"""
- self.package = FilePath(self.mktemp()).child('twisted_private_helper')
+ self.package = FilePath(self.mktemp().encode("utf-8")
+ ).child(b'twisted_private_helper')
self.package.makedirs()
- self.package.child('__init__.py').setContent('')
- self.package.child('module.py').setContent('''
+ self.package.child(b'__init__.py').setContent(b'')
+ self.package.child(b'module.py').setContent(b'''
"A module string"
from twisted.python import deprecate
@@ -361,8 +379,10 @@ def callTestFunction():
if b == 3:
deprecate.warnAboutFunction(testFunction, "A Warning String")
''')
- sys.path.insert(0, self.package.parent().path)
- self.addCleanup(sys.path.remove, self.package.parent().path)
+ # Python 3 doesn't accept bytes in sys.path:
+ packagePath = self.package.parent().path.decode("utf-8")
+ sys.path.insert(0, packagePath)
+ self.addCleanup(sys.path.remove, packagePath)
modules = sys.modules.copy()
self.addCleanup(
@@ -396,8 +416,8 @@ def test_warningLineNumber(self):
module.callTestFunction()
warningsShown = self.flushWarnings()
self.assertSamePath(
- FilePath(warningsShown[0]["filename"]),
- self.package.sibling('twisted_private_helper').child('module.py'))
+ FilePath(warningsShown[0]["filename"].encode("utf-8")),
+ self.package.sibling(b'twisted_private_helper').child(b'module.py'))
# Line number 9 is the last line in the testFunction in the helper
# module.
self.assertEqual(warningsShown[0]["lineno"], 9)
@@ -434,7 +454,11 @@ def test_renamedFile(self):
del sys.modules[module.__name__]
# Rename the source directory
- self.package.moveTo(self.package.sibling('twisted_renamed_helper'))
+ self.package.moveTo(self.package.sibling(b'twisted_renamed_helper'))
+
+ # Make sure importlib notices we've changed importable packages:
+ if invalidate_caches:
+ invalidate_caches()
# Import the newly renamed version
from twisted_renamed_helper import module
@@ -443,9 +467,9 @@ def test_renamedFile(self):
module.callTestFunction()
warningsShown = self.flushWarnings()
- warnedPath = FilePath(warningsShown[0]["filename"])
+ warnedPath = FilePath(warningsShown[0]["filename"].encode("utf-8"))
expectedPath = self.package.sibling(
- 'twisted_renamed_helper').child('module.py')
+ b'twisted_renamed_helper').child(b'module.py')
self.assertSamePath(warnedPath, expectedPath)
self.assertEqual(warningsShown[0]["lineno"], 9)
self.assertEqual(warningsShown[0]["message"], "A Warning String")
@@ -502,3 +526,259 @@ def test_filteredOnceWarning(self):
msg.endswith("module.py:9: DeprecationWarning: A Warning String\n"
" return a\n"),
"Unexpected warning string: %r" % (msg,))
+
+
+def dummyCallable():
+ """
+ Do nothing.
+
+ This is used to test the deprecation decorators.
+ """
+
+
+
+def dummyReplacementMethod():
+ """
+ Do nothing.
+
+ This is used to test the replacement parameter to L{deprecated}.
+ """
+
+
+
+class TestDeprecationWarnings(SynchronousTestCase):
+ def test_getDeprecationWarningString(self):
+ """
+ L{getDeprecationWarningString} returns a string that tells us that a
+ callable was deprecated at a certain released version of Twisted.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ self.assertEqual(
+ getDeprecationWarningString(self.test_getDeprecationWarningString,
+ version),
+ "%s.TestDeprecationWarnings.test_getDeprecationWarningString "
+ "was deprecated in Twisted 8.0.0" % (__name__,))
+
+
+ def test_getDeprecationWarningStringWithFormat(self):
+ """
+ L{getDeprecationWarningString} returns a string that tells us that a
+ callable was deprecated at a certain released version of Twisted, with
+ a message containing additional information about the deprecation.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ format = DEPRECATION_WARNING_FORMAT + ': This is a message'
+ self.assertEqual(
+ getDeprecationWarningString(self.test_getDeprecationWarningString,
+ version, format),
+ '%s.TestDeprecationWarnings.test_getDeprecationWarningString was '
+ 'deprecated in Twisted 8.0.0: This is a message' % (__name__,))
+
+
+ def test_deprecateEmitsWarning(self):
+ """
+ Decorating a callable with L{deprecated} emits a warning.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ dummy = deprecated(version)(dummyCallable)
+ def addStackLevel():
+ dummy()
+ with catch_warnings(record=True) as caught:
+ simplefilter("always")
+ addStackLevel()
+ self.assertEqual(caught[0].category, DeprecationWarning)
+ self.assertEqual(str(caught[0].message), getDeprecationWarningString(dummyCallable, version))
+ # rstrip in case .pyc/.pyo
+ self.assertEqual(caught[0].filename.rstrip('co'), __file__.rstrip('co'))
+
+
+ def test_deprecatedPreservesName(self):
+ """
+ The decorated function has the same name as the original.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ dummy = deprecated(version)(dummyCallable)
+ self.assertEqual(dummyCallable.__name__, dummy.__name__)
+ self.assertEqual(fullyQualifiedName(dummyCallable),
+ fullyQualifiedName(dummy))
+
+
+ def test_getDeprecationDocstring(self):
+ """
+ L{_getDeprecationDocstring} returns a note about the deprecation to go
+ into a docstring.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ self.assertEqual(
+ "Deprecated in Twisted 8.0.0.",
+ _getDeprecationDocstring(version, ''))
+
+
+ def test_deprecatedUpdatesDocstring(self):
+ """
+ The docstring of the deprecated function is appended with information
+ about the deprecation.
+ """
+
+ version = Version('Twisted', 8, 0, 0)
+ dummy = deprecated(version)(dummyCallable)
+
+ _appendToDocstring(
+ dummyCallable,
+ _getDeprecationDocstring(version, ''))
+
+ self.assertEqual(dummyCallable.__doc__, dummy.__doc__)
+
+
+ def test_versionMetadata(self):
+ """
+ Deprecating a function adds version information to the decorated
+ version of that function.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ dummy = deprecated(version)(dummyCallable)
+ self.assertEqual(version, dummy.deprecatedVersion)
+
+
+ def test_getDeprecationWarningStringReplacement(self):
+ """
+ L{getDeprecationWarningString} takes an additional replacement parameter
+ that can be used to add information to the deprecation. If the
+ replacement parameter is a string, it will be interpolated directly into
+ the result.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ warningString = getDeprecationWarningString(
+ self.test_getDeprecationWarningString, version,
+ replacement="something.foobar")
+ self.assertEqual(
+ warningString,
+ "%s was deprecated in Twisted 8.0.0; please use something.foobar "
+ "instead" % (
+ fullyQualifiedName(self.test_getDeprecationWarningString),))
+
+
+ def test_getDeprecationWarningStringReplacementWithCallable(self):
+ """
+ L{getDeprecationWarningString} takes an additional replacement parameter
+ that can be used to add information to the deprecation. If the
+ replacement parameter is a callable, its fully qualified name will be
+ interpolated into the result.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ warningString = getDeprecationWarningString(
+ self.test_getDeprecationWarningString, version,
+ replacement=dummyReplacementMethod)
+ self.assertEqual(
+ warningString,
+ "%s was deprecated in Twisted 8.0.0; please use "
+ "%s.dummyReplacementMethod instead" % (
+ fullyQualifiedName(self.test_getDeprecationWarningString),
+ __name__))
+
+
+ def test_deprecatedReplacement(self):
+ """
+ L{deprecated} takes an additional replacement parameter that can be used
+ to indicate the new, non-deprecated method developers should use. If
+ the replacement parameter is a string, it will be interpolated directly
+ into the warning message.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ dummy = deprecated(version, "something.foobar")(dummyCallable)
+ self.assertEqual(dummy.__doc__,
+ "\n"
+ " Do nothing.\n\n"
+ " This is used to test the deprecation decorators.\n\n"
+ " Deprecated in Twisted 8.0.0; please use "
+ "something.foobar"
+ " instead.\n"
+ " ")
+
+
+ def test_deprecatedReplacementWithCallable(self):
+ """
+ L{deprecated} takes an additional replacement parameter that can be used
+ to indicate the new, non-deprecated method developers should use. If
+ the replacement parameter is a callable, its fully qualified name will
+ be interpolated into the warning message.
+ """
+ version = Version('Twisted', 8, 0, 0)
+ decorator = deprecated(version, replacement=dummyReplacementMethod)
+ dummy = decorator(dummyCallable)
+ self.assertEqual(dummy.__doc__,
+ "\n"
+ " Do nothing.\n\n"
+ " This is used to test the deprecation decorators.\n\n"
+ " Deprecated in Twisted 8.0.0; please use "
+ "%s.dummyReplacementMethod instead.\n"
+ " " % (__name__,))
+
+
+
+class TestAppendToDocstring(SynchronousTestCase):
+ """
+ Test the _appendToDocstring function.
+
+ _appendToDocstring is used to add text to a docstring.
+ """
+
+ def test_appendToEmptyDocstring(self):
+ """
+ Appending to an empty docstring simply replaces the docstring.
+ """
+
+ def noDocstring():
+ pass
+
+ _appendToDocstring(noDocstring, "Appended text.")
+ self.assertEqual("Appended text.", noDocstring.__doc__)
+
+
+ def test_appendToSingleLineDocstring(self):
+ """
+ Appending to a single line docstring places the message on a new line,
+ with a blank line separating it from the rest of the docstring.
+
+ The docstring ends with a newline, conforming to Twisted and PEP 8
+ standards. Unfortunately, the indentation is incorrect, since the
+ existing docstring doesn't have enough info to help us indent
+ properly.
+ """
+
+ def singleLineDocstring():
+ """This doesn't comply with standards, but is here for a test."""
+
+ _appendToDocstring(singleLineDocstring, "Appended text.")
+ self.assertEqual(
+ ["This doesn't comply with standards, but is here for a test.",
+ "",
+ "Appended text."],
+ singleLineDocstring.__doc__.splitlines())
+ self.assertTrue(singleLineDocstring.__doc__.endswith('\n'))
+
+
+ def test_appendToMultilineDocstring(self):
+ """
+ Appending to a multi-line docstring places the messade on a new line,
+ with a blank line separating it from the rest of the docstring.
+
+ Because we have multiple lines, we have enough information to do
+ indentation.
+ """
+
+ def multiLineDocstring():
+ """
+ This is a multi-line docstring.
+ """
+
+ def expectedDocstring():
+ """
+ This is a multi-line docstring.
+
+ Appended text.
+ """
+
+ _appendToDocstring(multiLineDocstring, "Appended text.")
+ self.assertEqual(
+ expectedDocstring.__doc__, multiLineDocstring.__doc__)
View
275 twisted/python/test/test_deprecatepy3.py
@@ -1,275 +0,0 @@
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-"""
-Tests for the parts of L{twisted.python._deprecatepy3}, the parts of
-L{twisted.python.deprecate} which have been ported to Python 3.
-"""
-
-from __future__ import division, absolute_import
-
-from warnings import simplefilter, catch_warnings
-
-from twisted.trial.unittest import SynchronousTestCase
-
-from twisted.python.versions import Version
-from twisted.python._deprecatepy3 import (
- DEPRECATION_WARNING_FORMAT, getDeprecationWarningString, deprecated,
- _appendToDocstring, _getDeprecationDocstring,
- _fullyQualifiedName as fullyQualifiedName)
-
-
-def dummyCallable():
- """
- Do nothing.
-
- This is used to test the deprecation decorators.
- """
-
-
-
-def dummyReplacementMethod():
- """
- Do nothing.
-
- This is used to test the replacement parameter to L{deprecated}.
- """
-
-
-
-class TestDeprecationWarnings(SynchronousTestCase):
- def test_getDeprecationWarningString(self):
- """
- L{getDeprecationWarningString} returns a string that tells us that a
- callable was deprecated at a certain released version of Twisted.
- """
- version = Version('Twisted', 8, 0, 0)
- self.assertEqual(
- getDeprecationWarningString(self.test_getDeprecationWarningString,
- version),
- "%s.TestDeprecationWarnings.test_getDeprecationWarningString "
- "was deprecated in Twisted 8.0.0" % (__name__,))
-
-
- def test_getDeprecationWarningStringWithFormat(self):
- """
- L{getDeprecationWarningString} returns a string that tells us that a
- callable was deprecated at a certain released version of Twisted, with
- a message containing additional information about the deprecation.
- """
- version = Version('Twisted', 8, 0, 0)
- format = DEPRECATION_WARNING_FORMAT + ': This is a message'
- self.assertEqual(
- getDeprecationWarningString(self.test_getDeprecationWarningString,
- version, format),
- '%s.TestDeprecationWarnings.test_getDeprecationWarningString was '
- 'deprecated in Twisted 8.0.0: This is a message' % (__name__,))
-
-
- def test_deprecateEmitsWarning(self):
- """
- Decorating a callable with L{deprecated} emits a warning.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- def addStackLevel():
- dummy()
- with catch_warnings(record=True) as caught:
- simplefilter("always")
- addStackLevel()
- self.assertEqual(caught[0].category, DeprecationWarning)
- self.assertEqual(str(caught[0].message), getDeprecationWarningString(dummyCallable, version))
- # rstrip in case .pyc/.pyo
- self.assertEqual(caught[0].filename.rstrip('co'), __file__.rstrip('co'))
-
-
- def test_deprecatedPreservesName(self):
- """
- The decorated function has the same name as the original.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- self.assertEqual(dummyCallable.__name__, dummy.__name__)
- self.assertEqual(fullyQualifiedName(dummyCallable),
- fullyQualifiedName(dummy))
-
-
- def test_getDeprecationDocstring(self):
- """
- L{_getDeprecationDocstring} returns a note about the deprecation to go
- into a docstring.
- """
- version = Version('Twisted', 8, 0, 0)
- self.assertEqual(
- "Deprecated in Twisted 8.0.0.",
- _getDeprecationDocstring(version, ''))
-
-
- def test_deprecatedUpdatesDocstring(self):
- """
- The docstring of the deprecated function is appended with information
- about the deprecation.
- """
-
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
-
- _appendToDocstring(
- dummyCallable,
- _getDeprecationDocstring(version, ''))
-
- self.assertEqual(dummyCallable.__doc__, dummy.__doc__)
-
-
- def test_versionMetadata(self):
- """
- Deprecating a function adds version information to the decorated
- version of that function.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version)(dummyCallable)
- self.assertEqual(version, dummy.deprecatedVersion)
-
-
- def test_getDeprecationWarningStringReplacement(self):
- """
- L{getDeprecationWarningString} takes an additional replacement parameter
- that can be used to add information to the deprecation. If the
- replacement parameter is a string, it will be interpolated directly into
- the result.
- """
- version = Version('Twisted', 8, 0, 0)
- warningString = getDeprecationWarningString(
- self.test_getDeprecationWarningString, version,
- replacement="something.foobar")
- self.assertEqual(
- warningString,
- "%s was deprecated in Twisted 8.0.0; please use something.foobar "
- "instead" % (
- fullyQualifiedName(self.test_getDeprecationWarningString),))
-
-
- def test_getDeprecationWarningStringReplacementWithCallable(self):
- """
- L{getDeprecationWarningString} takes an additional replacement parameter
- that can be used to add information to the deprecation. If the
- replacement parameter is a callable, its fully qualified name will be
- interpolated into the result.
- """
- version = Version('Twisted', 8, 0, 0)
- warningString = getDeprecationWarningString(
- self.test_getDeprecationWarningString, version,
- replacement=dummyReplacementMethod)
- self.assertEqual(
- warningString,
- "%s was deprecated in Twisted 8.0.0; please use "
- "%s.dummyReplacementMethod instead" % (
- fullyQualifiedName(self.test_getDeprecationWarningString),
- __name__))
-
-
- def test_deprecatedReplacement(self):
- """
- L{deprecated} takes an additional replacement parameter that can be used
- to indicate the new, non-deprecated method developers should use. If
- the replacement parameter is a string, it will be interpolated directly
- into the warning message.
- """
- version = Version('Twisted', 8, 0, 0)
- dummy = deprecated(version, "something.foobar")(dummyCallable)
- self.assertEqual(dummy.__doc__,
- "\n"
- " Do nothing.\n\n"
- " This is used to test the deprecation decorators.\n\n"
- " Deprecated in Twisted 8.0.0; please use "
- "something.foobar"
- " instead.\n"
- " ")
-
-
- def test_deprecatedReplacementWithCallable(self):
- """
- L{deprecated} takes an additional replacement parameter that can be used
- to indicate the new, non-deprecated method developers should use. If
- the replacement parameter is a callable, its fully qualified name will
- be interpolated into the warning message.
- """
- version = Version('Twisted', 8, 0, 0)
- decorator = deprecated(version, replacement=dummyReplacementMethod)
- dummy = decorator(dummyCallable)
- self.assertEqual(dummy.__doc__,
- "\n"
- " Do nothing.\n\n"
- " This is used to test the deprecation decorators.\n\n"
- " Deprecated in Twisted 8.0.0; please use "
- "%s.dummyReplacementMethod instead.\n"
- " " % (__name__,))
-
-
-
-class TestAppendToDocstring(SynchronousTestCase):
- """
- Test the _appendToDocstring function.
-
- _appendToDocstring is used to add text to a docstring.
- """
-
- def test_appendToEmptyDocstring(self):
- """
- Appending to an empty docstring simply replaces the docstring.
- """
-
- def noDocstring():
- pass
-
- _appendToDocstring(noDocstring, "Appended text.")
- self.assertEqual("Appended text.", noDocstring.__doc__)
-
-
- def test_appendToSingleLineDocstring(self):
- """
- Appending to a single line docstring places the message on a new line,
- with a blank line separating it from the rest of the docstring.
-
- The docstring ends with a newline, conforming to Twisted and PEP 8
- standards. Unfortunately, the indentation is incorrect, since the
- existing docstring doesn't have enough info to help us indent
- properly.
- """
-
- def singleLineDocstring():
- """This doesn't comply with standards, but is here for a test."""
-
- _appendToDocstring(singleLineDocstring, "Appended text.")
- self.assertEqual(
- ["This doesn't comply with standards, but is here for a test.",
- "",
- "Appended text."],
- singleLineDocstring.__doc__.splitlines())
- self.assertTrue(singleLineDocstring.__doc__.endswith('\n'))
-
-
- def test_appendToMultilineDocstring(self):
- """
- Appending to a multi-line docstring places the messade on a new line,
- with a blank line separating it from the rest of the docstring.
-
- Because we have multiple lines, we have enough information to do
- indentation.
- """
-
- def multiLineDocstring():
- """
- This is a multi-line docstring.
- """
-
- def expectedDocstring():
- """
- This is a multi-line docstring.
-
- Appended text.
- """
-
- _appendToDocstring(multiLineDocstring, "Appended text.")
- self.assertEqual(
- expectedDocstring.__doc__, multiLineDocstring.__doc__)
View
3 twisted/python/test/test_reflectpy3.py
@@ -17,8 +17,7 @@
# After twisted.python.reflect is fully ported to Python 3, import
# fullyQualifiedName from there instead, to test the actual public interface
# instead of this implementation detail. See #5929.
-from twisted.python._deprecatepy3 import (
- _fullyQualifiedName as fullyQualifiedName)
+from twisted.python.deprecate import _fullyQualifiedName as fullyQualifiedName
from twisted.python import _utilpy3 as util
View
0 twisted/topfiles/6036.misc
No changes.

0 comments on commit 907b165

Please sign in to comment.