mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	Issue #27173: Add 'IDLE Modern Unix' to the built-in key sets.
Make the default key set depend on the platform. Add tests for changes to the config module.
This commit is contained in:
		
							parent
							
								
									ce85acff3a
								
							
						
					
					
						commit
						9bdb1edf35
					
				
					 5 changed files with 270 additions and 57 deletions
				
			
		| 
						 | 
					@ -109,6 +109,57 @@ change-indentwidth=<Alt-Key-u>
 | 
				
			||||||
del-word-left=<Alt-Key-BackSpace>
 | 
					del-word-left=<Alt-Key-BackSpace>
 | 
				
			||||||
del-word-right=<Alt-Key-d>
 | 
					del-word-right=<Alt-Key-d>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[IDLE Modern Unix]
 | 
				
			||||||
 | 
					copy = <Control-Shift-Key-C> <Control-Key-Insert>
 | 
				
			||||||
 | 
					cut = <Control-Key-x> <Shift-Key-Delete>
 | 
				
			||||||
 | 
					paste = <Control-Key-v> <Shift-Key-Insert>
 | 
				
			||||||
 | 
					beginning-of-line = <Key-Home>
 | 
				
			||||||
 | 
					center-insert = <Control-Key-l>
 | 
				
			||||||
 | 
					close-all-windows = <Control-Key-q>
 | 
				
			||||||
 | 
					close-window = <Control-Key-w> <Control-Shift-Key-W>
 | 
				
			||||||
 | 
					do-nothing = <Control-Key-F12>
 | 
				
			||||||
 | 
					end-of-file = <Control-Key-d>
 | 
				
			||||||
 | 
					history-next = <Alt-Key-n> <Meta-Key-n>
 | 
				
			||||||
 | 
					history-previous = <Alt-Key-p> <Meta-Key-p>
 | 
				
			||||||
 | 
					interrupt-execution = <Control-Key-c>
 | 
				
			||||||
 | 
					view-restart = <Key-F6>
 | 
				
			||||||
 | 
					restart-shell = <Control-Key-F6>
 | 
				
			||||||
 | 
					open-class-browser = <Control-Key-b>
 | 
				
			||||||
 | 
					open-module = <Control-Key-m>
 | 
				
			||||||
 | 
					open-new-window = <Control-Key-n>
 | 
				
			||||||
 | 
					open-window-from-file = <Control-Key-o>
 | 
				
			||||||
 | 
					plain-newline-and-indent = <Control-Key-j>
 | 
				
			||||||
 | 
					print-window = <Control-Key-p>
 | 
				
			||||||
 | 
					python-context-help = <Shift-Key-F1>
 | 
				
			||||||
 | 
					python-docs = <Key-F1>
 | 
				
			||||||
 | 
					redo = <Control-Shift-Key-Z>
 | 
				
			||||||
 | 
					remove-selection = <Key-Escape>
 | 
				
			||||||
 | 
					save-copy-of-window-as-file = <Alt-Shift-Key-S>
 | 
				
			||||||
 | 
					save-window-as-file = <Control-Shift-Key-S>
 | 
				
			||||||
 | 
					save-window = <Control-Key-s>
 | 
				
			||||||
 | 
					select-all = <Control-Key-a>
 | 
				
			||||||
 | 
					toggle-auto-coloring = <Control-Key-slash>
 | 
				
			||||||
 | 
					undo = <Control-Key-z>
 | 
				
			||||||
 | 
					find = <Control-Key-f>
 | 
				
			||||||
 | 
					find-again = <Key-F3>
 | 
				
			||||||
 | 
					find-in-files = <Control-Shift-Key-f>
 | 
				
			||||||
 | 
					find-selection = <Control-Key-h>
 | 
				
			||||||
 | 
					replace = <Control-Key-r>
 | 
				
			||||||
 | 
					goto-line = <Control-Key-g>
 | 
				
			||||||
 | 
					smart-backspace = <Key-BackSpace>
 | 
				
			||||||
 | 
					newline-and-indent = <Key-Return> <Key-KP_Enter>
 | 
				
			||||||
 | 
					smart-indent = <Key-Tab>
 | 
				
			||||||
 | 
					indent-region = <Control-Key-bracketright>
 | 
				
			||||||
 | 
					dedent-region = <Control-Key-bracketleft>
 | 
				
			||||||
 | 
					comment-region = <Control-Key-d>
 | 
				
			||||||
 | 
					uncomment-region = <Control-Shift-Key-D>
 | 
				
			||||||
 | 
					tabify-region = <Alt-Key-5>
 | 
				
			||||||
 | 
					untabify-region = <Alt-Key-6>
 | 
				
			||||||
 | 
					toggle-tabs = <Control-Key-T>
 | 
				
			||||||
 | 
					change-indentwidth = <Alt-Key-u>
 | 
				
			||||||
 | 
					del-word-left = <Control-Key-BackSpace>
 | 
				
			||||||
 | 
					del-word-right = <Control-Key-Delete>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[IDLE Classic Mac]
 | 
					[IDLE Classic Mac]
 | 
				
			||||||
copy=<Command-Key-c>
 | 
					copy=<Command-Key-c>
 | 
				
			||||||
cut=<Command-Key-x>
 | 
					cut=<Command-Key-x>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,9 @@ name2=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Keys]
 | 
					[Keys]
 | 
				
			||||||
default= 1
 | 
					default= 1
 | 
				
			||||||
name= IDLE Classic Windows
 | 
					name=
 | 
				
			||||||
 | 
					name2=
 | 
				
			||||||
 | 
					# name2 set in user config-main.cfg for keys added after 2016 July 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[History]
 | 
					[History]
 | 
				
			||||||
cyclic=1
 | 
					cyclic=1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,10 +234,7 @@ def GetOption(self, configType, section, option, default=None, type=None,
 | 
				
			||||||
                       ' from section %r: %r' %
 | 
					                       ' from section %r: %r' %
 | 
				
			||||||
                       (type, option, section,
 | 
					                       (type, option, section,
 | 
				
			||||||
                       self.userCfg[configType].Get(section, option, raw=raw)))
 | 
					                       self.userCfg[configType].Get(section, option, raw=raw)))
 | 
				
			||||||
            try:
 | 
					            _warn(warning, configType, section, option)
 | 
				
			||||||
                print(warning, file=sys.stderr)
 | 
					 | 
				
			||||||
            except OSError:
 | 
					 | 
				
			||||||
                pass
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if self.defaultCfg[configType].has_option(section,option):
 | 
					            if self.defaultCfg[configType].has_option(section,option):
 | 
				
			||||||
                return self.defaultCfg[configType].Get(
 | 
					                return self.defaultCfg[configType].Get(
 | 
				
			||||||
| 
						 | 
					@ -251,10 +248,7 @@ def GetOption(self, configType, section, option, default=None, type=None,
 | 
				
			||||||
                       ' from section %r.\n'
 | 
					                       ' from section %r.\n'
 | 
				
			||||||
                       ' returning default value: %r' %
 | 
					                       ' returning default value: %r' %
 | 
				
			||||||
                       (option, section, default))
 | 
					                       (option, section, default))
 | 
				
			||||||
            try:
 | 
					            _warn(warning, configType, section, option)
 | 
				
			||||||
                print(warning, file=sys.stderr)
 | 
					 | 
				
			||||||
            except OSError:
 | 
					 | 
				
			||||||
                pass
 | 
					 | 
				
			||||||
        return default
 | 
					        return default
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def SetOption(self, configType, section, option, value):
 | 
					    def SetOption(self, configType, section, option, value):
 | 
				
			||||||
| 
						 | 
					@ -362,47 +356,68 @@ def GetThemeDict(self, type, themeName):
 | 
				
			||||||
                           '\n from theme %r.\n'
 | 
					                           '\n from theme %r.\n'
 | 
				
			||||||
                           ' returning default color: %r' %
 | 
					                           ' returning default color: %r' %
 | 
				
			||||||
                           (element, themeName, theme[element]))
 | 
					                           (element, themeName, theme[element]))
 | 
				
			||||||
                try:
 | 
					                _warn(warning, 'highlight', themeName, element)
 | 
				
			||||||
                    print(warning, file=sys.stderr)
 | 
					 | 
				
			||||||
                except OSError:
 | 
					 | 
				
			||||||
                    pass
 | 
					 | 
				
			||||||
            theme[element] = cfgParser.Get(
 | 
					            theme[element] = cfgParser.Get(
 | 
				
			||||||
                    themeName, element, default=theme[element])
 | 
					                    themeName, element, default=theme[element])
 | 
				
			||||||
        return theme
 | 
					        return theme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def CurrentTheme(self):
 | 
					    def CurrentTheme(self):
 | 
				
			||||||
        """Return the name of the currently active text color theme.
 | 
					        "Return the name of the currently active text color theme."
 | 
				
			||||||
 | 
					        return self.current_colors_and_keys('Theme')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def CurrentKeys(self):
 | 
				
			||||||
 | 
					        """Return the name of the currently active key set."""
 | 
				
			||||||
 | 
					        return self.current_colors_and_keys('Keys')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def current_colors_and_keys(self, section):
 | 
				
			||||||
 | 
					        """Return the currently active name for Theme or Keys section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        idlelib.config-main.def ('default') includes these sections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        idlelib.config-main.def includes this section
 | 
					 | 
				
			||||||
        [Theme]
 | 
					        [Theme]
 | 
				
			||||||
        default= 1
 | 
					        default= 1
 | 
				
			||||||
        name= IDLE Classic
 | 
					        name= IDLE Classic
 | 
				
			||||||
        name2=
 | 
					        name2=
 | 
				
			||||||
        # name2 set in user config-main.cfg for themes added after 2015 Oct 1
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Item name2 is needed because setting name to a new builtin
 | 
					        [Keys]
 | 
				
			||||||
        causes older IDLEs to display multiple error messages or quit.
 | 
					        default= 1
 | 
				
			||||||
 | 
					        name=
 | 
				
			||||||
 | 
					        name2=
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Item 'name2', is used for built-in ('default') themes and keys
 | 
				
			||||||
 | 
					        added after 2015 Oct 1 and 2016 July 1.  This kludge is needed
 | 
				
			||||||
 | 
					        because setting 'name' to a builtin not defined in older IDLEs
 | 
				
			||||||
 | 
					        to display multiple error messages or quit.
 | 
				
			||||||
        See https://bugs.python.org/issue25313.
 | 
					        See https://bugs.python.org/issue25313.
 | 
				
			||||||
        When default = True, name2 takes precedence over name,
 | 
					        When default = True, 'name2' takes precedence over 'name',
 | 
				
			||||||
        while older IDLEs will just use name.
 | 
					        while older IDLEs will just use name.  When default = False,
 | 
				
			||||||
 | 
					        'name2' may still be set, but it is ignored.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        cfgname = 'highlight' if section == 'Theme' else 'keys'
 | 
				
			||||||
        default = self.GetOption('main', 'Theme', 'default',
 | 
					        default = self.GetOption('main', 'Theme', 'default',
 | 
				
			||||||
                                 type='bool', default=True)
 | 
					                                 type='bool', default=True)
 | 
				
			||||||
 | 
					        name = ''
 | 
				
			||||||
        if default:
 | 
					        if default:
 | 
				
			||||||
            theme = self.GetOption('main', 'Theme', 'name2', default='')
 | 
					            name = self.GetOption('main', section, 'name2', default='')
 | 
				
			||||||
        if default and not theme or not default:
 | 
					        if not name:
 | 
				
			||||||
            theme = self.GetOption('main', 'Theme', 'name', default='')
 | 
					            name = self.GetOption('main', section, 'name', default='')
 | 
				
			||||||
 | 
					        if name:
 | 
				
			||||||
            source = self.defaultCfg if default else self.userCfg
 | 
					            source = self.defaultCfg if default else self.userCfg
 | 
				
			||||||
        if source['highlight'].has_section(theme):
 | 
					            if source[cfgname].has_section(name):
 | 
				
			||||||
            return theme
 | 
					                return name
 | 
				
			||||||
 | 
					        return "IDLE Classic" if section == 'Theme' else self.default_keys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def default_keys():
 | 
				
			||||||
 | 
					        if sys.platform[:3] == 'win':
 | 
				
			||||||
 | 
					            return 'IDLE Classic Windows'
 | 
				
			||||||
 | 
					        elif sys.platform == 'darwin':
 | 
				
			||||||
 | 
					            return 'IDLE Classic OSX'
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return "IDLE Classic"
 | 
					            return 'IDLE Modern Unix'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def CurrentKeys(self):
 | 
					    def GetExtensions(self, active_only=True,
 | 
				
			||||||
        "Return the name of the currently active key set."
 | 
					                      editor_only=False, shell_only=False):
 | 
				
			||||||
        return self.GetOption('main', 'Keys', 'name', default='')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
 | 
					 | 
				
			||||||
        """Return extensions in default and user config-extensions files.
 | 
					        """Return extensions in default and user config-extensions files.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        If active_only True, only return active (enabled) extensions
 | 
					        If active_only True, only return active (enabled) extensions
 | 
				
			||||||
| 
						 | 
					@ -422,7 +437,7 @@ def GetExtensions(self, active_only=True, editor_only=False, shell_only=False):
 | 
				
			||||||
                if self.GetOption('extensions', extn, 'enable', default=True,
 | 
					                if self.GetOption('extensions', extn, 'enable', default=True,
 | 
				
			||||||
                                  type='bool'):
 | 
					                                  type='bool'):
 | 
				
			||||||
                    #the extension is enabled
 | 
					                    #the extension is enabled
 | 
				
			||||||
                    if editor_only or shell_only:  # TODO if both, contradictory
 | 
					                    if editor_only or shell_only:  # TODO both True contradict
 | 
				
			||||||
                        if editor_only:
 | 
					                        if editor_only:
 | 
				
			||||||
                            option = "enable_editor"
 | 
					                            option = "enable_editor"
 | 
				
			||||||
                        else:
 | 
					                        else:
 | 
				
			||||||
| 
						 | 
					@ -527,7 +542,8 @@ def GetKeyBinding(self, keySetName, eventStr):
 | 
				
			||||||
        eventStr - virtual event, including brackets, as in '<<event>>'.
 | 
					        eventStr - virtual event, including brackets, as in '<<event>>'.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        eventName = eventStr[2:-2] #trim off the angle brackets
 | 
					        eventName = eventStr[2:-2] #trim off the angle brackets
 | 
				
			||||||
        binding = self.GetOption('keys', keySetName, eventName, default='').split()
 | 
					        binding = self.GetOption('keys', keySetName, eventName, default='',
 | 
				
			||||||
 | 
					                                 warn_on_default=False).split()
 | 
				
			||||||
        return binding
 | 
					        return binding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def GetCurrentKeySet(self):
 | 
					    def GetCurrentKeySet(self):
 | 
				
			||||||
| 
						 | 
					@ -638,20 +654,28 @@ def GetCoreKeys(self, keySetName=None):
 | 
				
			||||||
            '<<del-word-right>>': ['<Control-Key-Delete>']
 | 
					            '<<del-word-right>>': ['<Control-Key-Delete>']
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        if keySetName:
 | 
					        if keySetName:
 | 
				
			||||||
 | 
					            if not (self.userCfg['keys'].has_section(keySetName) or
 | 
				
			||||||
 | 
					                    self.defaultCfg['keys'].has_section(keySetName)):
 | 
				
			||||||
 | 
					                warning = (
 | 
				
			||||||
 | 
					                    '\n Warning: config.py - IdleConf.GetCoreKeys -\n'
 | 
				
			||||||
 | 
					                    ' key set %r is not defined, using default bindings.' %
 | 
				
			||||||
 | 
					                    (keySetName,)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                _warn(warning, 'keys', keySetName)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
                for event in keyBindings:
 | 
					                for event in keyBindings:
 | 
				
			||||||
                    binding = self.GetKeyBinding(keySetName, event)
 | 
					                    binding = self.GetKeyBinding(keySetName, event)
 | 
				
			||||||
                    if binding:
 | 
					                    if binding:
 | 
				
			||||||
                        keyBindings[event] = binding
 | 
					                        keyBindings[event] = binding
 | 
				
			||||||
                    else: #we are going to return a default, print warning
 | 
					                    else: #we are going to return a default, print warning
 | 
				
			||||||
                    warning=('\n Warning: config.py - IdleConf.GetCoreKeys'
 | 
					                        warning = (
 | 
				
			||||||
                               ' -\n problem retrieving key binding for event %r'
 | 
					                            '\n Warning: config.py - IdleConf.GetCoreKeys -\n'
 | 
				
			||||||
                               '\n from key set %r.\n'
 | 
					                            ' problem retrieving key binding for event %r\n'
 | 
				
			||||||
 | 
					                            ' from key set %r.\n'
 | 
				
			||||||
                            ' returning default value: %r' %
 | 
					                            ' returning default value: %r' %
 | 
				
			||||||
                               (event, keySetName, keyBindings[event]))
 | 
					                            (event, keySetName, keyBindings[event])
 | 
				
			||||||
                    try:
 | 
					                        )
 | 
				
			||||||
                        print(warning, file=sys.stderr)
 | 
					                        _warn(warning, 'keys', keySetName, event)
 | 
				
			||||||
                    except OSError:
 | 
					 | 
				
			||||||
                        pass
 | 
					 | 
				
			||||||
        return keyBindings
 | 
					        return keyBindings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def GetExtraHelpSourceList(self, configSet):
 | 
					    def GetExtraHelpSourceList(self, configSet):
 | 
				
			||||||
| 
						 | 
					@ -735,6 +759,18 @@ def SaveUserCfgFiles(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
idleConf = IdleConf()
 | 
					idleConf = IdleConf()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_warned = set()
 | 
				
			||||||
 | 
					def _warn(msg, *key):
 | 
				
			||||||
 | 
					    key = (msg,) + key
 | 
				
			||||||
 | 
					    if key not in _warned:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            print(msg, file=sys.stderr)
 | 
				
			||||||
 | 
					        except OSError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        _warned.add(key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# TODO Revise test output, write expanded unittest
 | 
					# TODO Revise test output, write expanded unittest
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -341,6 +341,7 @@ def CreatePageKeys(self):
 | 
				
			||||||
        buttonSaveCustomKeys = Button(
 | 
					        buttonSaveCustomKeys = Button(
 | 
				
			||||||
                frames[1], text='Save as New Custom Key Set',
 | 
					                frames[1], text='Save as New Custom Key Set',
 | 
				
			||||||
                command=self.SaveAsNewKeySet)
 | 
					                command=self.SaveAsNewKeySet)
 | 
				
			||||||
 | 
					        self.new_custom_keys = Label(frames[0], bd=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ##widget packing
 | 
					        ##widget packing
 | 
				
			||||||
        #body
 | 
					        #body
 | 
				
			||||||
| 
						 | 
					@ -361,6 +362,7 @@ def CreatePageKeys(self):
 | 
				
			||||||
        self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS)
 | 
					        self.radioKeysCustom.grid(row=1, column=0, sticky=W+NS)
 | 
				
			||||||
        self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW)
 | 
					        self.optMenuKeysBuiltin.grid(row=0, column=1, sticky=NSEW)
 | 
				
			||||||
        self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW)
 | 
					        self.optMenuKeysCustom.grid(row=1, column=1, sticky=NSEW)
 | 
				
			||||||
 | 
					        self.new_custom_keys.grid(row=0, column=2, sticky=NSEW, padx=5, pady=5)
 | 
				
			||||||
        self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
 | 
					        self.buttonDeleteCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
 | 
				
			||||||
        buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
 | 
					        buttonSaveCustomKeys.pack(side=LEFT, fill=X, expand=True, padx=2)
 | 
				
			||||||
        frames[0].pack(side=TOP, fill=BOTH, expand=True)
 | 
					        frames[0].pack(side=TOP, fill=BOTH, expand=True)
 | 
				
			||||||
| 
						 | 
					@ -514,10 +516,11 @@ def VarChanged_colour(self, *params):
 | 
				
			||||||
        self.OnNewColourSet()
 | 
					        self.OnNewColourSet()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def VarChanged_builtinTheme(self, *params):
 | 
					    def VarChanged_builtinTheme(self, *params):
 | 
				
			||||||
 | 
					        oldthemes = ('IDLE Classic', 'IDLE New')
 | 
				
			||||||
        value = self.builtinTheme.get()
 | 
					        value = self.builtinTheme.get()
 | 
				
			||||||
        if value == 'IDLE Dark':
 | 
					        if value not in oldthemes:
 | 
				
			||||||
            if idleConf.GetOption('main', 'Theme', 'name') != 'IDLE New':
 | 
					            if idleConf.GetOption('main', 'Theme', 'name') not in oldthemes:
 | 
				
			||||||
                self.AddChangedItem('main', 'Theme', 'name', 'IDLE Classic')
 | 
					                self.AddChangedItem('main', 'Theme', 'name', oldthemes[0])
 | 
				
			||||||
            self.AddChangedItem('main', 'Theme', 'name2', value)
 | 
					            self.AddChangedItem('main', 'Theme', 'name2', value)
 | 
				
			||||||
            self.new_custom_theme.config(text='New theme, see Help',
 | 
					            self.new_custom_theme.config(text='New theme, see Help',
 | 
				
			||||||
                                         fg='#500000')
 | 
					                                         fg='#500000')
 | 
				
			||||||
| 
						 | 
					@ -557,8 +560,23 @@ def VarChanged_keyBinding(self, *params):
 | 
				
			||||||
            self.AddChangedItem('extensions', extKeybindSection, event, value)
 | 
					            self.AddChangedItem('extensions', extKeybindSection, event, value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def VarChanged_builtinKeys(self, *params):
 | 
					    def VarChanged_builtinKeys(self, *params):
 | 
				
			||||||
 | 
					        oldkeys = (
 | 
				
			||||||
 | 
					            'IDLE Classic Windows',
 | 
				
			||||||
 | 
					            'IDLE Classic Unix',
 | 
				
			||||||
 | 
					            'IDLE Classic Mac',
 | 
				
			||||||
 | 
					            'IDLE Classic OSX',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        value = self.builtinKeys.get()
 | 
					        value = self.builtinKeys.get()
 | 
				
			||||||
 | 
					        if value not in oldkeys:
 | 
				
			||||||
 | 
					            if idleConf.GetOption('main', 'Keys', 'name') not in oldkeys:
 | 
				
			||||||
 | 
					                self.AddChangedItem('main', 'Keys', 'name', oldkeys[0])
 | 
				
			||||||
 | 
					            self.AddChangedItem('main', 'Keys', 'name2', value)
 | 
				
			||||||
 | 
					            self.new_custom_keys.config(text='New key set, see Help',
 | 
				
			||||||
 | 
					                                        fg='#500000')
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
            self.AddChangedItem('main', 'Keys', 'name', value)
 | 
					            self.AddChangedItem('main', 'Keys', 'name', value)
 | 
				
			||||||
 | 
					            self.AddChangedItem('main', 'Keys', 'name2', '')
 | 
				
			||||||
 | 
					            self.new_custom_keys.config(text='', fg='black')
 | 
				
			||||||
        self.LoadKeysList(value)
 | 
					        self.LoadKeysList(value)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def VarChanged_customKeys(self, *params):
 | 
					    def VarChanged_customKeys(self, *params):
 | 
				
			||||||
| 
						 | 
					@ -767,8 +785,10 @@ def DeleteCustomKeys(self):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
 | 
					            self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
 | 
				
			||||||
        #revert to default key set
 | 
					        #revert to default key set
 | 
				
			||||||
        self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
 | 
					        self.keysAreBuiltin.set(idleConf.defaultCfg['main']
 | 
				
			||||||
        self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
 | 
					                                .Get('Keys', 'default'))
 | 
				
			||||||
 | 
					        self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name')
 | 
				
			||||||
 | 
					                             or idleConf.default_keys())
 | 
				
			||||||
        #user can't back out of these changes, they must be applied now
 | 
					        #user can't back out of these changes, they must be applied now
 | 
				
			||||||
        self.SaveAllChangedConfigs()
 | 
					        self.SaveAllChangedConfigs()
 | 
				
			||||||
        self.ActivateConfigChanges()
 | 
					        self.ActivateConfigChanges()
 | 
				
			||||||
| 
						 | 
					@ -1067,7 +1087,7 @@ def LoadKeyCfg(self):
 | 
				
			||||||
            self.optMenuKeysCustom.SetMenu(itemList, currentOption)
 | 
					            self.optMenuKeysCustom.SetMenu(itemList, currentOption)
 | 
				
			||||||
            itemList = idleConf.GetSectionList('default', 'keys')
 | 
					            itemList = idleConf.GetSectionList('default', 'keys')
 | 
				
			||||||
            itemList.sort()
 | 
					            itemList.sort()
 | 
				
			||||||
            self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
 | 
					            self.optMenuKeysBuiltin.SetMenu(itemList, idleConf.default_keys())
 | 
				
			||||||
        self.SetKeysType()
 | 
					        self.SetKeysType()
 | 
				
			||||||
        ##load keyset element list
 | 
					        ##load keyset element list
 | 
				
			||||||
        keySetName = idleConf.CurrentKeys()
 | 
					        keySetName = idleConf.CurrentKeys()
 | 
				
			||||||
| 
						 | 
					@ -1374,7 +1394,13 @@ def save_all_changed_extensions(self):
 | 
				
			||||||
The IDLE Dark color theme is new in October 2015.  It can only
 | 
					The IDLE Dark color theme is new in October 2015.  It can only
 | 
				
			||||||
be used with older IDLE releases if it is saved as a custom
 | 
					be used with older IDLE releases if it is saved as a custom
 | 
				
			||||||
theme, with a different name.
 | 
					theme, with a different name.
 | 
				
			||||||
'''
 | 
					''',
 | 
				
			||||||
 | 
					    'Keys': '''
 | 
				
			||||||
 | 
					Keys:
 | 
				
			||||||
 | 
					The IDLE Modern Unix key set is new in June 2016.  It can only
 | 
				
			||||||
 | 
					be used with older IDLE releases if it is saved as a custom
 | 
				
			||||||
 | 
					key set, with a different name.
 | 
				
			||||||
 | 
					''',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										98
									
								
								Lib/idlelib/idle_test/test_config.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								Lib/idlelib/idle_test/test_config.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,98 @@
 | 
				
			||||||
 | 
					'''Test idlelib.config.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Much is tested by opening config dialog live or in test_configdialog.
 | 
				
			||||||
 | 
					Coverage: 27%
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					from sys import modules
 | 
				
			||||||
 | 
					from test.support import captured_stderr
 | 
				
			||||||
 | 
					from tkinter import Tk
 | 
				
			||||||
 | 
					import unittest
 | 
				
			||||||
 | 
					from idlelib import config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Tests should not depend on fortuitous user configurations.
 | 
				
			||||||
 | 
					# They must not affect actual user .cfg files.
 | 
				
			||||||
 | 
					# Replace user parsers with empty parsers that cannot be saved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					idleConf = config.idleConf
 | 
				
			||||||
 | 
					usercfg = idleConf.userCfg
 | 
				
			||||||
 | 
					testcfg = {}
 | 
				
			||||||
 | 
					usermain = testcfg['main'] = config.IdleUserConfParser('')  # filename
 | 
				
			||||||
 | 
					userhigh = testcfg['highlight'] = config.IdleUserConfParser('')
 | 
				
			||||||
 | 
					userkeys = testcfg['keys'] = config.IdleUserConfParser('')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def setUpModule():
 | 
				
			||||||
 | 
					    idleConf.userCfg = testcfg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def tearDownModule():
 | 
				
			||||||
 | 
					    idleConf.userCfg = testcfg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CurrentColorKeysTest(unittest.TestCase):
 | 
				
			||||||
 | 
					    """Test correct scenarios for colorkeys and wrap functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The 5 correct patterns are possible results of config dialog.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    colorkeys = idleConf.current_colors_and_keys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_old_default(self):
 | 
				
			||||||
 | 
					        # name2 must be blank
 | 
				
			||||||
 | 
					        usermain.read_string('''
 | 
				
			||||||
 | 
					            [Theme]
 | 
				
			||||||
 | 
					            default= 1
 | 
				
			||||||
 | 
					            ''')
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE Classic')
 | 
				
			||||||
 | 
					        usermain['Theme']['name'] = 'IDLE New'
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE New')
 | 
				
			||||||
 | 
					        usermain['Theme']['name'] = 'non-default'  # error
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE Classic')
 | 
				
			||||||
 | 
					        usermain.remove_section('Theme')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_new_default(self):
 | 
				
			||||||
 | 
					        # name2 overrides name
 | 
				
			||||||
 | 
					        usermain.read_string('''
 | 
				
			||||||
 | 
					            [Theme]
 | 
				
			||||||
 | 
					            default= 1
 | 
				
			||||||
 | 
					            name= IDLE New
 | 
				
			||||||
 | 
					            name2= IDLE Dark
 | 
				
			||||||
 | 
					            ''')
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE Dark')
 | 
				
			||||||
 | 
					        usermain['Theme']['name2'] = 'non-default'  # error
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE Classic')
 | 
				
			||||||
 | 
					        usermain.remove_section('Theme')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_user_override(self):
 | 
				
			||||||
 | 
					        # name2 does not matter
 | 
				
			||||||
 | 
					        usermain.read_string('''
 | 
				
			||||||
 | 
					            [Theme]
 | 
				
			||||||
 | 
					            default= 0
 | 
				
			||||||
 | 
					            name= Custom Dark
 | 
				
			||||||
 | 
					            ''')  # error until set userhigh
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'IDLE Classic')
 | 
				
			||||||
 | 
					        userhigh.read_string('[Custom Dark]\na=b')
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'Custom Dark')
 | 
				
			||||||
 | 
					        usermain['Theme']['name2'] = 'IDLE Dark'
 | 
				
			||||||
 | 
					        self.assertEqual(self.colorkeys('Theme'), 'Custom Dark')
 | 
				
			||||||
 | 
					        usermain.remove_section('Theme')
 | 
				
			||||||
 | 
					        userhigh.remove_section('Custom Dark')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WarningTest(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_warn(self):
 | 
				
			||||||
 | 
					        Equal = self.assertEqual
 | 
				
			||||||
 | 
					        config._warned = set()
 | 
				
			||||||
 | 
					        with captured_stderr() as stderr:
 | 
				
			||||||
 | 
					            config._warn('warning', 'key')
 | 
				
			||||||
 | 
					        Equal(config._warned, {('warning','key')})
 | 
				
			||||||
 | 
					        Equal(stderr.getvalue(), 'warning'+'\n')
 | 
				
			||||||
 | 
					        with captured_stderr() as stderr:
 | 
				
			||||||
 | 
					            config._warn('warning', 'key')
 | 
				
			||||||
 | 
					        Equal(stderr.getvalue(), '')
 | 
				
			||||||
 | 
					        with captured_stderr() as stderr:
 | 
				
			||||||
 | 
					            config._warn('warn2', 'yek')
 | 
				
			||||||
 | 
					        Equal(config._warned, {('warning','key'), ('warn2','yek')})
 | 
				
			||||||
 | 
					        Equal(stderr.getvalue(), 'warn2'+'\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    unittest.main(verbosity=2)
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue