Page MenuHomePhabricator

replace.py display_edit_counter throws AttributeError: 'NoneType' object has no attribute 'output'
Closed, ResolvedPublic

Description

D:\Py\rewrite>pwb.py replace -regex -interwiki:Category:Francouzština -family:wiktionary -regex "\[\[za:(.*?)\]\]\n" ""


Exception in thread Put-Thread:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 551, in __bootstrap_inner
    self.run()
  File "C:\Python27\lib\threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "D:\Py\rewrite\pywikibot\__init__.py", line 679, in async_manager
    request(*args, **kwargs)
  File "D:\Py\rewrite\scripts\replace.py", line 724, in display_edit_counter
    pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)
AttributeError: 'NoneType' object has no attribute 'output'

in compat it works well


Version: core-(2.0)
Severity: normal

Details

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 3:44 AM
bzimport set Reference to bz72942.
bzimport added a subscriber: Unknown Object (????).

I was able to reproduce this. I ran pwb.py replace.py -lang:commons -family:commons -regex "(\|\s*Wikidata\s*=\s*)(\d+)" "\1Q\2" -usercontribs:Dexbot -summary:"Adding missing Wikidata Q"

After reviewing several edits (y,y,y), I switched to always (a).

It did quite a few edits and when it was supposed to stop and output some statistics:

No changes were necessary in [[Creator:Zamfir C. Arbure]]
Exception in thread Put-Thread:
Traceback (most recent call last):

File "C:\Python27\lib\threading.py", line 552, in __bootstrap_inner
  self.run()
File "C:\Python27\lib\threading.py", line 505, in run
  self.__target(*self.__args, **self.__kwargs)
File "C:\pywikibot\coredev\pywikibot\__init__.py", line 679, in async_manager
  request(*args, **kwargs)
File "C:\pywikibot\coredev\scripts\replace.py", line 724, in display_edit_coun

ter

pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)

AttributeError: 'NoneType' object has no attribute 'output'

The relevant code:

pywikibot.Site().login()
bot.run()

def display_edit_counter(bot):
    pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)

# Queue last request to display number of changed pages.
pywikibot.async_request(display_edit_counter, bot)

(why are we using subfunctions?)

pywikibot.async_request is in _init_.py . Is this caused by the fact that _init_.py doesn't iport pywikibot?

https://gerrit.wikimedia.org/r/#/c/165654/ seems to be the changeset that introduced this functionality and bug.

Seems to be a scoping issue -- replace.py (and thus most of the things inside it, including the pywikibot import) is unloaded when replace.py ends... which is before the function is called. Two options to solve this:

  1. Explicitly call pywikibot.stopme() at the end of replace.py. This will make sure the callback is triggered before replace.py is unloaded ...and then you can also juts do the output directly, which is *much* cleaner. I.e. instead of

    def display_edit_counter(bot): pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)
    1. Queue last request to display number of changed pages. pywikibot.async_request(display_edit_counter, bot)

we'd have

pywikibot.stopme()
pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)
  1. explicitly pass pywikibot so it's included in the scope, i.e.

    def display_edit_counter(pywikibot, bot): pywikibot.output(u'\n%s pages changed.' % bot.changed_pages)
    1. Queue last request to display number of changed pages. pywikibot.async_request(display_edit_counter, pywikibot, bot)

gerritadmin wrote:

Change 172044 had a related patch set uploaded by Mpaa:
replace.py: fix display_edit_counter_feature

https://gerrit.wikimedia.org/r/172044

gerritadmin wrote:

Change 172044 merged by jenkins-bot:
replace.py: fix display_edit_counter_feature

https://gerrit.wikimedia.org/r/172044

Xqt subscribed.

Reopened. We should use the edit counter feature which is implemented in BaseBot class. The exit() method prints it when the bot terminates the run() method. This ensures that bot classes derived from ReplaceBot can also have this counter message.

Change 282818 had a related patch set uploaded (by Xqt):
[bugfix] Port cache_output from compat

https://gerrit.wikimedia.org/r/282818

Xqt claimed this task.

Change 282818 merged by jenkins-bot:

[pywikibot/core@master] [bugfix] Port cache_output from compat

https://gerrit.wikimedia.org/r/282818