[Idle-dev] KeyConfig, KeyBinding and other related issues.
Terry Reedy
tjreedy at udel.edu
Mon Jun 16 04:05:59 CEST 2014
On 6/15/2014 7:53 AM, Saimadhav Heblikar wrote:
> Hi,
> I followed the above direction and made some progress.
> Lib/tkinter/__init__.py Line 998, gives some more info on the syntax
> for keysequence.
>
> https://gist.github.com/sahutd/289d2297eb83a020a6dd#file-test-keyseq-v2-diff.
> It only covers a few exceptions. I am posting this early, before I am
> far away in the wrong direction.
>
> Also, is the key_ok method intended as a replacement for the existing
> KeysOk method? Or are both going to exist?
My thoughts as of this evening:
What we want is a broader check function usable in multiple places.
Whatever you write for testing may need to be modified for use in
multiple places. If we imagine putting a module-level function into
KeybindingDialog.py, definitions of constants (in LaodFinalKeyList and
TranslateKey) could be moved from class to module scope to make them
available to a new check function. The TranslateKey methods could also
be elevated, as it has no dependence on 'self' and is not really an
instance method.
Parameterless KeysOK is specific to and intertwined with the basic
dialog (which is why it can work without overt inputs). Since it mostly
works with the pieces used to create the keystring, it avoids parsing
the keystrings (which is why it cannot work with advanced mode). This
make it awful to test, compared with a function that take the keystring
as a parameter and parses it without other info.
After the keystring is fetched, the rest of the body could be replaced
with a call to a function that *does* parse. But that is not important
either way at the moment.
Since KeysOK shows at most one error message, the tkMessagebox call
could be factored out of the switch, with each branch setting msg
(else: would set it to ''). Then add at the end
'if msg:
tkMessageBox.showerror(
parent=self, title='Key Sequence Error',
message='Keystring {}: {}'.format(keys, msg))
I might actually do this.
Once done, the logic of KeysOK could be inverted to KeysNotOk (or
KeysBad) by returning msg. The caller could replace 'self.KeysOk' with
'not self.KeysBad'.
And additional refinement would make KeysBad even easier to test: a
dictionary of error messages (which also makes it easy to see the
conditions tested).
keyerrors = {
'empty' : 'no keys specified.',
'end' : 'missing the final Key'.
'mod' : 'no modifier key(s) specified.'.
'shift' : 'the shift modifier by itself may not be used with'
' this key symbol.'.
'dup' : 'this key combination is already in use.',
}
Now, if KeysBad sets messages with statements like
if not keys: msg = keyerrors['empty']
a test such as
self.assertIn(keyerrors['empty'], KeysBad(''))
is not only clear and easy to write, but is also robust against message
edits in the one and only location, the dictionary.
As you might have guessed, I am writing the above to answer your
question below.
keyerrors = {
...
}
def key_bad(keystring, showerror=True): # False in test files
<test and set msg if error>
if msg and showerror: tkMessage....
return msg
If you decide or plan to detect and report multiple errors, the details
of message construction can be altered.
When Idle initializes from .def files, keystrings should first be given
to tk, as now, and the check function only used to display an error
message after catching tcl_error. If key_bad returns '' when tk has
rejected it, display a backup message: 'tk rejects %s, but we cannot
determine why' % keystring.
> On 14 June 2014 15:46, Tal Einat <taleinat at gmail.com> wrote:
>>
>> To give a bit more direction on the implementation, the steps for the
>> parsing function should be roughly:
>>
>> 1) basic parsing: remove '<' and '>' and ends and split by '_'.
Perhaps the person who suggested a finite automaton was suggesting
transitions based on words after such a split, rather than character
based transitions, as with re engines. My main concern is that errors
get detected and reported.
>> 2) group parts into the three groups while checking that they are
>> valid (not empty, etc.)
> Grouping required a single line of regex.
> pat = '^<(?P<modifiers>(({modifier})-){{0,3}})(({type})-)?({detail})>$'.format(modifier=modifier_regex,type=type_regex,
> detail=detail_regex)
>
>>
>> 3) return the groups
>>
>> Each step should give an informative message if an error is encountered.
> For the above point, should key_ok method raise an error or return
> False or display a tkMessageBox ?
See above.
--
Terry Jan Reedy
More information about the IDLE-dev
mailing list