Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6) #70860

Closed
wysaard mannequin opened this issue Mar 30, 2016 · 19 comments
Closed

Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6) #70860

wysaard mannequin opened this issue Mar 30, 2016 · 19 comments
Labels
topic-IDLE topic-tkinter type-bug An unexpected behavior, bug, or error

Comments

@wysaard
Copy link
Mannequin

wysaard mannequin commented Mar 30, 2016

BPO 26673
Nosy @terryjreedy, @doko42, @kbkaiser, @serwy, @encukou, @roseman, @serhiy-storchaka
PRs
  • bpo-31500: IDLE: Scale default fonts on HiDPI displays. #3639
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2016-05-22.19:02:26.556>
    created_at = <Date 2016-03-30.15:32:00.691>
    labels = ['expert-IDLE', 'type-bug', 'expert-tkinter']
    title = 'Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6)'
    updated_at = <Date 2017-09-19.21:53:51.050>
    user = 'https://bugs.python.org/wysaard'

    bugs.python.org fields:

    activity = <Date 2017-09-19.21:53:51.050>
    actor = 'serhiy.storchaka'
    assignee = 'none'
    closed = True
    closed_date = <Date 2016-05-22.19:02:26.556>
    closer = 'terry.reedy'
    components = ['IDLE', 'Tkinter']
    creation = <Date 2016-03-30.15:32:00.691>
    creator = 'wysaard'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 26673
    keywords = []
    message_count = 19.0
    messages = ['262670', '262741', '262752', '262755', '262759', '262770', '262797', '263175', '263210', '263242', '263273', '263330', '265188', '265189', '265203', '265204', '266066', '266095', '266100']
    nosy_count = 11.0
    nosy_names = ['terry.reedy', 'doko', 'kbk', 'gpolo', 'roger.serwy', 'petr.viktorin', 'markroseman', 'python-dev', 'serhiy.storchaka', 'wysaard', 'Odcar']
    pr_nums = ['3639']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue26673'
    versions = ['Python 2.7', 'Python 3.5', 'Python 3.6']

    @wysaard
    Copy link
    Mannequin Author

    wysaard mannequin commented Mar 30, 2016

    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.

    @wysaard wysaard mannequin added type-crash A hard crash of the interpreter, possibly with a core dump topic-IDLE labels Mar 30, 2016
    @SilentGhost SilentGhost mannequin added the topic-tkinter label Mar 31, 2016
    @wysaard
    Copy link
    Mannequin Author

    wysaard mannequin commented Apr 1, 2016

    I'm having the problem if I'm running idle with Python 2.7.11 too.

    @terryjreedy
    Copy link
    Member

    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.

    @wysaard
    Copy link
    Mannequin Author

    wysaard mannequin commented Apr 1, 2016

    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.

    @wysaard
    Copy link
    Mannequin Author

    wysaard mannequin commented Apr 1, 2016

    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.

    @terryjreedy
    Copy link
    Member

    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' ;-).

    @terryjreedy terryjreedy added invalid type-bug An unexpected behavior, bug, or error and removed type-crash A hard crash of the interpreter, possibly with a core dump labels Apr 1, 2016
    @wysaard
    Copy link
    Mannequin Author

    wysaard mannequin commented Apr 2, 2016

    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?

    @encukou
    Copy link
    Member

    encukou commented Apr 11, 2016

    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.)

    @terryjreedy
    Copy link
    Member

    bpo-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 bpo-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?

    @encukou
    Copy link
    Member

    encukou commented Apr 12, 2016

    buggy:
    configuredFont: ('DejaVu Sans Mono', 0, 'normal')
    fontSize: 0

    good:
    configuredFont: ('courier', 10, 'normal')
    fontSize: 10

    @terryjreedy
    Copy link
    Member

    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.

    @encukou
    Copy link
    Member

    encukou commented Apr 13, 2016

    Indeed, the size is 0 there:

    {'family': 'DejaVu Sans Mono', 'size': 0, 'slant': 'roman', 'weight': 'normal', 'overstrike': 0, 'underline': 0}

    @doko42
    Copy link
    Member

    doko42 commented May 9, 2016

    Seen on Debian and Ubuntu as well. All these distros have in common to use Tcl/Tk 8.6.

    @doko42 doko42 changed the title Tkinter error when opening IDLE configuration menu Tkinter error when opening IDLE configuration menu (Tcl/Tk 8.6) May 9, 2016
    @doko42
    Copy link
    Member

    doko42 commented May 9, 2016

    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 python/cpython#70860
    +        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)

    @terryjreedy
    Copy link
    Member

    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.

    @terryjreedy
    Copy link
    Member

    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?

    @Odcar
    Copy link
    Mannequin

    Odcar mannequin commented May 22, 2016

    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.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented May 22, 2016

    New changeset a873265366ba by Terry Jan Reedy in branch '2.7':
    Issue bpo-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 bpo-26673: Protect IDLE from Linux fonts with reported default size 0.
    https://hg.python.org/cpython/rev/1464df337152

    @terryjreedy
    Copy link
    Member

    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'.)

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    topic-IDLE topic-tkinter type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants