Menu

#252 8.5 breaks some Tkinter text widgets

open
27. Objects (2)
8
2009-07-29
2007-12-15
No

8.5 is causing the Tkinter EditorWindow class to break for some unknown reason. When the user clicks <1> the event is delivered, but for some reason the Tk code isn't behaving properly. Therefore you can't select text for copying and pasting.

This is this code that seems to break with 8.5, and I'm not sure why yet:
Python-2.5.1/Lib/idlelib/EditorWindow.py

The same code works fine with Python 2.5.1 using Tcl/Tk 8.4.

Here's what I've done so far:
I've verified that the events are being delivered with this code:
print(text.bind_class ("Text", "<1>", None, None))
cmd = text.bind_class("Text", "<1>", None, None)
cmd = 'puts TextB1;' + cmd
text.bind_class ("Text", "<1>", cmd)

I've gone hunting in various other places for the bug, with little success.

You can run: /path/to/8.5/using/python EditorWindow.py

Whatever this bug is breaks IDLE (the standard Python editor that uses Tkinter).

In a related note: they are using MacOSX private symbols, so it may already be broken on Mac OS X if those are MODULE_SCOPEd. Some sort of better cooperation is needed between the Tkinter and Tk developers.

Discussion

  • Anonymous

    Anonymous - 2007-12-15

    Logged In: YES
    user_id=585068
    Originator: YES

    I've discovered that a Tcl callback that Tkinter was evaluating was throwing an error and therefore not working properly. However Tkinter seems to ignore such errors, and there was no report of it to stderr or otherwise. :-/

    proc ::tk::dump val { puts DUMP:$val; return $val }
    proc ::tk::TextButton1 {w x y} {
    variable ::tk::Priv

    set Priv(selectMode) char
    set Priv(mouseMoved) 0
    set Priv(pressX) $x
    parray Priv

    puts "$w $x $y"
    if {[catch {$w mark set insert [TextClosestGap $w $x $y]} err]} {
    puts ERR:$err
    }
    ...
    }

    The ERR is: can't use non-numeric string as operand of "-"

    Here's where it gets weirder. For some reason in TextClosestGap the bbox subcommand is returning garbage like this: BBOX:(43, 3, 6, 10)

    This doesn't happen with 8.4. The same BBOX subcommand in 8.4 returns a proper *Tcl* list. All of which leaves me very puzzled. Perhaps Tkinter does something differently with 8.4 and assumes older code for the newer 8.5.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    Very strange: either the X coordinate is non-numeric or the result of [lindex $bbox 0] is non-numeric. Not sure which is worse.

    In general, setting a bgerror handler ought to pick up problems like this. Problem is, it might conflict with the Tkinter one (which sounds insufficiently robust against errors from the Tcl side of things...)

     
  • Don Porter

    Don Porter - 2007-12-17
    • priority: 9 --> 8
     
  • Martin v. Löwis

    Logged In: YES
    user_id=21627
    Originator: NO

    If there was a way for Python to raise a Python exception in _tkerror, so that Tk's bgerror won't subsequently open a window catching that exception - that would be a good thing. IIUC, Tkinter._tkerror is empty because there is no meaningful way to report the error (and Tk's default behavior of opening a window isn't quite acceptable).

     
  • Martin v. Löwis

    Logged In: YES
    user_id=21627
    Originator: NO

    I found the source of the problem: Lib.idlelib.WidgetRedirector.dispatch gets invoked, and invokes the original Tk bbox command. This returns a Tcl list, which _tkinter converts into a Python tuple, which gets returned from dispatch. In turn, _tkinter then converts the tuple back, but now returns a string to Tcl, in the interpreter result, such as "(41, 3, 8, 20)". This then causes the Tcl error, trying to index that string as a list.

    Apparently, in Tcl 8.4, bbox returned a space-separated list of numbers, instead of a Tcl list. When that got passed through, Tcl would happily consider it a list again.

     
  • Martin v. Löwis

    Logged In: YES
    user_id=21627
    Originator: NO

    This is now fixed in r59653 in the Python repository, for Python 2.6. I don't think the patch can be backported to 2.5, as it may have other side effects when Python callbacks stop always returning strings to Tcl.

     
  • Michael Schlenker

    Logged In: YES
    user_id=302287
    Originator: NO

    Hi Loewis,

    re: Tcl list or space seperated values are semantically the same on the Tcl script level, but as Tkinter fiddles with the intreps for performance stuff is a bit more fragile as you noticed and there have been some changes to list handling internally. I would have assumed a python tuple always gets converted to Tcl list its the natural mapping.

    re: bgerror
    You should be able to redefine bgerror to do what you want in your startup and initialization code for tkinter. Just add some Tcl proc named bgerror there that does what you want.

     
  • Martin v. Löwis

    Logged In: YES
    user_id=21627
    Originator: NO

    re "fiddles with the intreps for performance stuff". It's not just for performance, but also for correctness. While '100' and 100 are the same to Tcl, they are not in Python. We had huge problems with fragility when Tcl started using Unicode in some contexts; we really need to know it's a Unicode string, or else we cannot know whether to convert it to a Python byte string or a Unicode string.

    re bgerror: Please trust me that "define a procedure that does what you want" does not work. Just define

    def bgerror(msg):
    raise TclError(msg)

    and see for yourself.

     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    Re strings: they're always logically unicode with Tcl and Tk (but might be in utf-8 or a bytearray at the time) and have been so for many years. Using Tcl_GetStringFromObj will (unless something bad is happening) return UTF-8 (except with any embedded NUL characters denormalized so stuff like strlen() won't crap out on them).

    Re using internal representations: be aware that such things can be changed without warning (or much announcement) for purely performance-optimization reasons. Depending on them to indicate 'type' is manifestly unsafe. This is a fundamental difference in type systems... On the other hand, when it comes to bounding boxes, they're always 4-element Tcl lists of doubles at the logical level. :)

     
  • Martin v. Löwis

    Logged In: YES
    user_id=21627
    Originator: NO

    This tracker-item is probably the wrong place to discuss it - but if somebody thinks Python's usage of Tcl objects is incorrect, I would like to discuss alternatives, as I don't believe Tcl offers any viable alternative.

     
  • Anonymous

    Anonymous - 2008-01-16
    • assigned_to: georgeps --> hobbs
     
  • Donal K. Fellows

    • labels: 104346 -->
     
  • Donal K. Fellows

    Logged In: YES
    user_id=79902
    Originator: NO

    Transferred to different (unused) tracker to make old URLs to this issue invalid. Let's see if that stems the spam tide...

     
  • Donal K. Fellows

    • labels: --> 27. Objects
     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.