diff -r f581cbaedc87 Lib/test/test_tcl.py --- a/Lib/test/test_tcl.py Sat May 16 22:45:27 2015 -0500 +++ b/Lib/test/test_tcl.py Sat May 16 22:52:14 2015 -0500 @@ -7,9 +7,7 @@ # Skip this test if the _tkinter module wasn't built. _tkinter = support.import_module('_tkinter') -# Make sure tkinter._fix runs to set up the environment -tkinter = support.import_fresh_module('tkinter') - +import tkinter from tkinter import Tcl from _tkinter import TclError diff -r f581cbaedc87 Lib/test/test_tk.py --- a/Lib/test/test_tk.py Sat May 16 22:45:27 2015 -0500 +++ b/Lib/test/test_tk.py Sat May 16 22:52:14 2015 -0500 @@ -2,9 +2,6 @@ # Skip test if _tkinter wasn't built. support.import_module('_tkinter') -# Make sure tkinter._fix runs to set up the environment -support.import_fresh_module('tkinter') - # Skip test if tk cannot be initialized. support.requires('gui') diff -r f581cbaedc87 Lib/test/test_ttk_guionly.py --- a/Lib/test/test_ttk_guionly.py Sat May 16 22:45:27 2015 -0500 +++ b/Lib/test/test_ttk_guionly.py Sat May 16 22:52:14 2015 -0500 @@ -5,12 +5,10 @@ # Skip this test if _tkinter wasn't built. support.import_module('_tkinter') -# Make sure tkinter._fix runs to set up the environment -tkinter = support.import_fresh_module('tkinter') - # Skip test if tk cannot be initialized. support.requires('gui') +import tkinter from _tkinter import TclError from tkinter import ttk from tkinter.test import runtktests diff -r f581cbaedc87 Lib/test/test_ttk_textonly.py --- a/Lib/test/test_ttk_textonly.py Sat May 16 22:45:27 2015 -0500 +++ b/Lib/test/test_ttk_textonly.py Sat May 16 22:52:14 2015 -0500 @@ -4,9 +4,6 @@ # Skip this test if _tkinter does not exist. support.import_module('_tkinter') -# Make sure tkinter._fix runs to set up the environment -support.import_fresh_module('tkinter') - from tkinter.test import runtktests def test_main(): diff -r f581cbaedc87 Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py Sat May 16 22:45:27 2015 -0500 +++ b/Lib/tkinter/__init__.py Sat May 16 22:52:14 2015 -0500 @@ -31,9 +31,6 @@ """ import sys -if sys.platform == "win32": - # Attempt to configure Tcl/Tk without requiring PATH - from tkinter import _fix import _tkinter # If this fails your Python may not be configured for Tk TclError = _tkinter.TclError diff -r f581cbaedc87 Lib/tkinter/_fix.py --- a/Lib/tkinter/_fix.py Sat May 16 22:45:27 2015 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -import sys, os - -# Delay import _tkinter until we have set TCL_LIBRARY, -# so that Tcl_FindExecutable has a chance to locate its -# encoding directory. - -# Unfortunately, we cannot know the TCL_LIBRARY directory -# if we don't know the tcl version, which we cannot find out -# without import Tcl. Fortunately, Tcl will itself look in -# \..\tcl, so anything close to -# the real Tcl library will do. - -# Expand symbolic links on Vista -try: - import ctypes - ctypes.windll.kernel32.GetFinalPathNameByHandleW -except (ImportError, AttributeError): - def convert_path(s): - return s -else: - def convert_path(s): - if isinstance(s, bytes): - s = s.decode("mbcs") - hdir = ctypes.windll.kernel32.\ - CreateFileW(s, 0x80, # FILE_READ_ATTRIBUTES - 1, # FILE_SHARE_READ - None, 3, # OPEN_EXISTING - 0x02000000, # FILE_FLAG_BACKUP_SEMANTICS - None) - if hdir == -1: - # Cannot open directory, give up - return s - buf = ctypes.create_unicode_buffer("", 32768) - res = ctypes.windll.kernel32.\ - GetFinalPathNameByHandleW(hdir, buf, len(buf), - 0) # VOLUME_NAME_DOS - ctypes.windll.kernel32.CloseHandle(hdir) - if res == 0: - # Conversion failed (e.g. network location) - return s - s = buf[:res] - # Ignore leading \\?\ - if s.startswith("\\\\?\\"): - s = s[4:] - if s.startswith("UNC"): - s = "\\" + s[3:] - return s - -prefix = os.path.join(sys.base_prefix,"tcl") -if not os.path.exists(prefix): - # devdir/externals/tcltk/lib - prefix = os.path.join(sys.base_prefix, "externals", "tcltk", "lib") - prefix = os.path.abspath(prefix) -# if this does not exist, no further search is needed -if os.path.exists(prefix): - prefix = convert_path(prefix) - 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 - # Compute TK_LIBRARY, knowing that it has the same version - # as Tcl - import _tkinter - ver = str(_tkinter.TCL_VERSION) - if "TK_LIBRARY" not in os.environ: - v = os.path.join(prefix, 'tk'+ver) - if os.path.exists(os.path.join(v, "tclIndex")): - os.environ['TK_LIBRARY'] = v - # We don't know the Tix version, so we must search the entire - # directory - if "TIX_LIBRARY" not in os.environ: - for name in os.listdir(prefix): - if name.startswith("tix"): - tixdir = os.path.join(prefix,name) - if os.path.isdir(tixdir): - os.environ["TIX_LIBRARY"] = tixdir diff -r f581cbaedc87 Modules/_tkinter.c --- a/Modules/_tkinter.c Sat May 16 22:45:27 2015 -0500 +++ b/Modules/_tkinter.c Sat May 16 22:52:14 2015 -0500 @@ -101,7 +101,49 @@ #ifdef MS_WINDOWS #include #define WAIT_FOR_STDIN + +static PyObject * +_get_tcl_lib_path() +{ + static PyObject *tcl_library_path = NULL; + static int already_checked = 0; + + if (already_checked == 0) { + PyObject *prefix; + struct stat stat_buf; + + prefix = PyUnicode_FromWideChar(Py_GetPrefix(), -1); + if (prefix == NULL) { + return NULL; + } + + /* Check expected location for an installed Python first */ + tcl_library_path = PyUnicode_Concat(prefix, + PyUnicode_FromString( + "\\tcl\\tcl" TCL_VERSION)); + + if (_Py_stat(tcl_library_path, &stat_buf) == -1) { + /* install location doesn't exist, reset errno and see if + we're a repository build */ + errno = 0; +#ifdef Py_TCLTK_DIR + tcl_library_path = PyUnicode_FromString( + Py_TCLTK_DIR "\\lib\\tcl" TCL_VERSION); + if (_Py_stat(tcl_library_path, &stat_buf) == -1) { + /* tcltkDir for a repository build doesn't exist either, + reset errno and leave Tcl to its own devices */ + errno = 0; + tcl_library_path = NULL; + } +#else + tcl_library_path = NULL; #endif + } + already_checked = 1; + } + return tcl_library_path; +} +#endif /* MS_WINDOWS */ #ifdef WITH_THREAD @@ -681,6 +723,30 @@ PyMem_Free(args); } +#ifdef MS_WINDOWS + { + PyObject *str_path; + PyObject *utf8_path; + DWORD ret; + + ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); + if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + str_path = _get_tcl_lib_path(); + if (str_path != NULL) { + utf8_path = PyUnicode_AsUTF8String(str_path); + if (utf8_path == NULL) { + return NULL; + } + Tcl_SetVar(v->interp, + "tcl_library", + PyBytes_AsString(utf8_path), + TCL_GLOBAL_ONLY); + Py_DECREF(utf8_path); + } + } + } +#endif + if (Tcl_AppInit(v->interp) != TCL_OK) { PyObject *result = Tkinter_Error((PyObject *)v); #ifdef TKINTER_PROTECT_LOADTK @@ -3517,8 +3583,41 @@ uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); if (uexe) { cexe = PyUnicode_EncodeFSDefault(uexe); - if (cexe) + if (cexe) { +#ifdef MS_WINDOWS + int set_var = 0; + PyObject *str_path; + wchar_t *wcs_path; + DWORD ret; + + ret = GetEnvironmentVariableW(L"TCL_LIBRARY", NULL, 0); + + if (!ret && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { + str_path = _get_tcl_lib_path(); + if (str_path != NULL) { + wcs_path = PyUnicode_AsWideCharString(str_path, NULL); + if (wcs_path == NULL) { + return NULL; + } + SetEnvironmentVariableW(L"TCL_LIBRARY", wcs_path); + set_var = 1; + } else { + if (PyErr_Occurred()) { + return NULL; + } + } + } + Tcl_FindExecutable(PyBytes_AsString(cexe)); + + if (set_var) { + SetEnvironmentVariableW(L"TCL_LIBRARY", NULL); + PyMem_Free(wcs_path); + } +#else + Tcl_FindExecutable(PyBytes_AsString(cexe)); +#endif /* MS_WINDOWS */ + } Py_XDECREF(cexe); Py_DECREF(uexe); } diff -r f581cbaedc87 PCbuild/_tkinter.vcxproj --- a/PCbuild/_tkinter.vcxproj Sat May 16 22:45:27 2015 -0500 +++ b/PCbuild/_tkinter.vcxproj Sat May 16 22:52:14 2015 -0500 @@ -62,7 +62,7 @@ $(tcltkDir)include;%(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) + Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";WITH_APPINIT;%(PreprocessorDefinitions) $(tcltkLib);%(AdditionalDependencies) diff -r f581cbaedc87 Tools/buildbot/test-amd64.bat --- a/Tools/buildbot/test-amd64.bat Sat May 16 22:45:27 2015 -0500 +++ b/Tools/buildbot/test-amd64.bat Sat May 16 22:52:14 2015 -0500 @@ -1,7 +1,5 @@ @rem Used by the buildbot "test" step. setlocal -rem The following line should be removed before #20035 is closed -set TCL_LIBRARY=%~dp0..\..\externals\tcltk64\lib\tcl8.6 call "%~dp0..\..\PCbuild\rt.bat" -d -q -x64 -uall -rwW -n --timeout=3600 %* diff -r f581cbaedc87 Tools/buildbot/test.bat --- a/Tools/buildbot/test.bat Sat May 16 22:45:27 2015 -0500 +++ b/Tools/buildbot/test.bat Sat May 16 22:52:14 2015 -0500 @@ -1,7 +1,5 @@ @rem Used by the buildbot "test" step. setlocal -rem The following line should be removed before #20035 is closed -set TCL_LIBRARY=%~dp0..\..\externals\tcltk\lib\tcl8.6 call "%~dp0..\..\PCbuild\rt.bat" -d -q -uall -rwW -n --timeout=3600 %*