Author zach.ware
Recipients r.david.murray, serhiy.storchaka, terry.reedy, zach.ware
Date 2014-02-28.19:36:07
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1393616168.99.0.787945166861.issue20035@psf.upfronthosting.co.za>
In-reply-to
Content
Terry J. Reedy added the comment:
> However, rather than require a tearDowmnodule for every module that imports
​> ​tkinter, lets fix the root problem.

I agree that that would be the ideal solution.

> I thought of having the environment change warning function ignore changes to
​> ​TCL/TK/TIX_LIBRARY, but even better would be to not change them. Rename _fix 
> to ​_dirs and redefine its mission as setting and holding three module
> attributes: ​tcldir, tkdir, and tixdir. They would be set from either the 
> environment or the ​alternate search code. Any other modules that need the
> info should get it from ​_dirs rather the environment.

Unfortunately, environment variables are the easiest way to tell Tcl/Tk where to find init.tcl/tk.tcl.  Digging around in tclBasic.c and tkWindow.c, it looks like it should be possible to provide our own values for where to find the libraries, but it doesn't look especially easy.  It looks like it has to be done somewhere between Tcl_CreateInterp() and Tcl_Init(), which means it has to be done in _tkinter.c.

> I believe this part of _fix is buggy.
> +        if "TCL_LIBRARY" not in os.environ:
> +            for name in os.listdir(prefix):
> +                if name.startswith("tcl"):
> +                    tcldir = os.path.join(prefix,name)
> +                    if os.path.isdir(tcldir):
> +                        os.environ["TCL_LIBRARY"] = tcldir
> Both base/tcl and base/../tcktk/lib contain (for 3.4) directories named tcl8
> and​ tcl8.6. Since only tcl8.6 works, the code above depends on listdir
> presenting it​ second. The 'if name' clause could be augmented with
> 'and name[-2] == '.'.

Actually, setting TCL_LIBRARY to either one (full path to tcl8 or tcl8.6) or, in fact, the same path without any version qualifier at all, works (tested by manually setting the variables before calling tkinter.Tk()).  It looks like Tcl checks for a folder with the right version number on its own.

Also, from testing with installed 2.7, 3.3, and 3.4rc1, it looks like we only really need to set TCL_LIBRARY anyway: setting TK_LIBRARY and TIX_LIBRARY to '.', properly setting TCL_LIBRARY, and then calling tkinter.Tk(), the expected toplevel window pops up and root.tk.eval('package require Tix') returns the expected version number from Tix.

I'm convinced that my initial patches in this issue are the wrong way to attack the problem.  I'll look into changing _tkinter.c to do the job of tkinter._fix without changing environment variables, hopefully we can just do away with _fix entirely.
History
Date User Action Args
2014-02-28 19:36:09zach.waresetrecipients: + zach.ware, terry.reedy, r.david.murray, serhiy.storchaka
2014-02-28 19:36:08zach.waresetmessageid: <1393616168.99.0.787945166861.issue20035@psf.upfronthosting.co.za>
2014-02-28 19:36:08zach.warelinkissue20035 messages
2014-02-28 19:36:07zach.warecreate