jenkins-bot merged this change.
[bugfix] Enable EventStreams filter for multiple arguments
- tests added
- doc updated
Bug: T188832
Change-Id: If7210f29dffe904f9f1b48af3ff76623596ebeab
---
M pywikibot/comms/eventstreams.py
M tests/eventstreams_tests.py
2 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/pywikibot/comms/eventstreams.py b/pywikibot/comms/eventstreams.py
index a74baa1..fe34d66 100644
--- a/pywikibot/comms/eventstreams.py
+++ b/pywikibot/comms/eventstreams.py
@@ -16,6 +16,7 @@
from __future__ import absolute_import, unicode_literals
from distutils.version import LooseVersion
+from functools import partial
import json
import socket
@@ -51,7 +52,10 @@
Usage:
>>> stream = EventStreams(stream='recentchange')
+ >>> stream.register_filter(type='edit', wiki='wikidatawiki')
>>> change = next(iter(stream))
+ >>> print('{type} on page {title} by {user}.'.format(**change))
+ edit od page Q32857263 by XXN-bot.
>>> change
{'comment': '/* wbcreateclaim-create:1| */ [[Property:P31]]: [[Q4167836]]',
'wiki': 'wikidatawiki', 'type': 'edit', 'server_name': 'www.wikidata.org',
@@ -206,6 +210,15 @@
@type kwargs: str, list, tuple or other sequence
@raise TypeError: A given args parameter is not a callable.
"""
+ def _is(data, key=None, value=None):
+ return key in data and data[key] is value
+
+ def _eq(data, key=None, value=None):
+ return key in data and data[key] == value
+
+ def _in(data, key=None, value=None):
+ return key in data and data[key] in value
+
ftype = kwargs.pop('ftype', 'all') # set default ftype value
# register an external filter function
@@ -219,16 +232,13 @@
for key, value in kwargs.items():
# append function for singletons
if isinstance(value, (bool, type(None))):
- self.filter[ftype].append(lambda e: key in e and
- e[key] is value)
+ self.filter[ftype].append(partial(_is, key=key, value=value))
# append function for a single value
elif isinstance(value, (StringTypes, int)):
- self.filter[ftype].append(lambda e: key in e and
- e[key] == value)
+ self.filter[ftype].append(partial(_eq, key=key, value=value))
# append function for an iterable as value
else:
- self.filter[ftype].append(lambda e: key in e and
- e[key] in value)
+ self.filter[ftype].append(partial(_in, key=key, value=value))
def streamfilter(self, data):
"""Filter function for eventstreams.
diff --git a/tests/eventstreams_tests.py b/tests/eventstreams_tests.py
index 77b6b57..c53349d 100644
--- a/tests/eventstreams_tests.py
+++ b/tests/eventstreams_tests.py
@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
"""Tests for the eventstreams module."""
#
-# (C) Pywikibot team, 2017
+# (C) Pywikibot team, 2017-2018
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals
-
-from types import FunctionType
from tests import mock
@@ -139,7 +137,7 @@
def test_filter_settings(self):
"""Test EventStreams filter settings."""
self.es.register_filter(foo='bar')
- self.assertIsInstance(self.es.filter['all'][0], FunctionType)
+ self.assertTrue(callable(self.es.filter['all'][0]))
self.es.register_filter(bar='baz')
self.assertEqual(len(self.es.filter['all']), 2)
@@ -194,6 +192,20 @@
self.es.register_filter(foo=10)
self.assertFalse(self.es.streamfilter(self.data))
+ def test_filter_multiple(self):
+ """Test EventStreams filter with multiple arguments."""
+ self.es.register_filter(foo=False, bar='baz')
+ self.assertFalse(self.es.streamfilter(self.data))
+ self.es.filter = {'all': [], 'any': [], 'none': []}
+ self.es.register_filter(foo=True, bar='baz')
+ self.assertTrue(self.es.streamfilter(self.data))
+ # check whether filter functions are different
+ f, g = self.es.filter['all']
+ c = {'foo': True}
+ self.assertNotEqual(f(c), g(c))
+ c = {'bar': 'baz'}
+ self.assertNotEqual(f(c), g(c))
+
def _test_filter(self, none_type, all_type, any_type, result):
"""Test a single fixed filter."""
self.es.filter = {'all': [], 'any': [], 'none': []}
To view, visit change 416239. To unsubscribe, visit settings.