ttk.Treeview.insert() does not allow to insert item with iid=0

Hello, I found a possible bug with ttk.Treeview widget. I'm working on program that uses tkinter UI. I use ttk.Treeview to display some objects and I want to use integer iid of items. For example, I insert a row with treeview.insert(... iid=0, ...). But I encountered a problem when I try to get this item from treeview by iid when iid =0. There is no item with such iid. This item has autogenerated iid just like it's not specified. I investigated problem and found that in ttk.py, Treeview.insert(... iid=None, ...) in method's body has a check: if iid: res = self.tk.call(self._w, "insert", parent, index, "-id", iid, *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) It means that if iid is "True" then use it else autogenerate it. Maybe there should be "if iid is not None", not "if iid"? Or there are some reasons to do check this way? Igor Yakovchenko <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> Без вирусов. www.avast.ru <https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail> <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

On 3/16/2018 6:54 AM, Игорь Яковченко wrote: This might fit python-list better, and may become a bugs.python.org issue, but I will answer now, having just investigated.
I found a possible bug with ttk.Treeview widget.
See below.
I'm working on program that uses tkinter UI. I use ttk.Treeview to display some objects and I want to use integer iid of items.
For tk, the underlying graphics framework, iids are strings. "If iid is specified, it is used as the item identifier", from the Treeview doc, oversimplifies. When iid is specified, the iid used internally and returned by Treeview() is a string based on the value passed. 1 becomes '1', 1.0 becomes '1.0', (1,2,3) and [1,2,3] both become '1 2 3' (this is consistent in tkinter), and int becomes "<class 'int'>". Since the transformation is the same when referencing an item, as with tv.index(iid), one can usually ignore it. But it shows up if one prints a return value (as I did to discover the above), or tries to compare it with the original objects, or tries to use two different objects with the same tk string as iids.
For example, I insert a row with treeview.insert(... iid=0, ...). But I encountered a problem when I try to get this item from treeview by iid when iid =0.
Other things being equal, I agree that one should be able to pass 0 and 0.0 along with all other ints and floats. In the meanwhile, you could pass '0' and retrieve with either '0' or 0. To not special-case 0, always pass iid=int(row).
There is no item with such iid. This item has autogenerated iid just like it's not specified. I investigated problem and found that in ttk.py, Treeview.insert(... iid=None, ...) in method's body has a check: if iid: res = self.tk.call(self._w, "insert", parent, index, "-id", iid, *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) It means that if iid is "True" then use it else autogenerate it. Maybe there should be "if iid is not None", not "if iid"? Or there are some reasons to do check this way?
It might be that accepting '' as an iid would be a problem. Our current tkinter expert, Serhiy Storchaka, should know. If so, "if iid in (None, '')" would be needed. -- Terry Jan Reedy

On 2018-03-16 20:22, Terry Reedy wrote:
On 3/16/2018 6:54 AM, Игорь Яковченко wrote: [snip]
There is no item with such iid. This item has autogenerated iid just like it's not specified. I investigated problem and found that in ttk.py, Treeview.insert(... iid=None, ...) in method's body has a check: if iid: res = self.tk.call(self._w, "insert", parent, index, "-id", iid, *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) It means that if iid is "True" then use it else autogenerate it. Maybe there should be "if iid is not None", not "if iid"? Or there are some reasons to do check this way?
It might be that accepting '' as an iid would be a problem. Our current tkinter expert, Serhiy Storchaka, should know. If so, "if iid in (None, '')" would be needed.
The root of the tree has the iid ''.

On Fri, Mar 16, 2018 at 10:54 AM, Игорь Яковченко <truestarecat@gmail.com> wrote:
I investigated problem and found that in ttk.py, Treeview.insert(... iid=None, ...) in method's body has a check: if iid: res = self.tk.call(self._w, "insert", parent, index, "-id", iid, *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) It means that if iid is "True" then use it else autogenerate it. Maybe there should be "if iid is not None", not "if iid"? Or there are some reasons to do check this way?
isn't it considered pythonic to both: use None as a default for "not specified" AND use: if something is None to check if the parameter has been specified? however, this is a bit of an odd case: ids are strings, but it allows you to pass in a non-string and stringified version will be used. so None should be the only special case -- not "anything false" (but if the empty string is the root, then it's another special case -- again, good to check for none rather than anything Falsey) so it probably should do something like: if iid is not None: res = self.tk.call(self._w, "insert", parent, index, "-id", str(iid), *opts) else: res = self.tk.call(self._w, "insert", parent, index, *opts) note both the check for None and the str() call. I'm assuming the str() call happens under the hood at the boundary already, but better to make it explicit in teh Python. Alternatively: this has been around a LONG time, so the maybe the answer is "don't do that" -- i.e. don't use anything falsey as an iid. But it would still be good to make the docs more clear about that. -CHB ------- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
participants (4)
-
Chris Barker
-
MRAB
-
Terry Reedy
-
Игорь Яковченко