summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/buffer.rst8
-rw-r--r--Doc/library/dis.rst4
-rw-r--r--Doc/library/html.parser.rst2
-rw-r--r--Doc/library/inspect.rst15
-rw-r--r--Doc/library/os.path.rst17
-rw-r--r--Doc/library/tempfile.rst155
-rw-r--r--Doc/library/unittest.rst4
-rw-r--r--Doc/library/xml.etree.elementtree.rst30
-rw-r--r--Include/pymath.h24
-rw-r--r--Lib/asyncio/tasks.py6
-rwxr-xr-xLib/cgi.py5
-rw-r--r--Lib/configparser.py29
-rw-r--r--Lib/functools.py2
-rw-r--r--Lib/http/server.py3
-rw-r--r--Lib/idlelib/NEWS.txt13
-rw-r--r--Lib/idlelib/ScriptBinding.py2
-rw-r--r--Lib/idlelib/StackViewer.py8
-rw-r--r--Lib/test/test_asyncio/test_pep492.py17
-rw-r--r--Lib/test/test_asyncio/test_tasks.py32
-rw-r--r--Lib/test/test_cgi.py18
-rw-r--r--Lib/test/test_configparser.py7
-rw-r--r--Lib/test/test_functools.py18
-rw-r--r--Lib/unittest/case.py18
-rw-r--r--Lib/unittest/test/test_assertions.py15
-rw-r--r--Misc/ACKS6
-rw-r--r--Misc/NEWS69
-rw-r--r--PCbuild/get_externals.bat6
-rw-r--r--PCbuild/readme.txt2
-rw-r--r--PCbuild/tcl.vcxproj3
-rw-r--r--PCbuild/tcltk.props4
-rw-r--r--PCbuild/tix.vcxproj6
-rw-r--r--PCbuild/tk.vcxproj4
-rw-r--r--Tools/msi/build.bat8
-rw-r--r--Tools/msi/bundle/snapshot.wixproj7
-rw-r--r--Tools/msi/tcltk/tcltk.wixproj7
35 files changed, 419 insertions, 155 deletions
diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst
index 6cb474e..46c19d3 100644
--- a/Doc/c-api/buffer.rst
+++ b/Doc/c-api/buffer.rst
@@ -133,15 +133,15 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
called on non-NULL :c:member:`~Py_buffer.format` values.
Important exception: If a consumer requests a buffer without the
- :c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_Buffer.format` will
+ :c:macro:`PyBUF_FORMAT` flag, :c:member:`~Py_buffer.format` will
be set to *NULL*, but :c:member:`~Py_buffer.itemsize` still has
the value for the original format.
- If :c:member:`~Py_Buffer.shape` is present, the equality
+ If :c:member:`~Py_buffer.shape` is present, the equality
``product(shape) * itemsize == len`` still holds and the consumer
can use :c:member:`~Py_buffer.itemsize` to navigate the buffer.
- If :c:member:`~Py_Buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE`
+ If :c:member:`~Py_buffer.shape` is *NULL* as a result of a :c:macro:`PyBUF_SIMPLE`
or a :c:macro:`PyBUF_WRITABLE` request, the consumer must disregard
:c:member:`~Py_buffer.itemsize` and assume ``itemsize == 1``.
@@ -156,7 +156,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`.
.. c:member:: int ndim
The number of dimensions the memory represents as an n-dimensional array.
- If it is 0, :c:member:`~Py_Buffer.buf` points to a single item representing
+ If it is 0, :c:member:`~Py_buffer.buf` points to a single item representing
a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides`
and :c:member:`~Py_buffer.suboffsets` MUST be *NULL*.
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index 7a214ed..1bcb3a4 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -946,8 +946,8 @@ the more significant byte last.
Creates a new function object, sets its *__closure__* slot, and pushes it on
the stack. TOS is the :term:`qualified name` of the function, TOS1 is the
code associated with the function, and TOS2 is the tuple containing cells for
- the closure's free variables. The function also has *argc* default
- parameters, which are found below the cells.
+ the closure's free variables. *argc* is interpreted as in ``MAKE_FUNCTION``;
+ the annotations and defaults are also in the same order below TOS2.
.. opcode:: BUILD_SLICE (argc)
diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst
index b84c60b..824995e 100644
--- a/Doc/library/html.parser.rst
+++ b/Doc/library/html.parser.rst
@@ -185,7 +185,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`):
The content of Internet Explorer conditional comments (condcoms) will also be
sent to this method, so, for ``<!--[if IE 9]>IE9-specific content<![endif]-->``,
- this method will receive ``'[if IE 9]>IE-specific content<![endif]'``.
+ this method will receive ``'[if IE 9]>IE9-specific content<![endif]'``.
.. method:: HTMLParser.handle_decl(decl)
diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst
index 3b62e7f..d2247e8 100644
--- a/Doc/library/inspect.rst
+++ b/Doc/library/inspect.rst
@@ -178,6 +178,10 @@ attributes:
+-----------+-----------------+---------------------------+
| | gi_code | code |
+-----------+-----------------+---------------------------+
+| | gi_yieldfrom | object being iterated by |
+| | | ``yield from``, or |
+| | | ``None`` |
++-----------+-----------------+---------------------------+
| coroutine | __name__ | name |
+-----------+-----------------+---------------------------+
| | __qualname__ | qualified name |
@@ -191,10 +195,6 @@ attributes:
+-----------+-----------------+---------------------------+
| | cr_code | code |
+-----------+-----------------+---------------------------+
-| | gi_yieldfrom | object being iterated by |
-| | | ``yield from``, or |
-| | | ``None`` |
-+-----------+-----------------+---------------------------+
| builtin | __doc__ | documentation string |
+-----------+-----------------+---------------------------+
| | __name__ | original name of this |
@@ -209,9 +209,10 @@ attributes:
.. versionchanged:: 3.5
- Add ``__qualname__`` attribute to generators. The ``__name__`` attribute of
- generators is now set from the function name, instead of the code name, and
- it can now be modified.
+ Add ``__qualname__`` and ``gi_yieldfrom`` attributes to generators.
+
+ The ``__name__`` attribute of generators is now set from the function
+ name, instead of the code name, and it can now be modified.
.. function:: getmembers(object[, predicate])
diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst
index e4fe44e..a3fe73c 100644
--- a/Doc/library/os.path.rst
+++ b/Doc/library/os.path.rst
@@ -82,8 +82,21 @@ the :mod:`glob` module.)
Return the longest path prefix (taken character-by-character) that is a
prefix of all paths in *list*. If *list* is empty, return the empty string
- (``''``). Note that this may return invalid paths because it works a
- character at a time. To obtain a valid path, see :func:`commonpath`.
+ (``''``).
+
+ .. note::
+
+ This function may return invalid paths because it works a
+ character at a time. To obtain a valid path, see
+ :func:`commonpath`.
+
+ ::
+
+ >>> os.path.commonprefix(['/usr/lib', '/usr/local/lib'])
+ '/usr/l'
+
+ >>> os.path.commonpath(['/usr/lib', '/usr/local/lib'])
+ '/usr'
.. function:: dirname(path)
diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst
index 0387fb1..83f9941 100644
--- a/Doc/library/tempfile.rst
+++ b/Doc/library/tempfile.rst
@@ -16,16 +16,18 @@
--------------
-This module generates temporary files and directories. It works on all
-supported platforms. It provides three new functions,
-:func:`NamedTemporaryFile`, :func:`mkstemp`, and :func:`mkdtemp`, which should
-eliminate all remaining need to use the insecure :func:`mktemp` function.
-Temporary file names created by this module no longer contain the process ID;
-instead a string of six random characters is used.
-
-Also, all the user-callable functions now take additional arguments which
-allow direct control over the location and name of temporary files. It is
-no longer necessary to use the global *tempdir* variable.
+This module creates temporary files and directories. It works on all
+supported platforms. :class:`TemporaryFile`, :class:`NamedTemporaryFile`,
+:class:`TemporaryDirectory`, and :class:`SpooledTemporaryFile` are high-level
+interfaces which provide automatic cleanup and can be used as
+context managers. :func:`mkstemp` and
+:func:`mkdtemp` are lower-level functions which require manual cleanup.
+
+All the user-callable functions and constructors take additional arguments which
+allow direct control over the location and name of temporary files and
+directories. Files names used by this module include a string of
+random characters which allows those files to be securely created in
+shared temporary directories.
To maintain backward compatibility, the argument order is somewhat odd; it
is recommended to use keyword arguments for clarity.
@@ -34,28 +36,33 @@ The module defines the following user-callable items:
.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None)
Return a :term:`file-like object` that can be used as a temporary storage area.
- The file is created using :func:`mkstemp`. It will be destroyed as soon
+ The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon
as it is closed (including an implicit close when the object is garbage
- collected). Under Unix, the directory entry for the file is removed
+ collected). Under Unix, the directory entry for the file is either not created at all or is removed
immediately after the file is created. Other platforms do not support
this; your code should not rely on a temporary file created using this
function having or not having a visible name in the file system.
+ The resulting object can be used as a context manager (see
+ :ref:`tempfile-examples`). On completion of the context or
+ destruction of the file object the temporary file will be removed
+ from the filesystem.
+
The *mode* parameter defaults to ``'w+b'`` so that the file created can
be read and written without being closed. Binary mode is used so that it
behaves consistently on all platforms without regard for the data that is
stored. *buffering*, *encoding* and *newline* are interpreted as for
:func:`open`.
- The *dir*, *prefix* and *suffix* parameters are passed to :func:`mkstemp`.
+ The *dir*, *prefix* and *suffix* parameters have the same meaning
+ as with :func:`mkstemp`.
The returned object is a true file object on POSIX platforms. On other
platforms, it is a file-like object whose :attr:`!file` attribute is the
- underlying true file object. This file-like object can be used in a
- :keyword:`with` statement, just like a normal file.
+ underlying true file object.
The :py:data:`os.O_TMPFILE` flag is used if it is available and works
- (Linux-specific, require Linux kernel 3.11 or later).
+ (Linux-specific, requires Linux kernel 3.11 or later).
.. versionchanged:: 3.5
@@ -101,10 +108,9 @@ The module defines the following user-callable items:
.. function:: TemporaryDirectory(suffix='', prefix='tmp', dir=None)
- This function creates a temporary directory using :func:`mkdtemp`
- (the supplied arguments are passed directly to the underlying function).
+ This function securely creates a temporary directory using the same rules as :func:`mkdtemp`.
The resulting object can be used as a context manager (see
- :ref:`context-managers`). On completion of the context or destruction
+ :ref:`tempfile-examples`). On completion of the context or destruction
of the temporary directory object the newly created temporary directory
and all its contents are removed from the filesystem.
@@ -194,49 +200,14 @@ The module defines the following user-callable items:
an appropriate default value to be used.
-.. function:: mktemp(suffix='', prefix='tmp', dir=None)
-
- .. deprecated:: 2.3
- Use :func:`mkstemp` instead.
-
- Return an absolute pathname of a file that did not exist at the time the
- call is made. The *prefix*, *suffix*, and *dir* arguments are the same
- as for :func:`mkstemp`.
-
- .. warning::
-
- Use of this function may introduce a security hole in your program. By
- the time you get around to doing anything with the file name it returns,
- someone else may have beaten you to the punch. :func:`mktemp` usage can
- be replaced easily with :func:`NamedTemporaryFile`, passing it the
- ``delete=False`` parameter::
-
- >>> f = NamedTemporaryFile(delete=False)
- >>> f.name
- '/tmp/tmptjujjt'
- >>> f.write(b"Hello World!\n")
- 13
- >>> f.close()
- >>> os.unlink(f.name)
- >>> os.path.exists(f.name)
- False
-
-The module uses a global variable that tell it how to construct a
-temporary name. They are initialized at the first call to any of the
-functions above. The caller may change them, but this is discouraged; use
-the appropriate function arguments, instead.
-
+.. function:: gettempdir()
-.. data:: tempdir
+ Return the name of the directory used for temporary files. This
+ defines the default value for the *dir* argument to all functions
+ in this module.
- When set to a value other than ``None``, this variable defines the
- default value for the *dir* argument to all the functions defined in this
- module.
-
- If ``tempdir`` is unset or ``None`` at any call to any of the above
- functions, Python searches a standard list of directories and sets
- *tempdir* to the first one which the calling user can create files in.
- The list is:
+ Python searches a standard list of directories to find one which
+ the calling user can create files in. The list is:
#. The directory named by the :envvar:`TMPDIR` environment variable.
@@ -254,12 +225,8 @@ the appropriate function arguments, instead.
#. As a last resort, the current working directory.
-
-.. function:: gettempdir()
-
- Return the directory currently selected to create temporary files in. If
- :data:`tempdir` is not ``None``, this simply returns its contents; otherwise,
- the search described above is performed, and the result returned.
+ The result of this search is cached, see the description of
+ :data:`tempdir` below.
.. function:: gettempdirb()
@@ -278,6 +245,23 @@ the appropriate function arguments, instead.
.. versionadded:: 3.5
+The module uses a global variable to store the name of the directory
+used for temporary files returned by :func:`gettempdir`. It can be
+set directly to override the selection process, but this is discouraged.
+All functions in this module take a *dir* argument which can be used
+to specify the directory and this is the recommend approach.
+
+.. data:: tempdir
+
+ When set to a value other than ``None``, this variable defines the
+ default value for the *dir* argument to all the functions defined in this
+ module.
+
+ If ``tempdir`` is unset or ``None`` at any call to any of the above
+ functions except :func:`gettempprefix` it is initalized following the
+ algorithm described in :func:`gettempdir`.
+
+.. _tempfile-examples:
Examples
--------
@@ -311,3 +295,42 @@ Here are some examples of typical usage of the :mod:`tempfile` module::
>>>
# directory and contents have been removed
+
+Deprecated functions and variables
+----------------------------------
+
+A historical way to create temporary files was to first generate a
+file name with the :func:`mktemp` function and then create a file
+using this name. Unfortunately this is not secure, because a different
+process may create a file with this name in the time between the call
+to :func:`mktemp` and the subsequent attempt to create the file by the
+first process. The solution is to combine the two steps and create the
+file immediately. This approach is used by :func:`mkstemp` and the
+other functions described above.
+
+.. function:: mktemp(suffix='', prefix='tmp', dir=None)
+
+ .. deprecated:: 2.3
+ Use :func:`mkstemp` instead.
+
+ Return an absolute pathname of a file that did not exist at the time the
+ call is made. The *prefix*, *suffix*, and *dir* arguments are the same
+ as for :func:`mkstemp`.
+
+ .. warning::
+
+ Use of this function may introduce a security hole in your program. By
+ the time you get around to doing anything with the file name it returns,
+ someone else may have beaten you to the punch. :func:`mktemp` usage can
+ be replaced easily with :func:`NamedTemporaryFile`, passing it the
+ ``delete=False`` parameter::
+
+ >>> f = NamedTemporaryFile(delete=False)
+ >>> f.name
+ '/tmp/tmptjujjt'
+ >>> f.write(b"Hello World!\n")
+ 13
+ >>> f.close()
+ >>> os.unlink(f.name)
+ >>> os.path.exists(f.name)
+ False
diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst
index 5085703..1153f83 100644
--- a/Doc/library/unittest.rst
+++ b/Doc/library/unittest.rst
@@ -278,8 +278,8 @@ The :option:`-s`, :option:`-p`, and :option:`-t` options can be passed in
as positional arguments in that order. The following two command lines
are equivalent::
- python -m unittest discover -s project_directory -p '*_test.py'
- python -m unittest discover project_directory '*_test.py'
+ python -m unittest discover -s project_directory -p "*_test.py"
+ python -m unittest discover project_directory "*_test.py"
As well as being a path it is possible to pass a package name, for example
``myproject.subpackage.test``, as the start directory. The package name you
diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst
index eef1b58..14e5c99 100644
--- a/Doc/library/xml.etree.elementtree.rst
+++ b/Doc/library/xml.etree.elementtree.rst
@@ -651,21 +651,29 @@ Element Objects
.. attribute:: text
+ tail
- The *text* attribute can be used to hold additional data associated with
- the element. As the name implies this attribute is usually a string but
- may be any application-specific object. If the element is created from
- an XML file the attribute will contain any text found between the element
- tags.
+ These attributes can be used to hold additional data associated with
+ the element. Their values are usually strings but may be any
+ application-specific object. If the element is created from
+ an XML file, the *text* attribute holds either the text between
+ the element's start tag and its first child or end tag, or ``None``, and
+ the *tail* attribute holds either the text between the element's
+ end tag and the next tag, or ``None``. For the XML data
+ .. code-block:: xml
- .. attribute:: tail
+ <a><b>1<c>2<d/>3</c></b>4</a>
- The *tail* attribute can be used to hold additional data associated with
- the element. This attribute is usually a string but may be any
- application-specific object. If the element is created from an XML file
- the attribute will contain any text found after the element's end tag and
- before the next tag.
+ the *a* element has ``None`` for both *text* and *tail* attributes,
+ the *b* element has *text* ``"1"`` and *tail* ``"4"``,
+ the *c* element has *text* ``"2"`` and *tail* ``None``,
+ and the *d* element has *text* ``None`` and *tail* ``"3"``.
+
+ To collect the inner text of an element, see :meth:`itertext`, for
+ example ``"".join(element.itertext())``.
+
+ Applications may store arbitrary objects in these attributes.
.. attribute:: attrib
diff --git a/Include/pymath.h b/Include/pymath.h
index 62a6c42..1ea9ac1 100644
--- a/Include/pymath.h
+++ b/Include/pymath.h
@@ -150,7 +150,29 @@ PyAPI_FUNC(void) _Py_set_387controlword(unsigned short);
* doesn't support NaNs.
*/
#if !defined(Py_NAN) && !defined(Py_NO_NAN)
-#define Py_NAN (Py_HUGE_VAL * 0.)
+#if !defined(__INTEL_COMPILER)
+ #define Py_NAN (Py_HUGE_VAL * 0.)
+#else /* __INTEL_COMPILER */
+ #if defined(ICC_NAN_STRICT)
+ #pragma float_control(push)
+ #pragma float_control(precise, on)
+ #pragma float_control(except, on)
+ #if defined(_MSC_VER)
+ __declspec(noinline)
+ #else /* Linux */
+ __attribute__((noinline))
+ #endif /* _MSC_VER */
+ static double __icc_nan()
+ {
+ return sqrt(-1.0);
+ }
+ #pragma float_control (pop)
+ #define Py_NAN __icc_nan()
+ #else /* ICC_NAN_RELAXED as default for Intel Compiler */
+ static union { unsigned char buf[8]; double __icc_nan; } __nan_store = {0,0,0,0,0,0,0xf8,0x7f};
+ #define Py_NAN (__nan_store.__icc_nan)
+ #endif /* ICC_NAN_STRICT */
+#endif /* __INTEL_COMPILER */
#endif
/* Py_OVERFLOWED(X)
diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py
index 9bfc1cf..a235e74 100644
--- a/Lib/asyncio/tasks.py
+++ b/Lib/asyncio/tasks.py
@@ -128,7 +128,11 @@ class Task(futures.Future):
returned for a suspended coroutine.
"""
frames = []
- f = self._coro.gi_frame
+ try:
+ # 'async def' coroutines
+ f = self._coro.cr_frame
+ except AttributeError:
+ f = self._coro.gi_frame
if f is not None:
while f is not None:
if limit is not None:
diff --git a/Lib/cgi.py b/Lib/cgi.py
index 4be28ba..26d2544 100755
--- a/Lib/cgi.py
+++ b/Lib/cgi.py
@@ -720,6 +720,11 @@ class FieldStorage:
self.bytes_read += len(hdr_text)
parser.feed(hdr_text.decode(self.encoding, self.errors))
headers = parser.close()
+
+ # Some clients add Content-Length for part headers, ignore them
+ if 'content-length' in headers:
+ del headers['content-length']
+
part = klass(self.fp, headers, ib, environ, keep_blank_values,
strict_parsing,self.limit-self.bytes_read,
self.encoding, self.errors)
diff --git a/Lib/configparser.py b/Lib/configparser.py
index ecd0660..3a9fb56 100644
--- a/Lib/configparser.py
+++ b/Lib/configparser.py
@@ -263,12 +263,9 @@ class InterpolationMissingOptionError(InterpolationError):
"""A string substitution required a setting which was not available."""
def __init__(self, option, section, rawval, reference):
- msg = ("Bad value substitution:\n"
- "\tsection: [%s]\n"
- "\toption : %s\n"
- "\tkey : %s\n"
- "\trawval : %s\n"
- % (section, option, reference, rawval))
+ msg = ("Bad value substitution: option {!r} in section {!r} contains "
+ "an interpolation key {!r} which is not a valid option name. "
+ "Raw value: {!r}".format(option, section, reference, rawval))
InterpolationError.__init__(self, option, section, msg)
self.reference = reference
self.args = (option, section, rawval, reference)
@@ -286,11 +283,11 @@ class InterpolationDepthError(InterpolationError):
"""Raised when substitutions are nested too deeply."""
def __init__(self, option, section, rawval):
- msg = ("Value interpolation too deeply recursive:\n"
- "\tsection: [%s]\n"
- "\toption : %s\n"
- "\trawval : %s\n"
- % (section, option, rawval))
+ msg = ("Recursion limit exceeded in value substitution: option {!r} "
+ "in section {!r} contains an interpolation key which "
+ "cannot be substituted in {} steps. Raw value: {!r}"
+ "".format(option, section, MAX_INTERPOLATION_DEPTH,
+ rawval))
InterpolationError.__init__(self, option, section, msg)
self.args = (option, section, rawval)
@@ -406,8 +403,9 @@ class BasicInterpolation(Interpolation):
def _interpolate_some(self, parser, option, accum, rest, section, map,
depth):
+ rawval = parser.get(section, option, raw=True, fallback=rest)
if depth > MAX_INTERPOLATION_DEPTH:
- raise InterpolationDepthError(option, section, rest)
+ raise InterpolationDepthError(option, section, rawval)
while rest:
p = rest.find("%")
if p < 0:
@@ -432,7 +430,7 @@ class BasicInterpolation(Interpolation):
v = map[var]
except KeyError:
raise InterpolationMissingOptionError(
- option, section, rest, var) from None
+ option, section, rawval, var) from None
if "%" in v:
self._interpolate_some(parser, option, accum, v,
section, map, depth + 1)
@@ -466,8 +464,9 @@ class ExtendedInterpolation(Interpolation):
def _interpolate_some(self, parser, option, accum, rest, section, map,
depth):
+ rawval = parser.get(section, option, raw=True, fallback=rest)
if depth > MAX_INTERPOLATION_DEPTH:
- raise InterpolationDepthError(option, section, rest)
+ raise InterpolationDepthError(option, section, rawval)
while rest:
p = rest.find("$")
if p < 0:
@@ -504,7 +503,7 @@ class ExtendedInterpolation(Interpolation):
"More than one ':' found: %r" % (rest,))
except (KeyError, NoSectionError, NoOptionError):
raise InterpolationMissingOptionError(
- option, section, rest, ":".join(path)) from None
+ option, section, rawval, ":".join(path)) from None
if "$" in v:
self._interpolate_some(parser, opt, accum, v, sect,
dict(parser.items(sect, raw=True)),
diff --git a/Lib/functools.py b/Lib/functools.py
index 09df068..06a4ff1 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -567,7 +567,7 @@ def _c3_merge(sequences):
break # reject the current head, it appears later
else:
break
- if not candidate:
+ if candidate is None:
raise RuntimeError("Inconsistent hierarchy")
result.append(candidate)
# remove the chosen candidate
diff --git a/Lib/http/server.py b/Lib/http/server.py
index fd13be3..6a0e6fe 100644
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -1167,8 +1167,7 @@ def test(HandlerClass=BaseHTTPRequestHandler,
ServerClass=HTTPServer, protocol="HTTP/1.0", port=8000, bind=""):
"""Test the HTTP request handler class.
- This runs an HTTP server on port 8000 (or the first command line
- argument).
+ This runs an HTTP server on port 8000 (or the port argument).
"""
server_address = (bind, port)
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 2d8ce54..be063c4 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -2,6 +2,19 @@ What's New in IDLE 3.5.0?
=========================
*Release date: 2015-09-13* ??
+- Issue #23672: Allow Idle to edit and run files with astral chars in name.
+ Patch by Mohd Sanad Zaki Rizvi.
+
+- Issue 24745: Idle editor default font. Switch from Courier to
+ platform-sensitive TkFixedFont. This should not affect current customized
+ font selections. If there is a problem, edit $HOME/.idlerc/config-main.cfg
+ and remove 'fontxxx' entries from [Editor Window]. Patch by Mark Roseman.
+
+- Issue #21192: Idle editor. When a file is run, put its name in the restart bar.
+ Do not print false prompts. Original patch by Adnan Umer.
+
+- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy.
+
- Issue #23184: remove unused names and imports in idlelib.
Initial patch by Al Sweigart.
diff --git a/Lib/idlelib/ScriptBinding.py b/Lib/idlelib/ScriptBinding.py
index e8cb2fc..e5636df 100644
--- a/Lib/idlelib/ScriptBinding.py
+++ b/Lib/idlelib/ScriptBinding.py
@@ -69,7 +69,7 @@ class ScriptBinding:
try:
tabnanny.process_tokens(tokenize.generate_tokens(f.readline))
except tokenize.TokenError as msg:
- msgtxt, (lineno, start) = msg
+ msgtxt, (lineno, start) = msg.args
self.editwin.gotoline(lineno)
self.errorbox("Tabnanny Tokenizing Error",
"Token Error: %s" % msgtxt)
diff --git a/Lib/idlelib/StackViewer.py b/Lib/idlelib/StackViewer.py
index b1e5e26..36507ee 100644
--- a/Lib/idlelib/StackViewer.py
+++ b/Lib/idlelib/StackViewer.py
@@ -10,8 +10,7 @@ from idlelib.PyShell import PyShellFileList
def StackBrowser(root, flist=None, tb=None, top=None):
if top is None:
- from tkinter import Toplevel
- top = Toplevel(root)
+ top = tk.Toplevel(root)
sc = ScrolledCanvas(top, bg="white", highlightthickness=0)
sc.frame.pack(expand=1, fill="both")
item = StackTreeItem(flist, tb)
@@ -108,12 +107,9 @@ class VariablesTreeItem(ObjectTreeItem):
def IsExpandable(self):
return len(self.object) > 0
- def keys(self):
- return list(self.object.keys())
-
def GetSubList(self):
sublist = []
- for key in self.keys():
+ for key in self.object.keys():
try:
value = self.object[key]
except KeyError:
diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py
index b702efc..41e1b8a 100644
--- a/Lib/test/test_asyncio/test_pep492.py
+++ b/Lib/test/test_asyncio/test_pep492.py
@@ -186,6 +186,23 @@ class CoroutineTests(BaseTest):
data = self.loop.run_until_complete(coro())
self.assertEqual(data, 'spam')
+ def test_task_print_stack(self):
+ T = None
+
+ async def foo():
+ f = T.get_stack(limit=1)
+ try:
+ self.assertEqual(f[0].f_code.co_name, 'foo')
+ finally:
+ f = None
+
+ async def runner():
+ nonlocal T
+ T = asyncio.ensure_future(foo(), loop=self.loop)
+ await T
+
+ self.loop.run_until_complete(runner())
+
if __name__ == '__main__':
unittest.main()
diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py
index 251192a..0426787 100644
--- a/Lib/test/test_asyncio/test_tasks.py
+++ b/Lib/test/test_asyncio/test_tasks.py
@@ -2,6 +2,7 @@
import contextlib
import functools
+import io
import os
import re
import sys
@@ -162,6 +163,37 @@ class TaskTests(test_utils.TestCase):
'function is deprecated, use ensure_'):
self.assertIs(f, asyncio.async(f))
+ def test_get_stack(self):
+ T = None
+
+ @asyncio.coroutine
+ def foo():
+ yield from bar()
+
+ @asyncio.coroutine
+ def bar():
+ # test get_stack()
+ f = T.get_stack(limit=1)
+ try:
+ self.assertEqual(f[0].f_code.co_name, 'foo')
+ finally:
+ f = None
+
+ # test print_stack()
+ file = io.StringIO()
+ T.print_stack(limit=1, file=file)
+ file.seek(0)
+ tb = file.read()
+ self.assertRegex(tb, r'foo\(\) running')
+
+ @asyncio.coroutine
+ def runner():
+ nonlocal T
+ T = asyncio.ensure_future(foo(), loop=self.loop)
+ yield from T
+
+ self.loop.run_until_complete(runner())
+
def test_task_repr(self):
self.loop.set_debug(False)
diff --git a/Lib/test/test_cgi.py b/Lib/test/test_cgi.py
index a7a9d02..ab9f6ab 100644
--- a/Lib/test/test_cgi.py
+++ b/Lib/test/test_cgi.py
@@ -326,6 +326,24 @@ Content-Type: text/plain
got = getattr(files[x], k)
self.assertEqual(got, exp)
+ def test_fieldstorage_part_content_length(self):
+ BOUNDARY = "JfISa01"
+ POSTDATA = """--JfISa01
+Content-Disposition: form-data; name="submit-name"
+Content-Length: 5
+
+Larry
+--JfISa01"""
+ env = {
+ 'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'multipart/form-data; boundary={}'.format(BOUNDARY),
+ 'CONTENT_LENGTH': str(len(POSTDATA))}
+ fp = BytesIO(POSTDATA.encode('latin-1'))
+ fs = cgi.FieldStorage(fp, environ=env, encoding="latin-1")
+ self.assertEqual(len(fs.list), 1)
+ self.assertEqual(fs.list[0].name, 'submit-name')
+ self.assertEqual(fs.list[0].value, 'Larry')
+
def test_fieldstorage_as_context_manager(self):
fp = BytesIO(b'x' * 10)
env = {'REQUEST_METHOD': 'PUT'}
diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py
index 470d2cd..71a8f3f 100644
--- a/Lib/test/test_configparser.py
+++ b/Lib/test/test_configparser.py
@@ -847,7 +847,8 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase):
"something with lots of interpolation (10 steps)")
e = self.get_error(cf, configparser.InterpolationDepthError, "Foo", "bar11")
if self.interpolation == configparser._UNSET:
- self.assertEqual(e.args, ("bar11", "Foo", "%(with1)s"))
+ self.assertEqual(e.args, ("bar11", "Foo",
+ "something %(with11)s lots of interpolation (11 steps)"))
elif isinstance(self.interpolation, configparser.LegacyInterpolation):
self.assertEqual(e.args, ("bar11", "Foo",
"something %(with11)s lots of interpolation (11 steps)"))
@@ -861,7 +862,7 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase):
self.assertEqual(e.option, "name")
if self.interpolation == configparser._UNSET:
self.assertEqual(e.args, ('name', 'Interpolation Error',
- '', 'reference'))
+ '%(reference)s', 'reference'))
elif isinstance(self.interpolation, configparser.LegacyInterpolation):
self.assertEqual(e.args, ('name', 'Interpolation Error',
'%(reference)s', 'reference'))
@@ -1177,7 +1178,7 @@ class ConfigParserTestCaseExtendedInterpolation(BasicTestCase, unittest.TestCase
with self.assertRaises(exception_class) as cm:
cf['interpolated']['$trying']
self.assertEqual(cm.exception.reference, 'dollars:${sick')
- self.assertEqual(cm.exception.args[2], '}') #rawval
+ self.assertEqual(cm.exception.args[2], '${dollars:${sick}}') #rawval
def test_case_sensitivity_basic(self):
ini = textwrap.dedent("""
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index ac211c4..ae929ec 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -1491,6 +1491,24 @@ class TestSingleDispatch(unittest.TestCase):
many_abcs = [c.Mapping, c.Sized, c.Callable, c.Container, c.Iterable]
self.assertEqual(mro(X, abcs=many_abcs), expected)
+ def test_false_meta(self):
+ # see issue23572
+ class MetaA(type):
+ def __len__(self):
+ return 0
+ class A(metaclass=MetaA):
+ pass
+ class AA(A):
+ pass
+ @functools.singledispatch
+ def fun(a):
+ return 'base A'
+ @fun.register(A)
+ def _(a):
+ return 'fun A'
+ aa = AA()
+ self.assertEqual(fun(aa), 'fun A')
+
def test_mro_conflicts(self):
c = collections
@functools.singledispatch
diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py
index 7701ad3..a4a0a1f 100644
--- a/Lib/unittest/case.py
+++ b/Lib/unittest/case.py
@@ -1279,8 +1279,10 @@ class TestCase(object):
assert expected_regex, "expected_regex must not be empty."
expected_regex = re.compile(expected_regex)
if not expected_regex.search(text):
- msg = msg or "Regex didn't match"
- msg = '%s: %r not found in %r' % (msg, expected_regex.pattern, text)
+ standardMsg = "Regex didn't match: %r not found in %r" % (
+ expected_regex.pattern, text)
+ # _formatMessage ensures the longMessage option is respected
+ msg = self._formatMessage(msg, standardMsg)
raise self.failureException(msg)
def assertNotRegex(self, text, unexpected_regex, msg=None):
@@ -1289,11 +1291,12 @@ class TestCase(object):
unexpected_regex = re.compile(unexpected_regex)
match = unexpected_regex.search(text)
if match:
- msg = msg or "Regex matched"
- msg = '%s: %r matches %r in %r' % (msg,
- text[match.start():match.end()],
- unexpected_regex.pattern,
- text)
+ standardMsg = 'Regex matched: %r matches %r in %r' % (
+ text[match.start() : match.end()],
+ unexpected_regex.pattern,
+ text)
+ # _formatMessage ensures the longMessage option is respected
+ msg = self._formatMessage(msg, standardMsg)
raise self.failureException(msg)
@@ -1315,6 +1318,7 @@ class TestCase(object):
failIf = _deprecate(assertFalse)
assertRaisesRegexp = _deprecate(assertRaisesRegex)
assertRegexpMatches = _deprecate(assertRegex)
+ assertNotRegexpMatches = _deprecate(assertNotRegex)
diff --git a/Lib/unittest/test/test_assertions.py b/Lib/unittest/test/test_assertions.py
index c349a95..e6e2bc2 100644
--- a/Lib/unittest/test/test_assertions.py
+++ b/Lib/unittest/test/test_assertions.py
@@ -133,7 +133,6 @@ class Test_Assertions(unittest.TestCase):
try:
self.assertNotRegex('Ala ma kota', r'k.t', 'Message')
except self.failureException as e:
- self.assertIn("'kot'", e.args[0])
self.assertIn('Message', e.args[0])
else:
self.fail('assertNotRegex should have failed.')
@@ -329,6 +328,20 @@ class TestLongMessage(unittest.TestCase):
"^unexpectedly identical: None$",
"^unexpectedly identical: None : oops$"])
+ def testAssertRegex(self):
+ self.assertMessages('assertRegex', ('foo', 'bar'),
+ ["^Regex didn't match:",
+ "^oops$",
+ "^Regex didn't match:",
+ "^Regex didn't match: (.*) : oops$"])
+
+ def testAssertNotRegex(self):
+ self.assertMessages('assertNotRegex', ('foo', 'foo'),
+ ["^Regex matched:",
+ "^oops$",
+ "^Regex matched:",
+ "^Regex matched: (.*) : oops$"])
+
def assertMessagesCM(self, methodName, args, func, errors):
"""
diff --git a/Misc/ACKS b/Misc/ACKS
index e2e8387..b60ee73 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -594,6 +594,7 @@ Gregor Hoffleit
Chris Hoffman
Stefan Hoffmeister
Albert Hofkamp
+Chris Hogan
Tomas Hoger
Jonathan Hogg
Kamilla Holanda
@@ -621,6 +622,7 @@ Ken Howard
Brad Howes
Mike Hoy
Ben Hoyt
+Chiu-Hsiang Hsu
Chih-Hao Huang
Christian Hudon
Lawrence Hudson
@@ -784,6 +786,7 @@ Andrew Kuchling
Dave Kuhlman
Jon Kuhn
Toshio Kuratomi
+Ilia Kurenkov
Vladimir Kushnir
Erno Kuusela
Ross Lagerwall
@@ -793,6 +796,7 @@ Thomas Lamb
Valerie Lambert
Jean-Baptiste "Jiba" Lamy
Ronan Lamy
+Peter Landry
Torsten Landschoff
Łukasz Langa
Tino Lange
@@ -916,6 +920,7 @@ Daniel May
Madison May
Lucas Maystre
Arnaud Mazin
+Pam McA'Nulty
Matt McClure
Jack McCracken
Rebecca McCreary
@@ -1181,6 +1186,7 @@ Vlad Riscutia
Wes Rishel
Daniel Riti
Juan M. Bello Rivas
+Mohd Sanad Zaki Rizvi
Davide Rizzo
Anthony Roach
Carl Robben
diff --git a/Misc/NEWS b/Misc/NEWS
index 27a0564..7dd4aa4 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -2,6 +2,37 @@
Python News
+++++++++++
+
+What's New in Python 3.5.1
+==========================
+
+
+Release date: TBA
+
+
+Core and Builtins
+-----------------
+
+
+Library
+-------
+
+- Issue #20362: Honour TestCase.longMessage correctly in assertRegex.
+ Patch from Ilia Kurenkov.
+
+- Issue #24847: Removes vcruntime140.dll dependency from Tcl/Tk.
+
+- Issue #23572: Fixed functools.singledispatch on classes with falsy
+ metaclasses. Patch by Ethan Furman.
+
+
+Documentation
+-------------
+
+- Issue #22812: Fix unittest discovery examples.
+ Patch from Pam McA'Nulty.
+
+
What's New in Python 3.5.0 release candidate 2?
===============================================
@@ -10,11 +41,33 @@ Release date: 2015-08-23
Core and Builtins
-----------------
+- Issue #21167: NAN operations are now handled correctly when python is
+ compiled with ICC even if -fp-model strict is not specified.
+
Library
-------
+- Issue #24764: cgi.FieldStorage.read_multi() now ignores the Content-Length
+ header in part headers. Patch written by Peter Landry and reviewed by Pierre
+ Quentel.
+
+- Issue #24774: Fix docstring in http.server.test. Patch from Chiu-Hsiang Hsu.
+
+- Issue #21159: Improve message in configparser.InterpolationMissingOptionError.
+ Patch from Łukasz Langa.
+
+- Issue #24847: Fixes tcltk installer layout of VC runtime DLL
+
- Issue #24839: platform._syscmd_ver raises DeprecationWarning
+- Issue #24867: Fix Task.get_stack() for 'async def' coroutines
+
+Documentation
+-------------
+
+- Issue #23725: Overhaul tempfile docs. Note deprecated status of mktemp.
+ Patch from Zbigniew Jędrzejewski-Szmek.
+
What's New in Python 3.5.0 release candidate 1?
===============================================
@@ -74,6 +127,22 @@ Library
- Issue #24791: Fix grammar regression for call syntax: 'g(*a or b)'.
+IDLE
+----
+
+- Issue #23672: Allow Idle to edit and run files with astral chars in name.
+ Patch by Mohd Sanad Zaki Rizvi.
+
+- Issue 24745: Idle editor default font. Switch from Courier to
+ platform-sensitive TkFixedFont. This should not affect current customized
+ font selections. If there is a problem, edit $HOME/.idlerc/config-main.cfg
+ and remove 'fontxxx' entries from [Editor Window]. Patch by Mark Roseman.
+
+- Issue #21192: Idle editor. When a file is run, put its name in the restart bar.
+ Do not print false prompts. Original patch by Adnan Umer.
+
+- Issue #13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy.
+
Documentation
-------------
diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat
index 3037326..f9b740f 100644
--- a/PCbuild/get_externals.bat
+++ b/PCbuild/get_externals.bat
@@ -55,9 +55,9 @@ for %%e in (
bzip2-1.0.6
nasm-2.11.06
openssl-1.0.2d
- tcl-core-8.6.4.1
- tk-8.6.4.1
- tix-8.4.3.4
+ tcl-core-8.6.4.2
+ tk-8.6.4.2
+ tix-8.4.3.6
sqlite-3.8.11.0
xz-5.0.5
) do (
diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt
index 9d5f342..68cdb0f 100644
--- a/PCbuild/readme.txt
+++ b/PCbuild/readme.txt
@@ -236,7 +236,7 @@ _sqlite3
Homepage:
http://www.sqlite.org/
_tkinter
- Wraps version 8.6.1 of the Tk windowing system.
+ Wraps version 8.6.4 of the Tk windowing system.
Homepage:
http://www.tcl.tk/
diff --git a/PCbuild/tcl.vcxproj b/PCbuild/tcl.vcxproj
index 8f2544a..e9287c7 100644
--- a/PCbuild/tcl.vcxproj
+++ b/PCbuild/tcl.vcxproj
@@ -61,7 +61,8 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <TclOpts Condition="$(Configuration) == 'Debug'">symbols</TclOpts>
+ <TclOpts>ucrt</TclOpts>
+ <TclOpts Condition="$(Configuration) == 'Debug'">symbols,ucrt</TclOpts>
<TclDirs>INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TclDirs>
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags>
<NMakeBuildCommandLine>setlocal
diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props
index 96bd577..5e794e5 100644
--- a/PCbuild/tcltk.props
+++ b/PCbuild/tcltk.props
@@ -5,7 +5,7 @@
<TclMajorVersion>8</TclMajorVersion>
<TclMinorVersion>6</TclMinorVersion>
<TclPatchLevel>4</TclPatchLevel>
- <TclRevision>1</TclRevision>
+ <TclRevision>2</TclRevision>
<TkMajorVersion>$(TclMajorVersion)</TkMajorVersion>
<TkMinorVersion>$(TclMinorVersion)</TkMinorVersion>
<TkPatchLevel>$(TclPatchLevel)</TkPatchLevel>
@@ -13,7 +13,7 @@
<TixMajorVersion>8</TixMajorVersion>
<TixMinorVersion>4</TixMinorVersion>
<TixPatchLevel>3</TixPatchLevel>
- <TixRevision>4</TixRevision>
+ <TixRevision>6</TixRevision>
<tclDir>$(ExternalsDir)tcl-core-$(TclMajorVersion).$(TclMinorVersion).$(TclPatchLevel).$(TclRevision)\</tclDir>
<tkDir>$(ExternalsDir)tk-$(TkMajorVersion).$(TkMinorVersion).$(TkPatchLevel).$(TkRevision)\</tkDir>
<tixDir>$(ExternalsDir)tix-$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel).$(TixRevision)\</tixDir>
diff --git a/PCbuild/tix.vcxproj b/PCbuild/tix.vcxproj
index 74a6b84..a1dad1e 100644
--- a/PCbuild/tix.vcxproj
+++ b/PCbuild/tix.vcxproj
@@ -56,11 +56,9 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <TkOpts>msvcrt</TkOpts>
- <TkOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TkOpts>
<TixDirs>BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TixDirs>
- <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 TCL_DBGX=g DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags>
- <DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1</DebugFlags>
+ <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 UCRT=1 TCL_DBGX=g TK_DBGX=g</DebugFlags>
+ <DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1 UCRT=1</DebugFlags>
<NMakeBuildCommandLine>setlocal
@(ExpectedOutputs->'if not exist "%(FullPath)" goto build','
')
diff --git a/PCbuild/tk.vcxproj b/PCbuild/tk.vcxproj
index 20749f7..589338c 100644
--- a/PCbuild/tk.vcxproj
+++ b/PCbuild/tk.vcxproj
@@ -60,8 +60,8 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<PropertyGroup>
- <TkOpts>msvcrt</TkOpts>
- <TkOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TkOpts>
+ <TkOpts>ucrt</TkOpts>
+ <TkOpts Condition="$(Configuration) == 'Debug'">symbols,ucrt</TkOpts>
<TkDirs>TCLDIR="$(tclDir.TrimEnd(`\`))" INSTALLDIR="$(OutDir.TrimEnd(`\`))"</TkDirs>
<DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags>
<NMakeBuildCommandLine>setlocal
diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat
index 5ae512f..716934a 100644
--- a/Tools/msi/build.bat
+++ b/Tools/msi/build.bat
@@ -7,6 +7,7 @@ set BUILDX86=
set BUILDX64=
set BUILDDOC=
set BUILDPX=
+set BUILDPACK=
:CheckOpts
if "%~1" EQU "-h" goto Help
@@ -14,6 +15,7 @@ if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts
if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts
if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts
if "%~1" EQU "--test-marker" (set BUILDPX=1) && shift && goto CheckOpts
+if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts
if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1)
@@ -41,6 +43,9 @@ set BUILD_CMD="%D%bundle\snapshot.wixproj"
if defined BUILDPX (
set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true
)
+if defined BUILDPACK (
+ set BUILD_CMD=%BUILD_CMD% /p:Pack=true
+)
if defined BUILDX86 (
"%PCBUILD%win32\python.exe" "%D%get_wix.py"
@@ -56,9 +61,10 @@ if defined BUILDX64 (
exit /B 0
:Help
-echo build.bat [-x86] [-x64] [--doc] [-h] [--test-marker]
+echo build.bat [-x86] [-x64] [--doc] [-h] [--test-marker] [--pack]
echo.
echo -x86 Build x86 installers
echo -x64 Build x64 installers
echo --doc Build CHM documentation
echo --test-marker Build installers with 'x' markers
+echo --pack Embed core MSIs into installer
diff --git a/Tools/msi/bundle/snapshot.wixproj b/Tools/msi/bundle/snapshot.wixproj
index 8fe95a8..cc45043 100644
--- a/Tools/msi/bundle/snapshot.wixproj
+++ b/Tools/msi/bundle/snapshot.wixproj
@@ -9,9 +9,14 @@
<Import Project="..\msi.props" />
<PropertyGroup>
+ <DefineConstants Condition="'$(Pack)' != 'true'">
+ $(DefineConstants);CompressMSI=no;
+ </DefineConstants>
+ <DefineConstants Condition="'$(Pack)' == 'true'">
+ $(DefineConstants);CompressMSI=yes;
+ </DefineConstants>
<DefineConstants>
$(DefineConstants);
- CompressMSI=no;
CompressPDB=no;
CompressMSI_D=no;
</DefineConstants>
diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj
index e1addd9..f66fc14 100644
--- a/Tools/msi/tcltk/tcltk.wixproj
+++ b/Tools/msi/tcltk/tcltk.wixproj
@@ -27,13 +27,6 @@
<Target_>DLLs\</Target_>
<Group>tcltk_dlls</Group>
</InstallFiles>
- <InstallFiles Include="$(VCInstallDir)redist\$(Platform)\Microsoft.VC$(PlatformToolset.Substring(1)).CRT\vcruntime$(PlatformToolset.Substring(1)).dll">
- <SourceBase>$(VCInstallDir)redist\$(Platform)\</SourceBase>
- <Source>$(VCInstallDir)redist\$(Platform)\</Source>
- <TargetBase>$(VCInstallDir)redist\$(Platform)\</TargetBase>
- <Target_>DLLs\</Target_>
- <Group>tcltk_dlls</Group>
- </InstallFiles>
<InstallFiles Include="$(tcltkDir)lib\**\*">
<SourceBase>$(tcltkDir)</SourceBase>