classification
Title: Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6)
Type: behavior Stage: resolved
Components: IDLE, Tkinter Versions: Python 3.6, Python 3.5, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Odcar, doko, gpolo, kbk, markroseman, petr.viktorin, python-dev, roger.serwy, serhiy.storchaka, terry.reedy, wysaard
Priority: normal Keywords:

Created on 2016-03-30 15:32 by wysaard, last changed 2017-09-19 21:53 by serhiy.storchaka. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 3639 serhiy.storchaka, 2017-09-19 21:53
Messages (19)
msg262670 - (view) Author: (wysaard) Date: 2016-03-30 15:32
I'm using Python 3.5.1 on Arch Linux. I've restalled the python package which provides IDLE, and the tkinter package which is used by IDLE, but to no effect.

My problem is this: When in the menu at the top in IDLE, I click on Options -> Configure IDLE, the menu will stop responding, and nothing happens after that.

Doing this when I run IDLE in a terminal provides the following error on clicking `Configure IDLE`:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1549, in __call__
    return self.func(*args)
  File "/usr/lib/python3.5/idlelib/EditorWindow.py", line 516, in config_dialog
    configDialog.ConfigDialog(self.top,'Settings')
  File "/usr/lib/python3.5/idlelib/configDialog.py", line 74, in __init__
    self.LoadConfigs()
  File "/usr/lib/python3.5/idlelib/configDialog.py", line 1086, in LoadConfigs
    self.LoadFontCfg()
  File "/usr/lib/python3.5/idlelib/configDialog.py", line 988, in LoadFontCfg
    self.SetFontSample()
  File "/usr/lib/python3.5/idlelib/configDialog.py", line 866, in SetFontSample
    self.labelFontSample.config(font=newFont)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1330, in configure
    return self._configure('configure', cnf, kw)
  File "/usr/lib/python3.5/tkinter/__init__.py", line 1321, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: expected integer but got ""

I have no idea what to do here.
msg262741 - (view) Author: (wysaard) Date: 2016-04-01 14:02
I'm having the problem if I'm running idle with Python 2.7.11 too.
msg262752 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-04-01 17:51
Serhiy, what do you make of the TclError?  Could it be an ArchLinux-specific bug in tk?

Here is the entire function:

    def SetFontSample(self, event=None):
        fontName = self.fontName.get()
        fontWeight = tkFont.BOLD if self.fontBold.get() else tkFont.NORMAL
        newFont = (fontName, self.fontSize.get(), fontWeight)
        self.labelFontSample.config(font=newFont)
        self.textHighlightSample.configure(font=newFont)

The first 3 lines were last touched on 2014-08-03, the last 3 on 2012-10-22. The code seem unexceptional.  This works fine for me and, I presume, most everyone else.

wysaard: What tk version does Arch Linux provide you?  Check Help => About IDLE before you hit configure.
msg262755 - (view) Author: (wysaard) Date: 2016-04-01 18:53
In the screen of `About IDLE` it shows "Tk version 8.6.4".
It used to work, as least since last september (when I installed this) I've had no problems. I assumed reinstalling would solve it but that did nothing. I've removed the entire python package, made my package manager download a fresh version and install it from scratch, and did the same with Tk.

Trying to find any related bug reports on the Arch Linux bug tracker I found something linking to this (open) issue: https://bugs.python.org/issue24951
I'm not sure the cause is exactly the same,  but the traceback is near identical.

It seems to have something to do with a config file. Maybe there's something broken in there, or perhaps a something is missing?
A broken config file would be weird as reinstalling doesn't fix anything, unless my package manager doesn't remove the config file when uninstalling the package, which isn't impossible either.
msg262759 - (view) Author: (wysaard) Date: 2016-04-01 19:43
I just fixed this problem.

In my ~/.idlerc/ folder there was no `config-main.cfg` so I created it and used the settings found here: https://svn.python.org/projects/python/trunk/Mac/IDLE/config-main.def

After doing that everything worked fine again.

I'm not sure where this bug came from though, whether it's my package manager, or some bug in IDLE itself that created this problem; I also don't know if this is normal behavior for a missing config file; so I do n't know whether to close this or not, so I'll leave that to you.
msg262770 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-04-01 20:51
I should have thought of .idlerc as being a possible problem.  The usual fix is to delete its contents.

For this tracker, exiting with a traceback is a behavior issue; a crash is something worse, a core dump or whatever the MAC equivalent is.

.idlerc should not have config-main.cfg unless you change one of the values in idlelib/config-main.def.  If you change anything, the redundant entries will be removed.  Similarly for the other .idlerc/*.cfg versus idlelib/*.def files.

So missing that file should not have been a problem.  But it might have been if idlelib/config-main.def is corrupt.  I suggest you check it.  However, it it were, I would expect IDLE startup to fail, but it did not.

Since .idlerc is common to all installed version of Python, and hence to all IDLEs, it is not touched by installation or removal of any particular version.

The file you copied is perhaps a decade old.  However, the only changes should be

[EditorWindow]
font= TkFixedFont
[General]
print-command-posix=lpr %%s
print-command-win=start /min notepad /p %%s
[Theme]
name2=
# name2 set in user config-main.cfg for themes added after 2015 Oct 1

The third is needed if you select the new IDLE Dark color theme.

In ConfigDialog, self.fontSize is a StringVar, so it would seem that the error was it being '' rather than something like '10'.  Since you have 'fixed' the problem, I don't anticipate being to verify what its value was or why.  Hence I will close this.  However, feel free to post additional relevant information.  (Interpret 'Not a bug' here as 'cause unknown' ;-).
msg262797 - (view) Author: (wysaard) Date: 2016-04-02 15:15
For some reason the freshly downloaded files have this problem too. If I remove my config-main.def and let my package manager get a new one it breaks again. I don't really know the implications of this; is this just a problem with my particular setup or does this mean that maybe the file in the package is invalid?
msg263175 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2016-04-11 09:56
I can reproduce this with Python 2.7.11 and somewhat recent build from hg default (3.6.0a0) on Fedora 23.
Putting these lines in my personal config-main.cfg solves this::

    [EditorWindow]
    font= courier

idlelib/config-main.def has a different default::

    [EditorWindow]
    font= TkFixedFont

Putting that value in my personal config-main.cfg makes the bug manifest itself again.
With "nonexistent-font-name-7202125ed0a", the bug does not appear.
With an existing font, "DejaVu Sans Mono", the bug does not appear.

I hacked the code to get the values used in the line, ``self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))``. For TkFixedFont (the buggy case), they are::

    self._w: '.139719100555208.139719021773312.139719021373632.139719021374064.139719021375144.13971902101484
0.139719021045736.139719021045880'
    cmd: 'configure'
    cnf: {'font': ('dejavu sans mono', '', 'normal')}
    _flatten((self._w, cmd)): ('.139719100555208.139719021773312.139719021373632.139719021374064.139719021375144.1397190210148
40.139719021045736.139719021045880', 'configure')
    self._options(cnf): ('-font', u'{dejavu sans mono} {} normal')

For the good case ("courier" font):

    self._w:'.140181531287496.140181452501216.140181451999568.140181451999712.140181452055904.140181451660176.140181451660464',
    cmd: 'configure'
    cnf: {'font': ('courier', '10', 'normal')}
    _flatten((self._w, cmd)): ('.140181531287496.140181452501216.140181451999568.140181451999712.140181452055904.140181451660176.140181451660464', 'configure')
    self._options(cnf):  ('-font', u'courier 10 normal')

The difference is indeed that it's getting an empty string for the font size.
This happens even if "font-size= 10" is explicitly in the config file.

At this point I'm not sure how to investigate further. Could someone more familiar with Tk look at the issue? I'll be happy to provide more information. (Hopefully bugs.python.org notifications reach my inbox.)
msg263210 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-04-11 21:47
#24745 changed the default fixed font from Courier to TkFixedFontin 3.5.0, 3.4.4, and 2.7.11  when using tcl/tk 8.5+.  On some OSes, the latter is not Courier and looks much better.  I don't know why the two behave differently on some systems.

Since this is not a unique problem on one machine, I am reopening this to at least provide a workaround.  Regardless of ultimate cause, we can at least force a blank font size to a default int string, such as '10'.  I closed #24951 as a duplicate of this.

In class idlelib.configDialog.ConfigDialog, method CreatePageFontTab (line 114) creates StringVar self.fontSize, initialized to ''.  The Var is passed to class dynOptionMenuWidget.DynOptionMenu(tkinter.OptionMenu). The instance is bound to self.optMenuFontSize.  Method LoadFontCfg (line 963) sets retrieves the current Editor font as local name configeredFont and local fontSize therefrom. It passes fontSize to self.optMenuFontSize.SetMenu.  This in turns sets the stored self.fontSize to the passed in fontSize, overwriting the initial value.

(The OptionMenu.__init__ docstring and http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/optionmenu.html suggest that the variable must be a StringVar, which I presume is why self.fontSize is.  Experiment suggest otherwise in 8.6.  This would have to be verified on 8.5 and even 8.4 before changing to IntVar.)

If my understanding based on the above, fontSize must be set to '' when the current font is TkFixedFont, but not when the font is Courier.  Petr, could you confirm by adding "print(configuredFont, fontsize)" to LoadFontCfg after both names are set and running both buggy and good cases?
msg263242 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2016-04-12 10:01
buggy:
    configuredFont: ('DejaVu Sans Mono', 0, 'normal')
    fontSize: 0

good:
    configuredFont: ('courier', 10, 'normal')
    fontSize: 10
msg263273 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-04-12 19:44
Thank you.  I believe a see a bug in configHandler.)idleConf.GetFont(self, 'main', 'EditorWindow') returning a size of 0.  Could you post the result of running the following for the bad case?

import tkinter as tk
from tkinter.font import Font
root=tk.Tk()
f = Font(name='TkFixedFont', exists=True, root=root)
print(Font.actual(f))

There is still a question of how fontSize=0 becomes self.fontSize=='', but that will not matter when fontSize=0 is prevented.
msg263330 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2016-04-13 12:24
Indeed, the size is 0 there:

{'family': 'DejaVu Sans Mono', 'size': 0, 'slant': 'roman', 'weight': 'normal', 'overstrike': 0, 'underline': 0}
msg265188 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2016-05-09 10:44
Seen on Debian and Ubuntu as well. All these distros have in common to use Tcl/Tk 8.6.
msg265189 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2016-05-09 10:58
using this as a work-around, not tested with Tcl/Tk 8.5 or older.

--- a/Lib/idlelib/configDialog.py
+++ b/Lib/idlelib/configDialog.py
@@ -113,7 +113,11 @@ class ConfigDialog(Toplevel):
 
     def CreatePageFontTab(self):
         parent = self.parent
-        self.fontSize = StringVar(parent)
+        # see issue #26673
+        if TkVersion >= 8.6:
+            self.fontSize = IntVar(parent)
+        else:
+            self.fontSize = StringVar(parent)
         self.fontBold = BooleanVar(parent)
         self.fontName = StringVar(parent)
         self.spaceNum = IntVar(parent)
msg265203 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-05-09 15:54
Mark, changing the default font from Courier to TkFixedFont has introduced or exposed a bug in any of IDLE, tkinter, or tk 8.6.4 on Linux.  The result is that trying to open the configuration menu fails with TclError.  What do your think is the best solution?

Mathias, it seems to me that fontsize should alsways be an Intvar.  I have no idea why StringVar is used, except possibly as a workaround when the code was written.
msg265204 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-05-09 16:09
Anyone seeing problem: In /Lib/idlelib/configHandler.py, about line 685, in "if size < 0:", change '<' to '<='.  Remove the workaround of overriding 'TkFixedFont' with 'courier'.  Does this fix the problem?
msg266066 - (view) Author: (Odcar) Date: 2016-05-22 10:16
Terry J. Reedy: That fixes the problem for me!
Xubuntu 16.04, Python 2.7.11+, Tk 8.6.5. I have not tried it in Idle for Python 3 though.
msg266095 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2016-05-22 18:36
New changeset a873265366ba by Terry Jan Reedy in branch '2.7':
Issue #26673: Protect IDLE from Linux fonts with reported default size 0.
https://hg.python.org/cpython/rev/a873265366ba

New changeset 1464df337152 by Terry Jan Reedy in branch '3.5':
Issue #26673: Protect IDLE from Linux fonts with reported default size 0.
https://hg.python.org/cpython/rev/1464df337152
msg266100 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2016-05-22 19:02
I would like to change the code a bit more (like using IntVar for size everywhere), but I don't want to do so without tests.  The problem is that tk variables and font functions require a root window and none of the linux buildbots allow that.  (They all run 'headless'.)
History
Date User Action Args
2017-09-19 21:53:51serhiy.storchakasetpull_requests: + pull_request3652
2016-05-22 19:02:26terry.reedysetstatus: open -> closed
resolution: fixed
messages: + msg266100

stage: test needed -> resolved
2016-05-22 18:36:06python-devsetnosy: + python-dev
messages: + msg266095
2016-05-22 10:16:45Odcarsetnosy: + Odcar
messages: + msg266066
2016-05-09 16:09:45terry.reedysetmessages: + msg265204
2016-05-09 15:54:08terry.reedysetnosy: + markroseman
messages: + msg265203
2016-05-09 10:58:16dokosetmessages: + msg265189
2016-05-09 10:44:05dokosetnosy: + doko

messages: + msg265188
title: Tkinter error when opening IDLE configuration menu -> Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6)
2016-04-13 12:24:03petr.viktorinsetmessages: + msg263330
2016-04-12 19:44:57terry.reedysetmessages: + msg263273
2016-04-12 10:01:15petr.viktorinsetmessages: + msg263242
2016-04-11 21:47:39terry.reedysetstatus: closed -> open
versions: + Python 3.6
messages: + msg263210

resolution: not a bug -> (no value)
stage: resolved -> test needed
2016-04-11 20:11:43terry.reedylinkissue24951 superseder
2016-04-11 09:56:33petr.viktorinsetnosy: + petr.viktorin
messages: + msg263175
2016-04-02 15:15:02wysaardsetmessages: + msg262797
2016-04-01 20:51:05terry.reedysetstatus: open -> closed
type: crash -> behavior
messages: + msg262770

resolution: not a bug
stage: resolved
2016-04-01 19:43:02wysaardsetmessages: + msg262759
2016-04-01 18:53:18wysaardsetmessages: + msg262755
2016-04-01 17:51:18terry.reedysetmessages: + msg262752
2016-04-01 14:03:58SilentGhostsetversions: + Python 2.7
2016-04-01 14:02:39wysaardsetmessages: + msg262741
2016-03-31 05:18:57SilentGhostsetnosy: + terry.reedy, kbk, gpolo, roger.serwy, serhiy.storchaka
components: + Tkinter
2016-03-30 15:32:00wysaardcreate