classification
Title: tkinter Menu.delete bug
Type: Stage:
Components: Tkinter Versions: Python 3.0, Python 2.7, Python 2.6, Python 2.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, gpolo, indiedan, loewis, ocean-city, schuppenies, skomoroh, svenil
Priority: normal Keywords: easy, patch

Created on 2008-09-04 13:19 by skomoroh, last changed 2008-11-04 06:28 by ocean-city. This issue is now closed.

Files
File name Uploaded Description Edit
menu_bug.py skomoroh, 2008-09-04 13:19
menu_bag.patch ocean-city, 2008-09-04 14:18
issue3774.diff gpolo, 2008-09-12 15:58
menu_fix.patch skomoroh, 2008-09-12 16:03
issue3774_2.diff gpolo, 2008-09-12 19:14
Messages (24)
msg72501 - (view) Author: (skomoroh) Date: 2008-09-04 13:19
When I create a menu item without command and them remove it, I have a
error:
  File "/usr/local/lib/python3.0/tkinter/__init__.py", line 2661, in delete
    if c in self._tclCommands:
TypeError: argument of type 'NoneType' is not iterable
msg72502 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-09-04 13:28
I tried, and I confirmed released python2.5.2 runs fine. and
py3k, trunk, release25-maint fails. Probably something changed after
2.5.2 release.
msg72508 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-09-04 14:18
I've not tested this so heavily, but patch could be simple.
self._tclCommands could be None, so should check it.
msg73084 - (view) Author: Dan OD (indiedan) Date: 2008-09-12 12:14
Please forgive my rookie bug filing:

I'm getting this bug / crash sometimes when Menu.delete() is called too

It seems to be because self.index( ) sometimes returns None which is of 
course un-iterable and delete() tries to iterate through it:

for i in range(self.index(index1), self.index(index2)+1):

As a fix the previous (simpler) delete works for me, but I don't 
understand the purpose of the extra self.deletecommand() code appended 
so I'm probably missing something.

My crash:
  File "C:\CCPN\ccpn\python\memops\gui\Menu.py", line 127, in 
deleteMenuItems
    self.delete(0, Tkinter.END)
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 2665, in delete
    for i in range(self.index(index1), self.index(index2)+1):
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
msg73085 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-09-12 12:45
>for i in range(self.index(index1), self.index(index2)+1):

Probably your working copy is bit old. Please try latest file.
This issue was fixed in r65971. :-)

# I've added nosy list from issue1342811.
msg73090 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 14:56
Python 2.6b2 was released with this bug, and got fixed later.
msg73091 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 14:56
I meant beta3, sorry.
msg73093 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 14:59
Oops, sorry, I misread the bug report, reopening it (let me go eat
something now).
msg73094 - (view) Author: Dan OD (indiedan) Date: 2008-09-12 15:21
Thanks guys - I was running an old build. revision 65971 fixed this as Hirokazu mentioned.
msg73099 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 15:58
The patch attached is probably the most direct way to fix it, but, can
someone remind why we just don't call deletecommand (if there is a
command to delete) and let it try to remove the command from _tclCommand
then ? (note that this is not really the case for this bug report).
I'm attaching a patch that is a bit "different". It relies on the fact
that if the menu entry was created with add_command but no command was
specified, then there is no command to specify. And if a command was
specified then _tclCommands would be a list and deletecommand would work
properly.
msg73101 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 15:59
Again, I meant the previously attached patch (the one by ocean-city) was
the most direct way.
msg73102 - (view) Author: (skomoroh) Date: 2008-09-12 16:03
Seems I found the bug.

I've attached the patch for current py3k-trunk.
msg73103 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 16:07
My patch already does what is proposed in your patch, except yours may
possibly not work. It is not guaranteed that "self.entrycget(i,
'command')" will return an empty string if the command associated to
that menu entry is an empty string. Tcl may return another object
containing the representation of this menu command so that if statement
will evalute as True while its representation is actually an empty string.
msg73108 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-09-12 17:33
self.deletecommand doesn't remove menu item, so we don't have to care
about index shifting like bellow. +1 for gpolo's patch.

>>> a = [0, 1, 2, 3]
>>> for i in xrange(len(a)):
...     del a[i]
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list assignment index out of range


I'm not sure (self._tclCommands is not None) check is not really needed.
I was looking for the place self._tclCommands is initialized, and found
_register() is that place, but what is 'needcleanup'? :-0
But probably, gpolo's patch is right.


P.S.
This is not related to this issue, I think
"""Delete menu items between INDEX1 and INDEX2 (not included)."""
should be changed to
"""Delete menu items between INDEX1 and INDEX2 (included)."""

Please look at http://www.tcl.tk/man/tcl8.5/TkCmd/menu.htm#M59
msg73119 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 18:59
This "needcleanup" parameter indicates that the function added to
_tclCommands needs to (and will) be removed later. Nevertheless, I
believe the proper initialization of _tclCommands should be done elsewhere.


And about that docstring.. yes, the change is needed. (I could swear I
saw it fixed some time ago, but no.. it didn't happen)
msg73123 - (view) Author: Guilherme Polo (gpolo) * (Python committer) Date: 2008-09-12 19:14
New patch, this one fixes the docstring previously mentioned and may set
_tclCommands to an empty list at BaseWidget.__init__
msg73297 - (view) Author: Dan OD (indiedan) Date: 2008-09-16 12:24
It may be because I'm calling delete incorrectly (I don't think so - see 
below) but I'm getting an error

  File "C:\CCPN\ccpn\python\memops\gui\Menu.py", line 127, in 
deleteMenuItems
    self.delete(0, Tkinter.END)
  File "C:\Python-2.6_svn\lib\lib-tk\Tkinter.py", line 2670, in delete
    if c in self._tclCommands:
TypeError: argument of type 'NoneType' is not iterable

Which can easily be fixed with 

- if c in self._tclCommands:
+ if c and c in self._tclCommands:

line 2670 Tkinter.py

Should I create a patch or have I missed something? Thanks.
msg74122 - (view) Author: Dan OD (indiedan) Date: 2008-10-01 10:20
gpolo's patch issue3774_2.diff does seem to fix this bug, but it's not in 
the SVN trunk - could this be done before 2.6 final? Thanks!
msg74130 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-10-01 14:53
I think gpolo's patch can go.

>I'm not sure (self._tclCommands is not None) check is not really needed.

I want to cancel this opinion. I saw no self._tclCommands check before
any other deletecommand() call, I beleive this is OK.
msg74139 - (view) Author: Martin v. Löwis (loewis) * (Python committer) Date: 2008-10-01 18:34
> gpolo's patch issue3774_2.diff does seem to fix this bug, but it's not in 
> the SVN trunk - could this be done before 2.6 final?

Definitely not. The release is about to be produced today.
msg75474 - (view) Author: Dan OD (indiedan) Date: 2008-11-03 17:17
Sorry to drag this up again, but if no-one has any complaints it would be 
a huge help if gpolo's patch could be checked in. Thanks
msg75475 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-11-03 18:20
Fixed in r67082(trunk), r67083(release26-maint), r67084(release25-maint).
msg75478 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-11-03 20:44
Could you port this to 3.0, please?
msg75490 - (view) Author: Hirokazu Yamamoto (ocean-city) * (Python committer) Date: 2008-11-04 06:28
Done. Fixed in r67095(py3k).
History
Date User Action Args
2008-11-04 06:28:19ocean-citysetmessages: + msg75490
2008-11-03 20:44:55benjamin.petersonsetmessages: + msg75478
2008-11-03 18:20:28ocean-citysetstatus: open -> closed
keywords: - needs review
messages: + msg75475
resolution: fixed
versions: + Python 2.7
2008-11-03 17:17:18indiedansetmessages: + msg75474
2008-10-01 18:34:41loewissetmessages: + msg74139
2008-10-01 14:53:19ocean-citysetmessages: + msg74130
2008-10-01 10:20:52indiedansetmessages: + msg74122
2008-09-16 12:24:52indiedansetmessages: + msg73297
2008-09-12 19:14:12gpolosetfiles: + issue3774_2.diff
messages: + msg73123
2008-09-12 18:59:54gpolosetmessages: + msg73119
2008-09-12 17:33:30ocean-citysetmessages: + msg73108
2008-09-12 16:07:13gpolosetmessages: + msg73103
2008-09-12 16:03:13skomorohsetfiles: + menu_fix.patch
messages: + msg73102
2008-09-12 15:59:17gpolosetmessages: + msg73101
2008-09-12 15:58:09gpolosetfiles: + issue3774.diff
messages: + msg73099
2008-09-12 15:21:35indiedansetmessages: + msg73094
2008-09-12 14:59:42gpolosetkeywords: + easy, needs review
2008-09-12 14:59:25gpolosetstatus: closed -> open
keywords: - easy, needs review
messages: + msg73093
resolution: out of date -> (no value)
2008-09-12 14:56:50gpolosetmessages: + msg73091
2008-09-12 14:56:13gpolosetstatus: open -> closed
resolution: out of date
messages: + msg73090
2008-09-12 12:45:16ocean-citysetnosy: + loewis, svenil, benjamin.peterson, gpolo, schuppenies
messages: + msg73085
2008-09-12 12:14:57indiedansetnosy: + indiedan
messages: + msg73084
2008-09-04 14:18:48ocean-citysetkeywords: + easy, needs review, patch
files: + menu_bag.patch
messages: + msg72508
2008-09-04 13:28:38ocean-citysetnosy: + ocean-city
messages: + msg72502
versions: + Python 2.6, Python 2.5
2008-09-04 13:19:15skomorohcreate