jenkins-bot has submitted this change and it was merged.
Change subject: [FIX] Page: Use repr-like if it can't be encoded ......................................................................
[FIX] Page: Use repr-like if it can't be encoded
When the title contains characters which can't be encoded it falls back to use an encoding which works like repr() on a unicode. It is also changing how it behaves on Python 3 as it doesn't encode the title anymore and is thus not a bytes anymore.
Bug: T107428 Change-Id: I25dddac881891291c5a0dbe3f5dd2b1a0beedf0f --- M pywikibot/page.py M tests/aspects.py M tests/page_tests.py M tests/utils.py 4 files changed, 49 insertions(+), 13 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py index 5c0ee75..890796a 100644 --- a/pywikibot/page.py +++ b/pywikibot/page.py @@ -57,7 +57,7 @@ UserRightsError, ) from pywikibot.tools import ( - PYTHON_VERSION, + PYTHON_VERSION, PY2, MediaWikiVersion, UnicodeMixin, ComparableMixin, DotReadableDict, deprecated, deprecate_arg, deprecated_args, issue_deprecation_warning, first_upper, remove_last_args, _NotImplementedWarning, @@ -280,7 +280,14 @@
def __repr__(self): """Return a more complete string representation.""" - title = self.title().encode(config.console_encoding) + if not PY2: + title = repr(self.title()) + else: + try: + title = self.title().encode(config.console_encoding) + except UnicodeEncodeError: + # okay console encoding didn't work, at least try something + title = self.title().encode('unicode_escape') return str('{0}({1})').format(self.__class__.__name__, title)
def _cmpkey(self): diff --git a/tests/aspects.py b/tests/aspects.py index f4016d7..187ba63 100644 --- a/tests/aspects.py +++ b/tests/aspects.py @@ -945,7 +945,7 @@ return self._mainpage
mainpage = pywikibot.Page(site, site.siteinfo['mainpage']) - if mainpage.isRedirectPage(): + if not isinstance(site, DrySite) and mainpage.isRedirectPage(): mainpage = mainpage.getRedirectTarget()
if force: diff --git a/tests/page_tests.py b/tests/page_tests.py index 087bc14..4d5d827 100644 --- a/tests/page_tests.py +++ b/tests/page_tests.py @@ -19,9 +19,8 @@
from tests.aspects import ( unittest, TestCase, DefaultSiteTestCase, SiteAttributeTestCase, - DeprecationTestCase, + DefaultDrySiteTestCase, DeprecationTestCase, ) -from tests.utils import expected_failure_if
if sys.version_info[0] > 2: basestring = (str, ) @@ -533,11 +532,20 @@ self.assertDeprecation()
-class TestPageRepr(DefaultSiteTestCase): +class TestPageBaseUnicode(DefaultDrySiteTestCase):
- """Test Page representation.""" + """Base class for tests requring a page using a unicode title."""
- cached = True + @classmethod + def setUpClass(cls): + """Initialize page instance.""" + super(TestPageBaseUnicode, cls).setUpClass() + cls.page = pywikibot.Page(cls.site, 'Ō') + + +class TestPageRepr(TestPageBaseUnicode): + + """Test for Page's repr implementation."""
def test_mainpage_type(self): u"""Test the return type of repr(Page(<main page>)) is str.""" @@ -549,7 +557,7 @@ page = pywikibot.Page(self.get_site(), u'Ō') self.assertIsInstance(repr(page), str)
- @expected_failure_if(sys.version_info[0] > 2) + @unittest.skipIf(not PY2, 'Python 2 specific test') def test_unicode_value(self): """Test repr(Page(u'<non-ascii>')) is represented simply as utf8.""" page = pywikibot.Page(self.get_site(), u'Ō') @@ -565,10 +573,9 @@ @unittest.skipIf(sys.version_info[0] < 3, 'Python 3+ specific test') def test_unicode_value_py3(self): """Test to capture actual Python 3 result pre unicode_literals.""" - page = pywikibot.Page(self.get_site(), u'Ō') - self.assertEqual(repr(page), "Page(b'\xc5\x8c')") - self.assertEqual(u'%r' % page, "Page(b'\xc5\x8c')") - self.assertEqual(u'{0!r}'.format(page), "Page(b'\xc5\x8c')") + self.assertEqual(repr(self.page), "Page('Ō')") + self.assertEqual('%r' % self.page, "Page('Ō')") + self.assertEqual('{0!r}'.format(self.page), "Page('Ō')")
@unittest.skipIf(not PY2, 'Python 2 specific test') @unittest.expectedFailure @@ -579,6 +586,27 @@ repr(page).decode('ascii')
+class TestPageReprASCII(TestPageBaseUnicode): + + """Test for Page's repr implementation when using ASCII encoding.""" + + def setUp(self): + """Patch the current console encoding to ASCII.""" + super(TestPageReprASCII, self).setUp() + self._old_encoding = config.console_encoding + config.console_encoding = 'ascii' + + def tearDown(self): + """Restore the original console encoding.""" + config.console_encoding = self._old_encoding + super(TestPageReprASCII, self).tearDown() + + @unittest.skipIf(not PY2, 'Python 2 specific test') + def test_incapable_encoding(self): + """Test that repr still works even if the console encoding does not.""" + self.assertEqual(repr(self.page), b'Page(\u014c)') + + class TestPageBotMayEdit(TestCase):
"""Test Page.botMayEdit() method.""" diff --git a/tests/utils.py b/tests/utils.py index c882d61..d7c3119 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -325,6 +325,7 @@ self._siteinfo._cache['case'] = ( 'case-sensitive' if self.family.name == 'wiktionary' else 'first-letter', True) + self._siteinfo._cache['mainpage'] = 'Main Page' extensions = [] if self.family.name == 'wikisource': extensions.append({'name': 'ProofreadPage'})
pywikibot-commits@lists.wikimedia.org