def test_callback_break(capsys): stuff = [] def non_breaking(): stuff.append('no break') def breaking(): stuff.append('break') return 'break' def wat(): stuff.append('wat') return 'wat' cb = teek.Callback() cb.connect(non_breaking) cb.connect(breaking) cb.connect(non_breaking) assert cb.run() == 'break' assert stuff == ['no break', 'break'] stuff.clear() cb2 = teek.Callback() cb2.connect(wat) cb2.connect(non_breaking) assert cb2.run() is None assert stuff == ['wat'] output, errors = capsys.readouterr() assert not output assert '\n cb2.connect(wat)\n' in errors assert errors.endswith( "\nValueError: expected None or 'break', got 'wat'\n")
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.on_delete_window = teek.Callback() self.on_take_focus = teek.Callback() # TODO: delete the commands when they are no longer needed, mem leak self._call(None, 'wm', 'protocol', self._get_wm_widget(), 'WM_DELETE_WINDOW', teek.create_command(self.on_delete_window.run)) self._call(None, 'wm', 'protocol', self._get_wm_widget(), 'WM_TAKE_FOCUS', teek.create_command(self.on_take_focus.run))
def __getitem__(self, sequence): if sequence in self._callback_objects: return self._callback_objects[sequence] # <1> and <Button-1> are equivalent, this handles that for equiv_sequence, equiv_callback in self._callback_objects.items(): # this equivalence check should handle corner cases imo because the # command names from create_command are unique if (self._call_bind(str, sequence) == self._call_bind( str, equiv_sequence)): # noqa: E129 # found an equivalent binding, tcl commands are the same self._callback_objects[sequence] = equiv_callback return equiv_callback callback = teek.Callback() runner = functools.partial(self._callback_runner, callback) command = teek.create_command(runner, [str] * len(_BIND_SUBS)) self.command_list.append(command) # avoid memory leaks subs_string = ' '.join(subs for subs, type_, name in _BIND_SUBS) self._call_bind( None, sequence, '+ if { [%s %s] eq {break} } { break }' % (command, subs_string)) self._callback_objects[sequence] = callback return callback
def _create_scrolling_command(self): result = teek.Callback() command_string = teek.create_command(self._command_runner, extra_args_type=str) self.command_list.append(command_string) self._call(None, self, 'configure', '-command', command_string) return result
def _create_command(self): self._check_in_menu() result = teek.Callback() command_string = teek.create_command(result.run) teek.tcl_call(None, self._menu, 'entryconfigure', self._index, '-command', command_string) self._menu.command_list.append(command_string) return result
def test_callbacks(capsys): result1 = [] result2 = [] cb = teek.Callback() cb.connect(result1.append) cb.connect(result1.append) # repeated intentionally cb.connect(result2.append) assert cb.run('lol') is None assert result1 == ['lol', 'lol'] assert result2 == ['lol'] result1.clear() result2.clear() if platform.python_implementation() == 'PyPy': # in pypy, [].append == [].append result1.append('woot') cb.disconnect(result1.append) result1.clear() else: cb.disconnect(result1.append) assert cb.run('wut') is None assert result1 == result2 == ['wut'] result1.clear() result2.clear() cb.disconnect(result1.append) cb.disconnect(result2.append) assert cb.run('wat wat') is None assert result1 == result2 == [] with pytest.raises(ValueError): cb.disconnect(result1) assert capsys.readouterr() == ('', '') def broken_callback(whatever): 1 / 0 stuff = [] cb.connect(broken_callback) cb.connect(stuff.append) assert cb.run('wat') is None # doesn't raise an error assert not stuff # running callbacks stopped because error output, errors = capsys.readouterr() assert not output assert '\n cb.connect(broken_callback)\n' in errors
def _create_scroll_callback(self, option_name): result = teek.Callback() command_string = teek.create_command(result.run, [float, float]) self.command_list.append(command_string) self._call(None, self, 'configure', '-' + option_name, command_string) return result
def _create_click_command(self): result = teek.Callback() command_string = teek.create_command(result.run) self.command_list.append(command_string) self._call(None, self, 'configure', '-command', command_string) return result