jenkins-bot has submitted this change and it was merged.
Change subject: Remove cyclic import between exceptions and data.api ......................................................................
Remove cyclic import between exceptions and data.api
Delay the loading of deprecated symbol 'exceptions.UploadWarning' which refers to the class 'data.api.UploadWarning'.
Change-Id: I5348ceb79f1440b1d119b730a4eced33de4ff77a --- M pywikibot/__init__.py M pywikibot/exceptions.py M pywikibot/tools/__init__.py M tests/exceptions_tests.py 4 files changed, 62 insertions(+), 25 deletions(-)
Approvals: XZise: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py index 9d6c7d1..0fee2a2 100644 --- a/pywikibot/__init__.py +++ b/pywikibot/__init__.py @@ -38,6 +38,7 @@ # the following are flagged as deprecated on usage handleArgs, ) +from pywikibot.data.api import UploadWarning as _UploadWarning from pywikibot.exceptions import ( Error, InvalidTitle, BadTitle, NoPage, NoMoveTarget, SectionError, SiteDefinitionError, NoSuchSite, UnknownSite, UnknownFamily, @@ -53,8 +54,8 @@ ) from pywikibot.tools import PY2, UnicodeMixin, redirect_func from pywikibot.i18n import translate -from pywikibot.data.api import UploadWarning from pywikibot.diff import PatchManager + import pywikibot.textlib as textlib import pywikibot.tools
@@ -757,8 +758,12 @@ wrapper._add_deprecated_attr( 'UserActionRefuse', pywikibot.exceptions._EmailUserError, warning_message='UserActionRefuse is deprecated; ' - 'use UserRightsError and/or NotEmailableError') + 'use UserRightsError and/or NotEmailableError instead.') wrapper._add_deprecated_attr( 'QuitKeyboardInterrupt', pywikibot.bot.QuitKeyboardInterrupt, warning_message='pywikibot.QuitKeyboardInterrupt is deprecated; ' - 'use pywikibot.bot.QuitKeyboardInterrupt instead') + 'use pywikibot.bot.QuitKeyboardInterrupt instead.') +wrapper._add_deprecated_attr( + 'UploadWarning', _UploadWarning, + warning_message='pywikibot.UploadWarning is deprecated; ' + 'use APISite.upload with a warning handler instead.') diff --git a/pywikibot/exceptions.py b/pywikibot/exceptions.py index 64b27d0..1d82980 100644 --- a/pywikibot/exceptions.py +++ b/pywikibot/exceptions.py @@ -74,7 +74,7 @@ - FamilyMaintenanceWarning: missing information in family definition """ # -# (C) Pywikibot team, 2008 +# (C) Pywikibot team, 2008-2015 # # Distributed under the terms of the MIT license. # @@ -82,12 +82,14 @@
__version__ = '$Id$'
-import sys - -from pywikibot.tools import UnicodeMixin, _NotImplementedWarning - -if sys.version_info[0] > 2: - unicode = str +from pywikibot.tools import ( + # __ to avoid conflict with ModuleDeprecationWrapper._deprecated + deprecated as __deprecated, + ModuleDeprecationWrapper as _ModuleDeprecationWrapper, + UnicodeMixin, + UnicodeType, + _NotImplementedWarning, +)
class NotImplementedWarning(_NotImplementedWarning): @@ -179,7 +181,7 @@ @property def args(self): """Expose args.""" - return unicode(self) + return UnicodeType(self)
class OtherPageSaveError(PageSaveRelatedError): @@ -200,7 +202,7 @@ @property def args(self): """Expose args.""" - return unicode(self.reason) + return UnicodeType(self.reason)
class NoUsername(Error): @@ -520,11 +522,7 @@ pass
-import pywikibot.data.api -import pywikibot.tools - - -@pywikibot.tools.deprecated +@__deprecated class DeprecatedPageNotFoundError(Error):
"""Page not found (deprecated).""" @@ -532,7 +530,7 @@ pass
-@pywikibot.tools.deprecated +@__deprecated class _EmailUserError(UserRightsError, NotEmailableError):
"""Email related error.""" @@ -540,8 +538,12 @@ pass
-wrapper = pywikibot.tools.ModuleDeprecationWrapper(__name__) -wrapper._add_deprecated_attr('UploadWarning', pywikibot.data.api.UploadWarning) +wrapper = _ModuleDeprecationWrapper(__name__) +wrapper._add_deprecated_attr( + 'UploadWarning', + replacement_name='pywikibot.data.api.UploadWarning', + warning_message='pywikibot.exceptions.UploadWarning is deprecated; ' + 'use APISite.upload with a warning handler instead.') wrapper._add_deprecated_attr('PageNotFound', DeprecatedPageNotFoundError, warning_message='{0}.{1} is deprecated, and no ' 'longer used by pywikibot; use ' diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index f0b7084..61b353d 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -1467,6 +1467,8 @@ @type replacement: any @param replacement_name: The name of the new replaced value. Required if C{replacement} is not None and it has no __name__ attribute. + If it contains a '.', it will be interpreted as a Python dotted + object name, and evaluated when the deprecated object is needed. @type replacement_name: str @param warning_message: The warning to display, with positional variables: {0} = module, {1} = attribute name, {2} = replacement. @@ -1515,6 +1517,20 @@ DeprecationWarning, 2) if self._deprecated[attr][1]: return self._deprecated[attr][1] + elif '.' in self._deprecated[attr][0]: + try: + package_name = self._deprecated[attr][0].split('.', 1)[0] + module = __import__(package_name) + context = {package_name: module} + replacement = eval(self._deprecated[attr][0], context) + self._deprecated[attr] = ( + self._deprecated[attr][0], + replacement, + self._deprecated[attr][2] + ) + return replacement + except Exception: + pass return getattr(self._module, attr)
diff --git a/tests/exceptions_tests.py b/tests/exceptions_tests.py index 853c3c1..5b238d6 100644 --- a/tests/exceptions_tests.py +++ b/tests/exceptions_tests.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Tests for exceptions.""" # -# (C) Pywikibot team, 2014 +# (C) Pywikibot team, 2014-2015 # # Distributed under the terms of the MIT license. # @@ -22,20 +22,34 @@
def test_UploadWarning(self): """Test exceptions.UploadWarning is deprecated only.""" - # Accessing from the main package should work fine. + # Accessing from the main package should be deprecated. cls = pywikibot.UploadWarning - self.assertNoDeprecation() + + self.assertOneDeprecationParts('pywikibot.UploadWarning', + 'APISite.upload with a warning handler') + e = cls('foo', 'bar') self.assertIsInstance(e, pywikibot.Error) self.assertNoDeprecation()
self._reset_messages()
- # But it sholdnt be accessed from the exceptions module. + # And it should not be accessed from the exceptions module either. + # The first access loads the symbol cls = pywikibot.exceptions.UploadWarning
self.assertOneDeprecationParts('pywikibot.exceptions.UploadWarning', - 'pywikibot.data.api.UploadWarning') + 'APISite.upload with a warning handler') + + e = cls('foo', 'bar') + self.assertIsInstance(e, pywikibot.Error) + self.assertNoDeprecation() + + # Check this again because the second time it should be cached + cls = pywikibot.exceptions.UploadWarning + + self.assertOneDeprecationParts('pywikibot.exceptions.UploadWarning', + 'APISite.upload with a warning handler')
e = cls('foo', 'bar') self.assertIsInstance(e, pywikibot.Error)