jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/399444 )
Change subject: tools/__init__.py: Make suppress_warnings also work as a decorator ......................................................................
tools/__init__.py: Make suppress_warnings also work as a decorator
`suppress_warnings` already worked as a context manager, but it could not be configured to suppress specific warnings. The new `message`, `category`, and `filename` parameters will allow that.
Make the exising usages of `suppress_warnings` more specific. Use it as a decorator in site_tests.py to suppress an expected DeprecationWarning in site.search.
Change-Id: Ic606d75f359c4d9c6bc74927da8e6cb0fdf67ab7 --- M pywikibot/tools/__init__.py M tests/archivebot_tests.py M tests/site_tests.py M tests/user_tests.py 4 files changed, 59 insertions(+), 10 deletions(-)
Approvals: jenkins-bot: Verified Xqt: Looks good to me, approved
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index 472bdbe..b9c99e0 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -23,7 +23,8 @@ import types
from distutils.version import Version -from warnings import catch_warnings, simplefilter, warn +from functools import wraps +from warnings import catch_warnings, showwarning, warn
PYTHON_VERSION = sys.version_info[:3] PY2 = (PYTHON_VERSION[0] == 2) @@ -209,12 +210,58 @@
class suppress_warnings(catch_warnings): # noqa: N801
- """A context manager that temporarily suppresses warnings.""" + """A decorator/context manager that temporarily suppresses warnings. + + Those suppressed warnings that do not match the parameters will be raised + shown upon exit. + """ + + def __init__(self, message='', category=Warning, filename=''): + """Initialize the object. + + The parameter semantics are similar to those of + `warnings.filterwarnings`. + + @param message: A string containing a regular expression that the start + of the warning message must match. (case-insensitive) + @type message: str + @param category: A class (a subclass of Warning) of which the warning + category must be a subclass in order to match. + @type category: Warning + @param filename: A string containing a regular expression that the + start of the path to the warning module must match. + (case-sensitive) + @type filename: str + """ + self.message_match = re.compile(message, re.I).match + self.category = category + self.filename_match = re.compile(filename).match + super(suppress_warnings, self).__init__(record=True)
def __enter__(self): - """Catch the old filter settings and ignore all warnings.""" - super(suppress_warnings, self).__enter__() - simplefilter('ignore') + """Catch all warnings and store them in `self.log`.""" + self.log = super(suppress_warnings, self).__enter__() + + def __exit__(self, exc_type, exc_val, exc_tb): + """Stop logging warnings and show those that do not match to params.""" + super(suppress_warnings, self).__exit__() + for warning in self.log: + if ( + not issubclass(warning.category, self.category) + or not self.message_match(str(warning.message)) + or not self.filename_match(warning.filename) + ): + showwarning( + warning.message, warning.category, warning.filename, + warning.lineno, warning.file, warning.line) + + def __call__(self, func): + """Decorate func to suppress warnings.""" + @wraps(func) + def suppressed_func(*args, **kwargs): + with self: + return func(*args, **kwargs) + return suppressed_func
class UnicodeMixin(object): diff --git a/tests/archivebot_tests.py b/tests/archivebot_tests.py index ac253ce..3340b89 100644 --- a/tests/archivebot_tests.py +++ b/tests/archivebot_tests.py @@ -98,7 +98,7 @@ def test_checkstr(self): """Test for extracting key and duration from shorthand notation of durations.""" self.assertEqual(archivebot.checkstr('400s'), ('s', '400')) - with suppress_warnings(): + with suppress_warnings('Time period without qualifier', UserWarning): self.assertEqual(archivebot.checkstr('3000'), ('s', '3000')) self.assertEqual(archivebot.checkstr('7d'), ('d', '7')) self.assertEqual(archivebot.checkstr('3y'), ('y', '3')) diff --git a/tests/site_tests.py b/tests/site_tests.py index df886aa..bd77485 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -27,6 +27,7 @@ MediaWikiVersion, PY2, StringTypes as basestring, + suppress_warnings, UnicodeType as unicode, )
@@ -1477,6 +1478,7 @@ raise unittest.SkipTest("gsrsearch returned timeout on site: %r" % e) raise
+ @suppress_warnings("where='title' is deprecated", DeprecationWarning) def test_search_where_title(self): """Test site.search() method with 'where' parameter set to title.""" try: diff --git a/tests/user_tests.py b/tests/user_tests.py index 149cb41..e8678f6 100644 --- a/tests/user_tests.py +++ b/tests/user_tests.py @@ -25,7 +25,7 @@ def test_registered_user(self): """Test registered user.""" user = User(self.site, 'Xqt') - with suppress_warnings(): + with suppress_warnings('pywikibot.page.User.name', DeprecationWarning): self.assertEqual(user.name(), user.username) self.assertEqual(user.title(withNamespace=False), user.username) self.assertTrue(user.isRegistered()) @@ -60,7 +60,7 @@ def test_anonymous_user(self): """Test registered user.""" user = User(self.site, '123.45.67.89') - with suppress_warnings(): + with suppress_warnings('pywikibot.page.User.name', DeprecationWarning): self.assertEqual(user.name(), user.username) self.assertEqual(user.title(withNamespace=False), user.username) self.assertFalse(user.isRegistered()) @@ -73,7 +73,7 @@ def test_unregistered_user(self): """Test unregistered user.""" user = User(self.site, 'This user name is not registered yet') - with suppress_warnings(): + with suppress_warnings('pywikibot.page.User.name', DeprecationWarning): self.assertEqual(user.name(), user.username) self.assertEqual(user.title(withNamespace=False), user.username) self.assertFalse(user.isRegistered()) @@ -86,7 +86,7 @@ def test_invalid_user(self): """Test invalid user.""" user = User(self.site, 'Invalid char\x9f in Name') - with suppress_warnings(): + with suppress_warnings('pywikibot.page.User.name', DeprecationWarning): self.assertEqual(user.name(), user.username) self.assertEqual(user.title(withNamespace=False), user.username) self.assertFalse(user.isRegistered())
pywikibot-commits@lists.wikimedia.org