Open maj113 opened 1 month ago
Hello, @maj113
The result of my test is no problem, my environment is as follows:
The code I tested is as follows:
import tkinter
root = tkinter.Tk()
radio_button = tkinter.Radiobutton(root)
state = radio_button.cget("state")
is_normal = state == tkinter.NORMAL
print(f"{is_normal=}, {type(state)=}")
The output is as follows:
is_normal=True, type(state)=<class 'str'>
Obviously, it's not a _tkinter.Tcl_Obj
. Therefore you should specifically point out the environment, as this may be a problem that only arises in certain environments. If there's a problem with the way I'm testing, feel free to point it out.
Obviously, it's not a
_tkinter.Tcl_Obj
. Therefore you should specifically point out the environment, as this may be a problem that only arises in certain environments. If there's a problem with the way I'm testing, feel free to point it out.
I'm testing this on Windows 11 24H2 with the same behavior on (C)python 3.12.5 and 3.13.0
okay the issue occurs ONLY with ttk widgets, not regular tk ones
Ok, I'll try to create a PR later to fix this.
I don't think this should be solved just by modifying the docstring, _tkinter.Tcl_Obj
should be converted to a string type.
I've encountered the same issue yesterday by accessing the state using the key directly. Took me way to long to figure out that the state isn't string type.
self.entry_box = ttk.Entry(self.root, width=40)
# This doesn't work!
if (self.entry_box['state'] == 'normal'):
print('State is normal')
The weird thing is, if you access the state before hand by printing it as a string, then it becomes a string type.
import tkinter as tk
from tkinter import ttk, messagebox
class App:
def __init__(self, root):
self.root = root
self.entry_box = ttk.Entry(self.root, width=40)
self.entry_box.pack(padx=10, pady=10)
messagebox.showinfo(message=f"Type: {type(self.entry_box['state'])}\nState: {self.entry_box['state']}\nType after access: {type(self.entry_box['state'])}")
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop()
Result:
Type: <class '_tkinter.Tcl_Obj'>
State: normal
Type after access: <class 'str'>
Hello, @brianzhouzc
I tested your code and it turned out to be different from yours:
Result:
Type: <class '_tkinter.Tcl_Obj'>
State: normal
Type after access: <class '_tkinter.Tcl_Obj'>
Perhaps you should point out your environment.
@serhiy-storchaka We need a decision on what to do before too much effort is put into PRs.
The docstring is outdated. Perhaps it was written when all low-level Tkinter API returned only strings. "as string" should be removed.
Hello, @brianzhouzc
I tested your code and it turned out to be different from yours:
Result:
Type: <class '_tkinter.Tcl_Obj'> State: normal Type after access: <class '_tkinter.Tcl_Obj'>
Perhaps you should point out your environment.
Apologies, my environment is Windows 10 Business 22H2 19045.5011, Python 3.11.9.
Tried on Python 3.12.6 as well and the behaviours is indeed different, like what you have in your reply.
The docstring is outdated. Perhaps it was written when all low-level Tkinter API returned only strings. "as string" should be removed.
I don't think just removing that would be enough to clarify the return value, it still might confuse people that the same key behaves differently comparing tk vs ttk, I haven't checked how tkinter.Tcl_Obj is implemented but maybe it can be extended with a eq so that at least string comparisons work as expected without the need to wrap it in a str
This is a Tk implementation detail. Depending on the key, the Tk version, the way of creating and modifying the widget, you can get a number, a boolean, a string, a tuple, a Tcl_Obj. If you get a Tcl_Obj and need a string, just call str().
Making Tcl_Obj comparable with str is an interesting idea, but this is a new feature which can only be added in a new Python version. It may require significant internal changes in Tkinter.
The docstring is outdated. Perhaps it was written when all low-level Tkinter API returned only strings. "as string" should be removed.
Is it possible that the "as string" in the comment refers to the KEY, not the return value? This can really be misleading.
But beyond that, it's also a problem that widgets of tk don't behave consistently with widgets of ttk.
What I understood wrongly: the key is a string, the return value is a string as well because everything is stored as a string. But this was wrong! (I think?)
The key is a string, the return value is anything. Am I correct now?
The key is a string, the return value is anything. Am I correct now?
I think so.
The docstring:
"""Return the resource value for a KEY given as string."""
claims it returns as a string however it returns a_tkinter.Tcl_Obj
which seems to lack__eq__
/the ability to compare it to a string so something like this:Will always return false no matter what unless its wrapped in a str()
I propose either clarifying the docstr or returning as a str() wrapped obj but i presume that's a breaking change
Linked PRs