jenkins-bot has submitted this change and it was merged.
Change subject: Execute user config in sandbox ......................................................................
Execute user config in sandbox
Give the user-config script a global environment which does not have private methods or necessary imports, and copy only known configuration items into the globals of the config module.
Change-Id: I4e31d05c1ff6f55f96e1ceffcddf06e54216c25b --- M pywikibot/config2.py 1 file changed, 29 insertions(+), 5 deletions(-)
Approvals: John Vandenberg: Looks good to me, but someone else must approve Legoktm: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py index 667a65c..4b31fc1 100644 --- a/pywikibot/config2.py +++ b/pywikibot/config2.py @@ -24,6 +24,8 @@
import os import sys +# Please keep _imported_modules in sync with the imports above +_imported_modules = ('os', 'sys')
# IMPORTANT: # Do not change any of the variables in this file. Instead, make @@ -705,13 +707,25 @@ return path # System-level and User-level changes. # Store current variables and their types. -_glv = {} -_glv.update(globals()) +_glv = dict((_key, _val) for _key, _val in globals().items() + if _key[0] != '_' and _key not in _imported_modules) _gl = list(_glv.keys()) _tp = {} for _key in _gl: if _key[0] != '_': _tp[_key] = type(globals()[_key]) + +# Create an environment for user-config.py which is +# a shallow copy of the core config settings, so that +# we can detect modified config items easily. +_uc = {} +for _key, _val in _glv.items(): + if isinstance(_val, dict): + _uc[_key] = {} + if len(_val.keys()) > 0: + _uc[_key].update(_val) + else: + _uc[_key] = _val
# Get the user files _thislevel = 0 @@ -728,7 +742,7 @@ _fileuid = _filestatus[4] if sys.platform == 'win32' or _fileuid in [os.getuid(), 0]: if sys.platform == 'win32' or _filemode & 0o02 == 0: - exec(compile(open(_filename).read(), _filename, 'exec')) + exec(compile(open(_filename).read(), _filename, 'exec'), _uc) else: print("WARNING: Skipped '%(fn)s': writeable by others." % {'fn': _filename}) @@ -737,8 +751,10 @@ % {'fn': _filename})
# Test for obsoleted and/or unknown variables. -for _key, _val in list(globals().items()): +for _key, _val in list(_uc.items()): if _key.startswith('_'): + pass + elif _key in _imported_modules: pass elif _key in _gl: nt = type(_val) @@ -760,6 +776,14 @@ print("WARNING: " "Configuration variable %(_key)r is defined but unknown.\n" "Misspelled?" % locals()) + +# Copy the user config settings into globals +_modified = [_key for _key in _gl + if _uc[_key] != globals()[_key] or + _key in ('usernames', 'sysopnames', 'disambiguation_comment')] + +for _key in _modified: + globals()[_key] = _uc[_key]
# Fix up default console_encoding if console_encoding is None: @@ -799,7 +823,7 @@ if _name[0] != '_': if not type(globals()[_name]) in [types.FunctionType, types.ModuleType]: - if _all or _glv[_name] != globals()[_name]: + if _all or _name in _modified: _value = globals()[_name] if _name in _private_values and _value: if isinstance(_value, dict):