Page MenuHomePhabricator

test_watchlist_revs of tests.site_tests.SiteWatchlistRevsTestCase fails some times
Open, HighPublic

Description

test_watchlist_revs of tests.site_tests.SiteWatchlistRevsTestCase fails some times due to pywikibot.data.api.APIError: notloggedin Exception

======================================================================
ERROR: test_watchlist_revs (tests.site_tests.SiteWatchlistRevsTestCase)
Test the site.watchlist_revs() method.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/wikimedia/pywikibot/tests/site_tests.py", line 1834, in test_watchlist_revs
    for rev in mysite.watchlist_revs(minor=False, total=5):
  File "/home/travis/build/wikimedia/pywikibot/pywikibot/data/api.py", line 2807, in __iter__
    self.data = self.request.submit()
  File "/home/travis/build/wikimedia/pywikibot/pywikibot/data/api.py", line 2079, in submit
    raise APIError(**result['error'])
pywikibot.data.api.APIError: notloggedin: Please log in to view or edit items on your watchlist. [help:See https://zh.wikisource.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at <https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce> for notice of API deprecations and breaking changes.]

----------------------------------------------------------------------

Event Timeline

Restricted Application added subscribers: pywikibot-bugs-list, Aklapper. · View Herald Transcript
Xqt triaged this task as Medium priority.Jul 22 2019, 12:06 PM

There is a more informative traceback found:

=================================== FAILURES ===================================
___________________ TestUserWatchedPages.test_watched_pages ____________________

self = <tests.site_tests.TestUserWatchedPages testMethod=test_watched_pages>

    def test_watched_pages(self):
        """Test the site.watched_pages() method."""
        gen = self.site.watched_pages(total=5, force=False)
        self.assertIsInstance(gen.request, api.CachedRequest)
>       for page in gen:

tests/site_tests.py:1566: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pywikibot/data/api.py:2807: in __iter__
    self.data = self.request.submit()
pywikibot/data/api.py:2234: in submit
    self._data = super(CachedRequest, self).submit()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = pywikibot.data.api.CachedRequest<wikipedia:en->'/w/api.php?prop=info|imageinfo|categoryinfo&inprop=protection&iiprop=t...tchlistraw&action=query&indexpageids=&continue=&gwrlimit=5&meta=userinfo&uiprop=blockinfo|hasmsg&maxlag=5&format=json'>

    def submit(self):
        """
        Submit a query and parse the response.
    
        @return: a dict containing data retrieved from api.php
        @rtype: dict
        """
        self._add_defaults()
        use_get = self._use_get()
    
        while True:
            paramstring = self._http_param_string()
    
            simulate = self._simulate(self.action)
            if simulate:
                return simulate
    
            if self.throttle:
                self.site.throttle(write=self.write)
            else:
                pywikibot.log(
                    "Submitting unthrottled action '{0}'.".format(self.action))
    
            use_get, uri, body, headers = self._get_request_params(use_get,
                                                                   paramstring)
            rawdata, use_get = self._http_request(use_get, uri, body, headers,
                                                  paramstring)
            if rawdata is None:
                continue
    
            result = self._json_loads(rawdata)
            if result is None:
                continue
    
            if self._userinfo_query(result):
                continue
    
            self._handle_warnings(result)
    
            if 'error' not in result:
                return result
    
            error = result['error'].copy()
            for key in result:
                if key in ('error', 'warnings'):
                    continue
                assert key not in error
                assert isinstance(result[key], UnicodeType), \
                    'Unexpected %s: %r' % (key, result[key])
                error[key] = result[key]
    
            if '*' in result['error']:
                # help text returned
                result['error']['help'] = result['error'].pop('*')
            code = result['error'].setdefault('code', 'Unknown')
            info = result['error'].setdefault('info', None)
    
            if not self._logged_in(code):
                continue
    
            if code == 'maxlag':
                lag = lagpattern.search(info)
                pywikibot.log('Pausing due to database lag: ' + info)
                if lag:
                    lag = lag.group('lag')
                self.site.throttle.lag(int(lag or 0))
                continue
    
            elif code == 'help' and self.action == 'help':
                # The help module returns an error result with the complete
                # API information. As this data was requested, return the
                # data instead of raising an exception.
                return {'help': {'mime': 'text/plain',
                                 'help': result['error']['help']}}
    
            pywikibot.warning('API error %s: %s' % (code, info))
    
            if self._internal_api_error(code, error, result):
                continue
    
            # Phab. tickets T48535, T64126, T68494, T68619
            if code == 'failed-save' and \
               self.action == 'wbeditentity' and \
               self._is_wikibase_error_retryable(result['error']):
                self.wait()
                continue
    
            # If readapidenied is returned try to login
            if code == 'readapidenied' and self.site._loginstatus in (-3, -1):
                self.site.login()
                continue
    
            if self._bad_token(code):
                continue
    
            if 'mwoauth-invalid-authorization' in code:
                if 'Nonce already used' in info:
                    pywikibot.error(
                        'Retrying failed OAuth authentication for {0}: {1}'
                        .format(self.site, info))
                    continue
                raise NoUsername('Failed OAuth authentication for %s: %s'
                                 % (self.site, info))
            if code == 'cirrussearch-too-busy-error':  # T170647
                self.wait()
                continue
    
            # raise error
            try:
                # Due to bug T66958, Page's repr may return non ASCII bytes
                # Get as bytes in PY2 and decode with the console encoding as
                # the rest should be ASCII anyway.
                param_repr = str(self._params)
                if PY2:
                    param_repr = param_repr.decode(config.console_encoding)
                pywikibot.log('API Error: query=\n%s'
                              % pprint.pformat(param_repr))
                pywikibot.log('           response=\n%s'
                              % result)
    
>               raise APIError(**result['error'])
E               pywikibot.data.api.APIError: notloggedin: Please log in to view or edit items on your watchlist. [help:See https://en.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.]

pywikibot/data/api.py:2079: APIError
------------------------------ Captured log setup ------------------------------
logging.py                 109 VERBOSE  Found 1 wikipedia:en processes running, including this one.
------------------------------ Captured log call -------------------------------
logging.py                 109 VERBOSE  APISite("en", "wikipedia").login(False) called when a previous login was in progress.
logging.py                 109 WARNING  API error notloggedin: Please log in to view or edit items on your watchlist.
logging.py                 109 VERBOSE  API Error: query=
("{'prop': ['info', 'imageinfo', 'categoryinfo'], 'inprop': ['protection'], "
 "'iiprop': ['timestamp', 'user', 'comment', 'url', 'size', 'sha1', "
 "'metadata'], 'iilimit': ['max'], 'generator': ['watchlistraw'], 'action': "
 "['query'], 'indexpageids': [True], 'continue': [True], 'gwrlimit': ['5'], "
 "'meta': ['userinfo'], 'uiprop': ['blockinfo', 'hasmsg'], 'maxlag': ['5'], "
 "'format': ['json']}")
logging.py                 109 VERBOSE             response=
{'error': {'code': 'notloggedin', 'info': 'Please log in to view or edit items on your watchlist.', 'help': 'See https://en.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.'}, 'servedby': 'mw1341'}
_______________ TestUserWatchedPages.test_watched_pages_uncached _______________

self = <tests.site_tests.TestUserWatchedPages testMethod=test_watched_pages_uncached>

    def test_watched_pages_uncached(self):
        """Test the site.watched_pages() method uncached."""
        gen = self.site.watched_pages(total=5, force=True)
        self.assertIsInstance(gen.request, api.Request)
        self.assertFalse(issubclass(gen.request_class, api.CachedRequest))
>       for page in gen:

tests/site_tests.py:1579: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
pywikibot/data/api.py:2807: in __iter__
    self.data = self.request.submit()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = pywikibot.data.api.Request<wikipedia:en->'/w/api.php?prop=info|imageinfo|categoryinfo&inprop=protection&iiprop=timesta...tchlistraw&action=query&indexpageids=&continue=&gwrlimit=5&meta=userinfo&uiprop=blockinfo|hasmsg&maxlag=5&format=json'>

    def submit(self):
        """
        Submit a query and parse the response.
    
        @return: a dict containing data retrieved from api.php
        @rtype: dict
        """
        self._add_defaults()
        use_get = self._use_get()
    
        while True:
            paramstring = self._http_param_string()
    
            simulate = self._simulate(self.action)
            if simulate:
                return simulate
    
            if self.throttle:
                self.site.throttle(write=self.write)
            else:
                pywikibot.log(
                    "Submitting unthrottled action '{0}'.".format(self.action))
    
            use_get, uri, body, headers = self._get_request_params(use_get,
                                                                   paramstring)
            rawdata, use_get = self._http_request(use_get, uri, body, headers,
                                                  paramstring)
            if rawdata is None:
                continue
    
            result = self._json_loads(rawdata)
            if result is None:
                continue
    
            if self._userinfo_query(result):
                continue
    
            self._handle_warnings(result)
    
            if 'error' not in result:
                return result
    
            error = result['error'].copy()
            for key in result:
                if key in ('error', 'warnings'):
                    continue
                assert key not in error
                assert isinstance(result[key], UnicodeType), \
                    'Unexpected %s: %r' % (key, result[key])
                error[key] = result[key]
    
            if '*' in result['error']:
                # help text returned
                result['error']['help'] = result['error'].pop('*')
            code = result['error'].setdefault('code', 'Unknown')
            info = result['error'].setdefault('info', None)
    
            if not self._logged_in(code):
                continue
    
            if code == 'maxlag':
                lag = lagpattern.search(info)
                pywikibot.log('Pausing due to database lag: ' + info)
                if lag:
                    lag = lag.group('lag')
                self.site.throttle.lag(int(lag or 0))
                continue
    
            elif code == 'help' and self.action == 'help':
                # The help module returns an error result with the complete
                # API information. As this data was requested, return the
                # data instead of raising an exception.
                return {'help': {'mime': 'text/plain',
                                 'help': result['error']['help']}}
    
            pywikibot.warning('API error %s: %s' % (code, info))
    
            if self._internal_api_error(code, error, result):
                continue
    
            # Phab. tickets T48535, T64126, T68494, T68619
            if code == 'failed-save' and \
               self.action == 'wbeditentity' and \
               self._is_wikibase_error_retryable(result['error']):
                self.wait()
                continue
    
            # If readapidenied is returned try to login
            if code == 'readapidenied' and self.site._loginstatus in (-3, -1):
                self.site.login()
                continue
    
            if self._bad_token(code):
                continue
    
            if 'mwoauth-invalid-authorization' in code:
                if 'Nonce already used' in info:
                    pywikibot.error(
                        'Retrying failed OAuth authentication for {0}: {1}'
                        .format(self.site, info))
                    continue
                raise NoUsername('Failed OAuth authentication for %s: %s'
                                 % (self.site, info))
            if code == 'cirrussearch-too-busy-error':  # T170647
                self.wait()
                continue
    
            # raise error
            try:
                # Due to bug T66958, Page's repr may return non ASCII bytes
                # Get as bytes in PY2 and decode with the console encoding as
                # the rest should be ASCII anyway.
                param_repr = str(self._params)
                if PY2:
                    param_repr = param_repr.decode(config.console_encoding)
                pywikibot.log('API Error: query=\n%s'
                              % pprint.pformat(param_repr))
                pywikibot.log('           response=\n%s'
                              % result)
    
>               raise APIError(**result['error'])
E               pywikibot.data.api.APIError: notloggedin: Please log in to view or edit items on your watchlist. [help:See https://en.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.]

pywikibot/data/api.py:2079: APIError
------------------------------ Captured log call -------------------------------
logging.py                 109 WARNING  API error notloggedin: Please log in to view or edit items on your watchlist.
logging.py                 109 VERBOSE  API Error: query=
("{'prop': ['info', 'imageinfo', 'categoryinfo'], 'inprop': ['protection'], "
 "'iiprop': ['timestamp', 'user', 'comment', 'url', 'size', 'sha1', "
 "'metadata'], 'iilimit': ['max'], 'generator': ['watchlistraw'], 'action': "
 "['query'], 'indexpageids': [True], 'continue': [True], 'gwrlimit': ['5'], "
 "'meta': ['userinfo'], 'uiprop': ['blockinfo', 'hasmsg'], 'maxlag': ['5'], "
 "'format': ['json']}")
logging.py                 109 VERBOSE             response=
{'error': {'code': 'notloggedin', 'info': 'Please log in to view or edit items on your watchlist.', 'help': 'See https://en.wikipedia.org/w/api.php for API usage. Subscribe to the mediawiki-api-announce mailing list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; for notice of API deprecations and breaking changes.'}, 'servedby': 'mw1316'}
Xqt raised the priority of this task from Medium to High.Feb 19 2020, 6:20 AM

This seems to be classic login issue lately. Tests can't login, can't relogin and are complaining they are not logged in.