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

DateEntry bug in with Python 3.8 #61

Closed
jslvtr opened this issue Oct 31, 2019 · 14 comments · Fixed by #63
Closed

DateEntry bug in with Python 3.8 #61

jslvtr opened this issue Oct 31, 2019 · 14 comments · Fixed by #63

Comments

@jslvtr
Copy link

jslvtr commented Oct 31, 2019

Hello!

Superb package, thank you so much for making it. I've been testing in Python 3.8 and found a bug when following your example code:

import tkinter as tk
from tkinter import ttk
from tkcalendar import DateEntry


def example3():
    top = tk.Toplevel(root)

    ttk.Label(top, text="Choose date").pack(padx=10, pady=10)

    cal = DateEntry(
        top,
        width=12,
        background="darkblue",
        foreground="white",
        borderwidth=2,
        year=2010,
    )
    cal.pack(padx=10, pady=10)


root = tk.Tk()
ttk.Button(root, text="DateEntry", command=example3).pack(padx=10, pady=10)

root.mainloop()

The error is as follows:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\jose\AppData\Local\Programs\Python\Python38-32\Lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:\Users\jose\AppData\Local\Programs\Python\Python38-32\Lib\tkinter\__init__.py", line 804, in callit
    func(*args)
  File "C:\Users\jose\.virtualenvs\code-9xLWUBmM\lib\site-packages\tkcalendar\dateentry.py", line 202, in _on_theme_change
    self._setup_style()
  File "C:\Users\jose\.virtualenvs\code-9xLWUBmM\lib\site-packages\tkcalendar\dateentry.py", line 160, in _setup_style
    self.style.map('DateEntry', **maps)
  File "C:\Users\jose\AppData\Local\Programs\Python\Python38-32\Lib\tkinter\ttk.py", line 403, in map
    self.tk.call(self._name, "map", style, *_format_mapdict(kw)),
_tkinter.TclError: Invalid state name r

After a lot of debugging, I figured out the reason for this.

The problem starts at dateentry.py:160 as per the stacktrace:

 maps = self.style.map('TCombobox')
if maps:
    self.style.map('DateEntry', **maps)

Line 160 is the third line ^

This goes on to call an internal ttk function, which then has multiple other internal calls.

One of the internal calls is to _format_mapdict, and receives the keyword arguments passed to self.style.map:

...
self.tk.call(self._name, "map", style, *_format_mapdict(kw)),
...

Allegedly that function takes a mapdict and formats it to pass it off to tk.call. This is that function's documentation:

"""Formats mapdict to pass it to tk.call.

    E.g. (script=False):
      {'expand': [('active', 'selected', 'grey'), ('focus', [1, 2, 3, 4])]}

      returns:

      ('-expand', '{active selected} grey focus {1, 2, 3, 4}')"""

However, my debugging suggests that in Python3.8, it's actually returning this: ('-expand', '{ a c t i v e s e l e c t e d } g r e y f o c u s { 1 , 2 , 3 , 4 } ')

This causes big problems, naturally.

The solution seems to be to not pass keyword arguments individually, but to pass the dictionary of keyword arguments itself. Then the _format_mapdict function will work properly:

maps = self.style.map('TCombobox')
if maps:
    self.style.map('DateEntry', maps)

I can make a PR for this if you agree with this analysis.

@jslvtr
Copy link
Author

jslvtr commented Nov 1, 2019

Nevermind, I made a mistake here--clearly passing as not keyword arguments is just passing it as a different argument.

I believe this is caused by a bug in Python, which I have logged in their issue tracker: https://bugs.python.org/issue38661?@ok_message=msg%20355818%20created%0Aissue%2038661%20created&@template=item

Can we keep this open for now, and see what they say?

@j4321
Copy link
Owner

j4321 commented Nov 6, 2019

Thanks a lot for noticing this and opening an issue in Python. I will leave this issue opened for now and if they decide not to restore the previous behavior, I will fix it in tkcalendar.

@j4321
Copy link
Owner

j4321 commented Nov 7, 2019

What OS are you using? I have just installed python 3.8.0 in Archlinux and tkcalendar works fine, I have the same output of map as in python 3.7.

@jslvtr
Copy link
Author

jslvtr commented Nov 7, 2019

I am using Windows, which sounds like it would be part of the problem!

@j4321
Copy link
Owner

j4321 commented Nov 7, 2019

Or maybe this issue is specific to the default windows ttk theme. Can you try to call style.map() but using the clam theme?

@j4321
Copy link
Owner

j4321 commented Dec 4, 2019

I have made a temporary fix in branch https://github.com/j4321/tkcalendar/tree/fix_63 (I manually input the correct style map).

@jslvtr
Copy link
Author

jslvtr commented Dec 4, 2019

Sounds good, although the fix will be theme-specific :(

@j4321
Copy link
Owner

j4321 commented Dec 4, 2019

If you give me the output style map for every ttk theme specific to windows (I cannot get them from linux), I can implement a more general fix which takes the theme into account. The themes I already have are 'clam' and 'alt'.

@jslvtr
Copy link
Author

jslvtr commented Dec 4, 2019

I can do! I generated them with this script:

from tkinter import ttk

style = ttk.Style()

for theme in style.theme_names():
    style.theme_use(theme)
    print(theme)
    print(style.map("TCombobox"))
    print()

This is the output:

winnative
{'focusfill': [('readonly', 'focus', 'SystemHighlight')], 'foreground': [('disabled', 'SystemGrayText'), ('readonly', 'focus', 'SystemHighlightText')], 'selectforeground': [('!focus', 'SystemWindowText')], 'fieldbackground': [('readonly', 'SystemButtonFace'), ('disabled', 'SystemButtonFace')], 'selectbackground': [('!focus', 'SystemWindow')]}

clam
{'foreground': [('readonly', 'focus', '#ffffff')], 'fieldbackground': ['readonly focus', '#4a6984', 'readonly', '#dcdad5'], 'background': [('active', '#eeebe7'), ('pressed', '#eeebe7')], 'arrowcolor': [('disabled', '#999999')]}

alt
{'fieldbackground': [('readonly', '#d9d9d9'), ('disabled', '#d9d9d9')], 'arrowcolor': ['disabled', '#a3a3a3']}

default
{'fieldbackground': [('readonly', '#d9d9d9'), ('disabled', '#d9d9d9')], 'arrowcolor': ['disabled', '#a3a3a3']}

classic
{'fieldbackground': [('readonly', '#d9d9d9'), ('disabled', '#d9d9d9')]}

vista
{'focusfill': [('readonly', 'focus', 'SystemHighlight')], 'foreground': [('disabled', 'SystemGrayText'), ('readonly', 'focus', 'SystemHighlightText')], 'selectforeground': [('!focus', 'SystemWindowText')], 'selectbackground': [('!focus', 'SystemWindow')]}

xpnative
{'focusfill': [('readonly', 'focus', 'SystemHighlight')], 'foreground': [('disabled', 'SystemGrayText'), ('readonly', 'focus', 'SystemHighlightText')], 'selectforeground': [('!focus', 'SystemWindowText')], 'selectbackground': [('!focus', 'SystemWindow')]}

I forgot to reply to your earlier comment--I was using clam when I encountered this bug!

@j4321
Copy link
Owner

j4321 commented Dec 4, 2019

Thanks, I have updated the code in branch https://github.com/j4321/tkcalendar/tree/fix_63. Can you test it? If this works fine for you I will merge it into master.

@j4321 j4321 closed this as completed in #63 Dec 12, 2019
@jslvtr
Copy link
Author

jslvtr commented Dec 13, 2019

Thank you @j4321 I haven't been able to try it yet I'm afraid, but it looks like a good temporary solution.

@jslvtr
Copy link
Author

jslvtr commented Dec 18, 2019

Hey @j4321 trying this in my project, but noticed the update is not yet in the pip release. Are you going to put it in pip, or wait until a proper fix is in place?

@j4321
Copy link
Owner

j4321 commented Dec 18, 2019

Hello @jslvtr I would like to take the time to check #62 before publishing the next version, which will include this fix. Hopefully I will be able to do it sometime next week.

@jslvtr
Copy link
Author

jslvtr commented Dec 18, 2019

Sounds good @j4321 , looking forward to using the updated version in my project and the course I'm teaching. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants