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 <talei...@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

_______________________________________________
IDLE-dev mailing list
IDLE-dev@python.org
https://mail.python.org/mailman/listinfo/idle-dev

Reply via email to