It no longer tries to create or access .idlerc or any files within.
Users must run IDLE to discover problems with saving settings.
to disk. Otherwise, remove the file from disk if it exists.
"""
fname = self.file
- if fname:
+ if fname and fname[0] != '#':
if not self.IsEmpty():
try:
cfgFile = open(fname, 'w')
def CreateConfigHandlers(self):
"Populate default and user config parser dictionaries."
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:
self.defaultCfg[cfg_type] = IdleConfParser(
os.path.join(idledir, f'config-{cfg_type}.def'))
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):
"""Return a filesystem directory for storing user config files.
userDir = os.path.expanduser('~')
if userDir != '~': # expanduser() found user home dir
if not os.path.exists(userDir):
- warn = ('\n Warning: os.path.expanduser("~") points to\n ' +
- userDir + ',\n but the path does not exist.')
- try:
- print(warn, file=sys.stderr)
- except OSError:
- pass
+ if not idlelib.testing:
+ warn = ('\n Warning: os.path.expanduser("~") points to\n ' +
+ userDir + ',\n but the path does not exist.')
+ try:
+ print(warn, file=sys.stderr)
+ except OSError:
+ pass
userDir = '~'
if userDir == "~": # still no path to home!
# traditionally IDLE has defaulted to os.getcwd(), is this adequate?
try:
os.mkdir(userDir)
except OSError:
- warn = ('\n Warning: unable to create user config directory\n' +
- userDir + '\n Check path and permissions.\n Exiting!\n')
if not idlelib.testing:
- print(warn, file=sys.stderr)
+ warn = ('\n Warning: unable to create user config directory\n' +
+ userDir + '\n Check path and permissions.\n Exiting!\n')
+ try:
+ print(warn, file=sys.stderr)
+ except OSError:
+ pass
raise SystemExit
# TODO continue without userDIr instead of exit
return userDir
self.tkinter_vars = {} # keys: Tkinter event names
# values: Tkinter variable instances
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')
self.prompt_last_line = '' # Override in PyShell
def update_recent_files_list(self, new_file=None):
"Load and update the recent files list and menus"
+ # TODO: move to iomenu.
rf_list = []
- if os.path.exists(self.recent_files_path):
- with open(self.recent_files_path, 'r',
+ file_path = self.recent_files_path
+ if file_path and os.path.exists(file_path):
+ with open(file_path, 'r',
encoding='utf_8', errors='replace') as rf_list_file:
rf_list = rf_list_file.readlines()
if new_file:
rf_list = [path for path in rf_list if path not in bad_paths]
ulchars = "1234567890ABCDEFGHIJK"
rf_list = rf_list[0:len(ulchars)]
- try:
- with open(self.recent_files_path, 'w',
- encoding='utf_8', errors='replace') as rf_file:
- rf_file.writelines(rf_list)
- except OSError as err:
- if not getattr(self.root, "recentfilelist_error_displayed", False):
- self.root.recentfilelist_error_displayed = True
- tkMessageBox.showwarning(title='IDLE Warning',
- message="Cannot update File menu Recent Files list. "
- "Your operating system says:\n%s\n"
- "Select OK and IDLE will continue without updating."
- % self._filename_to_unicode(str(err)),
- parent=self.text)
+ if file_path:
+ try:
+ with open(file_path, 'w',
+ encoding='utf_8', errors='replace') as rf_file:
+ rf_file.writelines(rf_list)
+ except OSError as err:
+ if not getattr(self.root, "recentfiles_message", False):
+ self.root.recentfiles_message = True
+ tkMessageBox.showwarning(title='IDLE Warning',
+ message="Cannot save Recent Files list to disk.\n"
+ f" {err}\n"
+ "Select OK to continue.",
+ parent=self.text)
# for each edit window instance, construct the recent files menu
for instance in self.top.instance_dict:
menu = instance.recent_files_menu
@unittest.skipIf(sys.platform.startswith('win'), 'this is test for unix system')
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)
# Check normal way should success
@unittest.skipIf(not sys.platform.startswith('win'), 'this is test for Windows system')
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)
# Check normal way should success
self.assertIsInstance(user_parser, config.IdleUserConfParser)
# 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,
- os.path.join(idle_dir, 'config-%s.def' % config_type))
- for config_type, parser in conf.userCfg.items():
+ os.path.join(idle_dir, f'config-{cfg_type}.def'))
+ for cfg_type, parser in conf.userCfg.items():
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):
conf = self.new_config(_utest=True)
'background': '#171717'})
def test_get_theme_dict(self):
- "XXX: NOT YET DONE"
+ # TODO: finish.
conf = self.mock_config()
# These two should be the same
self.text.bind("<<clear-breakpoint-here>>", self.clear_breakpoint_here)
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(
idleConf.userdir, 'breakpoints.lst')
# whenever a file is changed, restore breakpoints
--- /dev/null
+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.