Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit c689ab1

Browse files
author
Anselm Kruis
committed
merge branch 3.5 just after tagging v3.5.0rc4
2 parents 6c013cc + fff3e16 commit c689ab1

File tree

17 files changed

+181
-54
lines changed

17 files changed

+181
-54
lines changed

.hgtags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,4 @@ c0d64105463581f85d0e368e8d6e59b7fd8f12b1 v3.5.0b4
176176
1a58b1227501e046eee13d90f113417b60843301 v3.5.0rc1
177177
cc15d736d860303b9da90d43cd32db39bab048df v3.5.0rc2
178178
66ed52375df802f9d0a34480daaa8ce79fc41313 v3.5.0rc3
179+
2d033fedfa7f1e325fd14ccdaa9cb42155da206f v3.5.0rc4

Include/patchlevel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
#define PY_MINOR_VERSION 5
2121
#define PY_MICRO_VERSION 0
2222
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA
23-
#define PY_RELEASE_SERIAL 3
23+
#define PY_RELEASE_SERIAL 4
2424

2525
/* Version as a string */
26-
#define PY_VERSION "3.5.0rc3"
26+
#define PY_VERSION "3.5.0rc4"
2727
/*--end constants--*/
2828

2929
/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2.

Lib/distutils/_msvccompiler.py

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
# ported to VS 2015 by Steve Dower
1515

1616
import os
17+
import shutil
18+
import stat
1719
import subprocess
1820

1921
from distutils.errors import DistutilsExecError, DistutilsPlatformError, \
@@ -25,15 +27,15 @@
2527
import winreg
2628
from itertools import count
2729

28-
def _find_vcvarsall():
30+
def _find_vcvarsall(plat_spec):
2931
with winreg.OpenKeyEx(
3032
winreg.HKEY_LOCAL_MACHINE,
3133
r"Software\Microsoft\VisualStudio\SxS\VC7",
3234
access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY
3335
) as key:
3436
if not key:
3537
log.debug("Visual C++ is not registered")
36-
return None
38+
return None, None
3739

3840
best_version = 0
3941
best_dir = None
@@ -51,14 +53,23 @@ def _find_vcvarsall():
5153
best_version, best_dir = version, vc_dir
5254
if not best_version:
5355
log.debug("No suitable Visual C++ version found")
54-
return None
56+
return None, None
5557

5658
vcvarsall = os.path.join(best_dir, "vcvarsall.bat")
5759
if not os.path.isfile(vcvarsall):
5860
log.debug("%s cannot be found", vcvarsall)
59-
return None
61+
return None, None
6062

61-
return vcvarsall
63+
vcruntime = None
64+
vcruntime_spec = _VCVARS_PLAT_TO_VCRUNTIME_REDIST.get(plat_spec)
65+
if vcruntime_spec:
66+
vcruntime = os.path.join(best_dir,
67+
vcruntime_spec.format(best_version))
68+
if not os.path.isfile(vcruntime):
69+
log.debug("%s cannot be found", vcruntime)
70+
vcruntime = None
71+
72+
return vcvarsall, vcruntime
6273

6374
def _get_vc_env(plat_spec):
6475
if os.getenv("DISTUTILS_USE_SDK"):
@@ -67,7 +78,7 @@ def _get_vc_env(plat_spec):
6778
for key, value in os.environ.items()
6879
}
6980

70-
vcvarsall = _find_vcvarsall()
81+
vcvarsall, vcruntime = _find_vcvarsall(plat_spec)
7182
if not vcvarsall:
7283
raise DistutilsPlatformError("Unable to find vcvarsall.bat")
7384

@@ -83,12 +94,16 @@ def _get_vc_env(plat_spec):
8394
raise DistutilsPlatformError("Error executing {}"
8495
.format(exc.cmd))
8596

86-
return {
97+
env = {
8798
key.lower(): value
8899
for key, _, value in
89100
(line.partition('=') for line in out.splitlines())
90101
if key and value
91102
}
103+
104+
if vcruntime:
105+
env['py_vcruntime_redist'] = vcruntime
106+
return env
92107

93108
def _find_exe(exe, paths=None):
94109
"""Return path to an MSVC executable program.
@@ -115,6 +130,20 @@ def _find_exe(exe, paths=None):
115130
'win-amd64' : 'amd64',
116131
}
117132

133+
# A map keyed by get_platform() return values to the file under
134+
# the VC install directory containing the vcruntime redistributable.
135+
_VCVARS_PLAT_TO_VCRUNTIME_REDIST = {
136+
'x86' : 'redist\\x86\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll',
137+
'amd64' : 'redist\\x64\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll',
138+
'x86_amd64' : 'redist\\x64\\Microsoft.VC{0}0.CRT\\vcruntime{0}0.dll',
139+
}
140+
141+
# A set containing the DLLs that are guaranteed to be available for
142+
# all micro versions of this Python version. Known extension
143+
# dependencies that are not in this set will be copied to the output
144+
# path.
145+
_BUNDLED_DLLS = frozenset(['vcruntime140.dll'])
146+
118147
class MSVCCompiler(CCompiler) :
119148
"""Concrete class that implements an interface to Microsoft Visual C++,
120149
as defined by the CCompiler abstract class."""
@@ -189,6 +218,7 @@ def initialize(self, plat_name=None):
189218
self.rc = _find_exe("rc.exe", paths) # resource compiler
190219
self.mc = _find_exe("mc.exe", paths) # message compiler
191220
self.mt = _find_exe("mt.exe", paths) # message compiler
221+
self._vcruntime_redist = vc_env.get('py_vcruntime_redist', '')
192222

193223
for dir in vc_env.get('include', '').split(os.pathsep):
194224
if dir:
@@ -199,20 +229,26 @@ def initialize(self, plat_name=None):
199229
self.add_library_dir(dir)
200230

201231
self.preprocess_options = None
202-
# Use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib
232+
# If vcruntime_redist is available, link against it dynamically. Otherwise,
233+
# use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib
203234
# later to dynamically link to ucrtbase but not vcruntime.
204235
self.compile_options = [
205-
'/nologo', '/Ox', '/MT', '/W3', '/GL', '/DNDEBUG'
236+
'/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG'
206237
]
238+
self.compile_options.append('/MD' if self._vcruntime_redist else '/MT')
239+
207240
self.compile_options_debug = [
208-
'/nologo', '/Od', '/MTd', '/Zi', '/W3', '/D_DEBUG'
241+
'/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG'
209242
]
210243

211244
ldflags = [
212-
'/nologo', '/INCREMENTAL:NO', '/LTCG', '/nodefaultlib:libucrt.lib', 'ucrt.lib',
245+
'/nologo', '/INCREMENTAL:NO', '/LTCG'
213246
]
247+
if not self._vcruntime_redist:
248+
ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib'))
249+
214250
ldflags_debug = [
215-
'/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL', '/nodefaultlib:libucrtd.lib', 'ucrtd.lib',
251+
'/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL'
216252
]
217253

218254
self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1']
@@ -446,15 +482,29 @@ def link(self,
446482
if extra_postargs:
447483
ld_args.extend(extra_postargs)
448484

449-
self.mkpath(os.path.dirname(output_filename))
485+
output_dir = os.path.dirname(os.path.abspath(output_filename))
486+
self.mkpath(output_dir)
450487
try:
451488
log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args))
452489
self.spawn([self.linker] + ld_args)
490+
self._copy_vcruntime(output_dir)
453491
except DistutilsExecError as msg:
454492
raise LinkError(msg)
455493
else:
456494
log.debug("skipping %s (up-to-date)", output_filename)
457495

496+
def _copy_vcruntime(self, output_dir):
497+
vcruntime = self._vcruntime_redist
498+
if not vcruntime or not os.path.isfile(vcruntime):
499+
return
500+
501+
if os.path.basename(vcruntime).lower() in _BUNDLED_DLLS:
502+
return
503+
504+
log.debug('Copying "%s"', vcruntime)
505+
vcruntime = shutil.copy(vcruntime, output_dir)
506+
os.chmod(vcruntime, stat.S_IWRITE)
507+
458508
def spawn(self, cmd):
459509
old_path = os.getenv('path')
460510
try:

Lib/distutils/tests/test_msvccompiler.py

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,73 @@ class msvccompilerTestCase(support.TempdirManager,
1616
unittest.TestCase):
1717

1818
def test_no_compiler(self):
19+
import distutils._msvccompiler as _msvccompiler
1920
# makes sure query_vcvarsall raises
2021
# a DistutilsPlatformError if the compiler
2122
# is not found
22-
from distutils._msvccompiler import _get_vc_env
23-
def _find_vcvarsall():
24-
return None
23+
def _find_vcvarsall(plat_spec):
24+
return None, None
2525

26-
import distutils._msvccompiler as _msvccompiler
2726
old_find_vcvarsall = _msvccompiler._find_vcvarsall
2827
_msvccompiler._find_vcvarsall = _find_vcvarsall
2928
try:
30-
self.assertRaises(DistutilsPlatformError, _get_vc_env,
29+
self.assertRaises(DistutilsPlatformError,
30+
_msvccompiler._get_vc_env,
3131
'wont find this version')
3232
finally:
3333
_msvccompiler._find_vcvarsall = old_find_vcvarsall
3434

35+
def test_compiler_options(self):
36+
import distutils._msvccompiler as _msvccompiler
37+
# suppress path to vcruntime from _find_vcvarsall to
38+
# check that /MT is added to compile options
39+
old_find_vcvarsall = _msvccompiler._find_vcvarsall
40+
def _find_vcvarsall(plat_spec):
41+
return old_find_vcvarsall(plat_spec)[0], None
42+
_msvccompiler._find_vcvarsall = _find_vcvarsall
43+
try:
44+
compiler = _msvccompiler.MSVCCompiler()
45+
compiler.initialize()
46+
47+
self.assertIn('/MT', compiler.compile_options)
48+
self.assertNotIn('/MD', compiler.compile_options)
49+
finally:
50+
_msvccompiler._find_vcvarsall = old_find_vcvarsall
51+
52+
def test_vcruntime_copy(self):
53+
import distutils._msvccompiler as _msvccompiler
54+
# force path to a known file - it doesn't matter
55+
# what we copy as long as its name is not in
56+
# _msvccompiler._BUNDLED_DLLS
57+
old_find_vcvarsall = _msvccompiler._find_vcvarsall
58+
def _find_vcvarsall(plat_spec):
59+
return old_find_vcvarsall(plat_spec)[0], __file__
60+
_msvccompiler._find_vcvarsall = _find_vcvarsall
61+
try:
62+
tempdir = self.mkdtemp()
63+
compiler = _msvccompiler.MSVCCompiler()
64+
compiler.initialize()
65+
compiler._copy_vcruntime(tempdir)
66+
67+
self.assertTrue(os.path.isfile(os.path.join(
68+
tempdir, os.path.basename(__file__))))
69+
finally:
70+
_msvccompiler._find_vcvarsall = old_find_vcvarsall
71+
72+
def test_vcruntime_skip_copy(self):
73+
import distutils._msvccompiler as _msvccompiler
74+
75+
tempdir = self.mkdtemp()
76+
compiler = _msvccompiler.MSVCCompiler()
77+
compiler.initialize()
78+
dll = compiler._vcruntime_redist
79+
self.assertTrue(os.path.isfile(dll))
80+
81+
compiler._copy_vcruntime(tempdir)
82+
83+
self.assertFalse(os.path.isfile(os.path.join(
84+
tempdir, os.path.basename(dll))))
85+
3586
def test_suite():
3687
return unittest.makeSuite(msvccompilerTestCase)
3788

Misc/NEWS

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,29 @@
22
Python News
33
+++++++++++
44

5+
What's New in Python 3.5.0 final?
6+
=================================
7+
8+
Release date: 2015-09-13
9+
10+
11+
What's New in Python 3.5.0 release candidate 4?
12+
===============================================
13+
14+
Release date: 2015-09-09
15+
16+
Library
17+
-------
18+
19+
- Issue #25029: Fixes MemoryError in test_strptime.
20+
21+
Build
22+
-----
23+
24+
- Issue #25027: Reverts partial-static build options and adds
25+
vcruntime140.dll to Windows installation.
26+
27+
528
What's New in Python 3.5.0 release candidate 3?
629
===============================================
730

Modules/timemodule.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,6 @@ time_strftime(PyObject *self, PyObject *args)
648648
* will be ahead of time...
649649
*/
650650
for (i = 1024; ; i += i) {
651-
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
652-
int err;
653-
#endif
654651
outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
655652
if (outbuf == NULL) {
656653
PyErr_NoMemory();
@@ -660,10 +657,14 @@ time_strftime(PyObject *self, PyObject *args)
660657
buflen = format_time(outbuf, i, fmt, &buf);
661658
_Py_END_SUPPRESS_IPH
662659
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
663-
err = errno;
660+
/* VisualStudio .NET 2005 does this properly */
661+
if (buflen == 0 && errno == EINVAL) {
662+
PyErr_SetString(PyExc_ValueError, "Invalid format string");
663+
PyMem_Free(outbuf);
664+
break;
665+
}
664666
#endif
665-
if (buflen > 0 || fmtlen == 0 ||
666-
(fmtlen > 4 && i >= 256 * fmtlen)) {
667+
if (buflen > 0 || i >= 256 * fmtlen) {
667668
/* If the buffer is 256 times as long as the format,
668669
it's probably not failing for lack of room!
669670
More likely, the format yields an empty result,
@@ -679,13 +680,6 @@ time_strftime(PyObject *self, PyObject *args)
679680
break;
680681
}
681682
PyMem_Free(outbuf);
682-
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
683-
/* VisualStudio .NET 2005 does this properly */
684-
if (buflen == 0 && err == EINVAL) {
685-
PyErr_SetString(PyExc_ValueError, "Invalid format string");
686-
break;
687-
}
688-
#endif
689683
}
690684
#ifdef HAVE_WCSFTIME
691685
PyMem_Free(format);

PCbuild/pyproject.props

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<IntrinsicFunctions>true</IntrinsicFunctions>
3737
<StringPooling>true</StringPooling>
3838
<ExceptionHandling></ExceptionHandling>
39-
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
39+
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
4040
<FunctionLevelLinking>true</FunctionLevelLinking>
4141
<WarningLevel>Level3</WarningLevel>
4242
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
@@ -47,7 +47,7 @@
4747
<ClCompile Condition="$(Configuration) == 'Debug'">
4848
<Optimization>Disabled</Optimization>
4949
<WholeProgramOptimization>false</WholeProgramOptimization>
50-
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
50+
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
5151
</ClCompile>
5252
<Link>
5353
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -57,9 +57,7 @@
5757
<RandomizedBaseAddress>true</RandomizedBaseAddress>
5858
<DataExecutionPrevention>true</DataExecutionPrevention>
5959
<SuppressStartupBanner>true</SuppressStartupBanner>
60-
<AdditionalDependencies Condition="$(Configuration) == 'Debug'">ucrtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
61-
<AdditionalDependencies Condition="$(Configuration) != 'Debug'">ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
62-
<IgnoreSpecificDefaultLibraries>LIBC;libucrt.lib;libucrtd.lib;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
60+
<IgnoreSpecificDefaultLibraries>LIBC;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
6361
<TargetMachine>MachineX86</TargetMachine>
6462
<TargetMachine Condition="'$(Platform)' == 'x64'">MachineX64</TargetMachine>
6563
<ProfileGuidedDatabase Condition="$(SupportPGO)">$(OutDir)$(TargetName).pgd</ProfileGuidedDatabase>

PCbuild/tcl.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
6262

6363
<PropertyGroup>
64-
<TclOpts>ucrt</TclOpts>
65-
<TclOpts Condition="$(Configuration) == 'Debug'">symbols,ucrt</TclOpts>
64+
<TclOpts>msvcrt</TclOpts>
65+
<TclOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TclOpts>
6666
<TclDirs>INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TclDirs>
6767
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags>
6868
<NMakeBuildCommandLine>setlocal

PCbuild/tix.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757

5858
<PropertyGroup>
5959
<TixDirs>BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TixDirs>
60-
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 UCRT=1 TCL_DBGX=g TK_DBGX=g</DebugFlags>
61-
<DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1 UCRT=1</DebugFlags>
60+
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g</DebugFlags>
61+
<DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1</DebugFlags>
6262
<NMakeBuildCommandLine>setlocal
6363
@(ExpectedOutputs->'if not exist "%(FullPath)" goto build','
6464
')

0 commit comments

Comments
 (0)