diff -r 0243f7da89cb Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py Wed Jul 30 19:24:47 2014 -0400 +++ b/Lib/idlelib/PyShell.py Mon Aug 04 15:49:43 2014 -0400 @@ -1042,6 +1042,15 @@ self.write("Python %s on %s\n%s\n%s" % (sys.version, sys.platform, self.COPYRIGHT, nosub)) + + for f in idleConf.failed: + cfg_name = "config-"+ f + ".cfg" + e = idleConf.failed[f] + msg = e.message.split('\n')[0] + msg += "\nIgnoring configurations within " + cfg_name + ".\n" + msg += "Delete this file or fix formatting errors to remove this warning." + idle_showwarning(msg, type(e), e.source, e.lineno, line=e.line) + self.showprompt() import tkinter tkinter._default_root = None # 03Jan04 KBK What's this? diff -r 0243f7da89cb Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py Wed Jul 30 19:24:47 2014 -0400 +++ b/Lib/idlelib/configHandler.py Mon Aug 04 15:49:43 2014 -0400 @@ -21,6 +21,7 @@ import sys from configparser import ConfigParser +import configparser class InvalidConfigType(Exception): pass class InvalidConfigSet(Exception): pass @@ -167,6 +168,7 @@ self.defaultCfg={} self.userCfg={} self.cfg={} + self.failed={} self.CreateConfigHandlers() self.LoadCfgFiles() #self.LoadCfg() @@ -691,7 +693,10 @@ """ for key in self.defaultCfg: self.defaultCfg[key].Load() - self.userCfg[key].Load() #same keys + try: + self.userCfg[key].Load() #same keys + except configparser.Error as e: + self.failed[key] = e def SaveUserCfgFiles(self): """ diff -r 0243f7da89cb Lib/idlelib/idle_test/test_config.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/test_config.py Mon Aug 04 15:49:43 2014 -0400 @@ -0,0 +1,137 @@ +import io +import os +import unittest +import sys + +from unittest.mock import patch, mock_open +from test import support +from configparser import MissingSectionHeaderError +support.requires('gui') + +PyShell = support.import_module('idlelib.PyShell') +configHandler = support.import_module('idlelib.configHandler') + +from tkinter import Tk +from idlelib import macosxSupport + +def_cfg = { + 'config-main.def': '', + 'config-extensions.def':'', + 'config-highlight.def': '', + 'config-keys.def': '', + } + +# Grabbing default config files so they can be used in tests with mock open. +for f in def_cfg: + file_name = os.path.join(os.path.dirname(__file__), '..', f) + with open (file_name, "r") as file: + def_cfg[f]= file.read() + +def stringIO_from_string(str): + s = io.StringIO() + s.write(str) + s.seek(0) + return s + +# Some initialization that allows us to create IDLE instances. +PyShell.use_subprocess = True +PyShell.root = Tk(className="Idle") +PyShell.flist = PyShell.PyShellFileList(PyShell.root) +macosxSupport.setupApp(PyShell.root, PyShell.flist) + +# Path to user defined config files. +idlerc = os.path.join(os.path.expanduser('~'), '.idlerc') + +class IdleConfigHandlerTest(unittest.TestCase): + @patch('builtins.open') + def test_default_configs(self, mock_open): + def cfg_string_io(file, encoding): + if (file.endswith('.def')): + return stringIO_from_string(def_cfg[os.path.basename(file)]) + return io.StringIO() + + mock_open.side_effect = cfg_string_io + + cfg = configHandler.IdleConf() + assert(cfg.failed == {}) + + @patch('builtins.open') + def test_missing_section_header_config(self, mock_open): + def cfg_string_io(file, encoding): + if (file.endswith('.def')): + return stringIO_from_string(def_cfg[os.path.basename(file)]) + if (file.endswith('config-extensions.cfg')): + return stringIO_from_string('[test') + return io.StringIO() + + mock_open.side_effect = cfg_string_io + + file_name = os.path.join(idlerc, 'config-extensions.cfg') + + failed = {'extensions': "File contains no section headers.\nfile: '" + file_name + "', line: 1\n'[test'"} + + cfg = configHandler.IdleConf() + + self.assertEqual(type(cfg.failed.get('extensions')), MissingSectionHeaderError) + + +class IdleConfigWarningTest(unittest.TestCase): + @patch('builtins.open') + def test_no_warnings_on_default_configs(self, mock_open): + def cfg_string_io(file, mode='r', encoding=None, errors=None): + if (file.endswith('.def')): + return stringIO_from_string(def_cfg[os.path.basename(file)]) + return io.StringIO() + + mock_open.side_effect = cfg_string_io + + PyShell.idleConf = configHandler.IdleConf() + cfg = PyShell.idleConf + cfg.LoadCfgFiles() + + with support.captured_stderr() as f: + shell = PyShell.PyShell() + PyShell.warning_stream = sys.stderr + shell.begin() + shell.close() + + self.assertEqual(f.getvalue().splitlines(), []) + + @patch('builtins.open') + def test_missing_section_header_warning(self, mock_open): + def cfg_string_io(file, mode='r', encoding=None, errors=None): + if (file.endswith('.def')): + return stringIO_from_string(def_cfg[os.path.basename(file)]) + if (file.endswith('config-extensions.cfg')): + return stringIO_from_string('[test') + return io.StringIO() + + mock_open.side_effect = cfg_string_io + + file_name = os.path.join(idlerc, 'config-extensions.cfg') + + failed = {'extensions': "File contains no section headers.\nfile: '" + file_name + "', line: 1\n'[test'"} + + warning = ['', + 'Warning (from warnings module):', + ' File "' + file_name + '", line 1', + ' [test', + 'MissingSectionHeaderError: File contains no section headers.', + 'Ignoring configurations within config-extensions.cfg.', + 'Delete this file or fix formatting errors to remove this warning.', + '>>> '] + + PyShell.idleConf = configHandler.IdleConf() + cfg = PyShell.idleConf + cfg.LoadCfgFiles() + + with support.captured_stderr() as f: + shell = PyShell.PyShell() + PyShell.warning_stream = sys.stderr + shell.begin() + shell.close() + + self.assertEqual(warning, f.getvalue().splitlines()) + +if __name__ == '__main__': + unittest.main(verbosity=2, exit=False)