BaseSite.__init__ has some special logic to support single site families, where it updates the global configuration variable "mylang" to the sites declared 'code' for its only site.
This allows users to only specify -family:mediawiki without needing to also specify -lang:mediawiki . However this breaks when the -user option is also used. The global argument -user is handled in bot.handle_args, which is before any BaseSite is initialised, so the incorrect lang code is used in bot.handle_args to add the username, but then in login.py the lang has changed so it doesnt find the stored and raises NoUsername.
e.g.
python pwb.py replace -family:mediawiki -user:JVbot -search:pywikipedia pywikipedia pywikibot WARNING: .../pywikibot/site.py:765: UserWarning: Global configuration variable "mylang" changed to "mediawiki" while instantiating site mediawiki:mediawiki WARNING: .../pywikibot/pagegenerators.py:404: UserWarning: Site mediawiki:mediawiki instantiated using different code "en" self._site = pywikibot.Site() The summary message for the command line replacements will be something like: Bot: Automated text replacement (-pywikipedia +pywikibot) Press Enter to use this automatic message, or enter a description of the changes your bot will make: Traceback (most recent call last): File "pwb.py", line 256, in <module> if not main(): File "pwb.py", line 250, in main run_python_file(filename, [filename] + args, argvu, file_package) File "pwb.py", line 121, in run_python_file main_mod.__dict__) File "./scripts/replace.py", line 1131, in <module> main() File "./scripts/replace.py", line 1121, in main site.login() File ".../pywikibot/site.py", line 2056, in login user=self._username[sysop]) File ".../pywikibot/tools/__init__.py", line 1368, in wrapper return obj(*__args, **__kw) File ".../pywikibot/login.py", line 115, in __init__ 'wiki_code': self.site.code}) pywikibot.exceptions.NoUsername: ERROR: Username for mediawiki:mediawiki is undefined. If you have an account for that site, please add a line to user-config.py: usernames['mediawiki']['mediawiki'] = 'myUsername' <class 'pywikibot.exceptions.NoUsername'> CRITICAL: Closing network session.
Essentially, instantiating a class shouldnt change global configuration, as it is unreliable (especially if used in a multi threaded app).
The same situation can be reliably without -user:. If the user-config sets config.family to be a single site family like commons, and config.mylang is en:
- Instantiate an APISite for 'wikipedia:' + config.mylang
- Instantiate an APISite for commons (mylang is now 'commons')
- use 'wikipedia:' + config.mylang assuming it refers to the same site instantiated in step 1, which would try to access non-existent site wikipedia:commons
Any usage of config.family/config.mylang in pywikibot core , except in pywikibot.Site, should be audited to ensure it works correctly if config.mylang is changed after the pywikibot bootstrap and 'bot'-strap.