Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tkinter in Python 3.4 for Windows incorrectly renders certain colors using non-TclTk RGB values #68170

Closed
MartyMacGyver mannequin opened this issue Apr 17, 2015 · 17 comments
Labels
OS-windows topic-tkinter type-bug An unexpected behavior, bug, or error

Comments

@MartyMacGyver
Copy link
Mannequin

MartyMacGyver mannequin commented Apr 17, 2015

BPO 23982
Nosy @terryjreedy, @tjguk, @ned-deily, @zware, @serhiy-storchaka, @zooba, @MartyMacGyver
Files
  • colortest.py: Python 2.7/3.4 script to demonstrate the issue
  • osx_installer_license_example.jpg
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2015-04-17.23:12:06.610>
    created_at = <Date 2015-04-17.00:51:39.451>
    labels = ['invalid', 'type-bug', 'expert-tkinter', 'OS-windows']
    title = 'Tkinter in Python 3.4 for Windows incorrectly renders certain colors using non-TclTk RGB values'
    updated_at = <Date 2015-04-20.06:41:59.093>
    user = 'https://github.com/MartyMacGyver'

    bugs.python.org fields:

    activity = <Date 2015-04-20.06:41:59.093>
    actor = 'MartyMacGyver'
    assignee = 'none'
    closed = True
    closed_date = <Date 2015-04-17.23:12:06.610>
    closer = 'serhiy.storchaka'
    components = ['Tkinter', 'Windows']
    creation = <Date 2015-04-17.00:51:39.451>
    creator = 'MartyMacGyver'
    dependencies = []
    files = ['39081', '39137']
    hgrepos = []
    issue_num = 23982
    keywords = []
    message_count = 17.0
    messages = ['241300', '241374', '241378', '241391', '241395', '241444', '241500', '241501', '241504', '241507', '241544', '241566', '241583', '241588', '241596', '241614', '241617']
    nosy_count = 7.0
    nosy_names = ['terry.reedy', 'tim.golden', 'ned.deily', 'zach.ware', 'serhiy.storchaka', 'steve.dower', 'MartyMacGyver']
    pr_nums = []
    priority = 'normal'
    resolution = 'not a bug'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue23982'
    versions = ['Python 3.4']

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 17, 2015

    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.

    @MartyMacGyver MartyMacGyver mannequin added topic-tkinter type-bug An unexpected behavior, bug, or error labels Apr 17, 2015
    @terryjreedy
    Copy link
    Member

    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.

    @serhiy-storchaka
    Copy link
    Member

    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

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 18, 2015

    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/

    @terryjreedy
    Copy link
    Member

    Aha. http://www.tcl.tk/man/tcl8.6/TkCmd/colors.htm should be changed. Not an issue for this tracker though.

    @ned-deily
    Copy link
    Member

    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).

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 19, 2015

    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.

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 19, 2015

    FYI, I've filed a bug with the TclTk people regarding their documentation.

    http://core.tcl.tk/tk/tktview/2a02881e4c23634022d0ae40a14383d9baad9eb9

    @serhiy-storchaka
    Copy link
    Member

    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.

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 19, 2015

    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).

    @terryjreedy
    Copy link
    Member

    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.

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 19, 2015

    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.

    @ned-deily
    Copy link
    Member

    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).

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 20, 2015

    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

    @terryjreedy
    Copy link
    Member

    Ned, I was indeed thinking of creating the string upon startup.

    Martin: "Works, using" ? using what?

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 20, 2015

    "Works, using" = this works, it's what I'm using (was trying to be brief - was too brief evidently).

    @MartyMacGyver
    Copy link
    Mannequin Author

    MartyMacGyver mannequin commented Apr 20, 2015

    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.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    OS-windows topic-tkinter type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    3 participants