Skip to content

Commit

Permalink
bpo-38183: Test_idle ignores user config directory pythonGH-16198)
Browse files Browse the repository at this point in the history
It no longer tries to create or access .idlerc or any files within.
Users must run IDLE to discover problems with saving settings.
  • Loading branch information
terryjreedy authored Sep 16, 2019
1 parent 81528ba commit 0048afc
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 35 deletions.
28 changes: 16 additions & 12 deletions Lib/idlelib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def Save(self):
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')
Expand Down Expand Up @@ -166,12 +166,12 @@ def __init__(self, _utest=False):
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.
Expand All @@ -182,12 +182,13 @@ def GetUserCfgDir(self):
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?
Expand All @@ -197,10 +198,13 @@ def GetUserCfgDir(self):
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
Expand Down
34 changes: 18 additions & 16 deletions Lib/idlelib/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
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
Expand Down Expand Up @@ -924,9 +924,11 @@ def display_extra_help(helpfile=helpfile):

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:
Expand All @@ -942,19 +944,19 @@ def update_recent_files_list(self, new_file=None):
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
Expand Down
14 changes: 7 additions & 7 deletions Lib/idlelib/idle_test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def mock_config(self):

@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
Expand All @@ -243,7 +243,7 @@ def test_get_user_cfg_dir_unix(self):

@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
Expand Down Expand Up @@ -284,12 +284,12 @@ def test_create_config_handlers(self):
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)
Expand Down Expand Up @@ -373,7 +373,7 @@ def test_get_highlight(self):
'background': '#171717'})

def test_get_theme_dict(self):
"XXX: NOT YET DONE"
# TODO: finish.
conf = self.mock_config()

# These two should be the same
Expand Down
1 change: 1 addition & 0 deletions Lib/idlelib/pyshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ def __init__(self, *args):
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
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.

0 comments on commit 0048afc

Please sign in to comment.