diff options
-rw-r--r-- | Doc/library/importlib.rst | 10 | ||||
-rw-r--r-- | Doc/whatsnew/3.5.rst | 66 | ||||
-rw-r--r-- | Lib/asyncio/base_events.py | 5 | ||||
-rw-r--r-- | Lib/asyncio/base_subprocess.py | 4 | ||||
-rw-r--r-- | Lib/asyncio/proactor_events.py | 4 | ||||
-rw-r--r-- | Lib/asyncio/selector_events.py | 4 | ||||
-rw-r--r-- | Lib/asyncio/sslproto.py | 4 | ||||
-rw-r--r-- | Lib/asyncio/unix_events.py | 5 | ||||
-rw-r--r-- | Lib/http/cookiejar.py | 2 | ||||
-rwxr-xr-x | Lib/idlelib/PyShell.py | 10 | ||||
-rwxr-xr-x | Lib/test/regrtest.py | 9 | ||||
-rw-r--r-- | Lib/test/test_asyncio/test_subprocess.py | 6 | ||||
-rw-r--r-- | Lib/test/test_http_cookiejar.py | 9 | ||||
-rw-r--r-- | Lib/test/test_typing.py | 24 | ||||
-rw-r--r-- | Lib/typing.py | 59 | ||||
-rw-r--r-- | Lib/urllib/request.py | 1 | ||||
-rw-r--r-- | Misc/ACKS | 3 | ||||
-rw-r--r-- | Misc/NEWS | 13 | ||||
-rw-r--r-- | Tools/msi/make_zip.py | 12 | ||||
-rw-r--r-- | Tools/msi/tcltk/tcltk.wixproj | 7 |
20 files changed, 211 insertions, 46 deletions
diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 771c4c5..632df75 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -179,11 +179,11 @@ Functions except NameError: cache = {} - It is legal though generally not very useful to reload built-in or - dynamically loaded modules (this is not true for e.g. :mod:`sys`, - :mod:`__main__`, :mod:`builtins` and other key modules where reloading is - frowned upon). In many cases, however, extension modules are not designed to - be initialized more than once, and may fail in arbitrary ways when reloaded. + It is generally not very useful to reload built-in or dynamically loaded + modules. Reloading :mod:`sys`, :mod:`__main__`, :mod:`builtins` and other + key modules is not recommended. In many cases extension modules are not + designed to be initialized more than once, and may fail in arbitrary ways + when reloaded. If a module imports objects from another module using :keyword:`from` ... :keyword:`import` ..., calling :func:`reload` for the other module does not diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index e7992d9..86c5b60 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -71,6 +71,7 @@ New syntax features: * :pep:`465`, a new matrix multiplication operator: ``a @ b``. * :pep:`492`, coroutines with async and await syntax. +* :pep:`448`, additional unpacking generalizations. New library modules: @@ -203,6 +204,71 @@ called ``@``. (Mnemonic: ``@`` is ``*`` for mATrices.) :pep:`465` -- A dedicated infix operator for matrix multiplication +PEP 448 - Additional Unpacking Generalizations +---------------------------------------------- + +This PEP proposes extended usages of the ``*`` iterable unpacking +operator and ``**`` dictionary unpacking operators +to allow unpacking in more positions, an arbitrary number of +times, and in additional circumstances. Specifically, +in function calls, in comprehensions and generator expressions, and +in displays. + +Function calls are proposed to support an arbitrary number of +unpackings rather than just one:: + + >>> print(*[1], *[2], 3) + 1 2 3 + >>> dict(**{'x': 1}, y=2, **{'z': 3}) + {'x': 1, 'y': 2, 'z': 3} + +Unpacking is proposed to be allowed inside tuple, list, set, +and dictionary displays:: + + >>> *range(4), 4 + (0, 1, 2, 3, 4) + >>> [*range(4), 4] + [0, 1, 2, 3, 4] + >>> {*range(4), 4} + {0, 1, 2, 3, 4} + >>> {'x': 1, **{'y': 2}} + {'x': 1, 'y': 2} + +In dictionaries, later values will always override earlier ones:: + + >>> {'x': 1, **{'x': 2}} + {'x': 2} + + >>> {**{'x': 2}, 'x': 1} + {'x': 1} + +.. seealso:: + + :pep:`448` -- Additional Unpacking Generalizations + + +PEP 484 - Type Hints +-------------------- + +This PEP introduces a provisional module to provide these standard +definitions and tools, along with some conventions for situations +where annotations are not available. + +For example, here is a simple function whose argument and return type +are declared in the annotations:: + + def greeting(name: str) -> str: + return 'Hello ' + name + +The type system supports unions, generic types, and a special type +named ``Any`` which is consistent with (i.e. assignable to and from) all +types. + +.. seealso:: + + :pep:`484` -- Type Hints + + PEP 471 - os.scandir() function -- a better and faster directory iterator ------------------------------------------------------------------------- diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 5a536a2..c205445 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -28,6 +28,7 @@ import traceback import sys import warnings +from . import compat from . import coroutines from . import events from . import futures @@ -378,7 +379,7 @@ class BaseEventLoop(events.AbstractEventLoop): # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if not self.is_closed(): warnings.warn("unclosed event loop %r" % self, ResourceWarning) @@ -1205,7 +1206,7 @@ class BaseEventLoop(events.AbstractEventLoop): return enabled = bool(enabled) - if self._coroutine_wrapper_set is enabled: + if self._coroutine_wrapper_set == enabled: return wrapper = coroutines.debug_wrapper diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py index a6971b1..6851cd2 100644 --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -1,8 +1,8 @@ import collections import subprocess -import sys import warnings +from . import compat from . import futures from . import protocols from . import transports @@ -116,7 +116,7 @@ class BaseSubprocessTransport(transports.SubprocessTransport): # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if not self._closed: warnings.warn("unclosed transport %r" % self, ResourceWarning) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index 9c2b8f1..abe4c12 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -7,10 +7,10 @@ proactor is only implemented on Windows with IOCP. __all__ = ['BaseProactorEventLoop'] import socket -import sys import warnings from . import base_events +from . import compat from . import constants from . import futures from . import sslproto @@ -79,7 +79,7 @@ class _ProactorBasePipeTransport(transports._FlowControlMixin, # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if self._sock is not None: warnings.warn("unclosed transport %r" % self, ResourceWarning) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 7c5b9b5..4a99658 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -10,7 +10,6 @@ import collections import errno import functools import socket -import sys import warnings try: import ssl @@ -18,6 +17,7 @@ except ImportError: # pragma: no cover ssl = None from . import base_events +from . import compat from . import constants from . import events from . import futures @@ -568,7 +568,7 @@ class _SelectorTransport(transports._FlowControlMixin, # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if self._sock is not None: warnings.warn("unclosed transport %r" % self, ResourceWarning) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 235855e..e566946 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -1,11 +1,11 @@ import collections -import sys import warnings try: import ssl except ImportError: # pragma: no cover ssl = None +from . import compat from . import protocols from . import transports from .log import logger @@ -317,7 +317,7 @@ class _SSLProtocolTransport(transports._FlowControlMixin, # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if not self._closed: warnings.warn("unclosed transport %r" % self, ResourceWarning) diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 75e7c9c..bf3b084 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -13,6 +13,7 @@ import warnings from . import base_events from . import base_subprocess +from . import compat from . import constants from . import coroutines from . import events @@ -370,7 +371,7 @@ class _UnixReadPipeTransport(transports.ReadTransport): # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if self._pipe is not None: warnings.warn("unclosed transport %r" % self, ResourceWarning) @@ -555,7 +556,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin, # On Python 3.3 and older, objects with a destructor part of a reference # cycle are never destroyed. It's not more the case on Python 3.4 thanks # to the PEP 442. - if sys.version_info >= (3, 4): + if compat.PY34: def __del__(self): if self._pipe is not None: warnings.warn("unclosed transport %r" % self, ResourceWarning) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index d54f58a..b1ba72e 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -758,7 +758,7 @@ class Cookie: ): if version is not None: version = int(version) - if expires is not None: expires = int(expires) + if expires is not None: expires = int(float(expires)) if port is None and port_specified is True: raise ValueError("if port is None, port_specified must be false") diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py index 4f7a6de..3869d45 100755 --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -23,16 +23,6 @@ except ImportError: "Your Python may not be configured for Tk. **", file=sys.__stderr__) sys.exit(1) import tkinter.messagebox as tkMessageBox -try: - from tkinter import ttk -except: - root = Tk() - root.withdraw() - tkMessageBox.showerror("Idle Cannot Start", - "Idle now requires the tkinter.ttk module from tcl/tk 8.5+.\n" - + "It found tk %s and no ttk." % TkVersion, - parent=root) - sys.exit(1) from idlelib.EditorWindow import EditorWindow, fixwordbreaks from idlelib.FileList import FileList diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 5b1fcc6..5650be0 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -810,7 +810,7 @@ def main(tests=None, **kwargs): if ns.verbose2 and bad: print("Re-running failed tests in verbose mode") - for test in bad: + for test in bad[:]: print("Re-running test %r in verbose mode" % test) sys.stdout.flush() try: @@ -821,6 +821,13 @@ def main(tests=None, **kwargs): # print a newline separate from the ^C print() break + else: + if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}: + bad.remove(test) + else: + if bad: + print(count(len(bad), 'test'), "failed again:") + printlist(bad) if ns.single: if next_single_test: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index 38f0cee..d138c26 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -417,11 +417,7 @@ class SubprocessMixin: def test_popen_error(self): # Issue #24763: check that the subprocess transport is closed # when BaseSubprocessTransport fails - if sys.platform == 'win32': - target = 'asyncio.windows_utils.Popen' - else: - target = 'subprocess.Popen' - with mock.patch(target) as popen: + with mock.patch('subprocess.Popen') as popen: exc = ZeroDivisionError popen.side_effect = exc diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index e9f0356..50260ff 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -566,6 +566,15 @@ class CookieTests(unittest.TestCase): self.assertEqual(len(c), 1) self.assertIn('spam="bar"', h) + # test if fractional expiry is accepted + cookie = Cookie(0, "name", "value", + None, False, "www.python.org", + True, False, "/", + False, False, "1444312383.018307", + False, None, None, + {}) + self.assertEqual(cookie.expires, 1444312383) + # XXX RFC 2965 expiry rules (some apply to V0 too) def test_default_path(self): diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 2bb21ed..b34007d 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -459,6 +459,14 @@ class CallableTests(TestCase): ctv = Callable[..., str] self.assertEqual(repr(ctv), 'typing.Callable[..., str]') + def test_callable_with_ellipsis(self): + + def foo(a: Callable[..., T]): + pass + + self.assertEqual(get_type_hints(foo, globals(), locals()), + {'a': Callable[..., T]}) + XK = TypeVar('XK', str, bytes) XV = TypeVar('XV') @@ -555,6 +563,14 @@ class GenericTests(TestCase): with self.assertRaises(TypeError): Y[str, bytes] + def test_init(self): + T = TypeVar('T') + S = TypeVar('S') + with self.assertRaises(TypeError): + Generic[T, T] + with self.assertRaises(TypeError): + Generic[T, S, T] + def test_repr(self): self.assertEqual(repr(SimpleMapping), __name__ + '.' + 'SimpleMapping[~XK, ~XV]') @@ -801,6 +817,14 @@ class ForwardRefTests(TestCase): self.assertEqual(get_type_hints(foo, globals(), locals()), {'a': Callable[[T], T]}) + def test_callable_with_ellipsis_forward(self): + + def foo(a: 'Callable[..., T]'): + pass + + self.assertEqual(get_type_hints(foo, globals(), locals()), + {'a': Callable[..., T]}) + def test_syntax_error(self): with self.assertRaises(SyntaxError): diff --git a/Lib/typing.py b/Lib/typing.py index bc6fcdd..ddaec3e 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -128,6 +128,8 @@ class TypingMeta(type): class Final: """Mix-in class to prevent instantiation.""" + __slots__ = () + def __new__(self, *args, **kwds): raise TypeError("Cannot instantiate %r" % self.__class__) @@ -204,6 +206,8 @@ class _TypeAlias: False. """ + __slots__ = ('name', 'type_var', 'impl_type', 'type_checker') + def __new__(cls, *args, **kwds): """Constructor. @@ -341,6 +345,8 @@ class Any(Final, metaclass=AnyMeta, _root=True): - As a special case, Any and object are subclasses of each other. """ + __slots__ = () + class TypeVar(TypingMeta, metaclass=TypingMeta, _root=True): """Type variable. @@ -635,6 +641,8 @@ class Optional(Final, metaclass=OptionalMeta, _root=True): Optional[X] is equivalent to Union[X, type(None)]. """ + __slots__ = () + class TupleMeta(TypingMeta): """Metaclass for Tuple.""" @@ -734,6 +742,8 @@ class Tuple(Final, metaclass=TupleMeta, _root=True): To specify a variable-length tuple of homogeneous type, use Sequence[T]. """ + __slots__ = () + class CallableMeta(TypingMeta): """Metaclass for Callable.""" @@ -767,7 +777,10 @@ class CallableMeta(TypingMeta): def _eval_type(self, globalns, localns): if self.__args__ is None and self.__result__ is None: return self - args = [_eval_type(t, globalns, localns) for t in self.__args__] + if self.__args__ is Ellipsis: + args = self.__args__ + else: + args = [_eval_type(t, globalns, localns) for t in self.__args__] result = _eval_type(self.__result__, globalns, localns) if args == self.__args__ and result == self.__result__: return self @@ -837,6 +850,8 @@ class Callable(Final, metaclass=CallableMeta, _root=True): such function types are rarely used as callback types. """ + __slots__ = () + def _gorg(a): """Return the farthest origin of a generic class.""" @@ -947,6 +962,8 @@ class GenericMeta(TypingMeta, abc.ABCMeta): if not isinstance(p, TypeVar): raise TypeError("Initial parameters must be " "type variables; got %s" % p) + if len(set(params)) != len(params): + raise TypeError("All type variables in Generic[...] must be distinct.") else: if len(params) != len(self.__parameters__): raise TypeError("Cannot change parameter count from %d to %d" % @@ -1039,6 +1056,8 @@ class Generic(metaclass=GenericMeta): # Same body as above. """ + __slots__ = () + def __new__(cls, *args, **kwds): next_in_mro = object # Look for the last occurrence of Generic or Generic[...]. @@ -1205,6 +1224,7 @@ class _ProtocolMeta(GenericMeta): attr != '__abstractmethods__' and attr != '_is_protocol' and attr != '__dict__' and + attr != '__slots__' and attr != '_get_protocol_attrs' and attr != '__parameters__' and attr != '__origin__' and @@ -1222,6 +1242,8 @@ class _Protocol(metaclass=_ProtocolMeta): such as Hashable). """ + __slots__ = () + _is_protocol = True @@ -1232,14 +1254,15 @@ Hashable = collections_abc.Hashable # Not generic. class Iterable(Generic[T_co], extra=collections_abc.Iterable): - pass + __slots__ = () class Iterator(Iterable[T_co], extra=collections_abc.Iterator): - pass + __slots__ = () class SupportsInt(_Protocol): + __slots__ = () @abstractmethod def __int__(self) -> int: @@ -1247,6 +1270,7 @@ class SupportsInt(_Protocol): class SupportsFloat(_Protocol): + __slots__ = () @abstractmethod def __float__(self) -> float: @@ -1254,6 +1278,7 @@ class SupportsFloat(_Protocol): class SupportsComplex(_Protocol): + __slots__ = () @abstractmethod def __complex__(self) -> complex: @@ -1261,30 +1286,34 @@ class SupportsComplex(_Protocol): class SupportsBytes(_Protocol): + __slots__ = () @abstractmethod def __bytes__(self) -> bytes: pass -class SupportsAbs(_Protocol[T]): +class SupportsAbs(_Protocol[T_co]): + __slots__ = () @abstractmethod - def __abs__(self) -> T: + def __abs__(self) -> T_co: pass -class SupportsRound(_Protocol[T]): +class SupportsRound(_Protocol[T_co]): + __slots__ = () @abstractmethod - def __round__(self, ndigits: int = 0) -> T: + def __round__(self, ndigits: int = 0) -> T_co: pass -class Reversible(_Protocol[T]): +class Reversible(_Protocol[T_co]): + __slots__ = () @abstractmethod - def __reversed__(self) -> 'Iterator[T]': + def __reversed__(self) -> 'Iterator[T_co]': pass @@ -1292,7 +1321,7 @@ Sized = collections_abc.Sized # Not generic. class Container(Generic[T_co], extra=collections_abc.Container): - pass + __slots__ = () # Callable was defined earlier. @@ -1308,7 +1337,7 @@ class MutableSet(AbstractSet[T], extra=collections_abc.MutableSet): # NOTE: Only the value type is covariant. -class Mapping(Sized, Iterable[KT], Container[KT], Generic[KT, VT_co], +class Mapping(Sized, Iterable[KT], Container[KT], Generic[VT_co], extra=collections_abc.Mapping): pass @@ -1366,6 +1395,7 @@ class _FrozenSetMeta(GenericMeta): class FrozenSet(frozenset, AbstractSet[T_co], metaclass=_FrozenSetMeta): + __slots__ = () def __new__(cls, *args, **kwds): if _geqv(cls, FrozenSet): @@ -1413,6 +1443,7 @@ else: class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co], extra=_G_base): + __slots__ = () def __new__(cls, *args, **kwds): if _geqv(cls, Generator): @@ -1456,6 +1487,8 @@ class IO(Generic[AnyStr]): way to track the other distinctions in the type system. """ + __slots__ = () + @abstractproperty def mode(self) -> str: pass @@ -1540,6 +1573,8 @@ class IO(Generic[AnyStr]): class BinaryIO(IO[bytes]): """Typed version of the return of open() in binary mode.""" + __slots__ = () + @abstractmethod def write(self, s: Union[bytes, bytearray]) -> int: pass @@ -1552,6 +1587,8 @@ class BinaryIO(IO[bytes]): class TextIO(IO[str]): """Typed version of the return of open() in text mode.""" + __slots__ = () + @abstractproperty def buffer(self) -> BinaryIO: pass diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index eada0a9..a7fd017 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -230,6 +230,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None): return result def urlcleanup(): + """Clean up temporary files from urlretrieve calls.""" for temp_file in _url_tempfiles: try: os.unlink(temp_file) @@ -518,6 +518,7 @@ Duncan Grisby Olivier Grisel Fabian Groffen Eric Groo +Daniel Andrade Groppe Dag Gruneau Filip Gruszczyński Thomas Guettler @@ -860,6 +861,7 @@ Anne Lord Tom Loredo Justin Love Ned Jackson Lovely +Peter Lovett Chalmer Lowe Jason Lowe Tony Lownds @@ -1125,6 +1127,7 @@ Paul Prescod Donovan Preston Paul Price Iuliia Proskurnia +Dorian Pula Jyrki Pulliainen Steve Purcell Eduardo Pérez @@ -13,6 +13,10 @@ Core and Builtins Library ------- +- Issue #23973: Update typing.py from GitHub repo. + +- Issue #23888: Handle fractional time in cookie expiry. Patch by ssh. + - Issue #23652: Make it possible to compile the select module against the libc headers from the Linux Standard Base, which do not include some EPOLL macros. Patch by Matt Frank. @@ -62,11 +66,20 @@ Library Documentation ------------- +- Issue #20769: Improve reload() docs. Patch by Dorian Pula. + - Issue #23589: Remove duplicate sentence from the FAQ. Patch by Yongzhi Pan. - Issue #24729: Correct IO tutorial to match implementation regarding encoding parameter to open function. +Tests +----- + +- Issue #24751: When running regrtest with the ``-w`` command line option, + a test run is no longer marked as a failure if all tests succeed when + re-run. + What's New in Python 3.5.0 beta 4? ================================== diff --git a/Tools/msi/make_zip.py b/Tools/msi/make_zip.py index 521ba93..bace19a 100644 --- a/Tools/msi/make_zip.py +++ b/Tools/msi/make_zip.py @@ -1,4 +1,5 @@ import argparse +import py_compile import re import sys import shutil @@ -82,7 +83,16 @@ def copy_to_layout(target, rel_sources): with ZipFile(str(target), 'w', ZIP_DEFLATED) as f: for s, rel in rel_sources: - f.write(str(s), str(rel)) + if rel.suffix.lower() == '.py': + pyc = Path(tempfile.gettempdir()) / rel.with_suffix('.pyc').name + try: + py_compile.compile(str(s), str(pyc), str(rel), doraise=True, optimize=2) + except py_compile.PyCompileError: + f.write(str(s), str(rel)) + else: + f.write(str(pyc), str(rel.with_suffix('.pyc'))) + else: + f.write(str(s), str(rel)) count += 1 else: diff --git a/Tools/msi/tcltk/tcltk.wixproj b/Tools/msi/tcltk/tcltk.wixproj index f66fc14..e1addd9 100644 --- a/Tools/msi/tcltk/tcltk.wixproj +++ b/Tools/msi/tcltk/tcltk.wixproj @@ -27,6 +27,13 @@ <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> |