classification
Title: Tkinter in Python 3.4 for Windows incorrectly renders certain colors using non-TclTk RGB values
Type: behavior Stage: resolved
Components: Tkinter, Windows Versions: Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: MartyMacGyver, ned.deily, serhiy.storchaka, steve.dower, terry.reedy, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2015-04-17 00:51 by MartyMacGyver, last changed 2015-04-20 06:41 by MartyMacGyver. This issue is now closed.

Files
File name Uploaded Description Edit
colortest.py MartyMacGyver, 2015-04-17 00:51 Python 2.7/3.4 script to demonstrate the issue
osx_installer_license_example.jpg ned.deily, 2015-04-20 01:27
Messages (17)
msg241300 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-17 00:51
In Python 2.7.9 for Windows, colors displayed match their RGB values as defined in TclTk:
http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm (8.6 is identical)

In Python 3.4.3 for Windows, the following colors differ noticeably from their TclTk counterparts: grey/gray, green, purple, and maroon.

Instead of the spec TclTk RGB values, these particular colors are rendered using the HTML RGB values.

This only happens in Python for Windows - OSX doesn't have this problem as it appears to use the same TclTk package for both 2.7 and 3.4 and correctly renders the colors per TclTk specs in each.

Tkinter ought to render named colors using the spec TclTk RGB values regardless of platform.
msg241374 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-04-17 22:52
I ran colortest on Win7 with 2.7.9, 3.3.5, 3.4.3, and 3.5.0a3.  The first two are the same, the last two are also the same, but with the muted colors noted.  The obvious difference is that for Windows, we changed from tcl/tk 8.5 to 8.6 in 3.4.0.  The same change will happen (I believe) on OSX for 3.5.0.  You might want to try 3.5.0a3 on OSX and see if a) the tcl/tk version has changed and b) if it affects the colors there.  (I believe some people have also installed and run tcl/tk 8.6 with Python 3.4 but I do not know the details.)

AFAIK, tkinter passes color words to tk unchanged and has nothing to do with conversion to rgb and color rendering.  I presume the data for the conversion dict is somewhere in the tcl/tk source. Perhaps Serhiy can commont on this.
msg241378 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-04-17 23:12
From Tcl/Tk 8.6 on, Tk uses Web colours instead of X11 ones, where they conflict.

http://www.tcl.tk/cgi-bin/tct/tip/403.html
msg241391 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-18 02:17
This change wasn't in their documentation anywhere:
http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm
http://www.tcl.tk/man/tcl8.6/TkCmd/colors.htm

It would be of value to call this out in the Python documentation (as far as I can find, there's nothing specifying which version of TclTk goes with what version of Python for Windows).

As for OSX, it appears to use whatever TclTk is installed on the system. The recommended version isn't consistent with this change either - Python specifies 8.5 for 2.7 and 3.4:
https://www.python.org/download/mac/tcltk/
msg241395 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-04-18 04:26
Aha. http://www.tcl.tk/man/tcl8.6/TkCmd/colors.htm should be changed.  Not an issue for this tracker though.
msg241444 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2015-04-18 19:06
Current source releases of Python do not specify which version of Tk they should be run with; that is largely up to the distributors of Python (including python.org binary installers for Windows and OS X) and the conventions of the platform the instances are running on.  There are versions of current Python 3.4.x and Python 2.7.x running on supported platforms (like OS X) with various flavors of Tk 8.6, 8.5, and even 8.4.  So Python documentation has to be careful to avoid making assumptions about Tk version-specific features.  FWIW, a link to Tk 8.6 differences is provided on the Tcl/Tk 8.6 release page (http://www.tcl.tk/software/tcltk/8.6.html) -> "Changes in Tcl/Tk 8.6" (http://wiki.tcl.tk/21276).
msg241500 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-19 09:08
Yes, the python.org releases specify the TclTK they should be used with, for OSX:
https://www.python.org/download/mac/tcltk/

If there's another python.org bug report list let me know, but this still seems to be the right place. Since Python.org's windows distribution is what led to this question, I'd like to at least see it documented somewhere what TclTk is compiled into the Python.org windows distribution. I didn't find any info on what TclTk Python.org's Windows build includes, and that's something that can be rectified here. (Since there are documented *recommendations* for what to use with the OSX builds from this site then there ought to be some similar documentation what is *built in* to the Windows builds from this site.)

As for the failure of TclTk to properly document the change they made to their colors, that's a matter for their bug tracker. I took their documentation at face value, and didn't find information to the contrary when I searched prior to posting this.
msg241501 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-19 09:28
FYI, I've filed a bug with the TclTk people regarding their documentation.

http://core.tcl.tk/tk/tktview/2a02881e4c23634022d0ae40a14383d9baad9eb9
msg241504 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-04-19 09:58
I don't think that we should document such minor details in Tkinter documentation. There are larger differences between Tcl/Tk versions that can make Python programs fail (e.g. introducing new internal Tcl/Tk type), and they are not documented.
msg241507 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-19 10:23
No, I don't expect something like the color change to be documented here (unless that thing is incorrectly documented within python.org's current release trees).

I do expect that just as python.org's OSX releases document the recommended version of TclTk to use (e.g., https://www.python.org/download/mac/tcltk/) there should be equivalent documentation describing what version of TckTk is actualy compiled into the Windows releases here (e.g., 8.5.9 or 8.6.4 or such. (Note that Tkinter.TclVersion/TkVersion aren't sufficiently detailed to dynamically determine the exact in-built versions either).

Beyond that, it's up to the user to read more about that specified or recommended release in the external Tcl/Tk docs (except where such documentation is present in the doc trees on python.org).
msg241544 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-04-19 19:08
The tkinter docs need to be expanded, but that is a different issue.

The complete tcl/tk version is displayed in Idle -> Help -> About Idle using "self.tk.call('info', 'patchlevel')".  Pending a reason not to, I would be in favor of adding this full info as a tkinter attribute (.version ?, .patch_level ?) in addition to the current .TclVersion and .TkVersion attributes (which are now always the same, though once probably not).  This would be a new tracker issue.  

Adding the tcl/tk version included with the windows installer to the download web page seems reasonable to me.  This would be a third issue, involving revision of PEP 101 on making releases.  The first change would be the RM (Release Manager) getting the info from the WE (Windows Expert).  This would go somewhere under "The WE then generates Windows installer files". Then somewhere under "Now it's time [for the RM] to twiddle the web site." would be something about inserting the tcl/tk version is a revised template page, or whatever.  I leave it to you to look as the site for the specific page to revise and how, and to read this section of the PEP.  Proposed PEP changes are usually sent to PEP editors.  If you want to pursue this, you might first email Barry to see what he would prefer.
msg241566 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-19 21:14
Thank you. Before going down the road of revising PEP 101 (which appears to be very non-trivial despite the simple (and certainly always present) data involved), I'd like to know: is version information about the pre-compiled Windows binaries (of which this is one) already being captured anywhere else publically visible on a per-release or per-build basis? It's useful that such binaries exist given Windows' unique requirements versus other systems, but are these binaries themselves documented anywhere as they are updated (e.g., how to re-create them)? Such a source of truth would simplify that revision request.
msg241583 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2015-04-20 01:27
I am im favor of adding documentation for the existing tkinter TclVerion and TkVersion attributes to the tkinter section of the Standard Library reference as well as documenting a form of tkinter.Tcl().call('info', 'patchlevel') and/or tkinter.Tk().call('info', 'patchlevel') to return the full patchlevel string.  These spellings will work with every supported version of tkinter, Tcl, Tk, and platform.  Note that, while Tcl and Tk do have independent patch level strings, Tcl and Tk should normally always be installed at the same patch level; AFAIK, they are always released simultaneously upstream and are intended to be installed together.  If one were to add Tcl and Tk patchlevel attributes to tkinter, the code should be careful to dynamically get patchlevels via the equivalent of the above calls, and should not use the compile-time strings from Tcl/Tk include files tcl.h and tk.h, since on many platforms Tcl and Tk are installed as shared libraries and can be updated to a new patch level independently of the Python distribution.

As far as documenting the exact version of Tcl/Tk used in building the Python provided by a python.org Windows installer, that's a special case of documenting the versions of all third-party libraries used in the build.  I believe all of the information is available in the source tree PCBuild project files: Steve or Zach should be able to address whether that info is and/or should be available as part of the install process.  Adding all of that info to the release download page on python.org would be overkill as would a new PEP or a modification to PEP 101, IMO.  We do include general license information for possibly-included third-party libraries at the end of the license page in the release documentation set (https://docs.python.org/3/license.html) but, correctly, do not include specific version numbers there.  As a data point, for the python.org OS X installers, we now do include the specific version numbers of included libraries when producing the installer license file displayed as part of the installation process on OS X, with a link to the documentation set license page for the full text of the third-party licenses (see the attached jpg for an example).
msg241588 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-20 02:12
FYI, I'm currently using calls into Tkinter to get more detailed version info. Some methods work better than others... I've outlined my attempts below for reference (the last tcl_ver and tk_ver outputs are the ones I'm using, even though they are somewhat different in how they are written).

try:  # Python2
    import Tkinter as tk
except ImportError:  # Python3
    import tkinter as tk

root = tk.Tk()

tcl_ver = tk.TclVersion  # Typical but low precsion
tcl_ver = tk.Tcl().eval('info patchlevel')  # Works but uses eval()
tcl_ver = root.tcl.call('info', 'patchlevel')  # Fails (AttributeError)
tcl_ver = tk.Tcl().call('info', 'patchlevel')  # Works, using

tk_ver = tk.TkVersion  # Typical but low precsion
tk_ver = tk.Tk().eval('info patchlevel')  # Works but makes extra window, uses eval()
tk_ver = tk.Tk().call('info', 'patchlevel')  # Works but makes extra window
tk_ver = root.tk.call('info', 'patchlevel')  # Works, using
msg241596 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2015-04-20 03:52
Ned, I was indeed thinking of creating the string upon startup.

Martin: "Works, using" ? using what?
msg241614 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-20 06:32
"Works, using" = this works, it's what I'm using (was trying to be brief - was too brief evidently).
msg241617 - (view) Author: Martin Falatic (MartyMacGyver) * Date: 2015-04-20 06:41
There may be a more uniform way to do all this that I'm not aware of. root.tcl.call() and root.tk.call() would be most symmetric while not creating extraneous windows, but that's not an option for the former, thus the methods I ended up using look different for Tk and Tcl.

Whatever the output, a tuple (8,5,9) or string "8.5.9" (easily converted to a tuple) will be nice, hiding any disparate implementation details.
History
Date User Action Args
2015-04-20 06:41:59MartyMacGyversetmessages: + msg241617
2015-04-20 06:32:39MartyMacGyversetmessages: + msg241614
2015-04-20 03:52:51terry.reedysetmessages: + msg241596
2015-04-20 02:12:37MartyMacGyversetmessages: + msg241588
2015-04-20 01:27:29ned.deilysetfiles: + osx_installer_license_example.jpg

messages: + msg241583
2015-04-19 21:14:11MartyMacGyversetmessages: + msg241566
2015-04-19 19:08:01terry.reedysetmessages: + msg241544
2015-04-19 10:23:55MartyMacGyversetmessages: + msg241507
2015-04-19 09:58:41serhiy.storchakasetmessages: + msg241504
2015-04-19 09:28:34MartyMacGyversetmessages: + msg241501
2015-04-19 09:08:33MartyMacGyversetmessages: + msg241500
2015-04-18 19:06:21ned.deilysetnosy: + ned.deily
messages: + msg241444
2015-04-18 04:26:22terry.reedysetmessages: + msg241395
2015-04-18 02:17:38MartyMacGyversetmessages: + msg241391
2015-04-17 23:12:06serhiy.storchakasetstatus: open -> closed
resolution: not a bug
messages: + msg241378

stage: test needed -> resolved
2015-04-17 22:52:58terry.reedysetnosy: + terry.reedy, serhiy.storchaka

messages: + msg241374
stage: test needed
2015-04-17 03:40:19ned.deilysetnosy: + tim.golden, zach.ware, steve.dower
components: + Windows
2015-04-17 00:51:39MartyMacGyvercreate