Commit 0048afc1 authored by Terry Jan Reedy's avatar Terry Jan Reedy Committed by GitHub

bpo-38183: Test_idle ignores user config directory GH-16198)

It no longer tries to create or access .idlerc or any files within.
Users must run IDLE to discover problems with saving settings.
parent 81528ba2
...@@ -130,7 +130,7 @@ class IdleUserConfParser(IdleConfParser): ...@@ -130,7 +130,7 @@ class IdleUserConfParser(IdleConfParser):
to disk. Otherwise, remove the file from disk if it exists. to disk. Otherwise, remove the file from disk if it exists.
""" """
fname = self.file fname = self.file
if fname: if fname and fname[0] != '#':
if not self.IsEmpty(): if not self.IsEmpty():
try: try:
cfgFile = open(fname, 'w') cfgFile = open(fname, 'w')
...@@ -166,12 +166,12 @@ class IdleConf: ...@@ -166,12 +166,12 @@ class IdleConf:
def CreateConfigHandlers(self): def CreateConfigHandlers(self):
"Populate default and user config parser dictionaries." "Populate default and user config parser dictionaries."
idledir = os.path.dirname(__file__) idledir = os.path.dirname(__file__)
self.userdir = userdir = self.GetUserCfgDir() self.userdir = userdir = '' if idlelib.testing else self.GetUserCfgDir()
for cfg_type in self.config_types: for cfg_type in self.config_types:
self.defaultCfg[cfg_type] = IdleConfParser( self.defaultCfg[cfg_type] = IdleConfParser(
os.path.join(idledir, f'config-{cfg_type}.def')) os.path.join(idledir, f'config-{cfg_type}.def'))
self.userCfg[cfg_type] = IdleUserConfParser( self.userCfg[cfg_type] = IdleUserConfParser(
os.path.join(userdir, f'config-{cfg_type}.cfg')) os.path.join(userdir or '#', f'config-{cfg_type}.cfg'))
def GetUserCfgDir(self): def GetUserCfgDir(self):
"""Return a filesystem directory for storing user config files. """Return a filesystem directory for storing user config files.
...@@ -182,6 +182,7 @@ class IdleConf: ...@@ -182,6 +182,7 @@ class IdleConf:
userDir = os.path.expanduser('~') userDir = os.path.expanduser('~')
if userDir != '~': # expanduser() found user home dir if userDir != '~': # expanduser() found user home dir
if not os.path.exists(userDir): if not os.path.exists(userDir):
if not idlelib.testing:
warn = ('\n Warning: os.path.expanduser("~") points to\n ' + warn = ('\n Warning: os.path.expanduser("~") points to\n ' +
userDir + ',\n but the path does not exist.') userDir + ',\n but the path does not exist.')
try: try:
...@@ -197,10 +198,13 @@ class IdleConf: ...@@ -197,10 +198,13 @@ class IdleConf:
try: try:
os.mkdir(userDir) os.mkdir(userDir)
except OSError: except OSError:
if not idlelib.testing:
warn = ('\n Warning: unable to create user config directory\n' + warn = ('\n Warning: unable to create user config directory\n' +
userDir + '\n Check path and permissions.\n Exiting!\n') userDir + '\n Check path and permissions.\n Exiting!\n')
if not idlelib.testing: try:
print(warn, file=sys.stderr) print(warn, file=sys.stderr)
except OSError:
pass
raise SystemExit raise SystemExit
# TODO continue without userDIr instead of exit # TODO continue without userDIr instead of exit
return userDir return userDir
......
...@@ -116,7 +116,7 @@ class EditorWindow(object): ...@@ -116,7 +116,7 @@ class EditorWindow(object):
self.tkinter_vars = {} # keys: Tkinter event names self.tkinter_vars = {} # keys: Tkinter event names
# values: Tkinter variable instances # values: Tkinter variable instances
self.top.instance_dict = {} self.top.instance_dict = {}
self.recent_files_path = os.path.join( self.recent_files_path = idleConf.userdir and os.path.join(
idleConf.userdir, 'recent-files.lst') idleConf.userdir, 'recent-files.lst')
self.prompt_last_line = '' # Override in PyShell self.prompt_last_line = '' # Override in PyShell
...@@ -924,9 +924,11 @@ class EditorWindow(object): ...@@ -924,9 +924,11 @@ class EditorWindow(object):
def update_recent_files_list(self, new_file=None): def update_recent_files_list(self, new_file=None):
"Load and update the recent files list and menus" "Load and update the recent files list and menus"
# TODO: move to iomenu.
rf_list = [] rf_list = []
if os.path.exists(self.recent_files_path): file_path = self.recent_files_path
with open(self.recent_files_path, 'r', if file_path and os.path.exists(file_path):
with open(file_path, 'r',
encoding='utf_8', errors='replace') as rf_list_file: encoding='utf_8', errors='replace') as rf_list_file:
rf_list = rf_list_file.readlines() rf_list = rf_list_file.readlines()
if new_file: if new_file:
...@@ -942,18 +944,18 @@ class EditorWindow(object): ...@@ -942,18 +944,18 @@ class EditorWindow(object):
rf_list = [path for path in rf_list if path not in bad_paths] rf_list = [path for path in rf_list if path not in bad_paths]
ulchars = "1234567890ABCDEFGHIJK" ulchars = "1234567890ABCDEFGHIJK"
rf_list = rf_list[0:len(ulchars)] rf_list = rf_list[0:len(ulchars)]
if file_path:
try: try:
with open(self.recent_files_path, 'w', with open(file_path, 'w',
encoding='utf_8', errors='replace') as rf_file: encoding='utf_8', errors='replace') as rf_file:
rf_file.writelines(rf_list) rf_file.writelines(rf_list)
except OSError as err: except OSError as err:
if not getattr(self.root, "recentfilelist_error_displayed", False): if not getattr(self.root, "recentfiles_message", False):
self.root.recentfilelist_error_displayed = True self.root.recentfiles_message = True
tkMessageBox.showwarning(title='IDLE Warning', tkMessageBox.showwarning(title='IDLE Warning',
message="Cannot update File menu Recent Files list. " message="Cannot save Recent Files list to disk.\n"
"Your operating system says:\n%s\n" f" {err}\n"
"Select OK and IDLE will continue without updating." "Select OK to continue.",
% self._filename_to_unicode(str(err)),
parent=self.text) parent=self.text)
# for each edit window instance, construct the recent files menu # for each edit window instance, construct the recent files menu
for instance in self.top.instance_dict: for instance in self.top.instance_dict:
......
...@@ -220,7 +220,7 @@ class IdleConfTest(unittest.TestCase): ...@@ -220,7 +220,7 @@ class IdleConfTest(unittest.TestCase):
@unittest.skipIf(sys.platform.startswith('win'), 'this is test for unix system') @unittest.skipIf(sys.platform.startswith('win'), 'this is test for unix system')
def test_get_user_cfg_dir_unix(self): def test_get_user_cfg_dir_unix(self):
"Test to get user config directory under unix" # Test to get user config directory under unix.
conf = self.new_config(_utest=True) conf = self.new_config(_utest=True)
# Check normal way should success # Check normal way should success
...@@ -243,7 +243,7 @@ class IdleConfTest(unittest.TestCase): ...@@ -243,7 +243,7 @@ class IdleConfTest(unittest.TestCase):
@unittest.skipIf(not sys.platform.startswith('win'), 'this is test for Windows system') @unittest.skipIf(not sys.platform.startswith('win'), 'this is test for Windows system')
def test_get_user_cfg_dir_windows(self): def test_get_user_cfg_dir_windows(self):
"Test to get user config directory under Windows" # Test to get user config directory under Windows.
conf = self.new_config(_utest=True) conf = self.new_config(_utest=True)
# Check normal way should success # Check normal way should success
...@@ -284,12 +284,12 @@ class IdleConfTest(unittest.TestCase): ...@@ -284,12 +284,12 @@ class IdleConfTest(unittest.TestCase):
self.assertIsInstance(user_parser, config.IdleUserConfParser) self.assertIsInstance(user_parser, config.IdleUserConfParser)
# Check config path are correct # Check config path are correct
for config_type, parser in conf.defaultCfg.items(): for cfg_type, parser in conf.defaultCfg.items():
self.assertEqual(parser.file, self.assertEqual(parser.file,
os.path.join(idle_dir, 'config-%s.def' % config_type)) os.path.join(idle_dir, f'config-{cfg_type}.def'))
for config_type, parser in conf.userCfg.items(): for cfg_type, parser in conf.userCfg.items():
self.assertEqual(parser.file, self.assertEqual(parser.file,
os.path.join(conf.userdir, 'config-%s.cfg' % config_type)) os.path.join(conf.userdir or '#', f'config-{cfg_type}.cfg'))
def test_load_cfg_files(self): def test_load_cfg_files(self):
conf = self.new_config(_utest=True) conf = self.new_config(_utest=True)
...@@ -373,7 +373,7 @@ class IdleConfTest(unittest.TestCase): ...@@ -373,7 +373,7 @@ class IdleConfTest(unittest.TestCase):
'background': '#171717'}) 'background': '#171717'})
def test_get_theme_dict(self): def test_get_theme_dict(self):
"XXX: NOT YET DONE" # TODO: finish.
conf = self.mock_config() conf = self.mock_config()
# These two should be the same # These two should be the same
......
...@@ -133,6 +133,7 @@ class PyShellEditorWindow(EditorWindow): ...@@ -133,6 +133,7 @@ class PyShellEditorWindow(EditorWindow):
self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here) self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
self.text.bind("<<open-python-shell>>", self.flist.open_shell) self.text.bind("<<open-python-shell>>", self.flist.open_shell)
#TODO: don't read/write this from/to .idlerc when testing
self.breakpointPath = os.path.join( self.breakpointPath = os.path.join(
idleConf.userdir, 'breakpoints.lst') idleConf.userdir, 'breakpoints.lst')
# whenever a file is changed, restore breakpoints # whenever a file is changed, restore breakpoints
......
To avoid problems, test_idle ignores the user config directory.
It no longer tries to create or access .idlerc or any files within.
Users must run IDLE to discover problems with saving settings.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment