Skip to content

Commit a5749af

Browse files
Merge branch 'main' into structmember-tests
2 parents 1c56e15 + d466052 commit a5749af

File tree

4 files changed

+119
-11
lines changed

4 files changed

+119
-11
lines changed

Lib/test/test_tkinter/test_misc.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,101 @@ def test3(e): pass
706706
self.assertCommandExist(funcid2)
707707
self.assertCommandExist(funcid3)
708708

709+
def _test_tag_bind(self, w):
710+
tag = 'sel'
711+
event = '<Control-Alt-Key-a>'
712+
w.pack()
713+
self.assertRaises(TypeError, w.tag_bind)
714+
tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind
715+
if isinstance(w, tkinter.Text):
716+
self.assertRaises(TypeError, w.tag_bind, tag)
717+
self.assertRaises(TypeError, w.tag_bind, tag, event)
718+
self.assertEqual(tag_bind(tag), ())
719+
self.assertEqual(tag_bind(tag, event), '')
720+
def test1(e): pass
721+
def test2(e): pass
722+
723+
funcid = w.tag_bind(tag, event, test1)
724+
self.assertEqual(tag_bind(tag), (event,))
725+
script = tag_bind(tag, event)
726+
self.assertIn(funcid, script)
727+
self.assertCommandExist(funcid)
728+
729+
funcid2 = w.tag_bind(tag, event, test2, add=True)
730+
script = tag_bind(tag, event)
731+
self.assertIn(funcid, script)
732+
self.assertIn(funcid2, script)
733+
self.assertCommandExist(funcid)
734+
self.assertCommandExist(funcid2)
735+
736+
def _test_tag_unbind(self, w):
737+
tag = 'sel'
738+
event = '<Control-Alt-Key-b>'
739+
w.pack()
740+
tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind
741+
self.assertEqual(tag_bind(tag), ())
742+
self.assertEqual(tag_bind(tag, event), '')
743+
def test1(e): pass
744+
def test2(e): pass
745+
746+
funcid = w.tag_bind(tag, event, test1)
747+
funcid2 = w.tag_bind(tag, event, test2, add=True)
748+
749+
self.assertRaises(TypeError, w.tag_unbind, tag)
750+
w.tag_unbind(tag, event)
751+
self.assertEqual(tag_bind(tag, event), '')
752+
self.assertEqual(tag_bind(tag), ())
753+
754+
def _test_tag_bind_rebind(self, w):
755+
tag = 'sel'
756+
event = '<Control-Alt-Key-d>'
757+
w.pack()
758+
tag_bind = w._tag_bind if isinstance(w, tkinter.Text) else w.tag_bind
759+
self.assertEqual(tag_bind(tag), ())
760+
self.assertEqual(tag_bind(tag, event), '')
761+
def test1(e): pass
762+
def test2(e): pass
763+
def test3(e): pass
764+
765+
funcid = w.tag_bind(tag, event, test1)
766+
funcid2 = w.tag_bind(tag, event, test2, add=True)
767+
script = tag_bind(tag, event)
768+
self.assertIn(funcid2, script)
769+
self.assertIn(funcid, script)
770+
self.assertCommandExist(funcid)
771+
self.assertCommandExist(funcid2)
772+
773+
funcid3 = w.tag_bind(tag, event, test3)
774+
script = tag_bind(tag, event)
775+
self.assertNotIn(funcid, script)
776+
self.assertNotIn(funcid2, script)
777+
self.assertIn(funcid3, script)
778+
self.assertCommandExist(funcid3)
779+
780+
def test_canvas_tag_bind(self):
781+
c = tkinter.Canvas(self.frame)
782+
self._test_tag_bind(c)
783+
784+
def test_canvas_tag_unbind(self):
785+
c = tkinter.Canvas(self.frame)
786+
self._test_tag_unbind(c)
787+
788+
def test_canvas_tag_bind_rebind(self):
789+
c = tkinter.Canvas(self.frame)
790+
self._test_tag_bind_rebind(c)
791+
792+
def test_text_tag_bind(self):
793+
t = tkinter.Text(self.frame)
794+
self._test_tag_bind(t)
795+
796+
def test_text_tag_unbind(self):
797+
t = tkinter.Text(self.frame)
798+
self._test_tag_unbind(t)
799+
800+
def test_text_tag_bind_rebind(self):
801+
t = tkinter.Text(self.frame)
802+
self._test_tag_bind_rebind(t)
803+
709804
def test_bindtags(self):
710805
f = self.frame
711806
self.assertEqual(self.root.bindtags(), ('.', 'Tk', 'all'))

Lib/tkinter/__init__.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,16 +1537,19 @@ def unbind(self, sequence, funcid=None):
15371537
Otherwise destroy the current binding for SEQUENCE, leaving SEQUENCE
15381538
unbound.
15391539
"""
1540+
self._unbind(('bind', self._w, sequence), funcid)
1541+
1542+
def _unbind(self, what, funcid=None):
15401543
if funcid is None:
1541-
self.tk.call('bind', self._w, sequence, '')
1544+
self.tk.call(*what, '')
15421545
else:
1543-
lines = self.tk.call('bind', self._w, sequence).split('\n')
1546+
lines = self.tk.call(what).split('\n')
15441547
prefix = f'if {{"[{funcid} '
15451548
keep = '\n'.join(line for line in lines
15461549
if not line.startswith(prefix))
15471550
if not keep.strip():
15481551
keep = ''
1549-
self.tk.call('bind', self._w, sequence, keep)
1552+
self.tk.call(*what, keep)
15501553
self.deletecommand(funcid)
15511554

15521555
def bind_all(self, sequence=None, func=None, add=None):
@@ -1558,7 +1561,7 @@ def bind_all(self, sequence=None, func=None, add=None):
15581561

15591562
def unbind_all(self, sequence):
15601563
"""Unbind for all widgets for event SEQUENCE all functions."""
1561-
self.tk.call('bind', 'all' , sequence, '')
1564+
self._root()._unbind(('bind', 'all', sequence))
15621565

15631566
def bind_class(self, className, sequence=None, func=None, add=None):
15641567
"""Bind to widgets with bindtag CLASSNAME at event
@@ -1573,7 +1576,7 @@ def bind_class(self, className, sequence=None, func=None, add=None):
15731576
def unbind_class(self, className, sequence):
15741577
"""Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE
15751578
all functions."""
1576-
self.tk.call('bind', className , sequence, '')
1579+
self._root()._unbind(('bind', className, sequence))
15771580

15781581
def mainloop(self, n=0):
15791582
"""Call the mainloop of Tk."""
@@ -2885,9 +2888,7 @@ def bbox(self, *args):
28852888
def tag_unbind(self, tagOrId, sequence, funcid=None):
28862889
"""Unbind for all items with TAGORID for event SEQUENCE the
28872890
function identified with FUNCID."""
2888-
self.tk.call(self._w, 'bind', tagOrId, sequence, '')
2889-
if funcid:
2890-
self.deletecommand(funcid)
2891+
self._unbind((self._w, 'bind', tagOrId, sequence), funcid)
28912892

28922893
def tag_bind(self, tagOrId, sequence=None, func=None, add=None):
28932894
"""Bind to all items with TAGORID at event SEQUENCE a call to function FUNC.
@@ -3997,9 +3998,7 @@ def tag_add(self, tagName, index1, *args):
39973998
def tag_unbind(self, tagName, sequence, funcid=None):
39983999
"""Unbind for all characters with TAGNAME for event SEQUENCE the
39994000
function identified with FUNCID."""
4000-
self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '')
4001-
if funcid:
4002-
self.deletecommand(funcid)
4001+
return self._unbind((self._w, 'tag', 'bind', tagName, sequence), funcid)
40034002

40044003
def tag_bind(self, tagName, sequence, func, add=None):
40054004
"""Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC.
@@ -4010,6 +4009,11 @@ def tag_bind(self, tagName, sequence, func, add=None):
40104009
return self._bind((self._w, 'tag', 'bind', tagName),
40114010
sequence, func, add)
40124011

4012+
def _tag_bind(self, tagName, sequence=None, func=None, add=None):
4013+
# For tests only
4014+
return self._bind((self._w, 'tag', 'bind', tagName),
4015+
sequence, func, add)
4016+
40134017
def tag_cget(self, tagName, option):
40144018
"""Return the value of OPTION for tag TAGNAME."""
40154019
if option[:1] != '-':
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Fix the behavior of ``tag_unbind()`` methods of :class:`tkinter.Text` and
2+
:class:`tkinter.Canvas` classes with three arguments. Previously,
3+
``widget.tag_unbind(tag, sequence, funcid)`` destroyed the current binding
4+
for *sequence*, leaving *sequence* unbound, and deleted the *funcid*
5+
command. Now it removes only *funcid* from the binding for *sequence*,
6+
keeping other commands, and deletes the *funcid* command. It leaves
7+
*sequence* unbound only if *funcid* was the last bound command.

Python/structmember.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
208208
if (overflow < 0) {
209209
PyErr_SetString(PyExc_OverflowError,
210210
"Python int too large to convert to C long");
211+
return -1;
211212
}
212213
else if (!overflow) {
213214
*(unsigned int *)addr = (unsigned int)(unsigned long)long_val;
@@ -247,6 +248,7 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v)
247248
if (overflow < 0) {
248249
PyErr_SetString(PyExc_OverflowError,
249250
"Python int too large to convert to C long");
251+
return -1;
250252
}
251253
else if (!overflow) {
252254
*(unsigned long *)addr = (unsigned long)long_val;

0 commit comments

Comments
 (0)