[issue15133] tkinter.BooleanVar.get() behavior and docstring disagree

2012-06-24 Thread klappnase

klappnase  added the comment:

The behavior of Tkinter when handling boolean values appears to be a bit 
erratic at times, not only BooleanVar.get() returns 0/1 instead of True/False 
(e.g. see the thread at tkinter-discuss: 
http://mail.python.org/pipermail/tkinter-discuss/2012-June/003176.html ). This 
is apparently because tk itself uses the strings '0' and '1' as boolean values, 
so behind the scenes Tkinter has to convert any bool into a string when setting 
a value and the string back into a bool when retrieving it, and it seems like 
most of the Tkinter code (and docstrings) was written in the good ol' days when 
Python used 0 / 1 itself.
Now when it comes to change Tkinter's behavior I'd tend to be careful. For 
example BooleanVar.get() could easily be changed to always return True/False. 
But imho this change would only make sense if you add strict input value 
checking for set() either, otherwise we just change one incoherency with 
another. But this would mean that we might end up breaking a lot of working 
code, for what seems to me a primarily aesthetic reason.

And of course, I don't see much use in isolated changes of the behavior of one 
function here and another method there. I feel that if the behavior of Tkinter 
concerning bool values was to be changed, there should at least be a thorough 
change of *any* Tkinter method that gets / sets boolean values so we at least 
end up with an overall coherent solution.
But again, this looks like quite a lot of work, will break running code and add 
no significant benefit besides a cosmetic improvement.
So my vote goes to accepting that 0 and 1 are ok boolean values in Tkinter and 
changing no more than misleading docstrings, as in this example of 
BooleanVar.get():

def get(self):
"""Return the value of the variable as 1 (True) or 0 (False)."""
return self._tk.getboolean(self._tk.globalgetvar(self._name))

--
nosy: +klappnase

___
Python tracker 
<http://bugs.python.org/issue15133>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15133] tkinter.BooleanVar.get() behavior and docstring disagree

2012-06-25 Thread klappnase

klappnase  added the comment:

I agree that get() should better return a boolean in any case, however the bug 
then is not one of BooleanVar but rather one of tk.getboolean(). I did some 
experimenting with get() and it seems that there are three possibilities: 
getboolean() returns True/False as it should when the variable value was 
previously set() to anything Tcl accepts as boolean value (like 'yes'/'no', 
'0'/'1', 'on'/'off', 'true'/'false'). If something which is not a proper 
Tcl-bool was passed to set() before, getboolean will produce a TclError or 
TypeError.
If set() got 0/1 (as integers) or True/False before, getboolean() will return 
0/1 and this appears to me to be the only bug here. But this is not at all a 
sole BooleanVar bug, e.g.:

>>> root=Tk()
>>> root.tk_strictMotif()
0
>>> root.tk_strictMotif(1)
1

You will find this everywhere in Tkinter where getboolean() is used, so I think 
that rather this should be fixed in _tkinter.c than applying a workaround to 
BooleanVar.get() and leaving all other uses of getboolean() as they are; even 
worse, if BooleanVar.set() was changed to accept only True/False and 
getboolean() left as it is, you could not pass the return value of getboolean() 
any longer to BooleanVar.get() which would be really bad.

As far as set() is concerned, it should at least allow everything that Tcl 
accepts as boolean, according to http://wiki.tcl.tk/16235 these are at least 
the above mentioned 'yes'/'no', '0'/'1', 'on'/'off', 'true'/'false' (btw. all 
of these seem to be ok even case insensitive on the tcl side) plus of course 
0/1 and True/False. Otherwise it might break existing code. 

Terry:
"Since the purpose of Variables is to synchronize values between user code and 
tk, TypeVar().set(x).get() should be x when has the proper type. That is now 
true for everything but bool/Boolean."
But when the input type is not proper you can do e.g.:

>>> d = DoubleVar()
>>> d.set('1.1')
>>> d.get()
1.1
>>> i = IntVar()
>>> i.set(True)
>>> i.get()
1
>>> 

I think the Variable classes can also be considered convenience objects that 
save the application programmer a lot of headaches when they have to convert 
Python objects into Tcl which usually expects strings, so I think there is 
nothing wrong with set() accepting "improper" values.

--

___
Python tracker 
<http://bugs.python.org/issue15133>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue15133] tkinter.BooleanVar.get() behavior and docstring disagree

2012-06-25 Thread klappnase

klappnase  added the comment:

"...you could not pass the return value of getboolean() any longer to 
BooleanVar.get() which would be really bad."

Ooops, typo, should be BooleanVar.set() of course.

--

___
Python tracker 
<http://bugs.python.org/issue15133>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-11-30 Thread klappnase

klappnase added the comment:

> What is your real name?
Michael Lange
> What should I add in the Misc/ACKS file?
Hmm, personally I'd prefer the nick, but it seems to be common practice to use 
the real name; I think I'll leave it to you ;)

--

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-12-01 Thread klappnase

klappnase added the comment:

> Are 'unloaded but available' themes really available to use?

Yes.

> Does Style.theme_use(available_name) work?

Yes.

> If so, it seems to me that available_name should
> be reported by theme_names.

I agree, one should think so. I am not 100% certain about that, but to me it 
seems that on the tcl side ttk:themes is newer and thus preferable to theme 
names which maybe is only still there for backwards compatibility.

Since as a Tkinter user I like Tkinter methods to behave like their Tcl/Tk 
counterparts (which, if nothing else, helps a lot in reading and understanding  
tcl code/documentation (and possibly "translating" tcl code into Python)) I had 
rather kept theme_names() intact to avoid confusion. Maybe there could simply a 
line like "Deprecated since Python-xy, use themes() instead." be added to 
theme_names' doc string ?

--

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue1525806] Tkdnd mouse cursor handling patch

2009-04-23 Thread klappnase

klappnase  added the comment:

Maybe this depends on whether the dragged item is "clickable" like
listbox items and buttons or not , like the Labels in the Tkdnd demo.
Ok, I wrote a second patch that solves this by adding another option to
dnd_start(); if this option is set to True (the default) the user gets
the classic behavior, if set to False the cursor changes when the motion
starts, as in the initial patch. I couldn't figure out a good name for
this option, so I called it "swapcursoronclick", at least the name says
what it is for ^_^

--
Added file: http://bugs.python.org/file13750/Tkdnd.diff

___
Python tracker 
<http://bugs.python.org/issue1525806>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing form ttk.py

2013-03-11 Thread klappnase

New submission from klappnase:

When trying to load third-party themes ttk.Style.theme_names() fails to list 
available themes. For example if the themes from the tile-themes project are 
installed one can do:

>>> from tkinter import *
>>> from tkinter import ttk
>>> root=Tk()
>>> s=ttk.Style()
>>> s.theme_names()
('clam', 'alt', 'default', 'classic')
>>> root.tk.call('ttk::themes')
('classic', 'default', 'clam', 'alt')
>>> root.tk.call('package', 'require', 'tile-themes')
'0.6'
>>> s.theme_names()
('clam', 'alt', 'default', 'classic')
>>> root.tk.call('ttk::themes')
('keramik', 'plastik', 'clam', 'winxpblue', 'alt', 'Aquativo', 'classic', 
'default', 'keramik_alt')
>>> 

This has been discussed in more detail at tkinter-discuss:
http://code.activestate.com/lists/python-tkinter-discuss/3373/

As ttk::themes is described as being part of the Public API inside ttk.tcl and 
is also documented in the tcl wiki at http://wiki.tcl.tk/14796 resp. 
http://wiki.tcl.tk/23676 it appears safe to add it to ttk.py.

Considering this I prepared a patch (against b10a9d4f08eb) that adds the 
following method to ttk.Style():

def themes(self, pattern=None):
'''Returns a list of theme names available. It can be passed an
argument which is used as an lsearch glob pattern while looking
for the theme names.'''
return self.tk.splitlist(self.tk.call('ttk::themes', pattern))

--
components: Tkinter
files: patch_ttk.diff
keywords: patch
messages: 183954
nosy: klappnase
priority: normal
severity: normal
status: open
title: ttk::themes missing form ttk.py
type: enhancement
Added file: http://bugs.python.org/file29377/patch_ttk.diff

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-03-12 Thread klappnase

Changes by klappnase :


--
title: ttk::themes missing form ttk.py -> ttk::themes missing from ttk.py

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-03-18 Thread klappnase

klappnase added the comment:

I am not familiar with python's test unit, but I tried my best.

As far as I see there are three possibilities to invoke the function:
* without pattern -> return tuple with all themes
* with pattern that matches one or more themes
* with pattern that matches no themes -> return empty tuple

So I tried to add a method to test_style.StyleTest() :

def test_themes(self):
installed_themes = self.style.themes()
some_themes = self.style.themes('*e*')
no_themes = self.style.themes('foobarbaz')

self.assertTrue(isinstance(installed_themes, tuple))
self.assertTrue(isinstance(some_themes, tuple))
self.assertTrue(isinstance(no_themes, tuple))

Oddly enough this fails on my own system (debian squeeze, tk-8.5.8, 
python-3.1.3 / -2.6.6):

$ python3 test_style.py
test_configure (__main__.StyleTest) ... ok
test_layout (__main__.StyleTest) ... ok
test_lookup (__main__.StyleTest) ... ok
test_map (__main__.StyleTest) ... ok
test_theme_use (__main__.StyleTest) ... ok
test_themes (__main__.StyleTest) ... ERROR

==
ERROR: test_themes (__main__.StyleTest)
--
Traceback (most recent call last):
  File "test_style.py", line 97, in test_themes
no_themes = self.style.themes('foobarbaz')
  File "/usr/lib/python3.1/tkinter/ttk.py", line 536, in themes
return self.tk.splitlist(self.tk.call('ttk::themes', pattern))
TypeError: Can't convert '_tkinter.Tcl_Obj' object to str implicitly

--
Ran 6 tests in 0.086s

FAILED (errors=1)
Traceback (most recent call last):
  File "test_style.py", line 108, in 
run_unittest(*tests_gui)
  File "/usr/lib/python3.1/test/support.py", line 955, in run_unittest
_run_suite(suite)
  File "/usr/lib/python3.1/test/support.py", line 938, in _run_suite
raise TestFailed(err)
test.support.TestFailed: Traceback (most recent call last):
  File "test_style.py", line 97, in test_themes
no_themes = self.style.themes('foobarbaz')
  File "/usr/lib/python3.1/tkinter/ttk.py", line 536, in themes
return self.tk.splitlist(self.tk.call('ttk::themes', pattern))
TypeError: Can't convert '_tkinter.Tcl_Obj' object to str implicitly

The same error occurs with python-2.6.6 (same tk). Apparently this is because:

$ python3
Python 3.1.3 (r313:86834, Nov 28 2010, 11:28:10) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from tkinter import *
>>> from tkinter import ttk
>>> r=Tk()
>>> s=ttk.Style()
>>> x = s.themes('foo')
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.1/tkinter/ttk.py", line 536, in themes
return self.tk.splitlist(self.tk.call('ttk::themes', pattern))
TypeError: Can't convert '_tkinter.Tcl_Obj' object to str implicitly
>>> x=r.tk.call('ttk::themes', 'foo')
>>> x

>>> str(x)
''
>>> 

Called from wish the same call returns an empty string as expected:

$ wish
% ttk::themes
classic default clam alt
% ttk::themes *e*
default
% ttk::themes foobarbaz
%

In python2.6, when setting Tkinter.wantobjects to 0, themes('foo') returns an 
empty tuple as expected.
So I guess this is due to a bug in debian's python/tkinter install. Can anyone 
confirm this?

--

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-03-18 Thread klappnase

klappnase added the comment:

Update: I just tried Python-3.3.0 on WinXP, the same error, so it is obviously 
_not_ a bug specific to the debian python install.

--

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue17397] ttk::themes missing from ttk.py

2013-03-18 Thread klappnase

klappnase added the comment:

Yes, I happen to encounter these TclObjects occasionally, e.g. (not tested with 
the latest python):

$ python3
Python 3.1.3 (r313:86834, Nov 28 2010, 11:28:10) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from tkinter import *
>>> from tkinter import ttk
>>> r=Tk()
>>> p=ttk.Progressbar(r)
>>> p.cget('mode')

>>> print(p.cget('mode'))
determinate
>>> p.cget('mode') == 'determinate'
False
>>> str(p.cget('mode')) == 'determinate'
True
>>> 

In Python2 the easiest way to work around this imho is to set wantobjects to 0, 
however this does not seem to work in Python3 anymore, not sure if this is for 
some reason intentional or deserves another bug report:

$ python3
Python 3.1.3 (r313:86834, Nov 28 2010, 11:28:10) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> tkinter.wantobjects = 0
>>> from tkinter import ttk
>>> r=tkinter.Tk()
>>> p=ttk.Progressbar(r)
>>> p.cget('mode')
''
>>>

To be honest, since these TclObjects never seem to work reliably I had 
preferred it a lot if they would have been turned off by default.

--

___
Python tracker 
<http://bugs.python.org/issue17397>
___
___
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-21 Thread klappnase

klappnase added the comment:

Funny thing, just today I came across the same issue. 
So far I came up with an a little bit refined version of the OP's suggestions. 
Until now I have tested this with Python-2.7.9 and tk-8.6.0 on debian Jessie, I 
think the same code should work for Python-3 , too.
The busy_current() function here always reports only the root window (the same 
when called from within wish, apparently a bug in this early version of Tk-8.6) 
so I was not able to figure out how to use and test the "pattern" option.

def busy(self, **kw):
'''Shortcut for the busy_hold() command.'''
self.tk.call(('tk', 'busy', self._w) + self._options(kw))

def busy_cget(self, option):
'''Queries the busy command configuration options for
this window.
The window must have been previously made busy by
the busy_hold() command. Returns the present value
of the specified option. Option may have
any of the values accepted by busy_hold().'''
return(self.tk.call('tk', 'busy', 'cget', self._w, '-'+option))

def busy_configure(self, cnf=None, **kw):
'''Queries or modifies the tk busy command configuration
options. The window must have been previously made busy by
busy_hold(). Option may have any of the values accepted by
busy_hold().
Please note that the option database is referenced by the
window. For example, if a Frame widget is to be made busy,
the busy cursor can be specified for it by :
w.option_add("*Frame.BusyCursor", "gumby")'''
if kw:
cnf = _cnfmerge((cnf, kw))
elif cnf:
cnf = _cnfmerge(cnf)
if cnf is None:
return(self._getconfigure(
'tk', 'busy', 'configure', self._w))
if type(cnf) is StringType:
return(self._getconfigure1(
'tk', 'busy', 'configure', self._w, '-'+cnf))
self.tk.call((
'tk', 'busy', 'configure', self._w) + self._options(cnf))
busy_config = busy_configure

def busy_current(self, pattern=None):
'''Returns the widget objects of all widgets that are
currently busy.
If a pattern is given, only the path names of busy widgets
matching PATTERN are returned. '''
return([self._nametowidget(x) for x in
self.tk.splitlist(self.tk.call(
   'tk', 'busy', 'current', self._w, pattern))])

def busy_forget(self):
'''Releases resources allocated by the busy() command for
this window, including the transparent window. User events will
again be received by the window. Resources are also released
when the window is destroyed. The window must have been
specified in the busy_hold() operation, otherwise an
exception is raised.'''
self.tk.call('tk', 'busy', 'forget', self._w)

def busy_hold(self, **kw):
'''Makes this window (and its descendants in the Tk window
hierarchy) appear busy. A transparent window is put in front
of the specified window. This transparent window is mapped
the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user
interactions. Normally update() should be called immediately
afterward to insure that the hold operation is in effect before
the application starts its processing. The following
configuration options are valid:
-cursor cursorName
Specifies the cursor to be displayed when the widget
is made busy. CursorName can be in any form accepted
by Tk_GetCursor. The default cursor is "wait" on
Windows and "watch" on other platforms.'''
self.tk.call((
'tk', 'busy', 'hold', self._w) + self._options(kw))

def busy_status(self):
'''Returns the busy status of this window.
If the window presently can not receive user interactions,
True is returned, otherwise False.'''
return((self.tk.getboolean(self.tk.call(
'tk', 'busy', 'status', self._w)) and True) or False)

--
nosy: +klappnase

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-21 Thread klappnase

klappnase added the comment:

Oops, just made a quick test with Python3, and found that I had missed that 
types.StringType is no longer present. So to be compatible with Python3 the 
busy_configure() func ought to look like:

def busy_configure(self, cnf=None, **kw):
if kw:
cnf = _cnfmerge((cnf, kw))
elif cnf:
cnf = _cnfmerge(cnf)
if cnf is None:
return(self._getconfigure(
'tk', 'busy', 'configure', self._w))
if isinstance(cnf, str):
return(self._getconfigure1(
'tk', 'busy', 'configure', self._w, '-'+cnf))
self.tk.call((
'tk', 'busy', 'configure', self._w) + self._options(cnf))

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-22 Thread klappnase

klappnase added the comment:

Ok, I investigated this a little further. First I noticed another bug with the 
code from my first post, the "self._w" must be omitted from the call to 
busy_current(), so the func should look like:

def busy_current(self, pattern=None):
return([self._nametowidget(x) for x in
self.tk.splitlist(self.tk.call(
   'tk', 'busy', 'current', pattern))])

I did then some more testing, the code now seems to work flawlessly both with 
Python-3.5.2 on windows 10 and with Python 2.7 on debian Jessie. So I finally 
prepared a patch (against the __init__.py file from the 3.5.2 windows 
installer). Following Miguel's suggestion I also added aliases prefixed with 
tk_ to the various busy_... methods.
Since I am not familiar with Python's "official" test mechanisms, for now I 
wrote a simple script that does a number of calls to the tk_busy_... functions 
to test if everything works as expected:

try:
import Tkinter
except:
import tkinter as Tkinter
#Tkinter.wantobjects = False

root = Tkinter.Tk()
f = Tkinter.Frame(root, name='f')
f.pack(fill='both', expand=1)
b=Tkinter.Button(f, name='b', text='hi', command=root.bell)
b.pack(padx=100, pady=100)

top = Tkinter.Toplevel(root, name='top')

def test1():
root.tk_busy()
def test2():
root.tk_busy_forget()
def test3():
root.tk_busy_hold(cursor='gumby')
def test4():
root.tk_busy_forget()
def test5():
root.tk_busy_hold()
top.tk_busy(cursor='gumby')
print(root.tk_busy_current())
print(root.tk_busy_current(pattern='*t*'))
def test6():
print(root.tk_busy_current())
def test7():
root.tk_busy_configure(cursor='gumby')
def test8():
print(root.tk_busy_configure())
print(root.tk_busy_configure('cursor'))
print(root.tk_busy_cget('cursor'))
def test9():
print(root.tk_busy_status())
def test10():
root.tk_busy_forget()
print(root.tk_busy_status())
print(root.tk_busy_current())

delay = 0
for test in (test1, test2, test3, test4, test5, test6, test7,
test8, test9, test10):
delay += 1000
root.after(delay, test)

root.mainloop()

--
keywords: +patch
Added file: http://bugs.python.org/file45190/tk_busy.diff

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-22 Thread klappnase

klappnase added the comment:

@Miguel
About tk_busy_configure():
I strongly suggest that my version of tk_busy_configure() is better, since it 
behaves exactly like the usual configure() methods in Tkinter (which includes 
e.g. Canvas.itemconfigure() or Text.tag_configure()), i.e. you can not only 
change the values of the configuration options, but also query available 
options and their default values. I think *this* follows the usual Tkinter 
conventions.
As you pointed out in your last post, I could not use _configure() directly for 
this, but had to "duplicate" the code with a slight modification, because of 
the order of arguments for tk_busy_configure().
The reason that this construct is not used for pack_configure() is simply that 
widget.pack_configure() does not return anything if called without arguments 
(in fact it appears to be the very same as widget.pack()).

About busy_status():
the construct I use here is to work around the broken _getboolean() which does 
not always return True or False, but often returns None instead of False (if 
wantobjects==True). Therefore I used (unlike most Tkinter methods) 
tkapp.getboolean() directly, however quite a while ago I noticed that this was 
broken, too, and sometimes returned 0 or 1 instead of True or False. However I 
admit that I did not test right now if this is still the case, in fact I just 
copy'n'pasted it from code I already use and that works perfectly well (BTW, I 
suggested the same method to fix these issue with _getboolean() here some time 
ago, and of course I agree that it would be preferrable to fix _getboolean() 
and possibly tkapp.getboolean() in the first place).

@Serhiy
Thanks for the link, I did not find the source tree on the new python web site 
(I admit I did not look too hard :) .
I now added a patch against the default branch'es __init__.py . Doc strings are 
(still :) included. I also changed the function names according to Miguel's 
suggestion.
I'll see if I find the time to add a proper test class one of these days (you 
guys make it really hard for outsiders to help out ;)

--
Added file: http://bugs.python.org/file45193/tk_busy.diff

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

As far as I can see, most internal Tkinter methods use _getboolean(), which 
currently looks like:

def _getboolean(self, string):
"""Internal function."""
if string:
return self.tk.getboolean(string)

I am not 100% sure about this, but I figure that when this was written it was 
intentional that if "string" is an empty string, it should return None instead 
of (back then) 0 or 1. Today this would probably translate into something like:

def _getboolean(self, value):
if not value in ('', None):
return bool(self.tk.getboolean(value))

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

Hi Miguel,
about _configure() :
the code you suggest:

def _configure(self, cmd, cnf, kw):
"""Internal function."""
if kw:
cnf = _cnfmerge((cnf, kw))
elif cnf:
cnf = _cnfmerge(cnf)
if cnf is None:
return self._getconfigure(cmd)
if isinstance(cnf, str):
return self._getconfigure1(cmd + ('-'+cnf,))
self.tk.call(cmd + self._options(cnf))

will break all other methods that use configure() and friends. A possible way 
to work around this might be:

def _configure(self, cmd, cnf, kw):
"""Internal function."""
if kw:
cnf = _cnfmerge((cnf, kw))
elif cnf:
cnf = _cnfmerge(cnf)
if not self._w in cmd:
cmd = _flatten((self._w, cmd))
if cnf is None:
return self._getconfigure(cmd)
if isinstance(cnf, str):
return self._getconfigure1(cmd + ('-'+cnf,))
self.tk.call(cmd + self._options(cnf))

Not sure if this is smart, though, it might require some thorough testing.

About getboolean() :

it seems like tkapp.getboolean() returns 1 or 0 when it is passed an integer 
value, at least this is still true here for Python-3.4.2:

$ python3
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from tkinter import *
>>> r=Tk()
>>> getboolean(1)
1
>>> getboolean('1')
True
>>> getboolean('yes')
True
>>> getboolean(True)
True
>>> 


Probably the best thing to do would be to fix this in the C code. The next best 
thing I think is to change tkinter.getboolean(), tkinter.Misc.getboolean() and 
tkinter.Misc._getboolean(). This however leaves a number of Tkinter methods 
like e.g. Text.compare() which directly use self.tk.getboolean() unresolved.

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

Your changed _configure() will also break Canvas/Listbox.itemconfigure(), 
Menu.entryconfigure() and a number of other methods, Tix is also affected. It 
will also break third party extensions that use _configure(), like pybwidget.
As another python motto says "Special cases aren't special enough to break the 
rules." :) I believe that breaking existing code is not justified by the 
"special case" of the tk_busy_configure() syntax, resp. the desire to avoid 10 
extra lines of code.

The change to _configure() I suggested otoh leaves all the existing 
configure()-like methods intact, and it seems at least very unlikely that some 
third party module uses a configure()-like method that adds the window path 
name to the cmd-tuple (which indeed would break my _configure() example.

However, following the "explicit is better than implicit" motto, I believe the 
best idea, if _configure() should be changed at all, is to add a new option to 
let the programmer decide if the window path should be added to the cmd tuple, 
which defaults to a value that keeps the old behavior intact, as in this 
example:

def _configure(self, cmd, cnf, kw, usewinpath=True):
"""Internal function."""
if kw:
cnf = _cnfmerge((cnf, kw))
elif cnf:
cnf = _cnfmerge(cnf)
if usewinpath:
cmd = _flatten((self._w, cmd))
else:
cmd = _flatten(cmd)
if cnf is None:
return self._getconfigure(cmd)
if isinstance(cnf, str):
return self._getconfigure1(cmd + ('-'+cnf,))
self.tk.call(cmd + self._options(cnf))

Then busy_configure might look like:

def busy_configure(self, cnf=None, **kw):
return self._configure(('tk', 'busy', 'configure', self._w),
cnf, kw, usewinpath=False)

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

"Also it's more efficient to use this than the function _flaten() in that 
situation:
   
   if not self._w in cmd:
  cmd = (self._w,) + cmd
"

The construct with _flatten() was not my invention, it's probably something to 
discuss with Guido ;)
The advantage of _flatten() may be, that it will also handle nested tuples 
properly, though I don't know if there is a real-life situation whee nested 
tuples might show up there. Anyway, thinking about optimisations on that level 
seems somewhat pointless to me, no one will probably iterate over configure() 
calls, and if yes, the bottleneck is clearly the self.tk.call() part.

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

"This is my point of view:
These functions are easy to change: 
itemconfigure(), entryconfigure(), image_configure(), tag_configure() and 
window_configure()

It's only to add self._w in the proper place. Only one line per method"

At least Tix would have to be changed, too.

"Other third party extensions should not rely on _configure() because it's an 
internal method (it starts with underscore). We have rights to change the 
semantics of this internal method in any moment without notification."

But why insist on your rights, if there is no actual need to do this? The 
function I posted in my previous message for example serves the same purpose 
without having to change any other function call and without breaking any 
third-party code that possibly uses _configure(). 
You sure have the right to do this, but I feel it is at least somewhat 
unfriendly if it is done without necessity.

Besides, one thing I missed in my last post:
"Also it's more efficient to use this than the function _flaten() in that 
situation:
   
   if not self._w in cmd:
  cmd = (self._w,) + cmd
"
If you want to discard the use of _flatten() you would also have to change 
Misc.configure() .

--
components: +Library (Lib), Tkinter -Installation

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

And another thing:

"There is no test that shows that self.tk.getboolean is buggy."

Well...

$ python3
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
>>> root=tkinter.Tk()
>>> root.tk.getboolean(root.tk_strictMotif())
0
>>>

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-23 Thread klappnase

klappnase added the comment:

The bug is that tk_strictMotif (which uses self.tk.getboolean() itself) returns 
0 instead of False. I used the "nested" command to point out, that 
self.tk.getboolean() is broken when used with wantobjects=True, because it does 
*not* return proper boolean values , i.e. True or False. It is probably the 
reduction to handling strings only that you mentioned that causes this wrong 
behavior, because with wantobjects=True self.tk.call() will convert the "0" 
tk_strictMotif returns into 0 which is not handled properly. With 
wantobjects=False, it will retunr True/False as expected. Its behavior is not 
consistent, *that* is the bug.

But to be honest, personally I don't give a dime if these calls return 
True/False or 1/0, I just wanted to make clear why I explicitely converted the 
output of self.tk.getboolean() in my tk_busy_status function. I believed that 
proper boolean values (True/False) were the desired thing.
I personally agree with you about the busy_status function, my construct is not 
necessary, if someone does not like it to return 0/1 , tkapp.getboolean() 
should be fixed instead.
And again I admit that I don't remember why I used that construct instead of 
just passing the result to bool(). I am quite sure I had a reason for this when 
I started to use this construct first some years ago, but back then 
tkapp.getboolean() behaved differently (and worse), some of which was 
apparently fixed in the meantime.

And one more time about _configure():

"I like elegancy..."

So do I, but can't expanding the functionality of a method by adding a new 
option be considered a more elegant solution than entirely changing its 
behavior with the effect of having to change a number of other things, too? 
(though I admit that the name for this option I picked first should seriously 
be reconsidered if it's supposed to be called "elegant", I confess that I am 
notoriously dumb in inventing names :)

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-24 Thread klappnase

klappnase added the comment:

At least with python 3.4 here wantobjects still is valid, and personally I 
really hope that it remains this way, because I use to set wantobjects=False in 
my own code to avoid having to deal with errors because of some method or other 
unexpectedly returning TclObjects instead of Python objects (which has been 
happening here occasionally ever since they were invented).
I am practically illiterate with C, so I cannot tell what this code does, but 
at least I believe I see clearly here that it appears to be still used:

static TkappObject *
Tkapp_New(const char *screenName, const char *className,
  int interactive, int wantobjects, int wantTk, int sync,
  const char *use)
{
TkappObject *v;
char *argv0;

v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
if (v == NULL)
return NULL;
Py_INCREF(Tkapp_Type);

v->interp = Tcl_CreateInterp();
v->wantobjects = wantobjects;
v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded",
TCL_GLOBAL_ONLY) != NULL;
v->thread_id = Tcl_GetCurrentThread();
v->dispatching = 0;
(...)

static PyObject*
Tkapp_CallResult(TkappObject *self)
{
PyObject *res = NULL;
Tcl_Obj *value = Tcl_GetObjResult(self->interp);
if(self->wantobjects) {
/* Not sure whether the IncrRef is necessary, but something
   may overwrite the interpreter result while we are
   converting it. */
Tcl_IncrRefCount(value);
res = FromObj((PyObject*)self, value);
Tcl_DecrRefCount(value);
} else {
res = unicodeFromTclObj(value);
}
return res;
}

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-24 Thread klappnase

klappnase added the comment:

Hi Serhiy,

thanks for the feedback.

"+def tk_busy(self, **kw):

Shouldn't it be just an alias to tk_busy_hold?"

Not sure, I figured since it is a separate command in tk I would make it a 
separate command in Python, too.

"+def tk_busy_hold(self, **kw):

Since the only supported option is cursor, just declare it.

def tk_busy_hold(self, cursor=None):
"

I thought so at first, too, but is this really wise, since if future versions 
of tk add other options another patch would be required?

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-26 Thread klappnase

klappnase added the comment:

Ok, I hope I applied all the required changes now.
The tests seemed to me to belong to test_misc, so I just added another function 
to the MiscTest class, I hope that is ok. The test runs well here, so I hope I 
did everything correctly.
Thanks for your patience!

--
Added file: http://bugs.python.org/file45230/tk_busy_3.diff

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-26 Thread klappnase

klappnase added the comment:

Oops, I guess I violated PEP257 again, sorry, corrected version #4 attached.

--
Added file: http://bugs.python.org/file45231/tk_busy_4.diff

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue28498] tk busy command

2016-10-26 Thread klappnase

klappnase added the comment:

This is something entirely different, since the commands you list here in tk do 
not accept keyword arguments at all.

--

___
Python tracker 
<http://bugs.python.org/issue28498>
___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com